summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThorsten Leemhuis <fedora@leemhuis.info>2016-02-27 10:07:03 +0100
committerThorsten Leemhuis <fedora@leemhuis.info>2016-02-27 10:07:03 +0100
commit158fd4b51d7f4f40bab95cc35dd1fefb80926a61 (patch)
tree4dd83dee6ec412b43a527d1735e6fd2c4e5950be
parente5fc472bad9a1c17efcf4e99f38c8818aeaadbc9 (diff)
parentb39d2e1dbbe2fc1b9529b0c5d0aab5860f8210fa (diff)
downloadkernel-158fd4b51d7f4f40bab95cc35dd1fefb80926a61.tar.gz
kernel-158fd4b51d7f4f40bab95cc35dd1fefb80926a61.tar.xz
kernel-158fd4b51d7f4f40bab95cc35dd1fefb80926a61.zip
Merge remote-tracking branch 'origin/f22' into f22-user-thl-vanilla-fedorakernel-4.4.3-200.vanilla.knurd.1.fc22
-rw-r--r--0001-Test-ata-fix.patch27
-rw-r--r--0001-usb-hub-fix-panic-in-usb_reset_and_verify_device.patch30
-rw-r--r--0001-watchdog-omap_wdt-fix-null-pointer-dereference.patch63
-rw-r--r--ARM-dts-Add-am335x-bonegreen.patch103
-rw-r--r--Add-EFI-signature-data-types.patch14
-rw-r--r--Btrfs-fix-fitrim-discarding-device-area-reserved-for.patch119
-rw-r--r--Input-aiptek-fix-crash-on-detecting-device-without-e.patch48
-rw-r--r--Input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch41
-rw-r--r--KEYS-Fix-handling-of-stored-error-in-a-negatively-in.patch125
-rw-r--r--KVM-x86-Reload-pit-counters-for-all-channels-when-re.patch59
-rw-r--r--SCSI-fix-bug-in-scsi_dev_info_list-matching.patch140
-rw-r--r--SCSI-refactor-device-matching-code-in-scsi_devinfo.c.patch183
-rw-r--r--amd-xgbe-a0-Add-support-for-XGBE-on-A0.patch10391
-rw-r--r--amd-xgbe-phy-a0-Add-support-for-XGBE-PHY-on-A0.patch1870
-rw-r--r--arm64-avoid-needing-console-to-enable-serial-console.patch14
-rw-r--r--btrfs-handle-invalid-num_stripes-in-sys_array.patch66
-rw-r--r--config-arm-generic55
-rw-r--r--config-arm6442
-rw-r--r--config-armv734
-rw-r--r--config-armv7-generic67
-rw-r--r--config-debug2
-rw-r--r--config-generic112
-rw-r--r--config-nodebug1
-rw-r--r--config-powerpc64-generic10
-rw-r--r--config-s390x27
-rw-r--r--config-x86-generic23
-rw-r--r--config-x86_64-generic13
-rw-r--r--drm-i915-shut-up-gen8-SDE-irq-dmesg-noise-again.patch68
-rw-r--r--drm-mgag200-fix-kernel-hang-in-cursor-code.patch107
-rw-r--r--drm-nouveau-Fix-pre-nv50-pageflip-events-v4.patch204
-rw-r--r--efi-Add-EFI_SECURE_BOOT-bit.patch16
-rw-r--r--fs-hugetlbfs-inode.c-fix-bugs-in-hugetlb_vmtruncate_.patch86
-rw-r--r--i915-stable-backports.patch1962
-rw-r--r--ideapad-laptop-Add-Lenovo-Yoga-700-to-no_hw_rfkill-d.patch40
-rw-r--r--ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch41
-rw-r--r--iommu-fix.patch92
-rw-r--r--kbuild-AFTER_LINK.patch24
-rw-r--r--kernel.spec185
-rw-r--r--megaraid_sas-Do-not-use-PAGE_SIZE-for-max_sectors.patch50
-rw-r--r--netfilter-ipset-Fix-extension-alignment.patch481
-rw-r--r--netfilter-ipset-Fix-hash-type-expiration.patch30
-rw-r--r--netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch47
-rw-r--r--netfilter-nf_nat_redirect-add-missing-NULL-pointer-c.patch83
-rw-r--r--nouveau-displayoff-fix.patch61
-rw-r--r--nouveau-stable-backports.patch105
-rw-r--r--ovl-fix-permission-checking-for-setattr.patch46
-rw-r--r--ptrace-being-capable-wrt-a-process-requires-mapped-u.patch108
-rw-r--r--rtlwifi-fix-memory-leak-for-USB-device.patch36
-rw-r--r--rtlwifi-rtl8821ae-Fix-5G-failure-when-EEPROM-is-inco.patch55
-rw-r--r--scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch13
-rw-r--r--selinux-fix-bug-in-conditional-rules-handling.patch51
-rw-r--r--sources6
-rw-r--r--unix-correctly-track-in-flight-fds-in-sending-proces.patch159
-rw-r--r--usb-make-xhci-platform-driver-use-64-bit-or-32-bit-D.patch40
-rw-r--r--watchdog-Disable-watchdog-on-virtual-machines.patch12
55 files changed, 770 insertions, 17117 deletions
diff --git a/0001-Test-ata-fix.patch b/0001-Test-ata-fix.patch
new file mode 100644
index 000000000..0ae2cf71e
--- /dev/null
+++ b/0001-Test-ata-fix.patch
@@ -0,0 +1,27 @@
+From bb4d91481dd2122351866e500b46cff9399f579d Mon Sep 17 00:00:00 2001
+From: Laura Abbott <labbott@fedoraproject.org>
+Date: Thu, 25 Feb 2016 11:40:07 -0800
+Subject: [PATCH] Test ata fix
+
+Signed-off-by: Laura Abbott <labbott@fedoraproject.org>
+---
+ drivers/ata/libahci.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
+index 1f225cc..998c6a8 100644
+--- a/drivers/ata/libahci.c
++++ b/drivers/ata/libahci.c
+@@ -1142,8 +1142,7 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
+
+ /* mark esata ports */
+ tmp = readl(port_mmio + PORT_CMD);
+- if ((tmp & PORT_CMD_HPCP) ||
+- ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS)))
++ if ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS))
+ ap->pflags |= ATA_PFLAG_EXTERNAL;
+ }
+
+--
+2.5.0
+
diff --git a/0001-usb-hub-fix-panic-in-usb_reset_and_verify_device.patch b/0001-usb-hub-fix-panic-in-usb_reset_and_verify_device.patch
new file mode 100644
index 000000000..1fa0e0fce
--- /dev/null
+++ b/0001-usb-hub-fix-panic-in-usb_reset_and_verify_device.patch
@@ -0,0 +1,30 @@
+From 07197eb61cfabc153846b1ae9d080a5d6c449d12 Mon Sep 17 00:00:00 2001
+From: "Du, Changbin" <changbin.du@intel.com>
+Date: Mon, 22 Feb 2016 10:08:36 +0800
+Subject: [PATCH] usb: hub: fix panic in usb_reset_and_verify_device
+
+Signed-off-by: Du, Changbin <changbin.du@intel.com>
+---
+ drivers/usb/core/hub.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 350dcd9..045f951 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -5501,8 +5501,10 @@ done:
+ return 0;
+
+ re_enumerate:
+- usb_release_bos_descriptor(udev);
+- udev->bos = bos;
++ if (udev->bos != bos) {
++ usb_release_bos_descriptor(udev);
++ udev->bos = bos;
++ }
+ re_enumerate_no_bos:
+ /* LPM state doesn't matter when we're about to destroy the device. */
+ hub_port_logical_disconnect(parent_hub, port1);
+--
+2.5.0
+
diff --git a/0001-watchdog-omap_wdt-fix-null-pointer-dereference.patch b/0001-watchdog-omap_wdt-fix-null-pointer-dereference.patch
deleted file mode 100644
index 7dab1ff5c..000000000
--- a/0001-watchdog-omap_wdt-fix-null-pointer-dereference.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 721ebb3cf4788107424f92ac2da6cfce20c67297 Mon Sep 17 00:00:00 2001
-From: Peter Robinson <pbrobinson@gmail.com>
-Date: Sun, 1 Nov 2015 23:54:08 +0000
-Subject: [PATCH] watchdog: omap_wdt: fix null pointer dereference
-
-Fix issue from two patches overlapping causing a kernel oops
-
-[ 3569.297449] Unable to handle kernel NULL pointer dereference at virtual address 00000088
-[ 3569.306272] pgd = dc894000
-[ 3569.309287] [00000088] *pgd=00000000
-[ 3569.313104] Internal error: Oops: 5 [#1] SMP ARM
-[ 3569.317986] Modules linked in: ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack ebtable_filter ebtable_nat ebtable_broute bridge stp llc ebtables ip6table_security ip6table_raw ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_filter ip6_tables iptable_security iptable_raw iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle musb_dsps cppi41 musb_hdrc phy_am335x udc_core phy_generic phy_am335x_control omap_sham omap_aes omap_rng omap_hwspinlock omap_mailbox hwspinlock_core musb_am335x omap_wdt at24 8250_omap leds_gpio cpufreq_dt smsc davinci_mdio mmc_block ti_cpsw cpsw_common ptp pps_core cpsw_ale davinci_cpdma omap_hsmmc omap_dma mmc_core i2c_dev
-[ 3569.386293] CPU: 0 PID: 1429 Comm: wdctl Not tainted 4.3.0-0.rc7.git0.1.fc24.armv7hl #1
-[ 3569.394740] Hardware name: Generic AM33XX (Flattened Device Tree)
-[ 3569.401179] task: dbd11a00 ti: dbaac000 task.ti: dbaac000
-[ 3569.406917] PC is at omap_wdt_get_timeleft+0xc/0x20 [omap_wdt]
-[ 3569.413106] LR is at watchdog_ioctl+0x3cc/0x42c
-[ 3569.417902] pc : [<bf0ab138>] lr : [<c0739c54>] psr: 600f0013
-[ 3569.417902] sp : dbaadf18 ip : 00000003 fp : 7f5d3bbe
-[ 3569.430014] r10: 00000000 r9 : 00000003 r8 : bef21ab8
-[ 3569.435535] r7 : dbbc0f7c r6 : dbbc0f18 r5 : bef21ab8 r4 : 00000000
-[ 3569.442427] r3 : 00000000 r2 : 00000000 r1 : 8004570a r0 : dbbc0f18
-[ 3569.449323] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
-[ 3569.456858] Control: 10c5387d Table: 9c894019 DAC: 00000051
-[ 3569.462927] Process wdctl (pid: 1429, stack limit = 0xdbaac220)
-[ 3569.469179] Stack: (0xdbaadf18 to 0xdbaae000)
-[ 3569.473790] df00: bef21ab8 dbf60e38
-[ 3569.482441] df20: dc91b840 8004570a bef21ab8 c03988a4 dbaadf48 dc854000 00000000 dd313850
-[ 3569.491092] df40: ddf033b8 0000570a dc91b80b dbaadf3c dbf60e38 00000020 c0df9250 c0df6c48
-[ 3569.499741] df60: dc91b840 8004570a 00000000 dc91b840 dc91b840 8004570a bef21ab8 00000003
-[ 3569.508389] df80: 00000000 c03989d4 bef21b74 7f5d3bad 00000003 00000036 c020fcc4 dbaac000
-[ 3569.517037] dfa0: 00000000 c020fb00 bef21b74 7f5d3bad 00000003 8004570a bef21ab8 00000001
-[ 3569.525685] dfc0: bef21b74 7f5d3bad 00000003 00000036 00000001 00000000 7f5e4eb0 7f5d3bbe
-[ 3569.534334] dfe0: 7f5e4f10 bef21a3c 7f5d0a54 b6e97e0c a00f0010 00000003 00000000 00000000
-[ 3569.543038] [<bf0ab138>] (omap_wdt_get_timeleft [omap_wdt]) from [<c0739c54>] (watchdog_ioctl+0x3cc/0x42c)
-[ 3569.553266] [<c0739c54>] (watchdog_ioctl) from [<c03988a4>] (do_vfs_ioctl+0x5bc/0x698)
-[ 3569.561648] [<c03988a4>] (do_vfs_ioctl) from [<c03989d4>] (SyS_ioctl+0x54/0x7c)
-[ 3569.569400] [<c03989d4>] (SyS_ioctl) from [<c020fb00>] (ret_fast_syscall+0x0/0x3c)
-[ 3569.577413] Code: e12fff1e e52de004 e8bd4000 e5903060 (e5933088)
-[ 3569.584089] ---[ end trace cec3039bd3ae610a ]---
-
-Cc: <stable@vger.kernel.org> # v4.2+
-Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
----
- drivers/watchdog/omap_wdt.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
-index d96bee0..6f17c93 100644
---- a/drivers/watchdog/omap_wdt.c
-+++ b/drivers/watchdog/omap_wdt.c
-@@ -205,7 +205,7 @@ static int omap_wdt_set_timeout(struct watchdog_device *wdog,
-
- static unsigned int omap_wdt_get_timeleft(struct watchdog_device *wdog)
- {
-- struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog);
-+ struct omap_wdt_dev *wdev = to_omap_wdt_dev(wdog);
- void __iomem *base = wdev->base;
- u32 value;
-
---
-2.5.0
-
diff --git a/ARM-dts-Add-am335x-bonegreen.patch b/ARM-dts-Add-am335x-bonegreen.patch
deleted file mode 100644
index 35fb3e4ef..000000000
--- a/ARM-dts-Add-am335x-bonegreen.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From patchwork Fri Sep 25 15:10:31 2015
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: ARM: dts: Add am335x-bonegreen
-From: Robert Nelson <robertcnelson@gmail.com>
-X-Patchwork-Id: 7265851
-Message-Id: <1443193831-5693-1-git-send-email-robertcnelson@gmail.com>
-To: tony@atomide.com, devicetree@vger.kernel.org
-Cc: linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
- Robert Nelson <robertcnelson@gmail.com>, Jason Kridner <jkridner@gmail.com>
-Date: Fri, 25 Sep 2015 10:10:31 -0500
-
-SeeedStudio BeagleBone Green (BBG) is clone of the BeagleBone Black (BBB) minus
-the HDMI port and addition of two Grove connectors (i2c2 and usart2).
-
-This board can be identified by the 1A value after A335BNLT (BBB) in the at24 eeprom:
-1A: [aa 55 33 ee 41 33 33 35 42 4e 4c 54 1a 00 00 00 |.U3.A335BNLT....|]
-
-http://beagleboard.org/green
-http://www.seeedstudio.com/wiki/Beaglebone_green
-
-Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
-CC: Tony Lindgren <tony@atomide.com>
-CC: Jason Kridner <jkridner@gmail.com>
-
----
-arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/am335x-bonegreen.dts | 53 ++++++++++++++++++++++++++++++++++
- 2 files changed, 54 insertions(+)
- create mode 100644 arch/arm/boot/dts/am335x-bonegreen.dts
-
-diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
-index 233159d..e45d771 100644
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -446,6 +446,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \
- am335x-base0033.dtb \
- am335x-bone.dtb \
- am335x-boneblack.dtb \
-+ am335x-bonegreen.dtb \
- am335x-sl50.dtb \
- am335x-evm.dtb \
- am335x-evmsk.dtb \
-diff --git a/arch/arm/boot/dts/am335x-bonegreen.dts b/arch/arm/boot/dts/am335x-bonegreen.dts
-new file mode 100644
-index 0000000..0f65bda
---- /dev/null
-+++ b/arch/arm/boot/dts/am335x-bonegreen.dts
-@@ -0,0 +1,53 @@
-+/*
-+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+/dts-v1/;
-+
-+#include "am33xx.dtsi"
-+#include "am335x-bone-common.dtsi"
-+
-+/ {
-+ model = "TI AM335x BeagleBone Green";
-+ compatible = "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
-+};
-+
-+&ldo3_reg {
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-always-on;
-+};
-+
-+&mmc1 {
-+ vmmc-supply = <&vmmcsd_fixed>;
-+};
-+
-+&mmc2 {
-+ vmmc-supply = <&vmmcsd_fixed>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&emmc_pins>;
-+ bus-width = <8>;
-+ status = "okay";
-+};
-+
-+&am33xx_pinmux {
-+ uart2_pins: uart2_pins {
-+ pinctrl-single,pins = <
-+ 0x150 (PIN_INPUT | MUX_MODE1) /* spi0_sclk.uart2_rxd */
-+ 0x154 (PIN_OUTPUT | MUX_MODE1) /* spi0_d0.uart2_txd */
-+ >;
-+ };
-+};
-+
-+&uart2 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart2_pins>;
-+ status = "okay";
-+};
-+
-+&rtc {
-+ system-power-controller;
-+};
diff --git a/Add-EFI-signature-data-types.patch b/Add-EFI-signature-data-types.patch
index f24473d44..637f83bd1 100644
--- a/Add-EFI-signature-data-types.patch
+++ b/Add-EFI-signature-data-types.patch
@@ -1,3 +1,4 @@
+From 47f6b5c281137394d627e275cb80980492d00d84 Mon Sep 17 00:00:00 2001
From: Dave Howells <dhowells@redhat.com>
Date: Tue, 23 Oct 2012 09:30:54 -0400
Subject: [PATCH] Add EFI signature data types
@@ -14,12 +15,12 @@ Signed-off-by: David Howells <dhowells@redhat.com>
1 file changed, 20 insertions(+)
diff --git a/include/linux/efi.h b/include/linux/efi.h
-index de3e45088d4a..fac43c611614 100644
+index 4dc970e..82d6218 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
-@@ -595,6 +595,12 @@ void efi_native_runtime_setup(void);
- #define DEVICE_TREE_GUID \
- EFI_GUID( 0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 )
+@@ -599,6 +599,12 @@ void efi_native_runtime_setup(void);
+ #define EFI_PROPERTIES_TABLE_GUID \
+ EFI_GUID( 0x880aaca3, 0x4adc, 0x4a04, 0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5 )
+#define EFI_CERT_SHA256_GUID \
+ EFI_GUID( 0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 )
@@ -30,7 +31,7 @@ index de3e45088d4a..fac43c611614 100644
typedef struct {
efi_guid_t guid;
u64 table;
-@@ -810,6 +816,20 @@ typedef struct _efi_file_io_interface {
+@@ -823,6 +829,20 @@ typedef struct {
#define EFI_INVALID_TABLE_ADDR (~0UL)
@@ -51,3 +52,6 @@ index de3e45088d4a..fac43c611614 100644
/*
* All runtime access to EFI goes through this structure:
*/
+--
+2.5.0
+
diff --git a/Btrfs-fix-fitrim-discarding-device-area-reserved-for.patch b/Btrfs-fix-fitrim-discarding-device-area-reserved-for.patch
deleted file mode 100644
index 63f66fb1b..000000000
--- a/Btrfs-fix-fitrim-discarding-device-area-reserved-for.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 259072b7a1c20f8612dcaa8e0e027004aa98f864 Mon Sep 17 00:00:00 2001
-From: Filipe Manana <fdmanana@suse.com>
-Date: Wed, 6 Jan 2016 22:42:35 +0000
-Subject: [PATCH 2/2] Btrfs: fix fitrim discarding device area reserved for
- boot loader's use
-
-As of the 4.3 kernel release, the fitrim ioctl can now discard any region
-of a disk that is not allocated to any chunk/block group, including the
-first megabyte which is used for our primary superblock and by the boot
-loader (grub for example).
-
-Fix this by not allowing to trim/discard any region in the device starting
-with an offset not greater than min(alloc_start_mount_option, 1Mb), just
-as it was not possible before 4.3.
-
-A reproducer test case for xfstests follows.
-
- seq=`basename $0`
- seqres=$RESULT_DIR/$seq
- echo "QA output created by $seq"
- tmp=/tmp/$$
- status=1 # failure is the default!
- trap "_cleanup; exit \$status" 0 1 2 3 15
-
- _cleanup()
- {
- cd /
- rm -f $tmp.*
- }
-
- # get standard environment, filters and checks
- . ./common/rc
- . ./common/filter
-
- # real QA test starts here
- _need_to_be_root
- _supported_fs btrfs
- _supported_os Linux
- _require_scratch
-
- rm -f $seqres.full
-
- _scratch_mkfs >>$seqres.full 2>&1
-
- # Write to the [0, 64Kb[ and [68Kb, 1Mb[ ranges of the device. These ranges are
- # reserved for a boot loader to use (GRUB for example) and btrfs should never
- # use them - neither for allocating metadata/data nor should trim/discard them.
- # The range [64Kb, 68Kb[ is used for the primary superblock of the filesystem.
- $XFS_IO_PROG -c "pwrite -S 0xfd 0 64K" $SCRATCH_DEV | _filter_xfs_io
- $XFS_IO_PROG -c "pwrite -S 0xfd 68K 956K" $SCRATCH_DEV | _filter_xfs_io
-
- # Now mount the filesystem and perform a fitrim against it.
- _scratch_mount
- _require_batched_discard $SCRATCH_MNT
- $FSTRIM_PROG $SCRATCH_MNT
-
- # Now unmount the filesystem and verify the content of the ranges was not
- # modified (no trim/discard happened on them).
- _scratch_unmount
- echo "Content of the ranges [0, 64Kb] and [68Kb, 1Mb[ after fitrim:"
- od -t x1 -N $((64 * 1024)) $SCRATCH_DEV
- od -t x1 -j $((68 * 1024)) -N $((956 * 1024)) $SCRATCH_DEV
-
- status=0
- exit
-
-Reported-by: Vincent Petry <PVince81@yahoo.fr>
-Reported-by: Andrei Borzenkov <arvidjaar@gmail.com>
-Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=109341
-Fixes: 499f377f49f0 (btrfs: iterate over unused chunk space in FITRIM)
-Cc: stable@vger.kernel.org # 4.3+
-Signed-off-by: Filipe Manana <fdmanana@suse.com>
----
- fs/btrfs/volumes.c | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
-diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
-index b816b3a2e118..96f8c827d563 100644
---- a/fs/btrfs/volumes.c
-+++ b/fs/btrfs/volumes.c
-@@ -1208,6 +1208,15 @@ int find_free_dev_extent_start(struct btrfs_transaction *transaction,
- int ret;
- int slot;
- struct extent_buffer *l;
-+ u64 min_search_start;
-+
-+ /*
-+ * We don't want to overwrite the superblock on the drive nor any area
-+ * used by the boot loader (grub for example), so we make sure to start
-+ * at an offset of at least 1MB.
-+ */
-+ min_search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
-+ search_start = max(search_start, min_search_start);
-
- path = btrfs_alloc_path();
- if (!path)
-@@ -1348,18 +1357,9 @@ int find_free_dev_extent(struct btrfs_trans_handle *trans,
- struct btrfs_device *device, u64 num_bytes,
- u64 *start, u64 *len)
- {
-- struct btrfs_root *root = device->dev_root;
-- u64 search_start;
--
- /* FIXME use last free of some kind */
--
-- /*
-- * we don't want to overwrite the superblock on the drive,
-- * so we make sure to start at an offset of at least 1MB
-- */
-- search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
- return find_free_dev_extent_start(trans->transaction, device,
-- num_bytes, search_start, start, len);
-+ num_bytes, 0, start, len);
- }
-
- static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
---
-2.5.0
-
diff --git a/Input-aiptek-fix-crash-on-detecting-device-without-e.patch b/Input-aiptek-fix-crash-on-detecting-device-without-e.patch
deleted file mode 100644
index 19dbaa343..000000000
--- a/Input-aiptek-fix-crash-on-detecting-device-without-e.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From a0edc539fda3f0a4a271f47a0fcf79d1305c1444 Mon Sep 17 00:00:00 2001
-From: Vladis Dronov <vdronov@redhat.com>
-Date: Wed, 25 Nov 2015 16:31:35 +0100
-Subject: [PATCH] Input: aiptek: fix crash on detecting device without
- endpoints
-
-The aiptek driver crashes in aiptek_probe() when a specially crafted usb device
-without endpoints is detected. This fix adds a check that the device has proper
-configuration expected by the driver. Also an error return value is changed to
-more matching one in one of the error paths.
-
-Reported-by: Ralf Spenneberg <ralf@spenneberg.net>
-Signed-off-by: Vladis Dronov <vdronov@redhat.com>
----
- drivers/input/tablet/aiptek.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
-index e7f966da6efa..78c0732fbb57 100644
---- a/drivers/input/tablet/aiptek.c
-+++ b/drivers/input/tablet/aiptek.c
-@@ -1819,6 +1819,15 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
- input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
- input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
-
-+ /* Verify that a device really has an endpoint
-+ */
-+ if (intf->altsetting[0].desc.bNumEndpoints < 1) {
-+ dev_warn(&intf->dev,
-+ "interface has %d endpoints, but must have minimum 1\n",
-+ intf->altsetting[0].desc.bNumEndpoints);
-+ err = -ENODEV;
-+ goto fail3;
-+ }
- endpoint = &intf->altsetting[0].endpoint[0].desc;
-
- /* Go set up our URB, which is called when the tablet receives
-@@ -1861,6 +1870,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
- if (i == ARRAY_SIZE(speeds)) {
- dev_info(&intf->dev,
- "Aiptek tried all speeds, no sane response\n");
-+ err = -ENODEV;
- goto fail3;
- }
-
---
-2.5.0
-
diff --git a/Input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch b/Input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch
deleted file mode 100644
index c02a0f53b..000000000
--- a/Input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 6544a1df11c48c8413071aac3316792e4678fbfb Mon Sep 17 00:00:00 2001
-From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
-Date: Mon, 11 Jan 2016 17:35:38 -0800
-Subject: [PATCH] Input: elantech - mark protocols v2 and v3 as semi-mt
-
-When using a protocol v2 or v3 hardware, elantech uses the function
-elantech_report_semi_mt_data() to report data. This devices are rather
-creepy because if num_finger is 3, (x2,y2) is (0,0). Yes, only one valid
-touch is reported.
-
-Anyway, userspace (libinput) is now confused by these (0,0) touches,
-and detect them as palm, and rejects them.
-
-Commit 3c0213d17a09 ("Input: elantech - fix semi-mt protocol for v3 HW")
-was sufficient enough for xf86-input-synaptics and libinput before it has
-palm rejection. Now we need to actually tell libinput that this device is
-a semi-mt one and it should not rely on the actual values of the 2 touches.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
-Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
----
- drivers/input/mouse/elantech.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
-index 537ebb0e193a..78f93cf68840 100644
---- a/drivers/input/mouse/elantech.c
-+++ b/drivers/input/mouse/elantech.c
-@@ -1222,7 +1222,7 @@ static int elantech_set_input_params(struct psmouse *psmouse)
- input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2,
- ETP_WMAX_V2, 0, 0);
- }
-- input_mt_init_slots(dev, 2, 0);
-+ input_mt_init_slots(dev, 2, INPUT_MT_SEMI_MT);
- input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
- input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
- break;
---
-2.5.0
-
diff --git a/KEYS-Fix-handling-of-stored-error-in-a-negatively-in.patch b/KEYS-Fix-handling-of-stored-error-in-a-negatively-in.patch
deleted file mode 100644
index 3837037e8..000000000
--- a/KEYS-Fix-handling-of-stored-error-in-a-negatively-in.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 3b34bea74e636583d34c8e472237a0bea1e3ba93 Mon Sep 17 00:00:00 2001
-From: David Howells <dhowells@redhat.com>
-Date: Tue, 24 Nov 2015 21:36:31 +0000
-Subject: [PATCH] KEYS: Fix handling of stored error in a negatively
- instantiated user key
-
-If a user key gets negatively instantiated, an error code is cached in the
-payload area. A negatively instantiated key may be then be positively
-instantiated by updating it with valid data. However, the ->update key
-type method must be aware that the error code may be there.
-
-The following may be used to trigger the bug in the user key type:
-
- keyctl request2 user user "" @u
- keyctl add user user "a" @u
-
-which manifests itself as:
-
- BUG: unable to handle kernel paging request at 00000000ffffff8a
- IP: [<ffffffff810a376f>] __call_rcu.constprop.76+0x1f/0x280 kernel/rcu/tree.c:3046
- PGD 7cc30067 PUD 0
- Oops: 0002 [#1] SMP
- Modules linked in:
- CPU: 3 PID: 2644 Comm: a.out Not tainted 4.3.0+ #49
- Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
- task: ffff88003ddea700 ti: ffff88003dd88000 task.ti: ffff88003dd88000
- RIP: 0010:[<ffffffff810a376f>] [<ffffffff810a376f>] __call_rcu.constprop.76+0x1f/0x280
- [<ffffffff810a376f>] __call_rcu.constprop.76+0x1f/0x280 kernel/rcu/tree.c:3046
- RSP: 0018:ffff88003dd8bdb0 EFLAGS: 00010246
- RAX: 00000000ffffff82 RBX: 0000000000000000 RCX: 0000000000000001
- RDX: ffffffff81e3fe40 RSI: 0000000000000000 RDI: 00000000ffffff82
- RBP: ffff88003dd8bde0 R08: ffff88007d2d2da0 R09: 0000000000000000
- R10: 0000000000000000 R11: ffff88003e8073c0 R12: 00000000ffffff82
- R13: ffff88003dd8be68 R14: ffff88007d027600 R15: ffff88003ddea700
- FS: 0000000000b92880(0063) GS:ffff88007fd00000(0000) knlGS:0000000000000000
- CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
- CR2: 00000000ffffff8a CR3: 000000007cc5f000 CR4: 00000000000006e0
- Stack:
- ffff88003dd8bdf0 ffffffff81160a8a 0000000000000000 00000000ffffff82
- ffff88003dd8be68 ffff88007d027600 ffff88003dd8bdf0 ffffffff810a39e5
- ffff88003dd8be20 ffffffff812a31ab ffff88007d027600 ffff88007d027620
- Call Trace:
- [<ffffffff810a39e5>] kfree_call_rcu+0x15/0x20 kernel/rcu/tree.c:3136
- [<ffffffff812a31ab>] user_update+0x8b/0xb0 security/keys/user_defined.c:129
- [< inline >] __key_update security/keys/key.c:730
- [<ffffffff8129e5c1>] key_create_or_update+0x291/0x440 security/keys/key.c:908
- [< inline >] SYSC_add_key security/keys/keyctl.c:125
- [<ffffffff8129fc21>] SyS_add_key+0x101/0x1e0 security/keys/keyctl.c:60
- [<ffffffff8185f617>] entry_SYSCALL_64_fastpath+0x12/0x6a arch/x86/entry/entry_64.S:185
-
-Note the error code (-ENOKEY) in EDX.
-
-A similar bug can be tripped by:
-
- keyctl request2 trusted user "" @u
- keyctl add trusted user "a" @u
-
-This should also affect encrypted keys - but that has to be correctly
-parameterised or it will fail with EINVAL before getting to the bit that
-will crashes.
-
-Reported-by: Dmitry Vyukov <dvyukov@google.com>
-Signed-off-by: David Howells <dhowells@redhat.com>
-Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
-Signed-off-by: James Morris <james.l.morris@oracle.com>
----
- security/keys/encrypted-keys/encrypted.c | 2 ++
- security/keys/trusted.c | 5 ++++-
- security/keys/user_defined.c | 5 ++++-
- 3 files changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
-index 7bed4ad7cd76..0a374a2ce030 100644
---- a/security/keys/encrypted-keys/encrypted.c
-+++ b/security/keys/encrypted-keys/encrypted.c
-@@ -845,6 +845,8 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
- size_t datalen = prep->datalen;
- int ret = 0;
-
-+ if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
-+ return -ENOKEY;
- if (datalen <= 0 || datalen > 32767 || !prep->data)
- return -EINVAL;
-
-diff --git a/security/keys/trusted.c b/security/keys/trusted.c
-index c0594cb07ada..aeb38f1a12e7 100644
---- a/security/keys/trusted.c
-+++ b/security/keys/trusted.c
-@@ -984,13 +984,16 @@ static void trusted_rcu_free(struct rcu_head *rcu)
- */
- static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
- {
-- struct trusted_key_payload *p = key->payload.data;
-+ struct trusted_key_payload *p;
- struct trusted_key_payload *new_p;
- struct trusted_key_options *new_o;
- size_t datalen = prep->datalen;
- char *datablob;
- int ret = 0;
-
-+ if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
-+ return -ENOKEY;
-+ p = key->payload.data;
- if (!p->migratable)
- return -EPERM;
- if (datalen <= 0 || datalen > 32767 || !prep->data)
-diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
-index 36b47bbd3d8c..7cf22260bdff 100644
---- a/security/keys/user_defined.c
-+++ b/security/keys/user_defined.c
-@@ -120,7 +120,10 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
-
- if (ret == 0) {
- /* attach the new data, displacing the old */
-- zap = key->payload.data;
-+ if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
-+ zap = key->payload.data;
-+ else
-+ zap = NULL;
- rcu_assign_keypointer(key, upayload);
- key->expiry = 0;
- }
---
-2.5.0
-
diff --git a/KVM-x86-Reload-pit-counters-for-all-channels-when-re.patch b/KVM-x86-Reload-pit-counters-for-all-channels-when-re.patch
deleted file mode 100644
index a9d88a009..000000000
--- a/KVM-x86-Reload-pit-counters-for-all-channels-when-re.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From f3b9db45027a40369fe13c4661c4249d1df8c8d0 Mon Sep 17 00:00:00 2001
-From: Andrew Honig <ahonig@google.com>
-Date: Wed, 18 Nov 2015 14:50:23 -0800
-Subject: [PATCH] KVM: x86: Reload pit counters for all channels when restoring
- state
-
-Currently if userspace restores the pit counters with a count of 0
-on channels 1 or 2 and the guest attempts to read the count on those
-channels, then KVM will perform a mod of 0 and crash. This will ensure
-that 0 values are converted to 65536 as per the spec.
-
-This is CVE-2015-7513.
-
-Signed-off-by: Andy Honig <ahonig@google.com>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-[Backported to 4.3.y by Josh Boyer <jwboyer@fedoraproject.org>]
----
- arch/x86/kvm/x86.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
-index 43609af03283..e124f9c8391e 100644
---- a/arch/x86/kvm/x86.c
-+++ b/arch/x86/kvm/x86.c
-@@ -3437,10 +3437,11 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
- static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
- {
- int r = 0;
--
-+ int i;
- mutex_lock(&kvm->arch.vpit->pit_state.lock);
- memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state));
-- kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0);
-+ for (i = 0; i < 3; i++)
-+ kvm_pit_load_count(kvm, i, ps->channels[i].count, 0);
- mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- return r;
- }
-@@ -3461,6 +3462,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
- static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
- {
- int r = 0, start = 0;
-+ int i;
- u32 prev_legacy, cur_legacy;
- mutex_lock(&kvm->arch.vpit->pit_state.lock);
- prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
-@@ -3470,7 +3472,8 @@ static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
- memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels,
- sizeof(kvm->arch.vpit->pit_state.channels));
- kvm->arch.vpit->pit_state.flags = ps->flags;
-- kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start);
-+ for (i = 0; i < 3; i++)
-+ kvm_pit_load_count(kvm, i, kvm->arch.vpit->pit_state.channels[i].count, start);
- mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- return r;
- }
---
-2.5.0
-
diff --git a/SCSI-fix-bug-in-scsi_dev_info_list-matching.patch b/SCSI-fix-bug-in-scsi_dev_info_list-matching.patch
deleted file mode 100644
index d79ccf923..000000000
--- a/SCSI-fix-bug-in-scsi_dev_info_list-matching.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-From 4abc12dd59bed74aa1730c2b3129d1750604d530 Mon Sep 17 00:00:00 2001
-From: Alan Stern <stern@rowland.harvard.edu>
-Date: Mon, 3 Aug 2015 11:57:29 -0400
-Subject: [PATCH 2/2] SCSI: fix bug in scsi_dev_info_list matching
-
-The "compatible" matching algorithm used for looking up old-style
-blacklist entries in a scsi_dev_info_list is buggy. The core of the
-algorithm looks like this:
-
- if (memcmp(devinfo->vendor, vendor,
- min(max, strlen(devinfo->vendor))))
- /* not a match */
-
-where max is the length of the device's vendor string after leading
-spaces have been removed but trailing spaces have not. Because of the
-min() computation, either entry could be a proper substring of the
-other and the code would still think that they match.
-
-In the case originally reported, the device's vendor and product
-strings were "Inateck " and " ". These matched against
-the following entry in the global device list:
-
- {"", "Scanner", "1.80", BLIST_NOLUN}
-
-because "" is a substring of "Inateck " and "" (the result of removing
-leading spaces from the device's product string) is a substring of
-"Scanner". The mistaken match prevented the system from scanning and
-finding the device's second Logical Unit.
-
-This patch fixes the problem by making two changes. First, the code
-for leading-space removal is hoisted out of the loop. (This means it
-will sometimes run unnecessarily, but since a large percentage of all
-lookups involve the "compatible" entries in global device list, this
-should be an overall improvement.) Second and more importantly, the
-patch removes trailing spaces and adds a check to verify that the two
-resulting strings are exactly the same length. This prevents matches
-where one entry is a proper substring of the other.
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Reported-by: Giulio Bernardi <ugilio@gmail.com>
-Tested-by: Giulio Bernardi <ugilio@gmail.com>
-Signed-off-by: James Bottomley <JBottomley@Odin.com>
----
- drivers/scsi/scsi_devinfo.c | 69 +++++++++++++++++++++++----------------------
- 1 file changed, 35 insertions(+), 34 deletions(-)
-
-diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
-index 2f49a224462d..2c1160c7ec92 100644
---- a/drivers/scsi/scsi_devinfo.c
-+++ b/drivers/scsi/scsi_devinfo.c
-@@ -407,51 +407,52 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
- struct scsi_dev_info_list *devinfo;
- struct scsi_dev_info_list_table *devinfo_table =
- scsi_devinfo_lookup_by_key(key);
-+ size_t vmax, mmax;
-+ const char *vskip, *mskip;
-
- if (IS_ERR(devinfo_table))
- return (struct scsi_dev_info_list *) devinfo_table;
-
-+ /* Prepare for "compatible" matches */
-+
-+ /*
-+ * XXX why skip leading spaces? If an odd INQUIRY
-+ * value, that should have been part of the
-+ * scsi_static_device_list[] entry, such as " FOO"
-+ * rather than "FOO". Since this code is already
-+ * here, and we don't know what device it is
-+ * trying to work with, leave it as-is.
-+ */
-+ vmax = 8; /* max length of vendor */
-+ vskip = vendor;
-+ while (vmax > 0 && *vskip == ' ') {
-+ vmax--;
-+ vskip++;
-+ }
-+ /* Also skip trailing spaces */
-+ while (vmax > 0 && vskip[vmax - 1] == ' ')
-+ --vmax;
-+
-+ mmax = 16; /* max length of model */
-+ mskip = model;
-+ while (mmax > 0 && *mskip == ' ') {
-+ mmax--;
-+ mskip++;
-+ }
-+ while (mmax > 0 && mskip[mmax - 1] == ' ')
-+ --mmax;
-+
- list_for_each_entry(devinfo, &devinfo_table->scsi_dev_info_list,
- dev_info_list) {
- if (devinfo->compatible) {
- /*
- * Behave like the older version of get_device_flags.
- */
-- size_t max;
-- /*
-- * XXX why skip leading spaces? If an odd INQUIRY
-- * value, that should have been part of the
-- * scsi_static_device_list[] entry, such as " FOO"
-- * rather than "FOO". Since this code is already
-- * here, and we don't know what device it is
-- * trying to work with, leave it as-is.
-- */
-- max = 8; /* max length of vendor */
-- while ((max > 0) && *vendor == ' ') {
-- max--;
-- vendor++;
-- }
-- /*
-- * XXX removing the following strlen() would be
-- * good, using it means that for a an entry not in
-- * the list, we scan every byte of every vendor
-- * listed in scsi_static_device_list[], and never match
-- * a single one (and still have to compare at
-- * least the first byte of each vendor).
-- */
-- if (memcmp(devinfo->vendor, vendor,
-- min(max, strlen(devinfo->vendor))))
-+ if (memcmp(devinfo->vendor, vskip, vmax) ||
-+ devinfo->vendor[vmax])
- continue;
-- /*
-- * Skip spaces again.
-- */
-- max = 16; /* max length of model */
-- while ((max > 0) && *model == ' ') {
-- max--;
-- model++;
-- }
-- if (memcmp(devinfo->model, model,
-- min(max, strlen(devinfo->model))))
-+ if (memcmp(devinfo->model, mskip, mmax) ||
-+ devinfo->model[mmax])
- continue;
- return devinfo;
- } else {
---
-2.5.0
-
diff --git a/SCSI-refactor-device-matching-code-in-scsi_devinfo.c.patch b/SCSI-refactor-device-matching-code-in-scsi_devinfo.c.patch
deleted file mode 100644
index e87baad50..000000000
--- a/SCSI-refactor-device-matching-code-in-scsi_devinfo.c.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-From 26d61e8347b27a981d647d3ea4ec8c7f462c1fcf Mon Sep 17 00:00:00 2001
-From: Alan Stern <stern@rowland.harvard.edu>
-Date: Mon, 3 Aug 2015 11:57:21 -0400
-Subject: [PATCH 1/2] SCSI: refactor device-matching code in scsi_devinfo.c
-
-In drivers/scsi/scsi_devinfo.c, the scsi_dev_info_list_del_keyed() and
-scsi_get_device_flags_keyed() routines contain a large amount of
-duplicate code for finding vendor/product matches in a
-scsi_dev_info_list. This patch factors out the duplicate code and
-puts it in a separate function, scsi_dev_info_list_find().
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Suggested-by: Giulio Bernardi <ugilio@gmail.com>
-Signed-off-by: James Bottomley <JBottomley@Odin.com>
----
- drivers/scsi/scsi_devinfo.c | 112 ++++++++++++++++----------------------------
- 1 file changed, 41 insertions(+), 71 deletions(-)
-
-diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
-index 9f77d23239a2..2f49a224462d 100644
---- a/drivers/scsi/scsi_devinfo.c
-+++ b/drivers/scsi/scsi_devinfo.c
-@@ -390,25 +390,26 @@ int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model,
- EXPORT_SYMBOL(scsi_dev_info_list_add_keyed);
-
- /**
-- * scsi_dev_info_list_del_keyed - remove one dev_info list entry.
-+ * scsi_dev_info_list_find - find a matching dev_info list entry.
- * @vendor: vendor string
- * @model: model (product) string
- * @key: specify list to use
- *
- * Description:
-- * Remove and destroy one dev_info entry for @vendor, @model
-+ * Finds the first dev_info entry matching @vendor, @model
- * in list specified by @key.
- *
-- * Returns: 0 OK, -error on failure.
-+ * Returns: pointer to matching entry, or ERR_PTR on failure.
- **/
--int scsi_dev_info_list_del_keyed(char *vendor, char *model, int key)
-+static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
-+ const char *model, int key)
- {
-- struct scsi_dev_info_list *devinfo, *found = NULL;
-+ struct scsi_dev_info_list *devinfo;
- struct scsi_dev_info_list_table *devinfo_table =
- scsi_devinfo_lookup_by_key(key);
-
- if (IS_ERR(devinfo_table))
-- return PTR_ERR(devinfo_table);
-+ return (struct scsi_dev_info_list *) devinfo_table;
-
- list_for_each_entry(devinfo, &devinfo_table->scsi_dev_info_list,
- dev_info_list) {
-@@ -452,25 +453,42 @@ int scsi_dev_info_list_del_keyed(char *vendor, char *model, int key)
- if (memcmp(devinfo->model, model,
- min(max, strlen(devinfo->model))))
- continue;
-- found = devinfo;
-+ return devinfo;
- } else {
- if (!memcmp(devinfo->vendor, vendor,
- sizeof(devinfo->vendor)) &&
- !memcmp(devinfo->model, model,
- sizeof(devinfo->model)))
-- found = devinfo;
-+ return devinfo;
- }
-- if (found)
-- break;
- }
-
-- if (found) {
-- list_del(&found->dev_info_list);
-- kfree(found);
-- return 0;
-- }
-+ return ERR_PTR(-ENOENT);
-+}
-+
-+/**
-+ * scsi_dev_info_list_del_keyed - remove one dev_info list entry.
-+ * @vendor: vendor string
-+ * @model: model (product) string
-+ * @key: specify list to use
-+ *
-+ * Description:
-+ * Remove and destroy one dev_info entry for @vendor, @model
-+ * in list specified by @key.
-+ *
-+ * Returns: 0 OK, -error on failure.
-+ **/
-+int scsi_dev_info_list_del_keyed(char *vendor, char *model, int key)
-+{
-+ struct scsi_dev_info_list *found;
-
-- return -ENOENT;
-+ found = scsi_dev_info_list_find(vendor, model, key);
-+ if (IS_ERR(found))
-+ return PTR_ERR(found);
-+
-+ list_del(&found->dev_info_list);
-+ kfree(found);
-+ return 0;
- }
- EXPORT_SYMBOL(scsi_dev_info_list_del_keyed);
-
-@@ -565,64 +583,16 @@ int scsi_get_device_flags_keyed(struct scsi_device *sdev,
- int key)
- {
- struct scsi_dev_info_list *devinfo;
-- struct scsi_dev_info_list_table *devinfo_table;
-+ int err;
-
-- devinfo_table = scsi_devinfo_lookup_by_key(key);
-+ devinfo = scsi_dev_info_list_find(vendor, model, key);
-+ if (!IS_ERR(devinfo))
-+ return devinfo->flags;
-
-- if (IS_ERR(devinfo_table))
-- return PTR_ERR(devinfo_table);
-+ err = PTR_ERR(devinfo);
-+ if (err != -ENOENT)
-+ return err;
-
-- list_for_each_entry(devinfo, &devinfo_table->scsi_dev_info_list,
-- dev_info_list) {
-- if (devinfo->compatible) {
-- /*
-- * Behave like the older version of get_device_flags.
-- */
-- size_t max;
-- /*
-- * XXX why skip leading spaces? If an odd INQUIRY
-- * value, that should have been part of the
-- * scsi_static_device_list[] entry, such as " FOO"
-- * rather than "FOO". Since this code is already
-- * here, and we don't know what device it is
-- * trying to work with, leave it as-is.
-- */
-- max = 8; /* max length of vendor */
-- while ((max > 0) && *vendor == ' ') {
-- max--;
-- vendor++;
-- }
-- /*
-- * XXX removing the following strlen() would be
-- * good, using it means that for a an entry not in
-- * the list, we scan every byte of every vendor
-- * listed in scsi_static_device_list[], and never match
-- * a single one (and still have to compare at
-- * least the first byte of each vendor).
-- */
-- if (memcmp(devinfo->vendor, vendor,
-- min(max, strlen(devinfo->vendor))))
-- continue;
-- /*
-- * Skip spaces again.
-- */
-- max = 16; /* max length of model */
-- while ((max > 0) && *model == ' ') {
-- max--;
-- model++;
-- }
-- if (memcmp(devinfo->model, model,
-- min(max, strlen(devinfo->model))))
-- continue;
-- return devinfo->flags;
-- } else {
-- if (!memcmp(devinfo->vendor, vendor,
-- sizeof(devinfo->vendor)) &&
-- !memcmp(devinfo->model, model,
-- sizeof(devinfo->model)))
-- return devinfo->flags;
-- }
-- }
- /* nothing found, return nothing */
- if (key != SCSI_DEVINFO_GLOBAL)
- return 0;
---
-2.5.0
-
diff --git a/amd-xgbe-a0-Add-support-for-XGBE-on-A0.patch b/amd-xgbe-a0-Add-support-for-XGBE-on-A0.patch
deleted file mode 100644
index 6b9d07dc7..000000000
--- a/amd-xgbe-a0-Add-support-for-XGBE-on-A0.patch
+++ /dev/null
@@ -1,10391 +0,0 @@
-From b634bc924371a7df6459af04f37c91f65ac59df2 Mon Sep 17 00:00:00 2001
-From: Tom Lendacky <thomas.lendacky@amd.com>
-Date: Thu, 28 May 2015 16:38:57 -0400
-Subject: [PATCH 1/2] amd-xgbe-a0: Add support for XGBE on A0
-
-Add XGBE driver support for A0 hardware.
-
-Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
-[fixup timespec -> timespec64]
-[use device_dma_is_coherent]
-Signed-off-by: Mark Salter <msalter@redhat.com>
----
- drivers/net/ethernet/amd/Makefile | 1 +
- drivers/net/ethernet/amd/xgbe-a0/Makefile | 8 +
- drivers/net/ethernet/amd/xgbe-a0/xgbe-common.h | 1142 +++++++++
- drivers/net/ethernet/amd/xgbe-a0/xgbe-dcb.c | 269 +++
- drivers/net/ethernet/amd/xgbe-a0/xgbe-debugfs.c | 373 +++
- drivers/net/ethernet/amd/xgbe-a0/xgbe-desc.c | 636 +++++
- drivers/net/ethernet/amd/xgbe-a0/xgbe-dev.c | 2930 +++++++++++++++++++++++
- drivers/net/ethernet/amd/xgbe-a0/xgbe-drv.c | 2218 +++++++++++++++++
- drivers/net/ethernet/amd/xgbe-a0/xgbe-ethtool.c | 616 +++++
- drivers/net/ethernet/amd/xgbe-a0/xgbe-main.c | 618 +++++
- drivers/net/ethernet/amd/xgbe-a0/xgbe-mdio.c | 312 +++
- drivers/net/ethernet/amd/xgbe-a0/xgbe-ptp.c | 278 +++
- drivers/net/ethernet/amd/xgbe-a0/xgbe.h | 868 +++++++
- 13 files changed, 10269 insertions(+)
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/Makefile
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-common.h
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-dcb.c
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-debugfs.c
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-desc.c
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-dev.c
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-drv.c
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-ethtool.c
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-main.c
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-mdio.c
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe-ptp.c
- create mode 100644 drivers/net/ethernet/amd/xgbe-a0/xgbe.h
-
-diff --git a/drivers/net/ethernet/amd/Makefile b/drivers/net/ethernet/amd/Makefile
-index a38a2dc..bf0cf2f 100644
---- a/drivers/net/ethernet/amd/Makefile
-+++ b/drivers/net/ethernet/amd/Makefile
-@@ -18,3 +18,4 @@ obj-$(CONFIG_PCNET32) += pcnet32.o
- obj-$(CONFIG_SUN3LANCE) += sun3lance.o
- obj-$(CONFIG_SUNLANCE) += sunlance.o
- obj-$(CONFIG_AMD_XGBE) += xgbe/
-+obj-$(CONFIG_AMD_XGBE) += xgbe-a0/
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/Makefile b/drivers/net/ethernet/amd/xgbe-a0/Makefile
-new file mode 100644
-index 0000000..561116f
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/Makefile
-@@ -0,0 +1,8 @@
-+obj-$(CONFIG_AMD_XGBE) += amd-xgbe-a0.o
-+
-+amd-xgbe-a0-objs := xgbe-main.o xgbe-drv.o xgbe-dev.o \
-+ xgbe-desc.o xgbe-ethtool.o xgbe-mdio.o \
-+ xgbe-ptp.o
-+
-+amd-xgbe-a0-$(CONFIG_AMD_XGBE_DCB) += xgbe-dcb.o
-+amd-xgbe-a0-$(CONFIG_DEBUG_FS) += xgbe-debugfs.o
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-common.h b/drivers/net/ethernet/amd/xgbe-a0/xgbe-common.h
-new file mode 100644
-index 0000000..75b08c6
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-common.h
-@@ -0,0 +1,1142 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#ifndef __XGBE_COMMON_H__
-+#define __XGBE_COMMON_H__
-+
-+/* DMA register offsets */
-+#define DMA_MR 0x3000
-+#define DMA_SBMR 0x3004
-+#define DMA_ISR 0x3008
-+#define DMA_AXIARCR 0x3010
-+#define DMA_AXIAWCR 0x3018
-+#define DMA_DSR0 0x3020
-+#define DMA_DSR1 0x3024
-+
-+/* DMA register entry bit positions and sizes */
-+#define DMA_AXIARCR_DRC_INDEX 0
-+#define DMA_AXIARCR_DRC_WIDTH 4
-+#define DMA_AXIARCR_DRD_INDEX 4
-+#define DMA_AXIARCR_DRD_WIDTH 2
-+#define DMA_AXIARCR_TEC_INDEX 8
-+#define DMA_AXIARCR_TEC_WIDTH 4
-+#define DMA_AXIARCR_TED_INDEX 12
-+#define DMA_AXIARCR_TED_WIDTH 2
-+#define DMA_AXIARCR_THC_INDEX 16
-+#define DMA_AXIARCR_THC_WIDTH 4
-+#define DMA_AXIARCR_THD_INDEX 20
-+#define DMA_AXIARCR_THD_WIDTH 2
-+#define DMA_AXIAWCR_DWC_INDEX 0
-+#define DMA_AXIAWCR_DWC_WIDTH 4
-+#define DMA_AXIAWCR_DWD_INDEX 4
-+#define DMA_AXIAWCR_DWD_WIDTH 2
-+#define DMA_AXIAWCR_RPC_INDEX 8
-+#define DMA_AXIAWCR_RPC_WIDTH 4
-+#define DMA_AXIAWCR_RPD_INDEX 12
-+#define DMA_AXIAWCR_RPD_WIDTH 2
-+#define DMA_AXIAWCR_RHC_INDEX 16
-+#define DMA_AXIAWCR_RHC_WIDTH 4
-+#define DMA_AXIAWCR_RHD_INDEX 20
-+#define DMA_AXIAWCR_RHD_WIDTH 2
-+#define DMA_AXIAWCR_TDC_INDEX 24
-+#define DMA_AXIAWCR_TDC_WIDTH 4
-+#define DMA_AXIAWCR_TDD_INDEX 28
-+#define DMA_AXIAWCR_TDD_WIDTH 2
-+#define DMA_ISR_MACIS_INDEX 17
-+#define DMA_ISR_MACIS_WIDTH 1
-+#define DMA_ISR_MTLIS_INDEX 16
-+#define DMA_ISR_MTLIS_WIDTH 1
-+#define DMA_MR_SWR_INDEX 0
-+#define DMA_MR_SWR_WIDTH 1
-+#define DMA_SBMR_EAME_INDEX 11
-+#define DMA_SBMR_EAME_WIDTH 1
-+#define DMA_SBMR_BLEN_256_INDEX 7
-+#define DMA_SBMR_BLEN_256_WIDTH 1
-+#define DMA_SBMR_UNDEF_INDEX 0
-+#define DMA_SBMR_UNDEF_WIDTH 1
-+
-+/* DMA register values */
-+#define DMA_DSR_RPS_WIDTH 4
-+#define DMA_DSR_TPS_WIDTH 4
-+#define DMA_DSR_Q_WIDTH (DMA_DSR_RPS_WIDTH + DMA_DSR_TPS_WIDTH)
-+#define DMA_DSR0_RPS_START 8
-+#define DMA_DSR0_TPS_START 12
-+#define DMA_DSRX_FIRST_QUEUE 3
-+#define DMA_DSRX_INC 4
-+#define DMA_DSRX_QPR 4
-+#define DMA_DSRX_RPS_START 0
-+#define DMA_DSRX_TPS_START 4
-+#define DMA_TPS_STOPPED 0x00
-+#define DMA_TPS_SUSPENDED 0x06
-+
-+/* DMA channel register offsets
-+ * Multiple channels can be active. The first channel has registers
-+ * that begin at 0x3100. Each subsequent channel has registers that
-+ * are accessed using an offset of 0x80 from the previous channel.
-+ */
-+#define DMA_CH_BASE 0x3100
-+#define DMA_CH_INC 0x80
-+
-+#define DMA_CH_CR 0x00
-+#define DMA_CH_TCR 0x04
-+#define DMA_CH_RCR 0x08
-+#define DMA_CH_TDLR_HI 0x10
-+#define DMA_CH_TDLR_LO 0x14
-+#define DMA_CH_RDLR_HI 0x18
-+#define DMA_CH_RDLR_LO 0x1c
-+#define DMA_CH_TDTR_LO 0x24
-+#define DMA_CH_RDTR_LO 0x2c
-+#define DMA_CH_TDRLR 0x30
-+#define DMA_CH_RDRLR 0x34
-+#define DMA_CH_IER 0x38
-+#define DMA_CH_RIWT 0x3c
-+#define DMA_CH_CATDR_LO 0x44
-+#define DMA_CH_CARDR_LO 0x4c
-+#define DMA_CH_CATBR_HI 0x50
-+#define DMA_CH_CATBR_LO 0x54
-+#define DMA_CH_CARBR_HI 0x58
-+#define DMA_CH_CARBR_LO 0x5c
-+#define DMA_CH_SR 0x60
-+
-+/* DMA channel register entry bit positions and sizes */
-+#define DMA_CH_CR_PBLX8_INDEX 16
-+#define DMA_CH_CR_PBLX8_WIDTH 1
-+#define DMA_CH_CR_SPH_INDEX 24
-+#define DMA_CH_CR_SPH_WIDTH 1
-+#define DMA_CH_IER_AIE_INDEX 15
-+#define DMA_CH_IER_AIE_WIDTH 1
-+#define DMA_CH_IER_FBEE_INDEX 12
-+#define DMA_CH_IER_FBEE_WIDTH 1
-+#define DMA_CH_IER_NIE_INDEX 16
-+#define DMA_CH_IER_NIE_WIDTH 1
-+#define DMA_CH_IER_RBUE_INDEX 7
-+#define DMA_CH_IER_RBUE_WIDTH 1
-+#define DMA_CH_IER_RIE_INDEX 6
-+#define DMA_CH_IER_RIE_WIDTH 1
-+#define DMA_CH_IER_RSE_INDEX 8
-+#define DMA_CH_IER_RSE_WIDTH 1
-+#define DMA_CH_IER_TBUE_INDEX 2
-+#define DMA_CH_IER_TBUE_WIDTH 1
-+#define DMA_CH_IER_TIE_INDEX 0
-+#define DMA_CH_IER_TIE_WIDTH 1
-+#define DMA_CH_IER_TXSE_INDEX 1
-+#define DMA_CH_IER_TXSE_WIDTH 1
-+#define DMA_CH_RCR_PBL_INDEX 16
-+#define DMA_CH_RCR_PBL_WIDTH 6
-+#define DMA_CH_RCR_RBSZ_INDEX 1
-+#define DMA_CH_RCR_RBSZ_WIDTH 14
-+#define DMA_CH_RCR_SR_INDEX 0
-+#define DMA_CH_RCR_SR_WIDTH 1
-+#define DMA_CH_RIWT_RWT_INDEX 0
-+#define DMA_CH_RIWT_RWT_WIDTH 8
-+#define DMA_CH_SR_FBE_INDEX 12
-+#define DMA_CH_SR_FBE_WIDTH 1
-+#define DMA_CH_SR_RBU_INDEX 7
-+#define DMA_CH_SR_RBU_WIDTH 1
-+#define DMA_CH_SR_RI_INDEX 6
-+#define DMA_CH_SR_RI_WIDTH 1
-+#define DMA_CH_SR_RPS_INDEX 8
-+#define DMA_CH_SR_RPS_WIDTH 1
-+#define DMA_CH_SR_TBU_INDEX 2
-+#define DMA_CH_SR_TBU_WIDTH 1
-+#define DMA_CH_SR_TI_INDEX 0
-+#define DMA_CH_SR_TI_WIDTH 1
-+#define DMA_CH_SR_TPS_INDEX 1
-+#define DMA_CH_SR_TPS_WIDTH 1
-+#define DMA_CH_TCR_OSP_INDEX 4
-+#define DMA_CH_TCR_OSP_WIDTH 1
-+#define DMA_CH_TCR_PBL_INDEX 16
-+#define DMA_CH_TCR_PBL_WIDTH 6
-+#define DMA_CH_TCR_ST_INDEX 0
-+#define DMA_CH_TCR_ST_WIDTH 1
-+#define DMA_CH_TCR_TSE_INDEX 12
-+#define DMA_CH_TCR_TSE_WIDTH 1
-+
-+/* DMA channel register values */
-+#define DMA_OSP_DISABLE 0x00
-+#define DMA_OSP_ENABLE 0x01
-+#define DMA_PBL_1 1
-+#define DMA_PBL_2 2
-+#define DMA_PBL_4 4
-+#define DMA_PBL_8 8
-+#define DMA_PBL_16 16
-+#define DMA_PBL_32 32
-+#define DMA_PBL_64 64 /* 8 x 8 */
-+#define DMA_PBL_128 128 /* 8 x 16 */
-+#define DMA_PBL_256 256 /* 8 x 32 */
-+#define DMA_PBL_X8_DISABLE 0x00
-+#define DMA_PBL_X8_ENABLE 0x01
-+
-+/* MAC register offsets */
-+#define MAC_TCR 0x0000
-+#define MAC_RCR 0x0004
-+#define MAC_PFR 0x0008
-+#define MAC_WTR 0x000c
-+#define MAC_HTR0 0x0010
-+#define MAC_VLANTR 0x0050
-+#define MAC_VLANHTR 0x0058
-+#define MAC_VLANIR 0x0060
-+#define MAC_IVLANIR 0x0064
-+#define MAC_RETMR 0x006c
-+#define MAC_Q0TFCR 0x0070
-+#define MAC_RFCR 0x0090
-+#define MAC_RQC0R 0x00a0
-+#define MAC_RQC1R 0x00a4
-+#define MAC_RQC2R 0x00a8
-+#define MAC_RQC3R 0x00ac
-+#define MAC_ISR 0x00b0
-+#define MAC_IER 0x00b4
-+#define MAC_RTSR 0x00b8
-+#define MAC_PMTCSR 0x00c0
-+#define MAC_RWKPFR 0x00c4
-+#define MAC_LPICSR 0x00d0
-+#define MAC_LPITCR 0x00d4
-+#define MAC_VR 0x0110
-+#define MAC_DR 0x0114
-+#define MAC_HWF0R 0x011c
-+#define MAC_HWF1R 0x0120
-+#define MAC_HWF2R 0x0124
-+#define MAC_GPIOCR 0x0278
-+#define MAC_GPIOSR 0x027c
-+#define MAC_MACA0HR 0x0300
-+#define MAC_MACA0LR 0x0304
-+#define MAC_MACA1HR 0x0308
-+#define MAC_MACA1LR 0x030c
-+#define MAC_RSSCR 0x0c80
-+#define MAC_RSSAR 0x0c88
-+#define MAC_RSSDR 0x0c8c
-+#define MAC_TSCR 0x0d00
-+#define MAC_SSIR 0x0d04
-+#define MAC_STSR 0x0d08
-+#define MAC_STNR 0x0d0c
-+#define MAC_STSUR 0x0d10
-+#define MAC_STNUR 0x0d14
-+#define MAC_TSAR 0x0d18
-+#define MAC_TSSR 0x0d20
-+#define MAC_TXSNR 0x0d30
-+#define MAC_TXSSR 0x0d34
-+
-+#define MAC_QTFCR_INC 4
-+#define MAC_MACA_INC 4
-+#define MAC_HTR_INC 4
-+
-+#define MAC_RQC2_INC 4
-+#define MAC_RQC2_Q_PER_REG 4
-+
-+/* MAC register entry bit positions and sizes */
-+#define MAC_HWF0R_ADDMACADRSEL_INDEX 18
-+#define MAC_HWF0R_ADDMACADRSEL_WIDTH 5
-+#define MAC_HWF0R_ARPOFFSEL_INDEX 9
-+#define MAC_HWF0R_ARPOFFSEL_WIDTH 1
-+#define MAC_HWF0R_EEESEL_INDEX 13
-+#define MAC_HWF0R_EEESEL_WIDTH 1
-+#define MAC_HWF0R_GMIISEL_INDEX 1
-+#define MAC_HWF0R_GMIISEL_WIDTH 1
-+#define MAC_HWF0R_MGKSEL_INDEX 7
-+#define MAC_HWF0R_MGKSEL_WIDTH 1
-+#define MAC_HWF0R_MMCSEL_INDEX 8
-+#define MAC_HWF0R_MMCSEL_WIDTH 1
-+#define MAC_HWF0R_RWKSEL_INDEX 6
-+#define MAC_HWF0R_RWKSEL_WIDTH 1
-+#define MAC_HWF0R_RXCOESEL_INDEX 16
-+#define MAC_HWF0R_RXCOESEL_WIDTH 1
-+#define MAC_HWF0R_SAVLANINS_INDEX 27
-+#define MAC_HWF0R_SAVLANINS_WIDTH 1
-+#define MAC_HWF0R_SMASEL_INDEX 5
-+#define MAC_HWF0R_SMASEL_WIDTH 1
-+#define MAC_HWF0R_TSSEL_INDEX 12
-+#define MAC_HWF0R_TSSEL_WIDTH 1
-+#define MAC_HWF0R_TSSTSSEL_INDEX 25
-+#define MAC_HWF0R_TSSTSSEL_WIDTH 2
-+#define MAC_HWF0R_TXCOESEL_INDEX 14
-+#define MAC_HWF0R_TXCOESEL_WIDTH 1
-+#define MAC_HWF0R_VLHASH_INDEX 4
-+#define MAC_HWF0R_VLHASH_WIDTH 1
-+#define MAC_HWF1R_ADVTHWORD_INDEX 13
-+#define MAC_HWF1R_ADVTHWORD_WIDTH 1
-+#define MAC_HWF1R_DBGMEMA_INDEX 19
-+#define MAC_HWF1R_DBGMEMA_WIDTH 1
-+#define MAC_HWF1R_DCBEN_INDEX 16
-+#define MAC_HWF1R_DCBEN_WIDTH 1
-+#define MAC_HWF1R_HASHTBLSZ_INDEX 24
-+#define MAC_HWF1R_HASHTBLSZ_WIDTH 3
-+#define MAC_HWF1R_L3L4FNUM_INDEX 27
-+#define MAC_HWF1R_L3L4FNUM_WIDTH 4
-+#define MAC_HWF1R_NUMTC_INDEX 21
-+#define MAC_HWF1R_NUMTC_WIDTH 3
-+#define MAC_HWF1R_RSSEN_INDEX 20
-+#define MAC_HWF1R_RSSEN_WIDTH 1
-+#define MAC_HWF1R_RXFIFOSIZE_INDEX 0
-+#define MAC_HWF1R_RXFIFOSIZE_WIDTH 5
-+#define MAC_HWF1R_SPHEN_INDEX 17
-+#define MAC_HWF1R_SPHEN_WIDTH 1
-+#define MAC_HWF1R_TSOEN_INDEX 18
-+#define MAC_HWF1R_TSOEN_WIDTH 1
-+#define MAC_HWF1R_TXFIFOSIZE_INDEX 6
-+#define MAC_HWF1R_TXFIFOSIZE_WIDTH 5
-+#define MAC_HWF2R_AUXSNAPNUM_INDEX 28
-+#define MAC_HWF2R_AUXSNAPNUM_WIDTH 3
-+#define MAC_HWF2R_PPSOUTNUM_INDEX 24
-+#define MAC_HWF2R_PPSOUTNUM_WIDTH 3
-+#define MAC_HWF2R_RXCHCNT_INDEX 12
-+#define MAC_HWF2R_RXCHCNT_WIDTH 4
-+#define MAC_HWF2R_RXQCNT_INDEX 0
-+#define MAC_HWF2R_RXQCNT_WIDTH 4
-+#define MAC_HWF2R_TXCHCNT_INDEX 18
-+#define MAC_HWF2R_TXCHCNT_WIDTH 4
-+#define MAC_HWF2R_TXQCNT_INDEX 6
-+#define MAC_HWF2R_TXQCNT_WIDTH 4
-+#define MAC_IER_TSIE_INDEX 12
-+#define MAC_IER_TSIE_WIDTH 1
-+#define MAC_ISR_MMCRXIS_INDEX 9
-+#define MAC_ISR_MMCRXIS_WIDTH 1
-+#define MAC_ISR_MMCTXIS_INDEX 10
-+#define MAC_ISR_MMCTXIS_WIDTH 1
-+#define MAC_ISR_PMTIS_INDEX 4
-+#define MAC_ISR_PMTIS_WIDTH 1
-+#define MAC_ISR_TSIS_INDEX 12
-+#define MAC_ISR_TSIS_WIDTH 1
-+#define MAC_MACA1HR_AE_INDEX 31
-+#define MAC_MACA1HR_AE_WIDTH 1
-+#define MAC_PFR_HMC_INDEX 2
-+#define MAC_PFR_HMC_WIDTH 1
-+#define MAC_PFR_HPF_INDEX 10
-+#define MAC_PFR_HPF_WIDTH 1
-+#define MAC_PFR_HUC_INDEX 1
-+#define MAC_PFR_HUC_WIDTH 1
-+#define MAC_PFR_PM_INDEX 4
-+#define MAC_PFR_PM_WIDTH 1
-+#define MAC_PFR_PR_INDEX 0
-+#define MAC_PFR_PR_WIDTH 1
-+#define MAC_PFR_VTFE_INDEX 16
-+#define MAC_PFR_VTFE_WIDTH 1
-+#define MAC_PMTCSR_MGKPKTEN_INDEX 1
-+#define MAC_PMTCSR_MGKPKTEN_WIDTH 1
-+#define MAC_PMTCSR_PWRDWN_INDEX 0
-+#define MAC_PMTCSR_PWRDWN_WIDTH 1
-+#define MAC_PMTCSR_RWKFILTRST_INDEX 31
-+#define MAC_PMTCSR_RWKFILTRST_WIDTH 1
-+#define MAC_PMTCSR_RWKPKTEN_INDEX 2
-+#define MAC_PMTCSR_RWKPKTEN_WIDTH 1
-+#define MAC_Q0TFCR_PT_INDEX 16
-+#define MAC_Q0TFCR_PT_WIDTH 16
-+#define MAC_Q0TFCR_TFE_INDEX 1
-+#define MAC_Q0TFCR_TFE_WIDTH 1
-+#define MAC_RCR_ACS_INDEX 1
-+#define MAC_RCR_ACS_WIDTH 1
-+#define MAC_RCR_CST_INDEX 2
-+#define MAC_RCR_CST_WIDTH 1
-+#define MAC_RCR_DCRCC_INDEX 3
-+#define MAC_RCR_DCRCC_WIDTH 1
-+#define MAC_RCR_HDSMS_INDEX 12
-+#define MAC_RCR_HDSMS_WIDTH 3
-+#define MAC_RCR_IPC_INDEX 9
-+#define MAC_RCR_IPC_WIDTH 1
-+#define MAC_RCR_JE_INDEX 8
-+#define MAC_RCR_JE_WIDTH 1
-+#define MAC_RCR_LM_INDEX 10
-+#define MAC_RCR_LM_WIDTH 1
-+#define MAC_RCR_RE_INDEX 0
-+#define MAC_RCR_RE_WIDTH 1
-+#define MAC_RFCR_PFCE_INDEX 8
-+#define MAC_RFCR_PFCE_WIDTH 1
-+#define MAC_RFCR_RFE_INDEX 0
-+#define MAC_RFCR_RFE_WIDTH 1
-+#define MAC_RFCR_UP_INDEX 1
-+#define MAC_RFCR_UP_WIDTH 1
-+#define MAC_RQC0R_RXQ0EN_INDEX 0
-+#define MAC_RQC0R_RXQ0EN_WIDTH 2
-+#define MAC_RSSAR_ADDRT_INDEX 2
-+#define MAC_RSSAR_ADDRT_WIDTH 1
-+#define MAC_RSSAR_CT_INDEX 1
-+#define MAC_RSSAR_CT_WIDTH 1
-+#define MAC_RSSAR_OB_INDEX 0
-+#define MAC_RSSAR_OB_WIDTH 1
-+#define MAC_RSSAR_RSSIA_INDEX 8
-+#define MAC_RSSAR_RSSIA_WIDTH 8
-+#define MAC_RSSCR_IP2TE_INDEX 1
-+#define MAC_RSSCR_IP2TE_WIDTH 1
-+#define MAC_RSSCR_RSSE_INDEX 0
-+#define MAC_RSSCR_RSSE_WIDTH 1
-+#define MAC_RSSCR_TCP4TE_INDEX 2
-+#define MAC_RSSCR_TCP4TE_WIDTH 1
-+#define MAC_RSSCR_UDP4TE_INDEX 3
-+#define MAC_RSSCR_UDP4TE_WIDTH 1
-+#define MAC_RSSDR_DMCH_INDEX 0
-+#define MAC_RSSDR_DMCH_WIDTH 4
-+#define MAC_SSIR_SNSINC_INDEX 8
-+#define MAC_SSIR_SNSINC_WIDTH 8
-+#define MAC_SSIR_SSINC_INDEX 16
-+#define MAC_SSIR_SSINC_WIDTH 8
-+#define MAC_TCR_SS_INDEX 29
-+#define MAC_TCR_SS_WIDTH 2
-+#define MAC_TCR_TE_INDEX 0
-+#define MAC_TCR_TE_WIDTH 1
-+#define MAC_TSCR_AV8021ASMEN_INDEX 28
-+#define MAC_TSCR_AV8021ASMEN_WIDTH 1
-+#define MAC_TSCR_SNAPTYPSEL_INDEX 16
-+#define MAC_TSCR_SNAPTYPSEL_WIDTH 2
-+#define MAC_TSCR_TSADDREG_INDEX 5
-+#define MAC_TSCR_TSADDREG_WIDTH 1
-+#define MAC_TSCR_TSCFUPDT_INDEX 1
-+#define MAC_TSCR_TSCFUPDT_WIDTH 1
-+#define MAC_TSCR_TSCTRLSSR_INDEX 9
-+#define MAC_TSCR_TSCTRLSSR_WIDTH 1
-+#define MAC_TSCR_TSENA_INDEX 0
-+#define MAC_TSCR_TSENA_WIDTH 1
-+#define MAC_TSCR_TSENALL_INDEX 8
-+#define MAC_TSCR_TSENALL_WIDTH 1
-+#define MAC_TSCR_TSEVNTENA_INDEX 14
-+#define MAC_TSCR_TSEVNTENA_WIDTH 1
-+#define MAC_TSCR_TSINIT_INDEX 2
-+#define MAC_TSCR_TSINIT_WIDTH 1
-+#define MAC_TSCR_TSIPENA_INDEX 11
-+#define MAC_TSCR_TSIPENA_WIDTH 1
-+#define MAC_TSCR_TSIPV4ENA_INDEX 13
-+#define MAC_TSCR_TSIPV4ENA_WIDTH 1
-+#define MAC_TSCR_TSIPV6ENA_INDEX 12
-+#define MAC_TSCR_TSIPV6ENA_WIDTH 1
-+#define MAC_TSCR_TSMSTRENA_INDEX 15
-+#define MAC_TSCR_TSMSTRENA_WIDTH 1
-+#define MAC_TSCR_TSVER2ENA_INDEX 10
-+#define MAC_TSCR_TSVER2ENA_WIDTH 1
-+#define MAC_TSCR_TXTSSTSM_INDEX 24
-+#define MAC_TSCR_TXTSSTSM_WIDTH 1
-+#define MAC_TSSR_TXTSC_INDEX 15
-+#define MAC_TSSR_TXTSC_WIDTH 1
-+#define MAC_TXSNR_TXTSSTSMIS_INDEX 31
-+#define MAC_TXSNR_TXTSSTSMIS_WIDTH 1
-+#define MAC_VLANHTR_VLHT_INDEX 0
-+#define MAC_VLANHTR_VLHT_WIDTH 16
-+#define MAC_VLANIR_VLTI_INDEX 20
-+#define MAC_VLANIR_VLTI_WIDTH 1
-+#define MAC_VLANIR_CSVL_INDEX 19
-+#define MAC_VLANIR_CSVL_WIDTH 1
-+#define MAC_VLANTR_DOVLTC_INDEX 20
-+#define MAC_VLANTR_DOVLTC_WIDTH 1
-+#define MAC_VLANTR_ERSVLM_INDEX 19
-+#define MAC_VLANTR_ERSVLM_WIDTH 1
-+#define MAC_VLANTR_ESVL_INDEX 18
-+#define MAC_VLANTR_ESVL_WIDTH 1
-+#define MAC_VLANTR_ETV_INDEX 16
-+#define MAC_VLANTR_ETV_WIDTH 1
-+#define MAC_VLANTR_EVLS_INDEX 21
-+#define MAC_VLANTR_EVLS_WIDTH 2
-+#define MAC_VLANTR_EVLRXS_INDEX 24
-+#define MAC_VLANTR_EVLRXS_WIDTH 1
-+#define MAC_VLANTR_VL_INDEX 0
-+#define MAC_VLANTR_VL_WIDTH 16
-+#define MAC_VLANTR_VTHM_INDEX 25
-+#define MAC_VLANTR_VTHM_WIDTH 1
-+#define MAC_VLANTR_VTIM_INDEX 17
-+#define MAC_VLANTR_VTIM_WIDTH 1
-+#define MAC_VR_DEVID_INDEX 8
-+#define MAC_VR_DEVID_WIDTH 8
-+#define MAC_VR_SNPSVER_INDEX 0
-+#define MAC_VR_SNPSVER_WIDTH 8
-+#define MAC_VR_USERVER_INDEX 16
-+#define MAC_VR_USERVER_WIDTH 8
-+
-+/* MMC register offsets */
-+#define MMC_CR 0x0800
-+#define MMC_RISR 0x0804
-+#define MMC_TISR 0x0808
-+#define MMC_RIER 0x080c
-+#define MMC_TIER 0x0810
-+#define MMC_TXOCTETCOUNT_GB_LO 0x0814
-+#define MMC_TXOCTETCOUNT_GB_HI 0x0818
-+#define MMC_TXFRAMECOUNT_GB_LO 0x081c
-+#define MMC_TXFRAMECOUNT_GB_HI 0x0820
-+#define MMC_TXBROADCASTFRAMES_G_LO 0x0824
-+#define MMC_TXBROADCASTFRAMES_G_HI 0x0828
-+#define MMC_TXMULTICASTFRAMES_G_LO 0x082c
-+#define MMC_TXMULTICASTFRAMES_G_HI 0x0830
-+#define MMC_TX64OCTETS_GB_LO 0x0834
-+#define MMC_TX64OCTETS_GB_HI 0x0838
-+#define MMC_TX65TO127OCTETS_GB_LO 0x083c
-+#define MMC_TX65TO127OCTETS_GB_HI 0x0840
-+#define MMC_TX128TO255OCTETS_GB_LO 0x0844
-+#define MMC_TX128TO255OCTETS_GB_HI 0x0848
-+#define MMC_TX256TO511OCTETS_GB_LO 0x084c
-+#define MMC_TX256TO511OCTETS_GB_HI 0x0850
-+#define MMC_TX512TO1023OCTETS_GB_LO 0x0854
-+#define MMC_TX512TO1023OCTETS_GB_HI 0x0858
-+#define MMC_TX1024TOMAXOCTETS_GB_LO 0x085c
-+#define MMC_TX1024TOMAXOCTETS_GB_HI 0x0860
-+#define MMC_TXUNICASTFRAMES_GB_LO 0x0864
-+#define MMC_TXUNICASTFRAMES_GB_HI 0x0868
-+#define MMC_TXMULTICASTFRAMES_GB_LO 0x086c
-+#define MMC_TXMULTICASTFRAMES_GB_HI 0x0870
-+#define MMC_TXBROADCASTFRAMES_GB_LO 0x0874
-+#define MMC_TXBROADCASTFRAMES_GB_HI 0x0878
-+#define MMC_TXUNDERFLOWERROR_LO 0x087c
-+#define MMC_TXUNDERFLOWERROR_HI 0x0880
-+#define MMC_TXOCTETCOUNT_G_LO 0x0884
-+#define MMC_TXOCTETCOUNT_G_HI 0x0888
-+#define MMC_TXFRAMECOUNT_G_LO 0x088c
-+#define MMC_TXFRAMECOUNT_G_HI 0x0890
-+#define MMC_TXPAUSEFRAMES_LO 0x0894
-+#define MMC_TXPAUSEFRAMES_HI 0x0898
-+#define MMC_TXVLANFRAMES_G_LO 0x089c
-+#define MMC_TXVLANFRAMES_G_HI 0x08a0
-+#define MMC_RXFRAMECOUNT_GB_LO 0x0900
-+#define MMC_RXFRAMECOUNT_GB_HI 0x0904
-+#define MMC_RXOCTETCOUNT_GB_LO 0x0908
-+#define MMC_RXOCTETCOUNT_GB_HI 0x090c
-+#define MMC_RXOCTETCOUNT_G_LO 0x0910
-+#define MMC_RXOCTETCOUNT_G_HI 0x0914
-+#define MMC_RXBROADCASTFRAMES_G_LO 0x0918
-+#define MMC_RXBROADCASTFRAMES_G_HI 0x091c
-+#define MMC_RXMULTICASTFRAMES_G_LO 0x0920
-+#define MMC_RXMULTICASTFRAMES_G_HI 0x0924
-+#define MMC_RXCRCERROR_LO 0x0928
-+#define MMC_RXCRCERROR_HI 0x092c
-+#define MMC_RXRUNTERROR 0x0930
-+#define MMC_RXJABBERERROR 0x0934
-+#define MMC_RXUNDERSIZE_G 0x0938
-+#define MMC_RXOVERSIZE_G 0x093c
-+#define MMC_RX64OCTETS_GB_LO 0x0940
-+#define MMC_RX64OCTETS_GB_HI 0x0944
-+#define MMC_RX65TO127OCTETS_GB_LO 0x0948
-+#define MMC_RX65TO127OCTETS_GB_HI 0x094c
-+#define MMC_RX128TO255OCTETS_GB_LO 0x0950
-+#define MMC_RX128TO255OCTETS_GB_HI 0x0954
-+#define MMC_RX256TO511OCTETS_GB_LO 0x0958
-+#define MMC_RX256TO511OCTETS_GB_HI 0x095c
-+#define MMC_RX512TO1023OCTETS_GB_LO 0x0960
-+#define MMC_RX512TO1023OCTETS_GB_HI 0x0964
-+#define MMC_RX1024TOMAXOCTETS_GB_LO 0x0968
-+#define MMC_RX1024TOMAXOCTETS_GB_HI 0x096c
-+#define MMC_RXUNICASTFRAMES_G_LO 0x0970
-+#define MMC_RXUNICASTFRAMES_G_HI 0x0974
-+#define MMC_RXLENGTHERROR_LO 0x0978
-+#define MMC_RXLENGTHERROR_HI 0x097c
-+#define MMC_RXOUTOFRANGETYPE_LO 0x0980
-+#define MMC_RXOUTOFRANGETYPE_HI 0x0984
-+#define MMC_RXPAUSEFRAMES_LO 0x0988
-+#define MMC_RXPAUSEFRAMES_HI 0x098c
-+#define MMC_RXFIFOOVERFLOW_LO 0x0990
-+#define MMC_RXFIFOOVERFLOW_HI 0x0994
-+#define MMC_RXVLANFRAMES_GB_LO 0x0998
-+#define MMC_RXVLANFRAMES_GB_HI 0x099c
-+#define MMC_RXWATCHDOGERROR 0x09a0
-+
-+/* MMC register entry bit positions and sizes */
-+#define MMC_CR_CR_INDEX 0
-+#define MMC_CR_CR_WIDTH 1
-+#define MMC_CR_CSR_INDEX 1
-+#define MMC_CR_CSR_WIDTH 1
-+#define MMC_CR_ROR_INDEX 2
-+#define MMC_CR_ROR_WIDTH 1
-+#define MMC_CR_MCF_INDEX 3
-+#define MMC_CR_MCF_WIDTH 1
-+#define MMC_CR_MCT_INDEX 4
-+#define MMC_CR_MCT_WIDTH 2
-+#define MMC_RIER_ALL_INTERRUPTS_INDEX 0
-+#define MMC_RIER_ALL_INTERRUPTS_WIDTH 23
-+#define MMC_RISR_RXFRAMECOUNT_GB_INDEX 0
-+#define MMC_RISR_RXFRAMECOUNT_GB_WIDTH 1
-+#define MMC_RISR_RXOCTETCOUNT_GB_INDEX 1
-+#define MMC_RISR_RXOCTETCOUNT_GB_WIDTH 1
-+#define MMC_RISR_RXOCTETCOUNT_G_INDEX 2
-+#define MMC_RISR_RXOCTETCOUNT_G_WIDTH 1
-+#define MMC_RISR_RXBROADCASTFRAMES_G_INDEX 3
-+#define MMC_RISR_RXBROADCASTFRAMES_G_WIDTH 1
-+#define MMC_RISR_RXMULTICASTFRAMES_G_INDEX 4
-+#define MMC_RISR_RXMULTICASTFRAMES_G_WIDTH 1
-+#define MMC_RISR_RXCRCERROR_INDEX 5
-+#define MMC_RISR_RXCRCERROR_WIDTH 1
-+#define MMC_RISR_RXRUNTERROR_INDEX 6
-+#define MMC_RISR_RXRUNTERROR_WIDTH 1
-+#define MMC_RISR_RXJABBERERROR_INDEX 7
-+#define MMC_RISR_RXJABBERERROR_WIDTH 1
-+#define MMC_RISR_RXUNDERSIZE_G_INDEX 8
-+#define MMC_RISR_RXUNDERSIZE_G_WIDTH 1
-+#define MMC_RISR_RXOVERSIZE_G_INDEX 9
-+#define MMC_RISR_RXOVERSIZE_G_WIDTH 1
-+#define MMC_RISR_RX64OCTETS_GB_INDEX 10
-+#define MMC_RISR_RX64OCTETS_GB_WIDTH 1
-+#define MMC_RISR_RX65TO127OCTETS_GB_INDEX 11
-+#define MMC_RISR_RX65TO127OCTETS_GB_WIDTH 1
-+#define MMC_RISR_RX128TO255OCTETS_GB_INDEX 12
-+#define MMC_RISR_RX128TO255OCTETS_GB_WIDTH 1
-+#define MMC_RISR_RX256TO511OCTETS_GB_INDEX 13
-+#define MMC_RISR_RX256TO511OCTETS_GB_WIDTH 1
-+#define MMC_RISR_RX512TO1023OCTETS_GB_INDEX 14
-+#define MMC_RISR_RX512TO1023OCTETS_GB_WIDTH 1
-+#define MMC_RISR_RX1024TOMAXOCTETS_GB_INDEX 15
-+#define MMC_RISR_RX1024TOMAXOCTETS_GB_WIDTH 1
-+#define MMC_RISR_RXUNICASTFRAMES_G_INDEX 16
-+#define MMC_RISR_RXUNICASTFRAMES_G_WIDTH 1
-+#define MMC_RISR_RXLENGTHERROR_INDEX 17
-+#define MMC_RISR_RXLENGTHERROR_WIDTH 1
-+#define MMC_RISR_RXOUTOFRANGETYPE_INDEX 18
-+#define MMC_RISR_RXOUTOFRANGETYPE_WIDTH 1
-+#define MMC_RISR_RXPAUSEFRAMES_INDEX 19
-+#define MMC_RISR_RXPAUSEFRAMES_WIDTH 1
-+#define MMC_RISR_RXFIFOOVERFLOW_INDEX 20
-+#define MMC_RISR_RXFIFOOVERFLOW_WIDTH 1
-+#define MMC_RISR_RXVLANFRAMES_GB_INDEX 21
-+#define MMC_RISR_RXVLANFRAMES_GB_WIDTH 1
-+#define MMC_RISR_RXWATCHDOGERROR_INDEX 22
-+#define MMC_RISR_RXWATCHDOGERROR_WIDTH 1
-+#define MMC_TIER_ALL_INTERRUPTS_INDEX 0
-+#define MMC_TIER_ALL_INTERRUPTS_WIDTH 18
-+#define MMC_TISR_TXOCTETCOUNT_GB_INDEX 0
-+#define MMC_TISR_TXOCTETCOUNT_GB_WIDTH 1
-+#define MMC_TISR_TXFRAMECOUNT_GB_INDEX 1
-+#define MMC_TISR_TXFRAMECOUNT_GB_WIDTH 1
-+#define MMC_TISR_TXBROADCASTFRAMES_G_INDEX 2
-+#define MMC_TISR_TXBROADCASTFRAMES_G_WIDTH 1
-+#define MMC_TISR_TXMULTICASTFRAMES_G_INDEX 3
-+#define MMC_TISR_TXMULTICASTFRAMES_G_WIDTH 1
-+#define MMC_TISR_TX64OCTETS_GB_INDEX 4
-+#define MMC_TISR_TX64OCTETS_GB_WIDTH 1
-+#define MMC_TISR_TX65TO127OCTETS_GB_INDEX 5
-+#define MMC_TISR_TX65TO127OCTETS_GB_WIDTH 1
-+#define MMC_TISR_TX128TO255OCTETS_GB_INDEX 6
-+#define MMC_TISR_TX128TO255OCTETS_GB_WIDTH 1
-+#define MMC_TISR_TX256TO511OCTETS_GB_INDEX 7
-+#define MMC_TISR_TX256TO511OCTETS_GB_WIDTH 1
-+#define MMC_TISR_TX512TO1023OCTETS_GB_INDEX 8
-+#define MMC_TISR_TX512TO1023OCTETS_GB_WIDTH 1
-+#define MMC_TISR_TX1024TOMAXOCTETS_GB_INDEX 9
-+#define MMC_TISR_TX1024TOMAXOCTETS_GB_WIDTH 1
-+#define MMC_TISR_TXUNICASTFRAMES_GB_INDEX 10
-+#define MMC_TISR_TXUNICASTFRAMES_GB_WIDTH 1
-+#define MMC_TISR_TXMULTICASTFRAMES_GB_INDEX 11
-+#define MMC_TISR_TXMULTICASTFRAMES_GB_WIDTH 1
-+#define MMC_TISR_TXBROADCASTFRAMES_GB_INDEX 12
-+#define MMC_TISR_TXBROADCASTFRAMES_GB_WIDTH 1
-+#define MMC_TISR_TXUNDERFLOWERROR_INDEX 13
-+#define MMC_TISR_TXUNDERFLOWERROR_WIDTH 1
-+#define MMC_TISR_TXOCTETCOUNT_G_INDEX 14
-+#define MMC_TISR_TXOCTETCOUNT_G_WIDTH 1
-+#define MMC_TISR_TXFRAMECOUNT_G_INDEX 15
-+#define MMC_TISR_TXFRAMECOUNT_G_WIDTH 1
-+#define MMC_TISR_TXPAUSEFRAMES_INDEX 16
-+#define MMC_TISR_TXPAUSEFRAMES_WIDTH 1
-+#define MMC_TISR_TXVLANFRAMES_G_INDEX 17
-+#define MMC_TISR_TXVLANFRAMES_G_WIDTH 1
-+
-+/* MTL register offsets */
-+#define MTL_OMR 0x1000
-+#define MTL_FDCR 0x1008
-+#define MTL_FDSR 0x100c
-+#define MTL_FDDR 0x1010
-+#define MTL_ISR 0x1020
-+#define MTL_RQDCM0R 0x1030
-+#define MTL_TCPM0R 0x1040
-+#define MTL_TCPM1R 0x1044
-+
-+#define MTL_RQDCM_INC 4
-+#define MTL_RQDCM_Q_PER_REG 4
-+#define MTL_TCPM_INC 4
-+#define MTL_TCPM_TC_PER_REG 4
-+
-+/* MTL register entry bit positions and sizes */
-+#define MTL_OMR_ETSALG_INDEX 5
-+#define MTL_OMR_ETSALG_WIDTH 2
-+#define MTL_OMR_RAA_INDEX 2
-+#define MTL_OMR_RAA_WIDTH 1
-+
-+/* MTL queue register offsets
-+ * Multiple queues can be active. The first queue has registers
-+ * that begin at 0x1100. Each subsequent queue has registers that
-+ * are accessed using an offset of 0x80 from the previous queue.
-+ */
-+#define MTL_Q_BASE 0x1100
-+#define MTL_Q_INC 0x80
-+
-+#define MTL_Q_TQOMR 0x00
-+#define MTL_Q_TQUR 0x04
-+#define MTL_Q_TQDR 0x08
-+#define MTL_Q_RQOMR 0x40
-+#define MTL_Q_RQMPOCR 0x44
-+#define MTL_Q_RQDR 0x4c
-+#define MTL_Q_IER 0x70
-+#define MTL_Q_ISR 0x74
-+
-+/* MTL queue register entry bit positions and sizes */
-+#define MTL_Q_RQOMR_EHFC_INDEX 7
-+#define MTL_Q_RQOMR_EHFC_WIDTH 1
-+#define MTL_Q_RQOMR_RFA_INDEX 8
-+#define MTL_Q_RQOMR_RFA_WIDTH 3
-+#define MTL_Q_RQOMR_RFD_INDEX 13
-+#define MTL_Q_RQOMR_RFD_WIDTH 3
-+#define MTL_Q_RQOMR_RQS_INDEX 16
-+#define MTL_Q_RQOMR_RQS_WIDTH 9
-+#define MTL_Q_RQOMR_RSF_INDEX 5
-+#define MTL_Q_RQOMR_RSF_WIDTH 1
-+#define MTL_Q_RQOMR_RTC_INDEX 0
-+#define MTL_Q_RQOMR_RTC_WIDTH 2
-+#define MTL_Q_TQOMR_FTQ_INDEX 0
-+#define MTL_Q_TQOMR_FTQ_WIDTH 1
-+#define MTL_Q_TQOMR_Q2TCMAP_INDEX 8
-+#define MTL_Q_TQOMR_Q2TCMAP_WIDTH 3
-+#define MTL_Q_TQOMR_TQS_INDEX 16
-+#define MTL_Q_TQOMR_TQS_WIDTH 10
-+#define MTL_Q_TQOMR_TSF_INDEX 1
-+#define MTL_Q_TQOMR_TSF_WIDTH 1
-+#define MTL_Q_TQOMR_TTC_INDEX 4
-+#define MTL_Q_TQOMR_TTC_WIDTH 3
-+#define MTL_Q_TQOMR_TXQEN_INDEX 2
-+#define MTL_Q_TQOMR_TXQEN_WIDTH 2
-+
-+/* MTL queue register value */
-+#define MTL_RSF_DISABLE 0x00
-+#define MTL_RSF_ENABLE 0x01
-+#define MTL_TSF_DISABLE 0x00
-+#define MTL_TSF_ENABLE 0x01
-+
-+#define MTL_RX_THRESHOLD_64 0x00
-+#define MTL_RX_THRESHOLD_96 0x02
-+#define MTL_RX_THRESHOLD_128 0x03
-+#define MTL_TX_THRESHOLD_32 0x01
-+#define MTL_TX_THRESHOLD_64 0x00
-+#define MTL_TX_THRESHOLD_96 0x02
-+#define MTL_TX_THRESHOLD_128 0x03
-+#define MTL_TX_THRESHOLD_192 0x04
-+#define MTL_TX_THRESHOLD_256 0x05
-+#define MTL_TX_THRESHOLD_384 0x06
-+#define MTL_TX_THRESHOLD_512 0x07
-+
-+#define MTL_ETSALG_WRR 0x00
-+#define MTL_ETSALG_WFQ 0x01
-+#define MTL_ETSALG_DWRR 0x02
-+#define MTL_RAA_SP 0x00
-+#define MTL_RAA_WSP 0x01
-+
-+#define MTL_Q_DISABLED 0x00
-+#define MTL_Q_ENABLED 0x02
-+
-+/* MTL traffic class register offsets
-+ * Multiple traffic classes can be active. The first class has registers
-+ * that begin at 0x1100. Each subsequent queue has registers that
-+ * are accessed using an offset of 0x80 from the previous queue.
-+ */
-+#define MTL_TC_BASE MTL_Q_BASE
-+#define MTL_TC_INC MTL_Q_INC
-+
-+#define MTL_TC_ETSCR 0x10
-+#define MTL_TC_ETSSR 0x14
-+#define MTL_TC_QWR 0x18
-+
-+/* MTL traffic class register entry bit positions and sizes */
-+#define MTL_TC_ETSCR_TSA_INDEX 0
-+#define MTL_TC_ETSCR_TSA_WIDTH 2
-+#define MTL_TC_QWR_QW_INDEX 0
-+#define MTL_TC_QWR_QW_WIDTH 21
-+
-+/* MTL traffic class register value */
-+#define MTL_TSA_SP 0x00
-+#define MTL_TSA_ETS 0x02
-+
-+/* PCS MMD select register offset
-+ * The MMD select register is used for accessing PCS registers
-+ * when the underlying APB3 interface is using indirect addressing.
-+ * Indirect addressing requires accessing registers in two phases,
-+ * an address phase and a data phase. The address phases requires
-+ * writing an address selection value to the MMD select regiesters.
-+ */
-+#define PCS_MMD_SELECT 0xff
-+
-+/* Descriptor/Packet entry bit positions and sizes */
-+#define RX_PACKET_ERRORS_CRC_INDEX 2
-+#define RX_PACKET_ERRORS_CRC_WIDTH 1
-+#define RX_PACKET_ERRORS_FRAME_INDEX 3
-+#define RX_PACKET_ERRORS_FRAME_WIDTH 1
-+#define RX_PACKET_ERRORS_LENGTH_INDEX 0
-+#define RX_PACKET_ERRORS_LENGTH_WIDTH 1
-+#define RX_PACKET_ERRORS_OVERRUN_INDEX 1
-+#define RX_PACKET_ERRORS_OVERRUN_WIDTH 1
-+
-+#define RX_PACKET_ATTRIBUTES_CSUM_DONE_INDEX 0
-+#define RX_PACKET_ATTRIBUTES_CSUM_DONE_WIDTH 1
-+#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX 1
-+#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1
-+#define RX_PACKET_ATTRIBUTES_INCOMPLETE_INDEX 2
-+#define RX_PACKET_ATTRIBUTES_INCOMPLETE_WIDTH 1
-+#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_INDEX 3
-+#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_WIDTH 1
-+#define RX_PACKET_ATTRIBUTES_CONTEXT_INDEX 4
-+#define RX_PACKET_ATTRIBUTES_CONTEXT_WIDTH 1
-+#define RX_PACKET_ATTRIBUTES_RX_TSTAMP_INDEX 5
-+#define RX_PACKET_ATTRIBUTES_RX_TSTAMP_WIDTH 1
-+#define RX_PACKET_ATTRIBUTES_RSS_HASH_INDEX 6
-+#define RX_PACKET_ATTRIBUTES_RSS_HASH_WIDTH 1
-+
-+#define RX_NORMAL_DESC0_OVT_INDEX 0
-+#define RX_NORMAL_DESC0_OVT_WIDTH 16
-+#define RX_NORMAL_DESC2_HL_INDEX 0
-+#define RX_NORMAL_DESC2_HL_WIDTH 10
-+#define RX_NORMAL_DESC3_CDA_INDEX 27
-+#define RX_NORMAL_DESC3_CDA_WIDTH 1
-+#define RX_NORMAL_DESC3_CTXT_INDEX 30
-+#define RX_NORMAL_DESC3_CTXT_WIDTH 1
-+#define RX_NORMAL_DESC3_ES_INDEX 15
-+#define RX_NORMAL_DESC3_ES_WIDTH 1
-+#define RX_NORMAL_DESC3_ETLT_INDEX 16
-+#define RX_NORMAL_DESC3_ETLT_WIDTH 4
-+#define RX_NORMAL_DESC3_FD_INDEX 29
-+#define RX_NORMAL_DESC3_FD_WIDTH 1
-+#define RX_NORMAL_DESC3_INTE_INDEX 30
-+#define RX_NORMAL_DESC3_INTE_WIDTH 1
-+#define RX_NORMAL_DESC3_L34T_INDEX 20
-+#define RX_NORMAL_DESC3_L34T_WIDTH 4
-+#define RX_NORMAL_DESC3_LD_INDEX 28
-+#define RX_NORMAL_DESC3_LD_WIDTH 1
-+#define RX_NORMAL_DESC3_OWN_INDEX 31
-+#define RX_NORMAL_DESC3_OWN_WIDTH 1
-+#define RX_NORMAL_DESC3_PL_INDEX 0
-+#define RX_NORMAL_DESC3_PL_WIDTH 14
-+#define RX_NORMAL_DESC3_RSV_INDEX 26
-+#define RX_NORMAL_DESC3_RSV_WIDTH 1
-+
-+#define RX_DESC3_L34T_IPV4_TCP 1
-+#define RX_DESC3_L34T_IPV4_UDP 2
-+#define RX_DESC3_L34T_IPV4_ICMP 3
-+#define RX_DESC3_L34T_IPV6_TCP 9
-+#define RX_DESC3_L34T_IPV6_UDP 10
-+#define RX_DESC3_L34T_IPV6_ICMP 11
-+
-+#define RX_CONTEXT_DESC3_TSA_INDEX 4
-+#define RX_CONTEXT_DESC3_TSA_WIDTH 1
-+#define RX_CONTEXT_DESC3_TSD_INDEX 6
-+#define RX_CONTEXT_DESC3_TSD_WIDTH 1
-+
-+#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_INDEX 0
-+#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_WIDTH 1
-+#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_INDEX 1
-+#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_WIDTH 1
-+#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX 2
-+#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1
-+#define TX_PACKET_ATTRIBUTES_PTP_INDEX 3
-+#define TX_PACKET_ATTRIBUTES_PTP_WIDTH 1
-+
-+#define TX_CONTEXT_DESC2_MSS_INDEX 0
-+#define TX_CONTEXT_DESC2_MSS_WIDTH 15
-+#define TX_CONTEXT_DESC3_CTXT_INDEX 30
-+#define TX_CONTEXT_DESC3_CTXT_WIDTH 1
-+#define TX_CONTEXT_DESC3_TCMSSV_INDEX 26
-+#define TX_CONTEXT_DESC3_TCMSSV_WIDTH 1
-+#define TX_CONTEXT_DESC3_VLTV_INDEX 16
-+#define TX_CONTEXT_DESC3_VLTV_WIDTH 1
-+#define TX_CONTEXT_DESC3_VT_INDEX 0
-+#define TX_CONTEXT_DESC3_VT_WIDTH 16
-+
-+#define TX_NORMAL_DESC2_HL_B1L_INDEX 0
-+#define TX_NORMAL_DESC2_HL_B1L_WIDTH 14
-+#define TX_NORMAL_DESC2_IC_INDEX 31
-+#define TX_NORMAL_DESC2_IC_WIDTH 1
-+#define TX_NORMAL_DESC2_TTSE_INDEX 30
-+#define TX_NORMAL_DESC2_TTSE_WIDTH 1
-+#define TX_NORMAL_DESC2_VTIR_INDEX 14
-+#define TX_NORMAL_DESC2_VTIR_WIDTH 2
-+#define TX_NORMAL_DESC3_CIC_INDEX 16
-+#define TX_NORMAL_DESC3_CIC_WIDTH 2
-+#define TX_NORMAL_DESC3_CPC_INDEX 26
-+#define TX_NORMAL_DESC3_CPC_WIDTH 2
-+#define TX_NORMAL_DESC3_CTXT_INDEX 30
-+#define TX_NORMAL_DESC3_CTXT_WIDTH 1
-+#define TX_NORMAL_DESC3_FD_INDEX 29
-+#define TX_NORMAL_DESC3_FD_WIDTH 1
-+#define TX_NORMAL_DESC3_FL_INDEX 0
-+#define TX_NORMAL_DESC3_FL_WIDTH 15
-+#define TX_NORMAL_DESC3_LD_INDEX 28
-+#define TX_NORMAL_DESC3_LD_WIDTH 1
-+#define TX_NORMAL_DESC3_OWN_INDEX 31
-+#define TX_NORMAL_DESC3_OWN_WIDTH 1
-+#define TX_NORMAL_DESC3_TCPHDRLEN_INDEX 19
-+#define TX_NORMAL_DESC3_TCPHDRLEN_WIDTH 4
-+#define TX_NORMAL_DESC3_TCPPL_INDEX 0
-+#define TX_NORMAL_DESC3_TCPPL_WIDTH 18
-+#define TX_NORMAL_DESC3_TSE_INDEX 18
-+#define TX_NORMAL_DESC3_TSE_WIDTH 1
-+
-+#define TX_NORMAL_DESC2_VLAN_INSERT 0x2
-+
-+/* MDIO undefined or vendor specific registers */
-+#ifndef MDIO_AN_COMP_STAT
-+#define MDIO_AN_COMP_STAT 0x0030
-+#endif
-+
-+/* Bit setting and getting macros
-+ * The get macro will extract the current bit field value from within
-+ * the variable
-+ *
-+ * The set macro will clear the current bit field value within the
-+ * variable and then set the bit field of the variable to the
-+ * specified value
-+ */
-+#define GET_BITS(_var, _index, _width) \
-+ (((_var) >> (_index)) & ((0x1 << (_width)) - 1))
-+
-+#define SET_BITS(_var, _index, _width, _val) \
-+do { \
-+ (_var) &= ~(((0x1 << (_width)) - 1) << (_index)); \
-+ (_var) |= (((_val) & ((0x1 << (_width)) - 1)) << (_index)); \
-+} while (0)
-+
-+#define GET_BITS_LE(_var, _index, _width) \
-+ ((le32_to_cpu((_var)) >> (_index)) & ((0x1 << (_width)) - 1))
-+
-+#define SET_BITS_LE(_var, _index, _width, _val) \
-+do { \
-+ (_var) &= cpu_to_le32(~(((0x1 << (_width)) - 1) << (_index))); \
-+ (_var) |= cpu_to_le32((((_val) & \
-+ ((0x1 << (_width)) - 1)) << (_index))); \
-+} while (0)
-+
-+/* Bit setting and getting macros based on register fields
-+ * The get macro uses the bit field definitions formed using the input
-+ * names to extract the current bit field value from within the
-+ * variable
-+ *
-+ * The set macro uses the bit field definitions formed using the input
-+ * names to set the bit field of the variable to the specified value
-+ */
-+#define XGMAC_GET_BITS(_var, _prefix, _field) \
-+ GET_BITS((_var), \
-+ _prefix##_##_field##_INDEX, \
-+ _prefix##_##_field##_WIDTH)
-+
-+#define XGMAC_SET_BITS(_var, _prefix, _field, _val) \
-+ SET_BITS((_var), \
-+ _prefix##_##_field##_INDEX, \
-+ _prefix##_##_field##_WIDTH, (_val))
-+
-+#define XGMAC_GET_BITS_LE(_var, _prefix, _field) \
-+ GET_BITS_LE((_var), \
-+ _prefix##_##_field##_INDEX, \
-+ _prefix##_##_field##_WIDTH)
-+
-+#define XGMAC_SET_BITS_LE(_var, _prefix, _field, _val) \
-+ SET_BITS_LE((_var), \
-+ _prefix##_##_field##_INDEX, \
-+ _prefix##_##_field##_WIDTH, (_val))
-+
-+/* Macros for reading or writing registers
-+ * The ioread macros will get bit fields or full values using the
-+ * register definitions formed using the input names
-+ *
-+ * The iowrite macros will set bit fields or full values using the
-+ * register definitions formed using the input names
-+ */
-+#define XGMAC_IOREAD(_pdata, _reg) \
-+ ioread32((_pdata)->xgmac_regs + _reg)
-+
-+#define XGMAC_IOREAD_BITS(_pdata, _reg, _field) \
-+ GET_BITS(XGMAC_IOREAD((_pdata), _reg), \
-+ _reg##_##_field##_INDEX, \
-+ _reg##_##_field##_WIDTH)
-+
-+#define XGMAC_IOWRITE(_pdata, _reg, _val) \
-+ iowrite32((_val), (_pdata)->xgmac_regs + _reg)
-+
-+#define XGMAC_IOWRITE_BITS(_pdata, _reg, _field, _val) \
-+do { \
-+ u32 reg_val = XGMAC_IOREAD((_pdata), _reg); \
-+ SET_BITS(reg_val, \
-+ _reg##_##_field##_INDEX, \
-+ _reg##_##_field##_WIDTH, (_val)); \
-+ XGMAC_IOWRITE((_pdata), _reg, reg_val); \
-+} while (0)
-+
-+/* Macros for reading or writing MTL queue or traffic class registers
-+ * Similar to the standard read and write macros except that the
-+ * base register value is calculated by the queue or traffic class number
-+ */
-+#define XGMAC_MTL_IOREAD(_pdata, _n, _reg) \
-+ ioread32((_pdata)->xgmac_regs + \
-+ MTL_Q_BASE + ((_n) * MTL_Q_INC) + _reg)
-+
-+#define XGMAC_MTL_IOREAD_BITS(_pdata, _n, _reg, _field) \
-+ GET_BITS(XGMAC_MTL_IOREAD((_pdata), (_n), _reg), \
-+ _reg##_##_field##_INDEX, \
-+ _reg##_##_field##_WIDTH)
-+
-+#define XGMAC_MTL_IOWRITE(_pdata, _n, _reg, _val) \
-+ iowrite32((_val), (_pdata)->xgmac_regs + \
-+ MTL_Q_BASE + ((_n) * MTL_Q_INC) + _reg)
-+
-+#define XGMAC_MTL_IOWRITE_BITS(_pdata, _n, _reg, _field, _val) \
-+do { \
-+ u32 reg_val = XGMAC_MTL_IOREAD((_pdata), (_n), _reg); \
-+ SET_BITS(reg_val, \
-+ _reg##_##_field##_INDEX, \
-+ _reg##_##_field##_WIDTH, (_val)); \
-+ XGMAC_MTL_IOWRITE((_pdata), (_n), _reg, reg_val); \
-+} while (0)
-+
-+/* Macros for reading or writing DMA channel registers
-+ * Similar to the standard read and write macros except that the
-+ * base register value is obtained from the ring
-+ */
-+#define XGMAC_DMA_IOREAD(_channel, _reg) \
-+ ioread32((_channel)->dma_regs + _reg)
-+
-+#define XGMAC_DMA_IOREAD_BITS(_channel, _reg, _field) \
-+ GET_BITS(XGMAC_DMA_IOREAD((_channel), _reg), \
-+ _reg##_##_field##_INDEX, \
-+ _reg##_##_field##_WIDTH)
-+
-+#define XGMAC_DMA_IOWRITE(_channel, _reg, _val) \
-+ iowrite32((_val), (_channel)->dma_regs + _reg)
-+
-+#define XGMAC_DMA_IOWRITE_BITS(_channel, _reg, _field, _val) \
-+do { \
-+ u32 reg_val = XGMAC_DMA_IOREAD((_channel), _reg); \
-+ SET_BITS(reg_val, \
-+ _reg##_##_field##_INDEX, \
-+ _reg##_##_field##_WIDTH, (_val)); \
-+ XGMAC_DMA_IOWRITE((_channel), _reg, reg_val); \
-+} while (0)
-+
-+/* Macros for building, reading or writing register values or bits
-+ * within the register values of XPCS registers.
-+ */
-+#define XPCS_IOWRITE(_pdata, _off, _val) \
-+ iowrite32(_val, (_pdata)->xpcs_regs + (_off))
-+
-+#define XPCS_IOREAD(_pdata, _off) \
-+ ioread32((_pdata)->xpcs_regs + (_off))
-+
-+/* Macros for building, reading or writing register values or bits
-+ * using MDIO. Different from above because of the use of standardized
-+ * Linux include values. No shifting is performed with the bit
-+ * operations, everything works on mask values.
-+ */
-+#define XMDIO_READ(_pdata, _mmd, _reg) \
-+ ((_pdata)->hw_if.read_mmd_regs((_pdata), 0, \
-+ MII_ADDR_C45 | (_mmd << 16) | ((_reg) & 0xffff)))
-+
-+#define XMDIO_READ_BITS(_pdata, _mmd, _reg, _mask) \
-+ (XMDIO_READ((_pdata), _mmd, _reg) & _mask)
-+
-+#define XMDIO_WRITE(_pdata, _mmd, _reg, _val) \
-+ ((_pdata)->hw_if.write_mmd_regs((_pdata), 0, \
-+ MII_ADDR_C45 | (_mmd << 16) | ((_reg) & 0xffff), (_val)))
-+
-+#define XMDIO_WRITE_BITS(_pdata, _mmd, _reg, _mask, _val) \
-+do { \
-+ u32 mmd_val = XMDIO_READ((_pdata), _mmd, _reg); \
-+ mmd_val &= ~_mask; \
-+ mmd_val |= (_val); \
-+ XMDIO_WRITE((_pdata), _mmd, _reg, mmd_val); \
-+} while (0)
-+
-+#endif
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-dcb.c b/drivers/net/ethernet/amd/xgbe-a0/xgbe-dcb.c
-new file mode 100644
-index 0000000..343301c
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-dcb.c
-@@ -0,0 +1,269 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/netdevice.h>
-+#include <net/dcbnl.h>
-+
-+#include "xgbe.h"
-+#include "xgbe-common.h"
-+
-+static int xgbe_dcb_ieee_getets(struct net_device *netdev,
-+ struct ieee_ets *ets)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+
-+ /* Set number of supported traffic classes */
-+ ets->ets_cap = pdata->hw_feat.tc_cnt;
-+
-+ if (pdata->ets) {
-+ ets->cbs = pdata->ets->cbs;
-+ memcpy(ets->tc_tx_bw, pdata->ets->tc_tx_bw,
-+ sizeof(ets->tc_tx_bw));
-+ memcpy(ets->tc_tsa, pdata->ets->tc_tsa,
-+ sizeof(ets->tc_tsa));
-+ memcpy(ets->prio_tc, pdata->ets->prio_tc,
-+ sizeof(ets->prio_tc));
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_dcb_ieee_setets(struct net_device *netdev,
-+ struct ieee_ets *ets)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ unsigned int i, tc_ets, tc_ets_weight;
-+
-+ tc_ets = 0;
-+ tc_ets_weight = 0;
-+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
-+ DBGPR(" TC%u: tx_bw=%hhu, rx_bw=%hhu, tsa=%hhu\n", i,
-+ ets->tc_tx_bw[i], ets->tc_rx_bw[i], ets->tc_tsa[i]);
-+ DBGPR(" PRIO%u: TC=%hhu\n", i, ets->prio_tc[i]);
-+
-+ if ((ets->tc_tx_bw[i] || ets->tc_tsa[i]) &&
-+ (i >= pdata->hw_feat.tc_cnt))
-+ return -EINVAL;
-+
-+ if (ets->prio_tc[i] >= pdata->hw_feat.tc_cnt)
-+ return -EINVAL;
-+
-+ switch (ets->tc_tsa[i]) {
-+ case IEEE_8021QAZ_TSA_STRICT:
-+ break;
-+ case IEEE_8021QAZ_TSA_ETS:
-+ tc_ets = 1;
-+ tc_ets_weight += ets->tc_tx_bw[i];
-+ break;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+
-+ /* Weights must add up to 100% */
-+ if (tc_ets && (tc_ets_weight != 100))
-+ return -EINVAL;
-+
-+ if (!pdata->ets) {
-+ pdata->ets = devm_kzalloc(pdata->dev, sizeof(*pdata->ets),
-+ GFP_KERNEL);
-+ if (!pdata->ets)
-+ return -ENOMEM;
-+ }
-+
-+ memcpy(pdata->ets, ets, sizeof(*pdata->ets));
-+
-+ pdata->hw_if.config_dcb_tc(pdata);
-+
-+ return 0;
-+}
-+
-+static int xgbe_dcb_ieee_getpfc(struct net_device *netdev,
-+ struct ieee_pfc *pfc)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+
-+ /* Set number of supported PFC traffic classes */
-+ pfc->pfc_cap = pdata->hw_feat.tc_cnt;
-+
-+ if (pdata->pfc) {
-+ pfc->pfc_en = pdata->pfc->pfc_en;
-+ pfc->mbc = pdata->pfc->mbc;
-+ pfc->delay = pdata->pfc->delay;
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_dcb_ieee_setpfc(struct net_device *netdev,
-+ struct ieee_pfc *pfc)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+
-+ DBGPR(" cap=%hhu, en=%hhx, mbc=%hhu, delay=%hhu\n",
-+ pfc->pfc_cap, pfc->pfc_en, pfc->mbc, pfc->delay);
-+
-+ if (!pdata->pfc) {
-+ pdata->pfc = devm_kzalloc(pdata->dev, sizeof(*pdata->pfc),
-+ GFP_KERNEL);
-+ if (!pdata->pfc)
-+ return -ENOMEM;
-+ }
-+
-+ memcpy(pdata->pfc, pfc, sizeof(*pdata->pfc));
-+
-+ pdata->hw_if.config_dcb_pfc(pdata);
-+
-+ return 0;
-+}
-+
-+static u8 xgbe_dcb_getdcbx(struct net_device *netdev)
-+{
-+ return DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE;
-+}
-+
-+static u8 xgbe_dcb_setdcbx(struct net_device *netdev, u8 dcbx)
-+{
-+ u8 support = xgbe_dcb_getdcbx(netdev);
-+
-+ DBGPR(" DCBX=%#hhx\n", dcbx);
-+
-+ if (dcbx & ~support)
-+ return 1;
-+
-+ if ((dcbx & support) != support)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static const struct dcbnl_rtnl_ops xgbe_dcbnl_ops = {
-+ /* IEEE 802.1Qaz std */
-+ .ieee_getets = xgbe_dcb_ieee_getets,
-+ .ieee_setets = xgbe_dcb_ieee_setets,
-+ .ieee_getpfc = xgbe_dcb_ieee_getpfc,
-+ .ieee_setpfc = xgbe_dcb_ieee_setpfc,
-+
-+ /* DCBX configuration */
-+ .getdcbx = xgbe_dcb_getdcbx,
-+ .setdcbx = xgbe_dcb_setdcbx,
-+};
-+
-+const struct dcbnl_rtnl_ops *xgbe_a0_get_dcbnl_ops(void)
-+{
-+ return &xgbe_dcbnl_ops;
-+}
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-debugfs.c b/drivers/net/ethernet/amd/xgbe-a0/xgbe-debugfs.c
-new file mode 100644
-index 0000000..ecfa6f9
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-debugfs.c
-@@ -0,0 +1,373 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/debugfs.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+
-+#include "xgbe.h"
-+#include "xgbe-common.h"
-+
-+static ssize_t xgbe_common_read(char __user *buffer, size_t count,
-+ loff_t *ppos, unsigned int value)
-+{
-+ char *buf;
-+ ssize_t len;
-+
-+ if (*ppos != 0)
-+ return 0;
-+
-+ buf = kasprintf(GFP_KERNEL, "0x%08x\n", value);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ if (count < strlen(buf)) {
-+ kfree(buf);
-+ return -ENOSPC;
-+ }
-+
-+ len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
-+ kfree(buf);
-+
-+ return len;
-+}
-+
-+static ssize_t xgbe_common_write(const char __user *buffer, size_t count,
-+ loff_t *ppos, unsigned int *value)
-+{
-+ char workarea[32];
-+ ssize_t len;
-+ int ret;
-+
-+ if (*ppos != 0)
-+ return 0;
-+
-+ if (count >= sizeof(workarea))
-+ return -ENOSPC;
-+
-+ len = simple_write_to_buffer(workarea, sizeof(workarea) - 1, ppos,
-+ buffer, count);
-+ if (len < 0)
-+ return len;
-+
-+ workarea[len] = '\0';
-+ ret = kstrtouint(workarea, 16, value);
-+ if (ret)
-+ return -EIO;
-+
-+ return len;
-+}
-+
-+static ssize_t xgmac_reg_addr_read(struct file *filp, char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+
-+ return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xgmac_reg);
-+}
-+
-+static ssize_t xgmac_reg_addr_write(struct file *filp,
-+ const char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+
-+ return xgbe_common_write(buffer, count, ppos,
-+ &pdata->debugfs_xgmac_reg);
-+}
-+
-+static ssize_t xgmac_reg_value_read(struct file *filp, char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+ unsigned int value;
-+
-+ value = XGMAC_IOREAD(pdata, pdata->debugfs_xgmac_reg);
-+
-+ return xgbe_common_read(buffer, count, ppos, value);
-+}
-+
-+static ssize_t xgmac_reg_value_write(struct file *filp,
-+ const char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+ unsigned int value;
-+ ssize_t len;
-+
-+ len = xgbe_common_write(buffer, count, ppos, &value);
-+ if (len < 0)
-+ return len;
-+
-+ XGMAC_IOWRITE(pdata, pdata->debugfs_xgmac_reg, value);
-+
-+ return len;
-+}
-+
-+static const struct file_operations xgmac_reg_addr_fops = {
-+ .owner = THIS_MODULE,
-+ .open = simple_open,
-+ .read = xgmac_reg_addr_read,
-+ .write = xgmac_reg_addr_write,
-+};
-+
-+static const struct file_operations xgmac_reg_value_fops = {
-+ .owner = THIS_MODULE,
-+ .open = simple_open,
-+ .read = xgmac_reg_value_read,
-+ .write = xgmac_reg_value_write,
-+};
-+
-+static ssize_t xpcs_mmd_read(struct file *filp, char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+
-+ return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_mmd);
-+}
-+
-+static ssize_t xpcs_mmd_write(struct file *filp, const char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+
-+ return xgbe_common_write(buffer, count, ppos,
-+ &pdata->debugfs_xpcs_mmd);
-+}
-+
-+static ssize_t xpcs_reg_addr_read(struct file *filp, char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+
-+ return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_reg);
-+}
-+
-+static ssize_t xpcs_reg_addr_write(struct file *filp, const char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+
-+ return xgbe_common_write(buffer, count, ppos,
-+ &pdata->debugfs_xpcs_reg);
-+}
-+
-+static ssize_t xpcs_reg_value_read(struct file *filp, char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+ unsigned int value;
-+
-+ value = XMDIO_READ(pdata, pdata->debugfs_xpcs_mmd,
-+ pdata->debugfs_xpcs_reg);
-+
-+ return xgbe_common_read(buffer, count, ppos, value);
-+}
-+
-+static ssize_t xpcs_reg_value_write(struct file *filp,
-+ const char __user *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ struct xgbe_prv_data *pdata = filp->private_data;
-+ unsigned int value;
-+ ssize_t len;
-+
-+ len = xgbe_common_write(buffer, count, ppos, &value);
-+ if (len < 0)
-+ return len;
-+
-+ XMDIO_WRITE(pdata, pdata->debugfs_xpcs_mmd, pdata->debugfs_xpcs_reg,
-+ value);
-+
-+ return len;
-+}
-+
-+static const struct file_operations xpcs_mmd_fops = {
-+ .owner = THIS_MODULE,
-+ .open = simple_open,
-+ .read = xpcs_mmd_read,
-+ .write = xpcs_mmd_write,
-+};
-+
-+static const struct file_operations xpcs_reg_addr_fops = {
-+ .owner = THIS_MODULE,
-+ .open = simple_open,
-+ .read = xpcs_reg_addr_read,
-+ .write = xpcs_reg_addr_write,
-+};
-+
-+static const struct file_operations xpcs_reg_value_fops = {
-+ .owner = THIS_MODULE,
-+ .open = simple_open,
-+ .read = xpcs_reg_value_read,
-+ .write = xpcs_reg_value_write,
-+};
-+
-+void xgbe_a0_debugfs_init(struct xgbe_prv_data *pdata)
-+{
-+ struct dentry *pfile;
-+ char *buf;
-+
-+ /* Set defaults */
-+ pdata->debugfs_xgmac_reg = 0;
-+ pdata->debugfs_xpcs_mmd = 1;
-+ pdata->debugfs_xpcs_reg = 0;
-+
-+ buf = kasprintf(GFP_KERNEL, "amd-xgbe-a0-%s", pdata->netdev->name);
-+ pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL);
-+ if (!pdata->xgbe_debugfs) {
-+ netdev_err(pdata->netdev, "debugfs_create_dir failed\n");
-+ return;
-+ }
-+
-+ pfile = debugfs_create_file("xgmac_register", 0600,
-+ pdata->xgbe_debugfs, pdata,
-+ &xgmac_reg_addr_fops);
-+ if (!pfile)
-+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
-+
-+ pfile = debugfs_create_file("xgmac_register_value", 0600,
-+ pdata->xgbe_debugfs, pdata,
-+ &xgmac_reg_value_fops);
-+ if (!pfile)
-+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
-+
-+ pfile = debugfs_create_file("xpcs_mmd", 0600,
-+ pdata->xgbe_debugfs, pdata,
-+ &xpcs_mmd_fops);
-+ if (!pfile)
-+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
-+
-+ pfile = debugfs_create_file("xpcs_register", 0600,
-+ pdata->xgbe_debugfs, pdata,
-+ &xpcs_reg_addr_fops);
-+ if (!pfile)
-+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
-+
-+ pfile = debugfs_create_file("xpcs_register_value", 0600,
-+ pdata->xgbe_debugfs, pdata,
-+ &xpcs_reg_value_fops);
-+ if (!pfile)
-+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
-+
-+ kfree(buf);
-+}
-+
-+void xgbe_a0_debugfs_exit(struct xgbe_prv_data *pdata)
-+{
-+ debugfs_remove_recursive(pdata->xgbe_debugfs);
-+ pdata->xgbe_debugfs = NULL;
-+}
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe-a0/xgbe-desc.c
-new file mode 100644
-index 0000000..5dd5777
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-desc.c
-@@ -0,0 +1,636 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include "xgbe.h"
-+#include "xgbe-common.h"
-+
-+static void xgbe_unmap_rdata(struct xgbe_prv_data *, struct xgbe_ring_data *);
-+
-+static void xgbe_free_ring(struct xgbe_prv_data *pdata,
-+ struct xgbe_ring *ring)
-+{
-+ struct xgbe_ring_data *rdata;
-+ unsigned int i;
-+
-+ if (!ring)
-+ return;
-+
-+ if (ring->rdata) {
-+ for (i = 0; i < ring->rdesc_count; i++) {
-+ rdata = XGBE_GET_DESC_DATA(ring, i);
-+ xgbe_unmap_rdata(pdata, rdata);
-+ }
-+
-+ kfree(ring->rdata);
-+ ring->rdata = NULL;
-+ }
-+
-+ if (ring->rx_hdr_pa.pages) {
-+ dma_unmap_page(pdata->dev, ring->rx_hdr_pa.pages_dma,
-+ ring->rx_hdr_pa.pages_len, DMA_FROM_DEVICE);
-+ put_page(ring->rx_hdr_pa.pages);
-+
-+ ring->rx_hdr_pa.pages = NULL;
-+ ring->rx_hdr_pa.pages_len = 0;
-+ ring->rx_hdr_pa.pages_offset = 0;
-+ ring->rx_hdr_pa.pages_dma = 0;
-+ }
-+
-+ if (ring->rx_buf_pa.pages) {
-+ dma_unmap_page(pdata->dev, ring->rx_buf_pa.pages_dma,
-+ ring->rx_buf_pa.pages_len, DMA_FROM_DEVICE);
-+ put_page(ring->rx_buf_pa.pages);
-+
-+ ring->rx_buf_pa.pages = NULL;
-+ ring->rx_buf_pa.pages_len = 0;
-+ ring->rx_buf_pa.pages_offset = 0;
-+ ring->rx_buf_pa.pages_dma = 0;
-+ }
-+
-+ if (ring->rdesc) {
-+ dma_free_coherent(pdata->dev,
-+ (sizeof(struct xgbe_ring_desc) *
-+ ring->rdesc_count),
-+ ring->rdesc, ring->rdesc_dma);
-+ ring->rdesc = NULL;
-+ }
-+}
-+
-+static void xgbe_free_ring_resources(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ DBGPR("-->xgbe_free_ring_resources\n");
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ xgbe_free_ring(pdata, channel->tx_ring);
-+ xgbe_free_ring(pdata, channel->rx_ring);
-+ }
-+
-+ DBGPR("<--xgbe_free_ring_resources\n");
-+}
-+
-+static int xgbe_init_ring(struct xgbe_prv_data *pdata,
-+ struct xgbe_ring *ring, unsigned int rdesc_count)
-+{
-+ DBGPR("-->xgbe_init_ring\n");
-+
-+ if (!ring)
-+ return 0;
-+
-+ /* Descriptors */
-+ ring->rdesc_count = rdesc_count;
-+ ring->rdesc = dma_alloc_coherent(pdata->dev,
-+ (sizeof(struct xgbe_ring_desc) *
-+ rdesc_count), &ring->rdesc_dma,
-+ GFP_KERNEL);
-+ if (!ring->rdesc)
-+ return -ENOMEM;
-+
-+ /* Descriptor information */
-+ ring->rdata = kcalloc(rdesc_count, sizeof(struct xgbe_ring_data),
-+ GFP_KERNEL);
-+ if (!ring->rdata)
-+ return -ENOMEM;
-+
-+ DBGPR(" rdesc=0x%p, rdesc_dma=0x%llx, rdata=0x%p\n",
-+ ring->rdesc, ring->rdesc_dma, ring->rdata);
-+
-+ DBGPR("<--xgbe_init_ring\n");
-+
-+ return 0;
-+}
-+
-+static int xgbe_alloc_ring_resources(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+ int ret;
-+
-+ DBGPR("-->xgbe_alloc_ring_resources\n");
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ DBGPR(" %s - tx_ring:\n", channel->name);
-+ ret = xgbe_init_ring(pdata, channel->tx_ring,
-+ pdata->tx_desc_count);
-+ if (ret) {
-+ netdev_alert(pdata->netdev,
-+ "error initializing Tx ring\n");
-+ goto err_ring;
-+ }
-+
-+ DBGPR(" %s - rx_ring:\n", channel->name);
-+ ret = xgbe_init_ring(pdata, channel->rx_ring,
-+ pdata->rx_desc_count);
-+ if (ret) {
-+ netdev_alert(pdata->netdev,
-+ "error initializing Tx ring\n");
-+ goto err_ring;
-+ }
-+ }
-+
-+ DBGPR("<--xgbe_alloc_ring_resources\n");
-+
-+ return 0;
-+
-+err_ring:
-+ xgbe_free_ring_resources(pdata);
-+
-+ return ret;
-+}
-+
-+static int xgbe_alloc_pages(struct xgbe_prv_data *pdata,
-+ struct xgbe_page_alloc *pa, gfp_t gfp, int order)
-+{
-+ struct page *pages = NULL;
-+ dma_addr_t pages_dma;
-+ int ret;
-+
-+ /* Try to obtain pages, decreasing order if necessary */
-+ gfp |= __GFP_COLD | __GFP_COMP;
-+ while (order >= 0) {
-+ pages = alloc_pages(gfp, order);
-+ if (pages)
-+ break;
-+
-+ order--;
-+ }
-+ if (!pages)
-+ return -ENOMEM;
-+
-+ /* Map the pages */
-+ pages_dma = dma_map_page(pdata->dev, pages, 0,
-+ PAGE_SIZE << order, DMA_FROM_DEVICE);
-+ ret = dma_mapping_error(pdata->dev, pages_dma);
-+ if (ret) {
-+ put_page(pages);
-+ return ret;
-+ }
-+
-+ pa->pages = pages;
-+ pa->pages_len = PAGE_SIZE << order;
-+ pa->pages_offset = 0;
-+ pa->pages_dma = pages_dma;
-+
-+ return 0;
-+}
-+
-+static void xgbe_set_buffer_data(struct xgbe_buffer_data *bd,
-+ struct xgbe_page_alloc *pa,
-+ unsigned int len)
-+{
-+ get_page(pa->pages);
-+ bd->pa = *pa;
-+
-+ bd->dma = pa->pages_dma + pa->pages_offset;
-+ bd->dma_len = len;
-+
-+ pa->pages_offset += len;
-+ if ((pa->pages_offset + len) > pa->pages_len) {
-+ /* This data descriptor is responsible for unmapping page(s) */
-+ bd->pa_unmap = *pa;
-+
-+ /* Get a new allocation next time */
-+ pa->pages = NULL;
-+ pa->pages_len = 0;
-+ pa->pages_offset = 0;
-+ pa->pages_dma = 0;
-+ }
-+}
-+
-+static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata,
-+ struct xgbe_ring *ring,
-+ struct xgbe_ring_data *rdata)
-+{
-+ int order, ret;
-+
-+ if (!ring->rx_hdr_pa.pages) {
-+ ret = xgbe_alloc_pages(pdata, &ring->rx_hdr_pa, GFP_ATOMIC, 0);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ if (!ring->rx_buf_pa.pages) {
-+ order = max_t(int, PAGE_ALLOC_COSTLY_ORDER - 1, 0);
-+ ret = xgbe_alloc_pages(pdata, &ring->rx_buf_pa, GFP_ATOMIC,
-+ order);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ /* Set up the header page info */
-+ xgbe_set_buffer_data(&rdata->rx.hdr, &ring->rx_hdr_pa,
-+ XGBE_SKB_ALLOC_SIZE);
-+
-+ /* Set up the buffer page info */
-+ xgbe_set_buffer_data(&rdata->rx.buf, &ring->rx_buf_pa,
-+ pdata->rx_buf_size);
-+
-+ return 0;
-+}
-+
-+static void xgbe_wrapper_tx_descriptor_init(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_channel *channel;
-+ struct xgbe_ring *ring;
-+ struct xgbe_ring_data *rdata;
-+ struct xgbe_ring_desc *rdesc;
-+ dma_addr_t rdesc_dma;
-+ unsigned int i, j;
-+
-+ DBGPR("-->xgbe_wrapper_tx_descriptor_init\n");
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ ring = channel->tx_ring;
-+ if (!ring)
-+ break;
-+
-+ rdesc = ring->rdesc;
-+ rdesc_dma = ring->rdesc_dma;
-+
-+ for (j = 0; j < ring->rdesc_count; j++) {
-+ rdata = XGBE_GET_DESC_DATA(ring, j);
-+
-+ rdata->rdesc = rdesc;
-+ rdata->rdesc_dma = rdesc_dma;
-+
-+ rdesc++;
-+ rdesc_dma += sizeof(struct xgbe_ring_desc);
-+ }
-+
-+ ring->cur = 0;
-+ ring->dirty = 0;
-+ memset(&ring->tx, 0, sizeof(ring->tx));
-+
-+ hw_if->tx_desc_init(channel);
-+ }
-+
-+ DBGPR("<--xgbe_wrapper_tx_descriptor_init\n");
-+}
-+
-+static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_channel *channel;
-+ struct xgbe_ring *ring;
-+ struct xgbe_ring_desc *rdesc;
-+ struct xgbe_ring_data *rdata;
-+ dma_addr_t rdesc_dma;
-+ unsigned int i, j;
-+
-+ DBGPR("-->xgbe_wrapper_rx_descriptor_init\n");
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ ring = channel->rx_ring;
-+ if (!ring)
-+ break;
-+
-+ rdesc = ring->rdesc;
-+ rdesc_dma = ring->rdesc_dma;
-+
-+ for (j = 0; j < ring->rdesc_count; j++) {
-+ rdata = XGBE_GET_DESC_DATA(ring, j);
-+
-+ rdata->rdesc = rdesc;
-+ rdata->rdesc_dma = rdesc_dma;
-+
-+ if (xgbe_map_rx_buffer(pdata, ring, rdata))
-+ break;
-+
-+ rdesc++;
-+ rdesc_dma += sizeof(struct xgbe_ring_desc);
-+ }
-+
-+ ring->cur = 0;
-+ ring->dirty = 0;
-+
-+ hw_if->rx_desc_init(channel);
-+ }
-+
-+ DBGPR("<--xgbe_wrapper_rx_descriptor_init\n");
-+}
-+
-+static void xgbe_unmap_rdata(struct xgbe_prv_data *pdata,
-+ struct xgbe_ring_data *rdata)
-+{
-+ if (rdata->skb_dma) {
-+ if (rdata->mapped_as_page) {
-+ dma_unmap_page(pdata->dev, rdata->skb_dma,
-+ rdata->skb_dma_len, DMA_TO_DEVICE);
-+ } else {
-+ dma_unmap_single(pdata->dev, rdata->skb_dma,
-+ rdata->skb_dma_len, DMA_TO_DEVICE);
-+ }
-+ rdata->skb_dma = 0;
-+ rdata->skb_dma_len = 0;
-+ }
-+
-+ if (rdata->skb) {
-+ dev_kfree_skb_any(rdata->skb);
-+ rdata->skb = NULL;
-+ }
-+
-+ if (rdata->rx.hdr.pa.pages)
-+ put_page(rdata->rx.hdr.pa.pages);
-+
-+ if (rdata->rx.hdr.pa_unmap.pages) {
-+ dma_unmap_page(pdata->dev, rdata->rx.hdr.pa_unmap.pages_dma,
-+ rdata->rx.hdr.pa_unmap.pages_len,
-+ DMA_FROM_DEVICE);
-+ put_page(rdata->rx.hdr.pa_unmap.pages);
-+ }
-+
-+ if (rdata->rx.buf.pa.pages)
-+ put_page(rdata->rx.buf.pa.pages);
-+
-+ if (rdata->rx.buf.pa_unmap.pages) {
-+ dma_unmap_page(pdata->dev, rdata->rx.buf.pa_unmap.pages_dma,
-+ rdata->rx.buf.pa_unmap.pages_len,
-+ DMA_FROM_DEVICE);
-+ put_page(rdata->rx.buf.pa_unmap.pages);
-+ }
-+
-+ memset(&rdata->tx, 0, sizeof(rdata->tx));
-+ memset(&rdata->rx, 0, sizeof(rdata->rx));
-+
-+ rdata->mapped_as_page = 0;
-+
-+ if (rdata->state_saved) {
-+ rdata->state_saved = 0;
-+ rdata->state.incomplete = 0;
-+ rdata->state.context_next = 0;
-+ rdata->state.skb = NULL;
-+ rdata->state.len = 0;
-+ rdata->state.error = 0;
-+ }
-+}
-+
-+static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
-+{
-+ struct xgbe_prv_data *pdata = channel->pdata;
-+ struct xgbe_ring *ring = channel->tx_ring;
-+ struct xgbe_ring_data *rdata;
-+ struct xgbe_packet_data *packet;
-+ struct skb_frag_struct *frag;
-+ dma_addr_t skb_dma;
-+ unsigned int start_index, cur_index;
-+ unsigned int offset, tso, vlan, datalen, len;
-+ unsigned int i;
-+
-+ DBGPR("-->xgbe_map_tx_skb: cur = %d\n", ring->cur);
-+
-+ offset = 0;
-+ start_index = ring->cur;
-+ cur_index = ring->cur;
-+
-+ packet = &ring->packet_data;
-+ packet->rdesc_count = 0;
-+ packet->length = 0;
-+
-+ tso = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ TSO_ENABLE);
-+ vlan = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ VLAN_CTAG);
-+
-+ /* Save space for a context descriptor if needed */
-+ if ((tso && (packet->mss != ring->tx.cur_mss)) ||
-+ (vlan && (packet->vlan_ctag != ring->tx.cur_vlan_ctag)))
-+ cur_index++;
-+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
-+
-+ if (tso) {
-+ DBGPR(" TSO packet\n");
-+
-+ /* Map the TSO header */
-+ skb_dma = dma_map_single(pdata->dev, skb->data,
-+ packet->header_len, DMA_TO_DEVICE);
-+ if (dma_mapping_error(pdata->dev, skb_dma)) {
-+ netdev_alert(pdata->netdev, "dma_map_single failed\n");
-+ goto err_out;
-+ }
-+ rdata->skb_dma = skb_dma;
-+ rdata->skb_dma_len = packet->header_len;
-+
-+ offset = packet->header_len;
-+
-+ packet->length += packet->header_len;
-+
-+ cur_index++;
-+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
-+ }
-+
-+ /* Map the (remainder of the) packet */
-+ for (datalen = skb_headlen(skb) - offset; datalen; ) {
-+ len = min_t(unsigned int, datalen, XGBE_TX_MAX_BUF_SIZE);
-+
-+ skb_dma = dma_map_single(pdata->dev, skb->data + offset, len,
-+ DMA_TO_DEVICE);
-+ if (dma_mapping_error(pdata->dev, skb_dma)) {
-+ netdev_alert(pdata->netdev, "dma_map_single failed\n");
-+ goto err_out;
-+ }
-+ rdata->skb_dma = skb_dma;
-+ rdata->skb_dma_len = len;
-+ DBGPR(" skb data: index=%u, dma=0x%llx, len=%u\n",
-+ cur_index, skb_dma, len);
-+
-+ datalen -= len;
-+ offset += len;
-+
-+ packet->length += len;
-+
-+ cur_index++;
-+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
-+ }
-+
-+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+ DBGPR(" mapping frag %u\n", i);
-+
-+ frag = &skb_shinfo(skb)->frags[i];
-+ offset = 0;
-+
-+ for (datalen = skb_frag_size(frag); datalen; ) {
-+ len = min_t(unsigned int, datalen,
-+ XGBE_TX_MAX_BUF_SIZE);
-+
-+ skb_dma = skb_frag_dma_map(pdata->dev, frag, offset,
-+ len, DMA_TO_DEVICE);
-+ if (dma_mapping_error(pdata->dev, skb_dma)) {
-+ netdev_alert(pdata->netdev,
-+ "skb_frag_dma_map failed\n");
-+ goto err_out;
-+ }
-+ rdata->skb_dma = skb_dma;
-+ rdata->skb_dma_len = len;
-+ rdata->mapped_as_page = 1;
-+ DBGPR(" skb data: index=%u, dma=0x%llx, len=%u\n",
-+ cur_index, skb_dma, len);
-+
-+ datalen -= len;
-+ offset += len;
-+
-+ packet->length += len;
-+
-+ cur_index++;
-+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
-+ }
-+ }
-+
-+ /* Save the skb address in the last entry. We always have some data
-+ * that has been mapped so rdata is always advanced past the last
-+ * piece of mapped data - use the entry pointed to by cur_index - 1.
-+ */
-+ rdata = XGBE_GET_DESC_DATA(ring, cur_index - 1);
-+ rdata->skb = skb;
-+
-+ /* Save the number of descriptor entries used */
-+ packet->rdesc_count = cur_index - start_index;
-+
-+ DBGPR("<--xgbe_map_tx_skb: count=%u\n", packet->rdesc_count);
-+
-+ return packet->rdesc_count;
-+
-+err_out:
-+ while (start_index < cur_index) {
-+ rdata = XGBE_GET_DESC_DATA(ring, start_index++);
-+ xgbe_unmap_rdata(pdata, rdata);
-+ }
-+
-+ DBGPR("<--xgbe_map_tx_skb: count=0\n");
-+
-+ return 0;
-+}
-+
-+void xgbe_a0_init_function_ptrs_desc(struct xgbe_desc_if *desc_if)
-+{
-+ DBGPR("-->xgbe_a0_init_function_ptrs_desc\n");
-+
-+ desc_if->alloc_ring_resources = xgbe_alloc_ring_resources;
-+ desc_if->free_ring_resources = xgbe_free_ring_resources;
-+ desc_if->map_tx_skb = xgbe_map_tx_skb;
-+ desc_if->map_rx_buffer = xgbe_map_rx_buffer;
-+ desc_if->unmap_rdata = xgbe_unmap_rdata;
-+ desc_if->wrapper_tx_desc_init = xgbe_wrapper_tx_descriptor_init;
-+ desc_if->wrapper_rx_desc_init = xgbe_wrapper_rx_descriptor_init;
-+
-+ DBGPR("<--xgbe_a0_init_function_ptrs_desc\n");
-+}
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe-a0/xgbe-dev.c
-new file mode 100644
-index 0000000..2d88739
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-dev.c
-@@ -0,0 +1,2930 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/phy.h>
-+#include <linux/mdio.h>
-+#include <linux/clk.h>
-+#include <linux/bitrev.h>
-+#include <linux/crc32.h>
-+
-+#include "xgbe.h"
-+#include "xgbe-common.h"
-+
-+static unsigned int xgbe_usec_to_riwt(struct xgbe_prv_data *pdata,
-+ unsigned int usec)
-+{
-+ unsigned long rate;
-+ unsigned int ret;
-+
-+ DBGPR("-->xgbe_usec_to_riwt\n");
-+
-+ rate = pdata->sysclk_rate;
-+
-+ /*
-+ * Convert the input usec value to the watchdog timer value. Each
-+ * watchdog timer value is equivalent to 256 clock cycles.
-+ * Calculate the required value as:
-+ * ( usec * ( system_clock_mhz / 10^6 ) / 256
-+ */
-+ ret = (usec * (rate / 1000000)) / 256;
-+
-+ DBGPR("<--xgbe_usec_to_riwt\n");
-+
-+ return ret;
-+}
-+
-+static unsigned int xgbe_riwt_to_usec(struct xgbe_prv_data *pdata,
-+ unsigned int riwt)
-+{
-+ unsigned long rate;
-+ unsigned int ret;
-+
-+ DBGPR("-->xgbe_riwt_to_usec\n");
-+
-+ rate = pdata->sysclk_rate;
-+
-+ /*
-+ * Convert the input watchdog timer value to the usec value. Each
-+ * watchdog timer value is equivalent to 256 clock cycles.
-+ * Calculate the required value as:
-+ * ( riwt * 256 ) / ( system_clock_mhz / 10^6 )
-+ */
-+ ret = (riwt * 256) / (rate / 1000000);
-+
-+ DBGPR("<--xgbe_riwt_to_usec\n");
-+
-+ return ret;
-+}
-+
-+static int xgbe_config_pblx8(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++)
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_CR, PBLX8,
-+ pdata->pblx8);
-+
-+ return 0;
-+}
-+
-+static int xgbe_get_tx_pbl_val(struct xgbe_prv_data *pdata)
-+{
-+ return XGMAC_DMA_IOREAD_BITS(pdata->channel, DMA_CH_TCR, PBL);
-+}
-+
-+static int xgbe_config_tx_pbl_val(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, PBL,
-+ pdata->tx_pbl);
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_get_rx_pbl_val(struct xgbe_prv_data *pdata)
-+{
-+ return XGMAC_DMA_IOREAD_BITS(pdata->channel, DMA_CH_RCR, PBL);
-+}
-+
-+static int xgbe_config_rx_pbl_val(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->rx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, PBL,
-+ pdata->rx_pbl);
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_config_osp_mode(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, OSP,
-+ pdata->tx_osp_mode);
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_config_rsf_mode(struct xgbe_prv_data *pdata, unsigned int val)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < pdata->rx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RSF, val);
-+
-+ return 0;
-+}
-+
-+static int xgbe_config_tsf_mode(struct xgbe_prv_data *pdata, unsigned int val)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < pdata->tx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TSF, val);
-+
-+ return 0;
-+}
-+
-+static int xgbe_config_rx_threshold(struct xgbe_prv_data *pdata,
-+ unsigned int val)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < pdata->rx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RTC, val);
-+
-+ return 0;
-+}
-+
-+static int xgbe_config_tx_threshold(struct xgbe_prv_data *pdata,
-+ unsigned int val)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < pdata->tx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TTC, val);
-+
-+ return 0;
-+}
-+
-+static int xgbe_config_rx_coalesce(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->rx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RIWT, RWT,
-+ pdata->rx_riwt);
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_config_tx_coalesce(struct xgbe_prv_data *pdata)
-+{
-+ return 0;
-+}
-+
-+static void xgbe_config_rx_buffer_size(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->rx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, RBSZ,
-+ pdata->rx_buf_size);
-+ }
-+}
-+
-+static void xgbe_config_tso_mode(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, TSE, 1);
-+ }
-+}
-+
-+static void xgbe_config_sph_mode(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->rx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_CR, SPH, 1);
-+ }
-+
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, HDSMS, XGBE_SPH_HDSMS_SIZE);
-+}
-+
-+static int xgbe_write_rss_reg(struct xgbe_prv_data *pdata, unsigned int type,
-+ unsigned int index, unsigned int val)
-+{
-+ unsigned int wait;
-+ int ret = 0;
-+
-+ mutex_lock(&pdata->rss_mutex);
-+
-+ if (XGMAC_IOREAD_BITS(pdata, MAC_RSSAR, OB)) {
-+ ret = -EBUSY;
-+ goto unlock;
-+ }
-+
-+ XGMAC_IOWRITE(pdata, MAC_RSSDR, val);
-+
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, RSSIA, index);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, ADDRT, type);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, CT, 0);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RSSAR, OB, 1);
-+
-+ wait = 1000;
-+ while (wait--) {
-+ if (!XGMAC_IOREAD_BITS(pdata, MAC_RSSAR, OB))
-+ goto unlock;
-+
-+ usleep_range(1000, 1500);
-+ }
-+
-+ ret = -EBUSY;
-+
-+unlock:
-+ mutex_unlock(&pdata->rss_mutex);
-+
-+ return ret;
-+}
-+
-+static int xgbe_write_rss_hash_key(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int key_regs = sizeof(pdata->rss_key) / sizeof(u32);
-+ unsigned int *key = (unsigned int *)&pdata->rss_key;
-+ int ret;
-+
-+ while (key_regs--) {
-+ ret = xgbe_write_rss_reg(pdata, XGBE_RSS_HASH_KEY_TYPE,
-+ key_regs, *key++);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_write_rss_lookup_table(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int i;
-+ int ret;
-+
-+ for (i = 0; i < ARRAY_SIZE(pdata->rss_table); i++) {
-+ ret = xgbe_write_rss_reg(pdata,
-+ XGBE_RSS_LOOKUP_TABLE_TYPE, i,
-+ pdata->rss_table[i]);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_rss_hash_key(struct xgbe_prv_data *pdata, const u8 *key)
-+{
-+ memcpy(pdata->rss_key, key, sizeof(pdata->rss_key));
-+
-+ return xgbe_write_rss_hash_key(pdata);
-+}
-+
-+static int xgbe_set_rss_lookup_table(struct xgbe_prv_data *pdata,
-+ const u32 *table)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(pdata->rss_table); i++)
-+ XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH, table[i]);
-+
-+ return xgbe_write_rss_lookup_table(pdata);
-+}
-+
-+static int xgbe_enable_rss(struct xgbe_prv_data *pdata)
-+{
-+ int ret;
-+
-+ if (!pdata->hw_feat.rss)
-+ return -EOPNOTSUPP;
-+
-+ /* Program the hash key */
-+ ret = xgbe_write_rss_hash_key(pdata);
-+ if (ret)
-+ return ret;
-+
-+ /* Program the lookup table */
-+ ret = xgbe_write_rss_lookup_table(pdata);
-+ if (ret)
-+ return ret;
-+
-+ /* Set the RSS options */
-+ XGMAC_IOWRITE(pdata, MAC_RSSCR, pdata->rss_options);
-+
-+ /* Enable RSS */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RSSCR, RSSE, 1);
-+
-+ return 0;
-+}
-+
-+static int xgbe_disable_rss(struct xgbe_prv_data *pdata)
-+{
-+ if (!pdata->hw_feat.rss)
-+ return -EOPNOTSUPP;
-+
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RSSCR, RSSE, 0);
-+
-+ return 0;
-+}
-+
-+static void xgbe_config_rss(struct xgbe_prv_data *pdata)
-+{
-+ int ret;
-+
-+ if (!pdata->hw_feat.rss)
-+ return;
-+
-+ if (pdata->netdev->features & NETIF_F_RXHASH)
-+ ret = xgbe_enable_rss(pdata);
-+ else
-+ ret = xgbe_disable_rss(pdata);
-+
-+ if (ret)
-+ netdev_err(pdata->netdev,
-+ "error configuring RSS, RSS disabled\n");
-+}
-+
-+static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int max_q_count, q_count;
-+ unsigned int reg, reg_val;
-+ unsigned int i;
-+
-+ /* Clear MTL flow control */
-+ for (i = 0; i < pdata->rx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
-+
-+ /* Clear MAC flow control */
-+ max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-+ q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
-+ reg = MAC_Q0TFCR;
-+ for (i = 0; i < q_count; i++) {
-+ reg_val = XGMAC_IOREAD(pdata, reg);
-+ XGMAC_SET_BITS(reg_val, MAC_Q0TFCR, TFE, 0);
-+ XGMAC_IOWRITE(pdata, reg, reg_val);
-+
-+ reg += MAC_QTFCR_INC;
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int max_q_count, q_count;
-+ unsigned int reg, reg_val;
-+ unsigned int i;
-+
-+ /* Set MTL flow control */
-+ for (i = 0; i < pdata->rx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 1);
-+
-+ /* Set MAC flow control */
-+ max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-+ q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
-+ reg = MAC_Q0TFCR;
-+ for (i = 0; i < q_count; i++) {
-+ reg_val = XGMAC_IOREAD(pdata, reg);
-+
-+ /* Enable transmit flow control */
-+ XGMAC_SET_BITS(reg_val, MAC_Q0TFCR, TFE, 1);
-+ /* Set pause time */
-+ XGMAC_SET_BITS(reg_val, MAC_Q0TFCR, PT, 0xffff);
-+
-+ XGMAC_IOWRITE(pdata, reg, reg_val);
-+
-+ reg += MAC_QTFCR_INC;
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_disable_rx_flow_control(struct xgbe_prv_data *pdata)
-+{
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RFCR, RFE, 0);
-+
-+ return 0;
-+}
-+
-+static int xgbe_enable_rx_flow_control(struct xgbe_prv_data *pdata)
-+{
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RFCR, RFE, 1);
-+
-+ return 0;
-+}
-+
-+static int xgbe_config_tx_flow_control(struct xgbe_prv_data *pdata)
-+{
-+ struct ieee_pfc *pfc = pdata->pfc;
-+
-+ if (pdata->tx_pause || (pfc && pfc->pfc_en))
-+ xgbe_enable_tx_flow_control(pdata);
-+ else
-+ xgbe_disable_tx_flow_control(pdata);
-+
-+ return 0;
-+}
-+
-+static int xgbe_config_rx_flow_control(struct xgbe_prv_data *pdata)
-+{
-+ struct ieee_pfc *pfc = pdata->pfc;
-+
-+ if (pdata->rx_pause || (pfc && pfc->pfc_en))
-+ xgbe_enable_rx_flow_control(pdata);
-+ else
-+ xgbe_disable_rx_flow_control(pdata);
-+
-+ return 0;
-+}
-+
-+static void xgbe_config_flow_control(struct xgbe_prv_data *pdata)
-+{
-+ struct ieee_pfc *pfc = pdata->pfc;
-+
-+ xgbe_config_tx_flow_control(pdata);
-+ xgbe_config_rx_flow_control(pdata);
-+
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE,
-+ (pfc && pfc->pfc_en) ? 1 : 0);
-+}
-+
-+static void xgbe_enable_dma_interrupts(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int dma_ch_isr, dma_ch_ier;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ /* Clear all the interrupts which are set */
-+ dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR);
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_ch_isr);
-+
-+ /* Clear all interrupt enable bits */
-+ dma_ch_ier = 0;
-+
-+ /* Enable following interrupts
-+ * NIE - Normal Interrupt Summary Enable
-+ * AIE - Abnormal Interrupt Summary Enable
-+ * FBEE - Fatal Bus Error Enable
-+ */
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, NIE, 1);
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, AIE, 1);
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 1);
-+
-+ if (channel->tx_ring) {
-+ /* Enable the following Tx interrupts
-+ * TIE - Transmit Interrupt Enable (unless using
-+ * per channel interrupts)
-+ */
-+ if (!pdata->per_channel_irq)
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1);
-+ }
-+ if (channel->rx_ring) {
-+ /* Enable following Rx interrupts
-+ * RBUE - Receive Buffer Unavailable Enable
-+ * RIE - Receive Interrupt Enable (unless using
-+ * per channel interrupts)
-+ */
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 1);
-+ if (!pdata->per_channel_irq)
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1);
-+ }
-+
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
-+ }
-+}
-+
-+static void xgbe_enable_mtl_interrupts(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int mtl_q_isr;
-+ unsigned int q_count, i;
-+
-+ q_count = max(pdata->hw_feat.tx_q_cnt, pdata->hw_feat.rx_q_cnt);
-+ for (i = 0; i < q_count; i++) {
-+ /* Clear all the interrupts which are set */
-+ mtl_q_isr = XGMAC_MTL_IOREAD(pdata, i, MTL_Q_ISR);
-+ XGMAC_MTL_IOWRITE(pdata, i, MTL_Q_ISR, mtl_q_isr);
-+
-+ /* No MTL interrupts to be enabled */
-+ XGMAC_MTL_IOWRITE(pdata, i, MTL_Q_IER, 0);
-+ }
-+}
-+
-+static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int mac_ier = 0;
-+
-+ /* Enable Timestamp interrupt */
-+ XGMAC_SET_BITS(mac_ier, MAC_IER, TSIE, 1);
-+
-+ XGMAC_IOWRITE(pdata, MAC_IER, mac_ier);
-+
-+ /* Enable all counter interrupts */
-+ XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xffffffff);
-+ XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xffffffff);
-+}
-+
-+static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata)
-+{
-+ if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0x3)
-+ return 0;
-+
-+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x3);
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_gmii_2500_speed(struct xgbe_prv_data *pdata)
-+{
-+ if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0x2)
-+ return 0;
-+
-+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x2);
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_xgmii_speed(struct xgbe_prv_data *pdata)
-+{
-+ if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0)
-+ return 0;
-+
-+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0);
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_promiscuous_mode(struct xgbe_prv_data *pdata,
-+ unsigned int enable)
-+{
-+ unsigned int val = enable ? 1 : 0;
-+
-+ if (XGMAC_IOREAD_BITS(pdata, MAC_PFR, PR) == val)
-+ return 0;
-+
-+ DBGPR(" %s promiscuous mode\n", enable ? "entering" : "leaving");
-+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, val);
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_all_multicast_mode(struct xgbe_prv_data *pdata,
-+ unsigned int enable)
-+{
-+ unsigned int val = enable ? 1 : 0;
-+
-+ if (XGMAC_IOREAD_BITS(pdata, MAC_PFR, PM) == val)
-+ return 0;
-+
-+ DBGPR(" %s allmulti mode\n", enable ? "entering" : "leaving");
-+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, val);
-+
-+ return 0;
-+}
-+
-+static void xgbe_set_mac_reg(struct xgbe_prv_data *pdata,
-+ struct netdev_hw_addr *ha, unsigned int *mac_reg)
-+{
-+ unsigned int mac_addr_hi, mac_addr_lo;
-+ u8 *mac_addr;
-+
-+ mac_addr_lo = 0;
-+ mac_addr_hi = 0;
-+
-+ if (ha) {
-+ mac_addr = (u8 *)&mac_addr_lo;
-+ mac_addr[0] = ha->addr[0];
-+ mac_addr[1] = ha->addr[1];
-+ mac_addr[2] = ha->addr[2];
-+ mac_addr[3] = ha->addr[3];
-+ mac_addr = (u8 *)&mac_addr_hi;
-+ mac_addr[0] = ha->addr[4];
-+ mac_addr[1] = ha->addr[5];
-+
-+ DBGPR(" adding mac address %pM at 0x%04x\n", ha->addr,
-+ *mac_reg);
-+
-+ XGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1);
-+ }
-+
-+ XGMAC_IOWRITE(pdata, *mac_reg, mac_addr_hi);
-+ *mac_reg += MAC_MACA_INC;
-+ XGMAC_IOWRITE(pdata, *mac_reg, mac_addr_lo);
-+ *mac_reg += MAC_MACA_INC;
-+}
-+
-+static void xgbe_set_mac_addn_addrs(struct xgbe_prv_data *pdata)
-+{
-+ struct net_device *netdev = pdata->netdev;
-+ struct netdev_hw_addr *ha;
-+ unsigned int mac_reg;
-+ unsigned int addn_macs;
-+
-+ mac_reg = MAC_MACA1HR;
-+ addn_macs = pdata->hw_feat.addn_mac;
-+
-+ if (netdev_uc_count(netdev) > addn_macs) {
-+ xgbe_set_promiscuous_mode(pdata, 1);
-+ } else {
-+ netdev_for_each_uc_addr(ha, netdev) {
-+ xgbe_set_mac_reg(pdata, ha, &mac_reg);
-+ addn_macs--;
-+ }
-+
-+ if (netdev_mc_count(netdev) > addn_macs) {
-+ xgbe_set_all_multicast_mode(pdata, 1);
-+ } else {
-+ netdev_for_each_mc_addr(ha, netdev) {
-+ xgbe_set_mac_reg(pdata, ha, &mac_reg);
-+ addn_macs--;
-+ }
-+ }
-+ }
-+
-+ /* Clear remaining additional MAC address entries */
-+ while (addn_macs--)
-+ xgbe_set_mac_reg(pdata, NULL, &mac_reg);
-+}
-+
-+static void xgbe_set_mac_hash_table(struct xgbe_prv_data *pdata)
-+{
-+ struct net_device *netdev = pdata->netdev;
-+ struct netdev_hw_addr *ha;
-+ unsigned int hash_reg;
-+ unsigned int hash_table_shift, hash_table_count;
-+ u32 hash_table[XGBE_MAC_HASH_TABLE_SIZE];
-+ u32 crc;
-+ unsigned int i;
-+
-+ hash_table_shift = 26 - (pdata->hw_feat.hash_table_size >> 7);
-+ hash_table_count = pdata->hw_feat.hash_table_size / 32;
-+ memset(hash_table, 0, sizeof(hash_table));
-+
-+ /* Build the MAC Hash Table register values */
-+ netdev_for_each_uc_addr(ha, netdev) {
-+ crc = bitrev32(~crc32_le(~0, ha->addr, ETH_ALEN));
-+ crc >>= hash_table_shift;
-+ hash_table[crc >> 5] |= (1 << (crc & 0x1f));
-+ }
-+
-+ netdev_for_each_mc_addr(ha, netdev) {
-+ crc = bitrev32(~crc32_le(~0, ha->addr, ETH_ALEN));
-+ crc >>= hash_table_shift;
-+ hash_table[crc >> 5] |= (1 << (crc & 0x1f));
-+ }
-+
-+ /* Set the MAC Hash Table registers */
-+ hash_reg = MAC_HTR0;
-+ for (i = 0; i < hash_table_count; i++) {
-+ XGMAC_IOWRITE(pdata, hash_reg, hash_table[i]);
-+ hash_reg += MAC_HTR_INC;
-+ }
-+}
-+
-+static int xgbe_add_mac_addresses(struct xgbe_prv_data *pdata)
-+{
-+ if (pdata->hw_feat.hash_table_size)
-+ xgbe_set_mac_hash_table(pdata);
-+ else
-+ xgbe_set_mac_addn_addrs(pdata);
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_mac_address(struct xgbe_prv_data *pdata, u8 *addr)
-+{
-+ unsigned int mac_addr_hi, mac_addr_lo;
-+
-+ mac_addr_hi = (addr[5] << 8) | (addr[4] << 0);
-+ mac_addr_lo = (addr[3] << 24) | (addr[2] << 16) |
-+ (addr[1] << 8) | (addr[0] << 0);
-+
-+ XGMAC_IOWRITE(pdata, MAC_MACA0HR, mac_addr_hi);
-+ XGMAC_IOWRITE(pdata, MAC_MACA0LR, mac_addr_lo);
-+
-+ return 0;
-+}
-+
-+static int xgbe_read_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
-+ int mmd_reg)
-+{
-+ unsigned int mmd_address;
-+ int mmd_data;
-+
-+ if (mmd_reg & MII_ADDR_C45)
-+ mmd_address = mmd_reg & ~MII_ADDR_C45;
-+ else
-+ mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
-+
-+ /* The PCS implementation has reversed the devices in
-+ * package registers so we need to change 05 to 06 and
-+ * 06 to 05 if being read (these registers are readonly
-+ * so no need to do this in the write function)
-+ */
-+ if ((mmd_address & 0xffff) == 0x05)
-+ mmd_address = (mmd_address & ~0xffff) | 0x06;
-+ else if ((mmd_address & 0xffff) == 0x06)
-+ mmd_address = (mmd_address & ~0xffff) | 0x05;
-+
-+ /* The PCS registers are accessed using mmio. The underlying APB3
-+ * management interface uses indirect addressing to access the MMD
-+ * register sets. This requires accessing of the PCS register in two
-+ * phases, an address phase and a data phase.
-+ *
-+ * The mmio interface is based on 32-bit offsets and values. All
-+ * register offsets must therefore be adjusted by left shifting the
-+ * offset 2 bits and reading 32 bits of data.
-+ */
-+ mutex_lock(&pdata->xpcs_mutex);
-+ XPCS_IOWRITE(pdata, PCS_MMD_SELECT << 2, mmd_address >> 8);
-+ mmd_data = XPCS_IOREAD(pdata, (mmd_address & 0xff) << 2);
-+ mutex_unlock(&pdata->xpcs_mutex);
-+
-+ return mmd_data;
-+}
-+
-+static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
-+ int mmd_reg, int mmd_data)
-+{
-+ unsigned int mmd_address;
-+
-+ if (mmd_reg & MII_ADDR_C45)
-+ mmd_address = mmd_reg & ~MII_ADDR_C45;
-+ else
-+ mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
-+
-+ /* If the PCS is changing modes, match the MAC speed to it */
-+ if (((mmd_address >> 16) == MDIO_MMD_PCS) &&
-+ ((mmd_address & 0xffff) == MDIO_CTRL2)) {
-+ struct phy_device *phydev = pdata->phydev;
-+
-+ if (mmd_data & MDIO_PCS_CTRL2_TYPE) {
-+ /* KX mode */
-+ if (phydev->supported & SUPPORTED_1000baseKX_Full)
-+ xgbe_set_gmii_speed(pdata);
-+ else
-+ xgbe_set_gmii_2500_speed(pdata);
-+ } else {
-+ /* KR mode */
-+ xgbe_set_xgmii_speed(pdata);
-+ }
-+ }
-+
-+ /* The PCS registers are accessed using mmio. The underlying APB3
-+ * management interface uses indirect addressing to access the MMD
-+ * register sets. This requires accessing of the PCS register in two
-+ * phases, an address phase and a data phase.
-+ *
-+ * The mmio interface is based on 32-bit offsets and values. All
-+ * register offsets must therefore be adjusted by left shifting the
-+ * offset 2 bits and reading 32 bits of data.
-+ */
-+ mutex_lock(&pdata->xpcs_mutex);
-+ XPCS_IOWRITE(pdata, PCS_MMD_SELECT << 2, mmd_address >> 8);
-+ XPCS_IOWRITE(pdata, (mmd_address & 0xff) << 2, mmd_data);
-+ mutex_unlock(&pdata->xpcs_mutex);
-+}
-+
-+static int xgbe_tx_complete(struct xgbe_ring_desc *rdesc)
-+{
-+ return !XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN);
-+}
-+
-+static int xgbe_disable_rx_csum(struct xgbe_prv_data *pdata)
-+{
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, IPC, 0);
-+
-+ return 0;
-+}
-+
-+static int xgbe_enable_rx_csum(struct xgbe_prv_data *pdata)
-+{
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, IPC, 1);
-+
-+ return 0;
-+}
-+
-+static int xgbe_enable_rx_vlan_stripping(struct xgbe_prv_data *pdata)
-+{
-+ /* Put the VLAN tag in the Rx descriptor */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLRXS, 1);
-+
-+ /* Don't check the VLAN type */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, DOVLTC, 1);
-+
-+ /* Check only C-TAG (0x8100) packets */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERSVLM, 0);
-+
-+ /* Don't consider an S-TAG (0x88A8) packet as a VLAN packet */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ESVL, 0);
-+
-+ /* Enable VLAN tag stripping */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0x3);
-+
-+ return 0;
-+}
-+
-+static int xgbe_disable_rx_vlan_stripping(struct xgbe_prv_data *pdata)
-+{
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0);
-+
-+ return 0;
-+}
-+
-+static int xgbe_enable_rx_vlan_filtering(struct xgbe_prv_data *pdata)
-+{
-+ /* Enable VLAN filtering */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 1);
-+
-+ /* Enable VLAN Hash Table filtering */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTHM, 1);
-+
-+ /* Disable VLAN tag inverse matching */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTIM, 0);
-+
-+ /* Only filter on the lower 12-bits of the VLAN tag */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ETV, 1);
-+
-+ /* In order for the VLAN Hash Table filtering to be effective,
-+ * the VLAN tag identifier in the VLAN Tag Register must not
-+ * be zero. Set the VLAN tag identifier to "1" to enable the
-+ * VLAN Hash Table filtering. This implies that a VLAN tag of
-+ * 1 will always pass filtering.
-+ */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VL, 1);
-+
-+ return 0;
-+}
-+
-+static int xgbe_disable_rx_vlan_filtering(struct xgbe_prv_data *pdata)
-+{
-+ /* Disable VLAN filtering */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 0);
-+
-+ return 0;
-+}
-+
-+#ifndef CRCPOLY_LE
-+#define CRCPOLY_LE 0xedb88320
-+#endif
-+static u32 xgbe_vid_crc32_le(__le16 vid_le)
-+{
-+ u32 poly = CRCPOLY_LE;
-+ u32 crc = ~0;
-+ u32 temp = 0;
-+ unsigned char *data = (unsigned char *)&vid_le;
-+ unsigned char data_byte = 0;
-+ int i, bits;
-+
-+ bits = get_bitmask_order(VLAN_VID_MASK);
-+ for (i = 0; i < bits; i++) {
-+ if ((i % 8) == 0)
-+ data_byte = data[i / 8];
-+
-+ temp = ((crc & 1) ^ data_byte) & 1;
-+ crc >>= 1;
-+ data_byte >>= 1;
-+
-+ if (temp)
-+ crc ^= poly;
-+ }
-+
-+ return crc;
-+}
-+
-+static int xgbe_update_vlan_hash_table(struct xgbe_prv_data *pdata)
-+{
-+ u32 crc;
-+ u16 vid;
-+ __le16 vid_le;
-+ u16 vlan_hash_table = 0;
-+
-+ /* Generate the VLAN Hash Table value */
-+ for_each_set_bit(vid, pdata->active_vlans, VLAN_N_VID) {
-+ /* Get the CRC32 value of the VLAN ID */
-+ vid_le = cpu_to_le16(vid);
-+ crc = bitrev32(~xgbe_vid_crc32_le(vid_le)) >> 28;
-+
-+ vlan_hash_table |= (1 << crc);
-+ }
-+
-+ /* Set the VLAN Hash Table filtering register */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANHTR, VLHT, vlan_hash_table);
-+
-+ return 0;
-+}
-+
-+static void xgbe_tx_desc_reset(struct xgbe_ring_data *rdata)
-+{
-+ struct xgbe_ring_desc *rdesc = rdata->rdesc;
-+
-+ /* Reset the Tx descriptor
-+ * Set buffer 1 (lo) address to zero
-+ * Set buffer 1 (hi) address to zero
-+ * Reset all other control bits (IC, TTSE, B2L & B1L)
-+ * Reset all other control bits (OWN, CTXT, FD, LD, CPC, CIC, etc)
-+ */
-+ rdesc->desc0 = 0;
-+ rdesc->desc1 = 0;
-+ rdesc->desc2 = 0;
-+ rdesc->desc3 = 0;
-+
-+ /* Make sure ownership is written to the descriptor */
-+ wmb();
-+}
-+
-+static void xgbe_tx_desc_init(struct xgbe_channel *channel)
-+{
-+ struct xgbe_ring *ring = channel->tx_ring;
-+ struct xgbe_ring_data *rdata;
-+ int i;
-+ int start_index = ring->cur;
-+
-+ DBGPR("-->tx_desc_init\n");
-+
-+ /* Initialze all descriptors */
-+ for (i = 0; i < ring->rdesc_count; i++) {
-+ rdata = XGBE_GET_DESC_DATA(ring, i);
-+
-+ /* Initialize Tx descriptor */
-+ xgbe_tx_desc_reset(rdata);
-+ }
-+
-+ /* Update the total number of Tx descriptors */
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_TDRLR, ring->rdesc_count - 1);
-+
-+ /* Update the starting address of descriptor ring */
-+ rdata = XGBE_GET_DESC_DATA(ring, start_index);
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_TDLR_HI,
-+ upper_32_bits(rdata->rdesc_dma));
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_TDLR_LO,
-+ lower_32_bits(rdata->rdesc_dma));
-+
-+ DBGPR("<--tx_desc_init\n");
-+}
-+
-+static void xgbe_rx_desc_reset(struct xgbe_ring_data *rdata)
-+{
-+ struct xgbe_ring_desc *rdesc = rdata->rdesc;
-+
-+ /* Reset the Rx descriptor
-+ * Set buffer 1 (lo) address to header dma address (lo)
-+ * Set buffer 1 (hi) address to header dma address (hi)
-+ * Set buffer 2 (lo) address to buffer dma address (lo)
-+ * Set buffer 2 (hi) address to buffer dma address (hi) and
-+ * set control bits OWN and INTE
-+ */
-+ rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->rx.hdr.dma));
-+ rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->rx.hdr.dma));
-+ rdesc->desc2 = cpu_to_le32(lower_32_bits(rdata->rx.buf.dma));
-+ rdesc->desc3 = cpu_to_le32(upper_32_bits(rdata->rx.buf.dma));
-+
-+ XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, INTE,
-+ rdata->interrupt ? 1 : 0);
-+
-+ /* Since the Rx DMA engine is likely running, make sure everything
-+ * is written to the descriptor(s) before setting the OWN bit
-+ * for the descriptor
-+ */
-+ wmb();
-+
-+ XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN, 1);
-+
-+ /* Make sure ownership is written to the descriptor */
-+ wmb();
-+}
-+
-+static void xgbe_rx_desc_init(struct xgbe_channel *channel)
-+{
-+ struct xgbe_prv_data *pdata = channel->pdata;
-+ struct xgbe_ring *ring = channel->rx_ring;
-+ struct xgbe_ring_data *rdata;
-+ unsigned int start_index = ring->cur;
-+ unsigned int rx_coalesce, rx_frames;
-+ unsigned int i;
-+
-+ DBGPR("-->rx_desc_init\n");
-+
-+ rx_coalesce = (pdata->rx_riwt || pdata->rx_frames) ? 1 : 0;
-+ rx_frames = pdata->rx_frames;
-+
-+ /* Initialize all descriptors */
-+ for (i = 0; i < ring->rdesc_count; i++) {
-+ rdata = XGBE_GET_DESC_DATA(ring, i);
-+
-+ /* Set interrupt on completion bit as appropriate */
-+ if (rx_coalesce && (!rx_frames || ((i + 1) % rx_frames)))
-+ rdata->interrupt = 0;
-+ else
-+ rdata->interrupt = 1;
-+
-+ /* Initialize Rx descriptor */
-+ xgbe_rx_desc_reset(rdata);
-+ }
-+
-+ /* Update the total number of Rx descriptors */
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDRLR, ring->rdesc_count - 1);
-+
-+ /* Update the starting address of descriptor ring */
-+ rdata = XGBE_GET_DESC_DATA(ring, start_index);
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDLR_HI,
-+ upper_32_bits(rdata->rdesc_dma));
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDLR_LO,
-+ lower_32_bits(rdata->rdesc_dma));
-+
-+ /* Update the Rx Descriptor Tail Pointer */
-+ rdata = XGBE_GET_DESC_DATA(ring, start_index + ring->rdesc_count - 1);
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
-+ lower_32_bits(rdata->rdesc_dma));
-+
-+ DBGPR("<--rx_desc_init\n");
-+}
-+
-+static void xgbe_update_tstamp_addend(struct xgbe_prv_data *pdata,
-+ unsigned int addend)
-+{
-+ /* Set the addend register value and tell the device */
-+ XGMAC_IOWRITE(pdata, MAC_TSAR, addend);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSADDREG, 1);
-+
-+ /* Wait for addend update to complete */
-+ while (XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSADDREG))
-+ udelay(5);
-+}
-+
-+static void xgbe_set_tstamp_time(struct xgbe_prv_data *pdata, unsigned int sec,
-+ unsigned int nsec)
-+{
-+ /* Set the time values and tell the device */
-+ XGMAC_IOWRITE(pdata, MAC_STSUR, sec);
-+ XGMAC_IOWRITE(pdata, MAC_STNUR, nsec);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSINIT, 1);
-+
-+ /* Wait for time update to complete */
-+ while (XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSINIT))
-+ udelay(5);
-+}
-+
-+static u64 xgbe_get_tstamp_time(struct xgbe_prv_data *pdata)
-+{
-+ u64 nsec;
-+
-+ nsec = XGMAC_IOREAD(pdata, MAC_STSR);
-+ nsec *= NSEC_PER_SEC;
-+ nsec += XGMAC_IOREAD(pdata, MAC_STNR);
-+
-+ return nsec;
-+}
-+
-+static u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int tx_snr;
-+ u64 nsec;
-+
-+ tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
-+ if (XGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS))
-+ return 0;
-+
-+ nsec = XGMAC_IOREAD(pdata, MAC_TXSSR);
-+ nsec *= NSEC_PER_SEC;
-+ nsec += tx_snr;
-+
-+ return nsec;
-+}
-+
-+static void xgbe_get_rx_tstamp(struct xgbe_packet_data *packet,
-+ struct xgbe_ring_desc *rdesc)
-+{
-+ u64 nsec;
-+
-+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSA) &&
-+ !XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSD)) {
-+ nsec = le32_to_cpu(rdesc->desc1);
-+ nsec <<= 32;
-+ nsec |= le32_to_cpu(rdesc->desc0);
-+ if (nsec != 0xffffffffffffffffULL) {
-+ packet->rx_tstamp = nsec;
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ RX_TSTAMP, 1);
-+ }
-+ }
-+}
-+
-+static int xgbe_config_tstamp(struct xgbe_prv_data *pdata,
-+ unsigned int mac_tscr)
-+{
-+ /* Set one nano-second accuracy */
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCTRLSSR, 1);
-+
-+ /* Set fine timestamp update */
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCFUPDT, 1);
-+
-+ /* Overwrite earlier timestamps */
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TXTSSTSM, 1);
-+
-+ XGMAC_IOWRITE(pdata, MAC_TSCR, mac_tscr);
-+
-+ /* Exit if timestamping is not enabled */
-+ if (!XGMAC_GET_BITS(mac_tscr, MAC_TSCR, TSENA))
-+ return 0;
-+
-+ /* Initialize time registers */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SSINC, XGBE_TSTAMP_SSINC);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SNSINC, XGBE_TSTAMP_SNSINC);
-+ xgbe_update_tstamp_addend(pdata, pdata->tstamp_addend);
-+ xgbe_set_tstamp_time(pdata, 0, 0);
-+
-+ /* Initialize the timecounter */
-+ timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc,
-+ ktime_to_ns(ktime_get_real()));
-+
-+ return 0;
-+}
-+
-+static void xgbe_config_dcb_tc(struct xgbe_prv_data *pdata)
-+{
-+ struct ieee_ets *ets = pdata->ets;
-+ unsigned int total_weight, min_weight, weight;
-+ unsigned int i;
-+
-+ if (!ets)
-+ return;
-+
-+ /* Set Tx to deficit weighted round robin scheduling algorithm (when
-+ * traffic class is using ETS algorithm)
-+ */
-+ XGMAC_IOWRITE_BITS(pdata, MTL_OMR, ETSALG, MTL_ETSALG_DWRR);
-+
-+ /* Set Traffic Class algorithms */
-+ total_weight = pdata->netdev->mtu * pdata->hw_feat.tc_cnt;
-+ min_weight = total_weight / 100;
-+ if (!min_weight)
-+ min_weight = 1;
-+
-+ for (i = 0; i < pdata->hw_feat.tc_cnt; i++) {
-+ switch (ets->tc_tsa[i]) {
-+ case IEEE_8021QAZ_TSA_STRICT:
-+ DBGPR(" TC%u using SP\n", i);
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA,
-+ MTL_TSA_SP);
-+ break;
-+ case IEEE_8021QAZ_TSA_ETS:
-+ weight = total_weight * ets->tc_tx_bw[i] / 100;
-+ weight = clamp(weight, min_weight, total_weight);
-+
-+ DBGPR(" TC%u using DWRR (weight %u)\n", i, weight);
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA,
-+ MTL_TSA_ETS);
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_QWR, QW,
-+ weight);
-+ break;
-+ }
-+ }
-+}
-+
-+static void xgbe_config_dcb_pfc(struct xgbe_prv_data *pdata)
-+{
-+ struct ieee_pfc *pfc = pdata->pfc;
-+ struct ieee_ets *ets = pdata->ets;
-+ unsigned int mask, reg, reg_val;
-+ unsigned int tc, prio;
-+
-+ if (!pfc || !ets)
-+ return;
-+
-+ for (tc = 0; tc < pdata->hw_feat.tc_cnt; tc++) {
-+ mask = 0;
-+ for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++) {
-+ if ((pfc->pfc_en & (1 << prio)) &&
-+ (ets->prio_tc[prio] == tc))
-+ mask |= (1 << prio);
-+ }
-+ mask &= 0xff;
-+
-+ DBGPR(" TC%u PFC mask=%#x\n", tc, mask);
-+ reg = MTL_TCPM0R + (MTL_TCPM_INC * (tc / MTL_TCPM_TC_PER_REG));
-+ reg_val = XGMAC_IOREAD(pdata, reg);
-+
-+ reg_val &= ~(0xff << ((tc % MTL_TCPM_TC_PER_REG) << 3));
-+ reg_val |= (mask << ((tc % MTL_TCPM_TC_PER_REG) << 3));
-+
-+ XGMAC_IOWRITE(pdata, reg, reg_val);
-+ }
-+
-+ xgbe_config_flow_control(pdata);
-+}
-+
-+static void xgbe_tx_start_xmit(struct xgbe_channel *channel,
-+ struct xgbe_ring *ring)
-+{
-+ struct xgbe_prv_data *pdata = channel->pdata;
-+ struct xgbe_ring_data *rdata;
-+
-+ /* Issue a poll command to Tx DMA by writing address
-+ * of next immediate free descriptor */
-+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO,
-+ lower_32_bits(rdata->rdesc_dma));
-+
-+ /* Start the Tx coalescing timer */
-+ if (pdata->tx_usecs && !channel->tx_timer_active) {
-+ channel->tx_timer_active = 1;
-+ hrtimer_start(&channel->tx_timer,
-+ ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC),
-+ HRTIMER_MODE_REL);
-+ }
-+
-+ ring->tx.xmit_more = 0;
-+}
-+
-+static void xgbe_dev_xmit(struct xgbe_channel *channel)
-+{
-+ struct xgbe_prv_data *pdata = channel->pdata;
-+ struct xgbe_ring *ring = channel->tx_ring;
-+ struct xgbe_ring_data *rdata;
-+ struct xgbe_ring_desc *rdesc;
-+ struct xgbe_packet_data *packet = &ring->packet_data;
-+ unsigned int csum, tso, vlan;
-+ unsigned int tso_context, vlan_context;
-+ unsigned int tx_set_ic;
-+ int start_index = ring->cur;
-+ int cur_index = ring->cur;
-+ int i;
-+
-+ DBGPR("-->xgbe_dev_xmit\n");
-+
-+ csum = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ CSUM_ENABLE);
-+ tso = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ TSO_ENABLE);
-+ vlan = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ VLAN_CTAG);
-+
-+ if (tso && (packet->mss != ring->tx.cur_mss))
-+ tso_context = 1;
-+ else
-+ tso_context = 0;
-+
-+ if (vlan && (packet->vlan_ctag != ring->tx.cur_vlan_ctag))
-+ vlan_context = 1;
-+ else
-+ vlan_context = 0;
-+
-+ /* Determine if an interrupt should be generated for this Tx:
-+ * Interrupt:
-+ * - Tx frame count exceeds the frame count setting
-+ * - Addition of Tx frame count to the frame count since the
-+ * last interrupt was set exceeds the frame count setting
-+ * No interrupt:
-+ * - No frame count setting specified (ethtool -C ethX tx-frames 0)
-+ * - Addition of Tx frame count to the frame count since the
-+ * last interrupt was set does not exceed the frame count setting
-+ */
-+ ring->coalesce_count += packet->tx_packets;
-+ if (!pdata->tx_frames)
-+ tx_set_ic = 0;
-+ else if (packet->tx_packets > pdata->tx_frames)
-+ tx_set_ic = 1;
-+ else if ((ring->coalesce_count % pdata->tx_frames) <
-+ packet->tx_packets)
-+ tx_set_ic = 1;
-+ else
-+ tx_set_ic = 0;
-+
-+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
-+ rdesc = rdata->rdesc;
-+
-+ /* Create a context descriptor if this is a TSO packet */
-+ if (tso_context || vlan_context) {
-+ if (tso_context) {
-+ DBGPR(" TSO context descriptor, mss=%u\n",
-+ packet->mss);
-+
-+ /* Set the MSS size */
-+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_CONTEXT_DESC2,
-+ MSS, packet->mss);
-+
-+ /* Mark it as a CONTEXT descriptor */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
-+ CTXT, 1);
-+
-+ /* Indicate this descriptor contains the MSS */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
-+ TCMSSV, 1);
-+
-+ ring->tx.cur_mss = packet->mss;
-+ }
-+
-+ if (vlan_context) {
-+ DBGPR(" VLAN context descriptor, ctag=%u\n",
-+ packet->vlan_ctag);
-+
-+ /* Mark it as a CONTEXT descriptor */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
-+ CTXT, 1);
-+
-+ /* Set the VLAN tag */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
-+ VT, packet->vlan_ctag);
-+
-+ /* Indicate this descriptor contains the VLAN tag */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
-+ VLTV, 1);
-+
-+ ring->tx.cur_vlan_ctag = packet->vlan_ctag;
-+ }
-+
-+ cur_index++;
-+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
-+ rdesc = rdata->rdesc;
-+ }
-+
-+ /* Update buffer address (for TSO this is the header) */
-+ rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->skb_dma));
-+ rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->skb_dma));
-+
-+ /* Update the buffer length */
-+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L,
-+ rdata->skb_dma_len);
-+
-+ /* VLAN tag insertion check */
-+ if (vlan)
-+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, VTIR,
-+ TX_NORMAL_DESC2_VLAN_INSERT);
-+
-+ /* Timestamp enablement check */
-+ if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP))
-+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, TTSE, 1);
-+
-+ /* Mark it as First Descriptor */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FD, 1);
-+
-+ /* Mark it as a NORMAL descriptor */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0);
-+
-+ /* Set OWN bit if not the first descriptor */
-+ if (cur_index != start_index)
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
-+
-+ if (tso) {
-+ /* Enable TSO */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, TSE, 1);
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, TCPPL,
-+ packet->tcp_payload_len);
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, TCPHDRLEN,
-+ packet->tcp_header_len / 4);
-+ } else {
-+ /* Enable CRC and Pad Insertion */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CPC, 0);
-+
-+ /* Enable HW CSUM */
-+ if (csum)
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3,
-+ CIC, 0x3);
-+
-+ /* Set the total length to be transmitted */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FL,
-+ packet->length);
-+ }
-+
-+ for (i = cur_index - start_index + 1; i < packet->rdesc_count; i++) {
-+ cur_index++;
-+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
-+ rdesc = rdata->rdesc;
-+
-+ /* Update buffer address */
-+ rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->skb_dma));
-+ rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->skb_dma));
-+
-+ /* Update the buffer length */
-+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L,
-+ rdata->skb_dma_len);
-+
-+ /* Set OWN bit */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
-+
-+ /* Mark it as NORMAL descriptor */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0);
-+
-+ /* Enable HW CSUM */
-+ if (csum)
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3,
-+ CIC, 0x3);
-+ }
-+
-+ /* Set LAST bit for the last descriptor */
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD, 1);
-+
-+ /* Set IC bit based on Tx coalescing settings */
-+ if (tx_set_ic)
-+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1);
-+
-+ /* Save the Tx info to report back during cleanup */
-+ rdata->tx.packets = packet->tx_packets;
-+ rdata->tx.bytes = packet->tx_bytes;
-+
-+ /* In case the Tx DMA engine is running, make sure everything
-+ * is written to the descriptor(s) before setting the OWN bit
-+ * for the first descriptor
-+ */
-+ wmb();
-+
-+ /* Set OWN bit for the first descriptor */
-+ rdata = XGBE_GET_DESC_DATA(ring, start_index);
-+ rdesc = rdata->rdesc;
-+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
-+
-+#ifdef XGMAC_ENABLE_TX_DESC_DUMP
-+ xgbe_a0_dump_tx_desc(ring, start_index, packet->rdesc_count, 1);
-+#endif
-+
-+ /* Make sure ownership is written to the descriptor */
-+ wmb();
-+
-+ ring->cur = cur_index + 1;
-+ if (!packet->skb->xmit_more ||
-+ netif_xmit_stopped(netdev_get_tx_queue(pdata->netdev,
-+ channel->queue_index)))
-+ xgbe_tx_start_xmit(channel, ring);
-+ else
-+ ring->tx.xmit_more = 1;
-+
-+ DBGPR(" %s: descriptors %u to %u written\n",
-+ channel->name, start_index & (ring->rdesc_count - 1),
-+ (ring->cur - 1) & (ring->rdesc_count - 1));
-+
-+ DBGPR("<--xgbe_dev_xmit\n");
-+}
-+
-+static int xgbe_dev_read(struct xgbe_channel *channel)
-+{
-+ struct xgbe_ring *ring = channel->rx_ring;
-+ struct xgbe_ring_data *rdata;
-+ struct xgbe_ring_desc *rdesc;
-+ struct xgbe_packet_data *packet = &ring->packet_data;
-+ struct net_device *netdev = channel->pdata->netdev;
-+ unsigned int err, etlt, l34t;
-+
-+ DBGPR("-->xgbe_dev_read: cur = %d\n", ring->cur);
-+
-+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
-+ rdesc = rdata->rdesc;
-+
-+ /* Check for data availability */
-+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN))
-+ return 1;
-+
-+ /* Make sure descriptor fields are read after reading the OWN bit */
-+ rmb();
-+
-+#ifdef XGMAC_ENABLE_RX_DESC_DUMP
-+ xgbe_a0_dump_rx_desc(ring, rdesc, ring->cur);
-+#endif
-+
-+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, CTXT)) {
-+ /* Timestamp Context Descriptor */
-+ xgbe_get_rx_tstamp(packet, rdesc);
-+
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ CONTEXT, 1);
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ CONTEXT_NEXT, 0);
-+ return 0;
-+ }
-+
-+ /* Normal Descriptor, be sure Context Descriptor bit is off */
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, CONTEXT, 0);
-+
-+ /* Indicate if a Context Descriptor is next */
-+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, CDA))
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ CONTEXT_NEXT, 1);
-+
-+ /* Get the header length */
-+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, FD))
-+ rdata->rx.hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2,
-+ RX_NORMAL_DESC2, HL);
-+
-+ /* Get the RSS hash */
-+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, RSV)) {
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ RSS_HASH, 1);
-+
-+ packet->rss_hash = le32_to_cpu(rdesc->desc1);
-+
-+ l34t = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, L34T);
-+ switch (l34t) {
-+ case RX_DESC3_L34T_IPV4_TCP:
-+ case RX_DESC3_L34T_IPV4_UDP:
-+ case RX_DESC3_L34T_IPV6_TCP:
-+ case RX_DESC3_L34T_IPV6_UDP:
-+ packet->rss_hash_type = PKT_HASH_TYPE_L4;
-+ break;
-+ default:
-+ packet->rss_hash_type = PKT_HASH_TYPE_L3;
-+ }
-+ }
-+
-+ /* Get the packet length */
-+ rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL);
-+
-+ if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD)) {
-+ /* Not all the data has been transferred for this packet */
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ INCOMPLETE, 1);
-+ return 0;
-+ }
-+
-+ /* This is the last of the data for this packet */
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ INCOMPLETE, 0);
-+
-+ /* Set checksum done indicator as appropriate */
-+ if (channel->pdata->netdev->features & NETIF_F_RXCSUM)
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ CSUM_DONE, 1);
-+
-+ /* Check for errors (only valid in last descriptor) */
-+ err = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, ES);
-+ etlt = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, ETLT);
-+ DBGPR(" err=%u, etlt=%#x\n", err, etlt);
-+
-+ if (!err || !etlt) {
-+ /* No error if err is 0 or etlt is 0 */
-+ if ((etlt == 0x09) &&
-+ (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ VLAN_CTAG, 1);
-+ packet->vlan_ctag = XGMAC_GET_BITS_LE(rdesc->desc0,
-+ RX_NORMAL_DESC0,
-+ OVT);
-+ DBGPR(" vlan-ctag=0x%04x\n", packet->vlan_ctag);
-+ }
-+ } else {
-+ if ((etlt == 0x05) || (etlt == 0x06))
-+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-+ CSUM_DONE, 0);
-+ else
-+ XGMAC_SET_BITS(packet->errors, RX_PACKET_ERRORS,
-+ FRAME, 1);
-+ }
-+
-+ DBGPR("<--xgbe_dev_read: %s - descriptor=%u (cur=%d)\n", channel->name,
-+ ring->cur & (ring->rdesc_count - 1), ring->cur);
-+
-+ return 0;
-+}
-+
-+static int xgbe_is_context_desc(struct xgbe_ring_desc *rdesc)
-+{
-+ /* Rx and Tx share CTXT bit, so check TDES3.CTXT bit */
-+ return XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT);
-+}
-+
-+static int xgbe_is_last_desc(struct xgbe_ring_desc *rdesc)
-+{
-+ /* Rx and Tx share LD bit, so check TDES3.LD bit */
-+ return XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD);
-+}
-+
-+static int xgbe_enable_int(struct xgbe_channel *channel,
-+ enum xgbe_int int_id)
-+{
-+ unsigned int dma_ch_ier;
-+
-+ dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
-+
-+ switch (int_id) {
-+ case XGMAC_INT_DMA_CH_SR_TI:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_TPS:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TXSE, 1);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_TBU:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TBUE, 1);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_RI:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_RBU:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 1);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_RPS:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RSE, 1);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_TI_RI:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1);
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_FBE:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 1);
-+ break;
-+ case XGMAC_INT_DMA_ALL:
-+ dma_ch_ier |= channel->saved_ier;
-+ break;
-+ default:
-+ return -1;
-+ }
-+
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
-+
-+ return 0;
-+}
-+
-+static int xgbe_disable_int(struct xgbe_channel *channel,
-+ enum xgbe_int int_id)
-+{
-+ unsigned int dma_ch_ier;
-+
-+ dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
-+
-+ switch (int_id) {
-+ case XGMAC_INT_DMA_CH_SR_TI:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 0);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_TPS:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TXSE, 0);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_TBU:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TBUE, 0);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_RI:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 0);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_RBU:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 0);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_RPS:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RSE, 0);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_TI_RI:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 0);
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 0);
-+ break;
-+ case XGMAC_INT_DMA_CH_SR_FBE:
-+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 0);
-+ break;
-+ case XGMAC_INT_DMA_ALL:
-+ channel->saved_ier = dma_ch_ier & XGBE_DMA_INTERRUPT_MASK;
-+ dma_ch_ier &= ~XGBE_DMA_INTERRUPT_MASK;
-+ break;
-+ default:
-+ return -1;
-+ }
-+
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
-+
-+ return 0;
-+}
-+
-+static int xgbe_exit(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int count = 2000;
-+
-+ DBGPR("-->xgbe_exit\n");
-+
-+ /* Issue a software reset */
-+ XGMAC_IOWRITE_BITS(pdata, DMA_MR, SWR, 1);
-+ usleep_range(10, 15);
-+
-+ /* Poll Until Poll Condition */
-+ while (count-- && XGMAC_IOREAD_BITS(pdata, DMA_MR, SWR))
-+ usleep_range(500, 600);
-+
-+ if (!count)
-+ return -EBUSY;
-+
-+ DBGPR("<--xgbe_exit\n");
-+
-+ return 0;
-+}
-+
-+static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int i, count;
-+
-+ if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) < 0x21)
-+ return 0;
-+
-+ for (i = 0; i < pdata->tx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, FTQ, 1);
-+
-+ /* Poll Until Poll Condition */
-+ for (i = 0; i < pdata->tx_q_count; i++) {
-+ count = 2000;
-+ while (count-- && XGMAC_MTL_IOREAD_BITS(pdata, i,
-+ MTL_Q_TQOMR, FTQ))
-+ usleep_range(500, 600);
-+
-+ if (!count)
-+ return -EBUSY;
-+ }
-+
-+ return 0;
-+}
-+
-+static void xgbe_config_dma_bus(struct xgbe_prv_data *pdata)
-+{
-+ /* Set enhanced addressing mode */
-+ XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, EAME, 1);
-+
-+ /* Set the System Bus mode */
-+ XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, UNDEF, 1);
-+ XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, BLEN_256, 1);
-+}
-+
-+static void xgbe_config_dma_cache(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int arcache, awcache;
-+
-+ arcache = 0;
-+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRC, pdata->arcache);
-+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRD, pdata->axdomain);
-+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, TEC, pdata->arcache);
-+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, TED, pdata->axdomain);
-+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, THC, pdata->arcache);
-+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, THD, pdata->axdomain);
-+ XGMAC_IOWRITE(pdata, DMA_AXIARCR, arcache);
-+
-+ awcache = 0;
-+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWC, pdata->awcache);
-+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWD, pdata->axdomain);
-+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPC, pdata->awcache);
-+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPD, pdata->axdomain);
-+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHC, pdata->awcache);
-+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHD, pdata->axdomain);
-+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDC, pdata->awcache);
-+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDD, pdata->axdomain);
-+ XGMAC_IOWRITE(pdata, DMA_AXIAWCR, awcache);
-+}
-+
-+static void xgbe_config_mtl_mode(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int i;
-+
-+ /* Set Tx to weighted round robin scheduling algorithm */
-+ XGMAC_IOWRITE_BITS(pdata, MTL_OMR, ETSALG, MTL_ETSALG_WRR);
-+
-+ /* Set Tx traffic classes to use WRR algorithm with equal weights */
-+ for (i = 0; i < pdata->hw_feat.tc_cnt; i++) {
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA,
-+ MTL_TSA_ETS);
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_QWR, QW, 1);
-+ }
-+
-+ /* Set Rx to strict priority algorithm */
-+ XGMAC_IOWRITE_BITS(pdata, MTL_OMR, RAA, MTL_RAA_SP);
-+}
-+
-+static unsigned int xgbe_calculate_per_queue_fifo(unsigned int fifo_size,
-+ unsigned int queue_count)
-+{
-+ unsigned int q_fifo_size = 0;
-+ enum xgbe_mtl_fifo_size p_fifo = XGMAC_MTL_FIFO_SIZE_256;
-+
-+ /* Calculate Tx/Rx fifo share per queue */
-+ switch (fifo_size) {
-+ case 0:
-+ q_fifo_size = XGBE_FIFO_SIZE_B(128);
-+ break;
-+ case 1:
-+ q_fifo_size = XGBE_FIFO_SIZE_B(256);
-+ break;
-+ case 2:
-+ q_fifo_size = XGBE_FIFO_SIZE_B(512);
-+ break;
-+ case 3:
-+ q_fifo_size = XGBE_FIFO_SIZE_KB(1);
-+ break;
-+ case 4:
-+ q_fifo_size = XGBE_FIFO_SIZE_KB(2);
-+ break;
-+ case 5:
-+ q_fifo_size = XGBE_FIFO_SIZE_KB(4);
-+ break;
-+ case 6:
-+ q_fifo_size = XGBE_FIFO_SIZE_KB(8);
-+ break;
-+ case 7:
-+ q_fifo_size = XGBE_FIFO_SIZE_KB(16);
-+ break;
-+ case 8:
-+ q_fifo_size = XGBE_FIFO_SIZE_KB(32);
-+ break;
-+ case 9:
-+ q_fifo_size = XGBE_FIFO_SIZE_KB(64);
-+ break;
-+ case 10:
-+ q_fifo_size = XGBE_FIFO_SIZE_KB(128);
-+ break;
-+ case 11:
-+ q_fifo_size = XGBE_FIFO_SIZE_KB(256);
-+ break;
-+ }
-+
-+ /* The configured value is not the actual amount of fifo RAM */
-+ q_fifo_size = min_t(unsigned int, XGBE_FIFO_MAX, q_fifo_size);
-+
-+ q_fifo_size = q_fifo_size / queue_count;
-+
-+ /* Set the queue fifo size programmable value */
-+ if (q_fifo_size >= XGBE_FIFO_SIZE_KB(256))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_256K;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(128))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_128K;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(64))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_64K;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(32))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_32K;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(16))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_16K;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(8))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_8K;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(4))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_4K;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(2))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_2K;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(1))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_1K;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_B(512))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_512;
-+ else if (q_fifo_size >= XGBE_FIFO_SIZE_B(256))
-+ p_fifo = XGMAC_MTL_FIFO_SIZE_256;
-+
-+ return p_fifo;
-+}
-+
-+static void xgbe_config_tx_fifo_size(struct xgbe_prv_data *pdata)
-+{
-+ enum xgbe_mtl_fifo_size fifo_size;
-+ unsigned int i;
-+
-+ fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.tx_fifo_size,
-+ pdata->tx_q_count);
-+
-+ for (i = 0; i < pdata->tx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TQS, fifo_size);
-+
-+ netdev_notice(pdata->netdev, "%d Tx queues, %d byte fifo per queue\n",
-+ pdata->tx_q_count, ((fifo_size + 1) * 256));
-+}
-+
-+static void xgbe_config_rx_fifo_size(struct xgbe_prv_data *pdata)
-+{
-+ enum xgbe_mtl_fifo_size fifo_size;
-+ unsigned int i;
-+
-+ fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.rx_fifo_size,
-+ pdata->rx_q_count);
-+
-+ for (i = 0; i < pdata->rx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RQS, fifo_size);
-+
-+ netdev_notice(pdata->netdev, "%d Rx queues, %d byte fifo per queue\n",
-+ pdata->rx_q_count, ((fifo_size + 1) * 256));
-+}
-+
-+static void xgbe_config_queue_mapping(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int qptc, qptc_extra, queue;
-+ unsigned int prio_queues;
-+ unsigned int ppq, ppq_extra, prio;
-+ unsigned int mask;
-+ unsigned int i, j, reg, reg_val;
-+
-+ /* Map the MTL Tx Queues to Traffic Classes
-+ * Note: Tx Queues >= Traffic Classes
-+ */
-+ qptc = pdata->tx_q_count / pdata->hw_feat.tc_cnt;
-+ qptc_extra = pdata->tx_q_count % pdata->hw_feat.tc_cnt;
-+
-+ for (i = 0, queue = 0; i < pdata->hw_feat.tc_cnt; i++) {
-+ for (j = 0; j < qptc; j++) {
-+ DBGPR(" TXq%u mapped to TC%u\n", queue, i);
-+ XGMAC_MTL_IOWRITE_BITS(pdata, queue, MTL_Q_TQOMR,
-+ Q2TCMAP, i);
-+ pdata->q2tc_map[queue++] = i;
-+ }
-+
-+ if (i < qptc_extra) {
-+ DBGPR(" TXq%u mapped to TC%u\n", queue, i);
-+ XGMAC_MTL_IOWRITE_BITS(pdata, queue, MTL_Q_TQOMR,
-+ Q2TCMAP, i);
-+ pdata->q2tc_map[queue++] = i;
-+ }
-+ }
-+
-+ /* Map the 8 VLAN priority values to available MTL Rx queues */
-+ prio_queues = min_t(unsigned int, IEEE_8021QAZ_MAX_TCS,
-+ pdata->rx_q_count);
-+ ppq = IEEE_8021QAZ_MAX_TCS / prio_queues;
-+ ppq_extra = IEEE_8021QAZ_MAX_TCS % prio_queues;
-+
-+ reg = MAC_RQC2R;
-+ reg_val = 0;
-+ for (i = 0, prio = 0; i < prio_queues;) {
-+ mask = 0;
-+ for (j = 0; j < ppq; j++) {
-+ DBGPR(" PRIO%u mapped to RXq%u\n", prio, i);
-+ mask |= (1 << prio);
-+ pdata->prio2q_map[prio++] = i;
-+ }
-+
-+ if (i < ppq_extra) {
-+ DBGPR(" PRIO%u mapped to RXq%u\n", prio, i);
-+ mask |= (1 << prio);
-+ pdata->prio2q_map[prio++] = i;
-+ }
-+
-+ reg_val |= (mask << ((i++ % MAC_RQC2_Q_PER_REG) << 3));
-+
-+ if ((i % MAC_RQC2_Q_PER_REG) && (i != prio_queues))
-+ continue;
-+
-+ XGMAC_IOWRITE(pdata, reg, reg_val);
-+ reg += MAC_RQC2_INC;
-+ reg_val = 0;
-+ }
-+
-+ /* Select dynamic mapping of MTL Rx queue to DMA Rx channel */
-+ reg = MTL_RQDCM0R;
-+ reg_val = 0;
-+ for (i = 0; i < pdata->rx_q_count;) {
-+ reg_val |= (0x80 << ((i++ % MTL_RQDCM_Q_PER_REG) << 3));
-+
-+ if ((i % MTL_RQDCM_Q_PER_REG) && (i != pdata->rx_q_count))
-+ continue;
-+
-+ XGMAC_IOWRITE(pdata, reg, reg_val);
-+
-+ reg += MTL_RQDCM_INC;
-+ reg_val = 0;
-+ }
-+}
-+
-+static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < pdata->rx_q_count; i++) {
-+ /* Activate flow control when less than 4k left in fifo */
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFA, 2);
-+
-+ /* De-activate flow control when more than 6k left in fifo */
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFD, 4);
-+ }
-+}
-+
-+static void xgbe_config_mac_address(struct xgbe_prv_data *pdata)
-+{
-+ xgbe_set_mac_address(pdata, pdata->netdev->dev_addr);
-+
-+ /* Filtering is done using perfect filtering and hash filtering */
-+ if (pdata->hw_feat.hash_table_size) {
-+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HMC, 1);
-+ }
-+}
-+
-+static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int val;
-+
-+ val = (pdata->netdev->mtu > XGMAC_STD_PACKET_MTU) ? 1 : 0;
-+
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val);
-+}
-+
-+static void xgbe_config_mac_speed(struct xgbe_prv_data *pdata)
-+{
-+ switch (pdata->phy_speed) {
-+ case SPEED_10000:
-+ xgbe_set_xgmii_speed(pdata);
-+ break;
-+
-+ case SPEED_2500:
-+ xgbe_set_gmii_2500_speed(pdata);
-+ break;
-+
-+ case SPEED_1000:
-+ xgbe_set_gmii_speed(pdata);
-+ break;
-+ }
-+}
-+
-+static void xgbe_config_checksum_offload(struct xgbe_prv_data *pdata)
-+{
-+ if (pdata->netdev->features & NETIF_F_RXCSUM)
-+ xgbe_enable_rx_csum(pdata);
-+ else
-+ xgbe_disable_rx_csum(pdata);
-+}
-+
-+static void xgbe_config_vlan_support(struct xgbe_prv_data *pdata)
-+{
-+ /* Indicate that VLAN Tx CTAGs come from context descriptors */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, CSVL, 0);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, VLTI, 1);
-+
-+ /* Set the current VLAN Hash Table register value */
-+ xgbe_update_vlan_hash_table(pdata);
-+
-+ if (pdata->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
-+ xgbe_enable_rx_vlan_filtering(pdata);
-+ else
-+ xgbe_disable_rx_vlan_filtering(pdata);
-+
-+ if (pdata->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
-+ xgbe_enable_rx_vlan_stripping(pdata);
-+ else
-+ xgbe_disable_rx_vlan_stripping(pdata);
-+}
-+
-+static u64 xgbe_mmc_read(struct xgbe_prv_data *pdata, unsigned int reg_lo)
-+{
-+ bool read_hi;
-+ u64 val;
-+
-+ switch (reg_lo) {
-+ /* These registers are always 64 bit */
-+ case MMC_TXOCTETCOUNT_GB_LO:
-+ case MMC_TXOCTETCOUNT_G_LO:
-+ case MMC_RXOCTETCOUNT_GB_LO:
-+ case MMC_RXOCTETCOUNT_G_LO:
-+ read_hi = true;
-+ break;
-+
-+ default:
-+ read_hi = false;
-+ };
-+
-+ val = XGMAC_IOREAD(pdata, reg_lo);
-+
-+ if (read_hi)
-+ val |= ((u64)XGMAC_IOREAD(pdata, reg_lo + 4) << 32);
-+
-+ return val;
-+}
-+
-+static void xgbe_tx_mmc_int(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_mmc_stats *stats = &pdata->mmc_stats;
-+ unsigned int mmc_isr = XGMAC_IOREAD(pdata, MMC_TISR);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_GB))
-+ stats->txoctetcount_gb +=
-+ xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_GB))
-+ stats->txframecount_gb +=
-+ xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_G))
-+ stats->txbroadcastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_G_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_G))
-+ stats->txmulticastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_G_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX64OCTETS_GB))
-+ stats->tx64octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX64OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX65TO127OCTETS_GB))
-+ stats->tx65to127octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX65TO127OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX128TO255OCTETS_GB))
-+ stats->tx128to255octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX128TO255OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX256TO511OCTETS_GB))
-+ stats->tx256to511octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX256TO511OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX512TO1023OCTETS_GB))
-+ stats->tx512to1023octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX512TO1023OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX1024TOMAXOCTETS_GB))
-+ stats->tx1024tomaxoctets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNICASTFRAMES_GB))
-+ stats->txunicastframes_gb +=
-+ xgbe_mmc_read(pdata, MMC_TXUNICASTFRAMES_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_GB))
-+ stats->txmulticastframes_gb +=
-+ xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_GB))
-+ stats->txbroadcastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNDERFLOWERROR))
-+ stats->txunderflowerror +=
-+ xgbe_mmc_read(pdata, MMC_TXUNDERFLOWERROR_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_G))
-+ stats->txoctetcount_g +=
-+ xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_G_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_G))
-+ stats->txframecount_g +=
-+ xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_G_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXPAUSEFRAMES))
-+ stats->txpauseframes +=
-+ xgbe_mmc_read(pdata, MMC_TXPAUSEFRAMES_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXVLANFRAMES_G))
-+ stats->txvlanframes_g +=
-+ xgbe_mmc_read(pdata, MMC_TXVLANFRAMES_G_LO);
-+}
-+
-+static void xgbe_rx_mmc_int(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_mmc_stats *stats = &pdata->mmc_stats;
-+ unsigned int mmc_isr = XGMAC_IOREAD(pdata, MMC_RISR);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFRAMECOUNT_GB))
-+ stats->rxframecount_gb +=
-+ xgbe_mmc_read(pdata, MMC_RXFRAMECOUNT_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_GB))
-+ stats->rxoctetcount_gb +=
-+ xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_G))
-+ stats->rxoctetcount_g +=
-+ xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_G_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXBROADCASTFRAMES_G))
-+ stats->rxbroadcastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_RXBROADCASTFRAMES_G_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXMULTICASTFRAMES_G))
-+ stats->rxmulticastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_RXMULTICASTFRAMES_G_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXCRCERROR))
-+ stats->rxcrcerror +=
-+ xgbe_mmc_read(pdata, MMC_RXCRCERROR_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXRUNTERROR))
-+ stats->rxrunterror +=
-+ xgbe_mmc_read(pdata, MMC_RXRUNTERROR);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXJABBERERROR))
-+ stats->rxjabbererror +=
-+ xgbe_mmc_read(pdata, MMC_RXJABBERERROR);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNDERSIZE_G))
-+ stats->rxundersize_g +=
-+ xgbe_mmc_read(pdata, MMC_RXUNDERSIZE_G);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOVERSIZE_G))
-+ stats->rxoversize_g +=
-+ xgbe_mmc_read(pdata, MMC_RXOVERSIZE_G);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX64OCTETS_GB))
-+ stats->rx64octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX64OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX65TO127OCTETS_GB))
-+ stats->rx65to127octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX65TO127OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX128TO255OCTETS_GB))
-+ stats->rx128to255octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX128TO255OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX256TO511OCTETS_GB))
-+ stats->rx256to511octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX256TO511OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX512TO1023OCTETS_GB))
-+ stats->rx512to1023octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX512TO1023OCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX1024TOMAXOCTETS_GB))
-+ stats->rx1024tomaxoctets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNICASTFRAMES_G))
-+ stats->rxunicastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_RXUNICASTFRAMES_G_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXLENGTHERROR))
-+ stats->rxlengtherror +=
-+ xgbe_mmc_read(pdata, MMC_RXLENGTHERROR_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOUTOFRANGETYPE))
-+ stats->rxoutofrangetype +=
-+ xgbe_mmc_read(pdata, MMC_RXOUTOFRANGETYPE_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXPAUSEFRAMES))
-+ stats->rxpauseframes +=
-+ xgbe_mmc_read(pdata, MMC_RXPAUSEFRAMES_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFIFOOVERFLOW))
-+ stats->rxfifooverflow +=
-+ xgbe_mmc_read(pdata, MMC_RXFIFOOVERFLOW_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXVLANFRAMES_GB))
-+ stats->rxvlanframes_gb +=
-+ xgbe_mmc_read(pdata, MMC_RXVLANFRAMES_GB_LO);
-+
-+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXWATCHDOGERROR))
-+ stats->rxwatchdogerror +=
-+ xgbe_mmc_read(pdata, MMC_RXWATCHDOGERROR);
-+}
-+
-+static void xgbe_read_mmc_stats(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_mmc_stats *stats = &pdata->mmc_stats;
-+
-+ /* Freeze counters */
-+ XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1);
-+
-+ stats->txoctetcount_gb +=
-+ xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_GB_LO);
-+
-+ stats->txframecount_gb +=
-+ xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_GB_LO);
-+
-+ stats->txbroadcastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_G_LO);
-+
-+ stats->txmulticastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_G_LO);
-+
-+ stats->tx64octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX64OCTETS_GB_LO);
-+
-+ stats->tx65to127octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX65TO127OCTETS_GB_LO);
-+
-+ stats->tx128to255octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX128TO255OCTETS_GB_LO);
-+
-+ stats->tx256to511octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX256TO511OCTETS_GB_LO);
-+
-+ stats->tx512to1023octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX512TO1023OCTETS_GB_LO);
-+
-+ stats->tx1024tomaxoctets_gb +=
-+ xgbe_mmc_read(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
-+
-+ stats->txunicastframes_gb +=
-+ xgbe_mmc_read(pdata, MMC_TXUNICASTFRAMES_GB_LO);
-+
-+ stats->txmulticastframes_gb +=
-+ xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
-+
-+ stats->txbroadcastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
-+
-+ stats->txunderflowerror +=
-+ xgbe_mmc_read(pdata, MMC_TXUNDERFLOWERROR_LO);
-+
-+ stats->txoctetcount_g +=
-+ xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_G_LO);
-+
-+ stats->txframecount_g +=
-+ xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_G_LO);
-+
-+ stats->txpauseframes +=
-+ xgbe_mmc_read(pdata, MMC_TXPAUSEFRAMES_LO);
-+
-+ stats->txvlanframes_g +=
-+ xgbe_mmc_read(pdata, MMC_TXVLANFRAMES_G_LO);
-+
-+ stats->rxframecount_gb +=
-+ xgbe_mmc_read(pdata, MMC_RXFRAMECOUNT_GB_LO);
-+
-+ stats->rxoctetcount_gb +=
-+ xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_GB_LO);
-+
-+ stats->rxoctetcount_g +=
-+ xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_G_LO);
-+
-+ stats->rxbroadcastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_RXBROADCASTFRAMES_G_LO);
-+
-+ stats->rxmulticastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_RXMULTICASTFRAMES_G_LO);
-+
-+ stats->rxcrcerror +=
-+ xgbe_mmc_read(pdata, MMC_RXCRCERROR_LO);
-+
-+ stats->rxrunterror +=
-+ xgbe_mmc_read(pdata, MMC_RXRUNTERROR);
-+
-+ stats->rxjabbererror +=
-+ xgbe_mmc_read(pdata, MMC_RXJABBERERROR);
-+
-+ stats->rxundersize_g +=
-+ xgbe_mmc_read(pdata, MMC_RXUNDERSIZE_G);
-+
-+ stats->rxoversize_g +=
-+ xgbe_mmc_read(pdata, MMC_RXOVERSIZE_G);
-+
-+ stats->rx64octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX64OCTETS_GB_LO);
-+
-+ stats->rx65to127octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX65TO127OCTETS_GB_LO);
-+
-+ stats->rx128to255octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX128TO255OCTETS_GB_LO);
-+
-+ stats->rx256to511octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX256TO511OCTETS_GB_LO);
-+
-+ stats->rx512to1023octets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX512TO1023OCTETS_GB_LO);
-+
-+ stats->rx1024tomaxoctets_gb +=
-+ xgbe_mmc_read(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
-+
-+ stats->rxunicastframes_g +=
-+ xgbe_mmc_read(pdata, MMC_RXUNICASTFRAMES_G_LO);
-+
-+ stats->rxlengtherror +=
-+ xgbe_mmc_read(pdata, MMC_RXLENGTHERROR_LO);
-+
-+ stats->rxoutofrangetype +=
-+ xgbe_mmc_read(pdata, MMC_RXOUTOFRANGETYPE_LO);
-+
-+ stats->rxpauseframes +=
-+ xgbe_mmc_read(pdata, MMC_RXPAUSEFRAMES_LO);
-+
-+ stats->rxfifooverflow +=
-+ xgbe_mmc_read(pdata, MMC_RXFIFOOVERFLOW_LO);
-+
-+ stats->rxvlanframes_gb +=
-+ xgbe_mmc_read(pdata, MMC_RXVLANFRAMES_GB_LO);
-+
-+ stats->rxwatchdogerror +=
-+ xgbe_mmc_read(pdata, MMC_RXWATCHDOGERROR);
-+
-+ /* Un-freeze counters */
-+ XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0);
-+}
-+
-+static void xgbe_config_mmc(struct xgbe_prv_data *pdata)
-+{
-+ /* Set counters to reset on read */
-+ XGMAC_IOWRITE_BITS(pdata, MMC_CR, ROR, 1);
-+
-+ /* Reset the counters */
-+ XGMAC_IOWRITE_BITS(pdata, MMC_CR, CR, 1);
-+}
-+
-+static void xgbe_prepare_tx_stop(struct xgbe_prv_data *pdata,
-+ struct xgbe_channel *channel)
-+{
-+ unsigned int tx_dsr, tx_pos, tx_qidx;
-+ unsigned int tx_status;
-+ unsigned long tx_timeout;
-+
-+ /* Calculate the status register to read and the position within */
-+ if (channel->queue_index < DMA_DSRX_FIRST_QUEUE) {
-+ tx_dsr = DMA_DSR0;
-+ tx_pos = (channel->queue_index * DMA_DSR_Q_WIDTH) +
-+ DMA_DSR0_TPS_START;
-+ } else {
-+ tx_qidx = channel->queue_index - DMA_DSRX_FIRST_QUEUE;
-+
-+ tx_dsr = DMA_DSR1 + ((tx_qidx / DMA_DSRX_QPR) * DMA_DSRX_INC);
-+ tx_pos = ((tx_qidx % DMA_DSRX_QPR) * DMA_DSR_Q_WIDTH) +
-+ DMA_DSRX_TPS_START;
-+ }
-+
-+ /* The Tx engine cannot be stopped if it is actively processing
-+ * descriptors. Wait for the Tx engine to enter the stopped or
-+ * suspended state. Don't wait forever though...
-+ */
-+ tx_timeout = jiffies + (XGBE_DMA_STOP_TIMEOUT * HZ);
-+ while (time_before(jiffies, tx_timeout)) {
-+ tx_status = XGMAC_IOREAD(pdata, tx_dsr);
-+ tx_status = GET_BITS(tx_status, tx_pos, DMA_DSR_TPS_WIDTH);
-+ if ((tx_status == DMA_TPS_STOPPED) ||
-+ (tx_status == DMA_TPS_SUSPENDED))
-+ break;
-+
-+ usleep_range(500, 1000);
-+ }
-+
-+ if (!time_before(jiffies, tx_timeout))
-+ netdev_info(pdata->netdev,
-+ "timed out waiting for Tx DMA channel %u to stop\n",
-+ channel->queue_index);
-+}
-+
-+static void xgbe_enable_tx(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ /* Enable each Tx DMA channel */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 1);
-+ }
-+
-+ /* Enable each Tx queue */
-+ for (i = 0; i < pdata->tx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN,
-+ MTL_Q_ENABLED);
-+
-+ /* Enable MAC Tx */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 1);
-+}
-+
-+static void xgbe_disable_tx(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ /* Prepare for Tx DMA channel stop */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ xgbe_prepare_tx_stop(pdata, channel);
-+ }
-+
-+ /* Disable MAC Tx */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0);
-+
-+ /* Disable each Tx queue */
-+ for (i = 0; i < pdata->tx_q_count; i++)
-+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN, 0);
-+
-+ /* Disable each Tx DMA channel */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 0);
-+ }
-+}
-+
-+static void xgbe_enable_rx(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int reg_val, i;
-+
-+ /* Enable each Rx DMA channel */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->rx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 1);
-+ }
-+
-+ /* Enable each Rx queue */
-+ reg_val = 0;
-+ for (i = 0; i < pdata->rx_q_count; i++)
-+ reg_val |= (0x02 << (i << 1));
-+ XGMAC_IOWRITE(pdata, MAC_RQC0R, reg_val);
-+
-+ /* Enable MAC Rx */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 1);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 1);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 1);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 1);
-+}
-+
-+static void xgbe_disable_rx(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ /* Disable MAC Rx */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 0);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 0);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 0);
-+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 0);
-+
-+ /* Disable each Rx queue */
-+ XGMAC_IOWRITE(pdata, MAC_RQC0R, 0);
-+
-+ /* Disable each Rx DMA channel */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->rx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 0);
-+ }
-+}
-+
-+static void xgbe_powerup_tx(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ /* Enable each Tx DMA channel */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 1);
-+ }
-+
-+ /* Enable MAC Tx */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 1);
-+}
-+
-+static void xgbe_powerdown_tx(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ /* Prepare for Tx DMA channel stop */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ xgbe_prepare_tx_stop(pdata, channel);
-+ }
-+
-+ /* Disable MAC Tx */
-+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0);
-+
-+ /* Disable each Tx DMA channel */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 0);
-+ }
-+}
-+
-+static void xgbe_powerup_rx(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ /* Enable each Rx DMA channel */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->rx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 1);
-+ }
-+}
-+
-+static void xgbe_powerdown_rx(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ /* Disable each Rx DMA channel */
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->rx_ring)
-+ break;
-+
-+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 0);
-+ }
-+}
-+
-+static int xgbe_init(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
-+ int ret;
-+
-+ DBGPR("-->xgbe_init\n");
-+
-+ /* Flush Tx queues */
-+ ret = xgbe_flush_tx_queues(pdata);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * Initialize DMA related features
-+ */
-+ xgbe_config_dma_bus(pdata);
-+ xgbe_config_dma_cache(pdata);
-+ xgbe_config_osp_mode(pdata);
-+ xgbe_config_pblx8(pdata);
-+ xgbe_config_tx_pbl_val(pdata);
-+ xgbe_config_rx_pbl_val(pdata);
-+ xgbe_config_rx_coalesce(pdata);
-+ xgbe_config_tx_coalesce(pdata);
-+ xgbe_config_rx_buffer_size(pdata);
-+ xgbe_config_tso_mode(pdata);
-+ xgbe_config_sph_mode(pdata);
-+ xgbe_config_rss(pdata);
-+ desc_if->wrapper_tx_desc_init(pdata);
-+ desc_if->wrapper_rx_desc_init(pdata);
-+ xgbe_enable_dma_interrupts(pdata);
-+
-+ /*
-+ * Initialize MTL related features
-+ */
-+ xgbe_config_mtl_mode(pdata);
-+ xgbe_config_queue_mapping(pdata);
-+ xgbe_config_tsf_mode(pdata, pdata->tx_sf_mode);
-+ xgbe_config_rsf_mode(pdata, pdata->rx_sf_mode);
-+ xgbe_config_tx_threshold(pdata, pdata->tx_threshold);
-+ xgbe_config_rx_threshold(pdata, pdata->rx_threshold);
-+ xgbe_config_tx_fifo_size(pdata);
-+ xgbe_config_rx_fifo_size(pdata);
-+ xgbe_config_flow_control_threshold(pdata);
-+ /*TODO: Error Packet and undersized good Packet forwarding enable
-+ (FEP and FUP)
-+ */
-+ xgbe_config_dcb_tc(pdata);
-+ xgbe_config_dcb_pfc(pdata);
-+ xgbe_enable_mtl_interrupts(pdata);
-+
-+ /*
-+ * Initialize MAC related features
-+ */
-+ xgbe_config_mac_address(pdata);
-+ xgbe_config_jumbo_enable(pdata);
-+ xgbe_config_flow_control(pdata);
-+ xgbe_config_mac_speed(pdata);
-+ xgbe_config_checksum_offload(pdata);
-+ xgbe_config_vlan_support(pdata);
-+ xgbe_config_mmc(pdata);
-+ xgbe_enable_mac_interrupts(pdata);
-+
-+ DBGPR("<--xgbe_init\n");
-+
-+ return 0;
-+}
-+
-+void xgbe_a0_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
-+{
-+ DBGPR("-->xgbe_a0_init_function_ptrs\n");
-+
-+ hw_if->tx_complete = xgbe_tx_complete;
-+
-+ hw_if->set_promiscuous_mode = xgbe_set_promiscuous_mode;
-+ hw_if->set_all_multicast_mode = xgbe_set_all_multicast_mode;
-+ hw_if->add_mac_addresses = xgbe_add_mac_addresses;
-+ hw_if->set_mac_address = xgbe_set_mac_address;
-+
-+ hw_if->enable_rx_csum = xgbe_enable_rx_csum;
-+ hw_if->disable_rx_csum = xgbe_disable_rx_csum;
-+
-+ hw_if->enable_rx_vlan_stripping = xgbe_enable_rx_vlan_stripping;
-+ hw_if->disable_rx_vlan_stripping = xgbe_disable_rx_vlan_stripping;
-+ hw_if->enable_rx_vlan_filtering = xgbe_enable_rx_vlan_filtering;
-+ hw_if->disable_rx_vlan_filtering = xgbe_disable_rx_vlan_filtering;
-+ hw_if->update_vlan_hash_table = xgbe_update_vlan_hash_table;
-+
-+ hw_if->read_mmd_regs = xgbe_read_mmd_regs;
-+ hw_if->write_mmd_regs = xgbe_write_mmd_regs;
-+
-+ hw_if->set_gmii_speed = xgbe_set_gmii_speed;
-+ hw_if->set_gmii_2500_speed = xgbe_set_gmii_2500_speed;
-+ hw_if->set_xgmii_speed = xgbe_set_xgmii_speed;
-+
-+ hw_if->enable_tx = xgbe_enable_tx;
-+ hw_if->disable_tx = xgbe_disable_tx;
-+ hw_if->enable_rx = xgbe_enable_rx;
-+ hw_if->disable_rx = xgbe_disable_rx;
-+
-+ hw_if->powerup_tx = xgbe_powerup_tx;
-+ hw_if->powerdown_tx = xgbe_powerdown_tx;
-+ hw_if->powerup_rx = xgbe_powerup_rx;
-+ hw_if->powerdown_rx = xgbe_powerdown_rx;
-+
-+ hw_if->dev_xmit = xgbe_dev_xmit;
-+ hw_if->dev_read = xgbe_dev_read;
-+ hw_if->enable_int = xgbe_enable_int;
-+ hw_if->disable_int = xgbe_disable_int;
-+ hw_if->init = xgbe_init;
-+ hw_if->exit = xgbe_exit;
-+
-+ /* Descriptor related Sequences have to be initialized here */
-+ hw_if->tx_desc_init = xgbe_tx_desc_init;
-+ hw_if->rx_desc_init = xgbe_rx_desc_init;
-+ hw_if->tx_desc_reset = xgbe_tx_desc_reset;
-+ hw_if->rx_desc_reset = xgbe_rx_desc_reset;
-+ hw_if->is_last_desc = xgbe_is_last_desc;
-+ hw_if->is_context_desc = xgbe_is_context_desc;
-+ hw_if->tx_start_xmit = xgbe_tx_start_xmit;
-+
-+ /* For FLOW ctrl */
-+ hw_if->config_tx_flow_control = xgbe_config_tx_flow_control;
-+ hw_if->config_rx_flow_control = xgbe_config_rx_flow_control;
-+
-+ /* For RX coalescing */
-+ hw_if->config_rx_coalesce = xgbe_config_rx_coalesce;
-+ hw_if->config_tx_coalesce = xgbe_config_tx_coalesce;
-+ hw_if->usec_to_riwt = xgbe_usec_to_riwt;
-+ hw_if->riwt_to_usec = xgbe_riwt_to_usec;
-+
-+ /* For RX and TX threshold config */
-+ hw_if->config_rx_threshold = xgbe_config_rx_threshold;
-+ hw_if->config_tx_threshold = xgbe_config_tx_threshold;
-+
-+ /* For RX and TX Store and Forward Mode config */
-+ hw_if->config_rsf_mode = xgbe_config_rsf_mode;
-+ hw_if->config_tsf_mode = xgbe_config_tsf_mode;
-+
-+ /* For TX DMA Operating on Second Frame config */
-+ hw_if->config_osp_mode = xgbe_config_osp_mode;
-+
-+ /* For RX and TX PBL config */
-+ hw_if->config_rx_pbl_val = xgbe_config_rx_pbl_val;
-+ hw_if->get_rx_pbl_val = xgbe_get_rx_pbl_val;
-+ hw_if->config_tx_pbl_val = xgbe_config_tx_pbl_val;
-+ hw_if->get_tx_pbl_val = xgbe_get_tx_pbl_val;
-+ hw_if->config_pblx8 = xgbe_config_pblx8;
-+
-+ /* For MMC statistics support */
-+ hw_if->tx_mmc_int = xgbe_tx_mmc_int;
-+ hw_if->rx_mmc_int = xgbe_rx_mmc_int;
-+ hw_if->read_mmc_stats = xgbe_read_mmc_stats;
-+
-+ /* For PTP config */
-+ hw_if->config_tstamp = xgbe_config_tstamp;
-+ hw_if->update_tstamp_addend = xgbe_update_tstamp_addend;
-+ hw_if->set_tstamp_time = xgbe_set_tstamp_time;
-+ hw_if->get_tstamp_time = xgbe_get_tstamp_time;
-+ hw_if->get_tx_tstamp = xgbe_get_tx_tstamp;
-+
-+ /* For Data Center Bridging config */
-+ hw_if->config_dcb_tc = xgbe_config_dcb_tc;
-+ hw_if->config_dcb_pfc = xgbe_config_dcb_pfc;
-+
-+ /* For Receive Side Scaling */
-+ hw_if->enable_rss = xgbe_enable_rss;
-+ hw_if->disable_rss = xgbe_disable_rss;
-+ hw_if->set_rss_hash_key = xgbe_set_rss_hash_key;
-+ hw_if->set_rss_lookup_table = xgbe_set_rss_lookup_table;
-+
-+ DBGPR("<--xgbe_a0_init_function_ptrs\n");
-+}
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe-a0/xgbe-drv.c
-new file mode 100644
-index 0000000..ca4af9e
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-drv.c
-@@ -0,0 +1,2218 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <linux/spinlock.h>
-+#include <linux/tcp.h>
-+#include <linux/if_vlan.h>
-+#include <net/busy_poll.h>
-+#include <linux/clk.h>
-+#include <linux/if_ether.h>
-+#include <linux/net_tstamp.h>
-+#include <linux/phy.h>
-+
-+#include "xgbe.h"
-+#include "xgbe-common.h"
-+
-+static int xgbe_one_poll(struct napi_struct *, int);
-+static int xgbe_all_poll(struct napi_struct *, int);
-+static void xgbe_set_rx_mode(struct net_device *);
-+
-+static int xgbe_alloc_channels(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel_mem, *channel;
-+ struct xgbe_ring *tx_ring, *rx_ring;
-+ unsigned int count, i;
-+ int ret = -ENOMEM;
-+
-+ count = max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count);
-+
-+ channel_mem = kcalloc(count, sizeof(struct xgbe_channel), GFP_KERNEL);
-+ if (!channel_mem)
-+ goto err_channel;
-+
-+ tx_ring = kcalloc(pdata->tx_ring_count, sizeof(struct xgbe_ring),
-+ GFP_KERNEL);
-+ if (!tx_ring)
-+ goto err_tx_ring;
-+
-+ rx_ring = kcalloc(pdata->rx_ring_count, sizeof(struct xgbe_ring),
-+ GFP_KERNEL);
-+ if (!rx_ring)
-+ goto err_rx_ring;
-+
-+ for (i = 0, channel = channel_mem; i < count; i++, channel++) {
-+ snprintf(channel->name, sizeof(channel->name), "channel-%d", i);
-+ channel->pdata = pdata;
-+ channel->queue_index = i;
-+ channel->dma_regs = pdata->xgmac_regs + DMA_CH_BASE +
-+ (DMA_CH_INC * i);
-+
-+ if (pdata->per_channel_irq) {
-+ /* Get the DMA interrupt (offset 1) */
-+ ret = platform_get_irq(pdata->pdev, i + 1);
-+ if (ret < 0) {
-+ netdev_err(pdata->netdev,
-+ "platform_get_irq %u failed\n",
-+ i + 1);
-+ goto err_irq;
-+ }
-+
-+ channel->dma_irq = ret;
-+ }
-+
-+ if (i < pdata->tx_ring_count) {
-+ spin_lock_init(&tx_ring->lock);
-+ channel->tx_ring = tx_ring++;
-+ }
-+
-+ if (i < pdata->rx_ring_count) {
-+ spin_lock_init(&rx_ring->lock);
-+ channel->rx_ring = rx_ring++;
-+ }
-+
-+ DBGPR(" %s: queue=%u, dma_regs=%p, dma_irq=%d, tx=%p, rx=%p\n",
-+ channel->name, channel->queue_index, channel->dma_regs,
-+ channel->dma_irq, channel->tx_ring, channel->rx_ring);
-+ }
-+
-+ pdata->channel = channel_mem;
-+ pdata->channel_count = count;
-+
-+ return 0;
-+
-+err_irq:
-+ kfree(rx_ring);
-+
-+err_rx_ring:
-+ kfree(tx_ring);
-+
-+err_tx_ring:
-+ kfree(channel_mem);
-+
-+err_channel:
-+ return ret;
-+}
-+
-+static void xgbe_free_channels(struct xgbe_prv_data *pdata)
-+{
-+ if (!pdata->channel)
-+ return;
-+
-+ kfree(pdata->channel->rx_ring);
-+ kfree(pdata->channel->tx_ring);
-+ kfree(pdata->channel);
-+
-+ pdata->channel = NULL;
-+ pdata->channel_count = 0;
-+}
-+
-+static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring)
-+{
-+ return (ring->rdesc_count - (ring->cur - ring->dirty));
-+}
-+
-+static inline unsigned int xgbe_rx_dirty_desc(struct xgbe_ring *ring)
-+{
-+ return (ring->cur - ring->dirty);
-+}
-+
-+static int xgbe_maybe_stop_tx_queue(struct xgbe_channel *channel,
-+ struct xgbe_ring *ring, unsigned int count)
-+{
-+ struct xgbe_prv_data *pdata = channel->pdata;
-+
-+ if (count > xgbe_tx_avail_desc(ring)) {
-+ DBGPR(" Tx queue stopped, not enough descriptors available\n");
-+ netif_stop_subqueue(pdata->netdev, channel->queue_index);
-+ ring->tx.queue_stopped = 1;
-+
-+ /* If we haven't notified the hardware because of xmit_more
-+ * support, tell it now
-+ */
-+ if (ring->tx.xmit_more)
-+ pdata->hw_if.tx_start_xmit(channel, ring);
-+
-+ return NETDEV_TX_BUSY;
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_calc_rx_buf_size(struct net_device *netdev, unsigned int mtu)
-+{
-+ unsigned int rx_buf_size;
-+
-+ if (mtu > XGMAC_JUMBO_PACKET_MTU) {
-+ netdev_alert(netdev, "MTU exceeds maximum supported value\n");
-+ return -EINVAL;
-+ }
-+
-+ rx_buf_size = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
-+ rx_buf_size = clamp_val(rx_buf_size, XGBE_RX_MIN_BUF_SIZE, PAGE_SIZE);
-+
-+ rx_buf_size = (rx_buf_size + XGBE_RX_BUF_ALIGN - 1) &
-+ ~(XGBE_RX_BUF_ALIGN - 1);
-+
-+ return rx_buf_size;
-+}
-+
-+static void xgbe_enable_rx_tx_ints(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_channel *channel;
-+ enum xgbe_int int_id;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (channel->tx_ring && channel->rx_ring)
-+ int_id = XGMAC_INT_DMA_CH_SR_TI_RI;
-+ else if (channel->tx_ring)
-+ int_id = XGMAC_INT_DMA_CH_SR_TI;
-+ else if (channel->rx_ring)
-+ int_id = XGMAC_INT_DMA_CH_SR_RI;
-+ else
-+ continue;
-+
-+ hw_if->enable_int(channel, int_id);
-+ }
-+}
-+
-+static void xgbe_disable_rx_tx_ints(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_channel *channel;
-+ enum xgbe_int int_id;
-+ unsigned int i;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (channel->tx_ring && channel->rx_ring)
-+ int_id = XGMAC_INT_DMA_CH_SR_TI_RI;
-+ else if (channel->tx_ring)
-+ int_id = XGMAC_INT_DMA_CH_SR_TI;
-+ else if (channel->rx_ring)
-+ int_id = XGMAC_INT_DMA_CH_SR_RI;
-+ else
-+ continue;
-+
-+ hw_if->disable_int(channel, int_id);
-+ }
-+}
-+
-+static irqreturn_t xgbe_isr(int irq, void *data)
-+{
-+ struct xgbe_prv_data *pdata = data;
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_channel *channel;
-+ unsigned int dma_isr, dma_ch_isr;
-+ unsigned int mac_isr, mac_tssr;
-+ unsigned int i;
-+
-+ /* The DMA interrupt status register also reports MAC and MTL
-+ * interrupts. So for polling mode, we just need to check for
-+ * this register to be non-zero
-+ */
-+ dma_isr = XGMAC_IOREAD(pdata, DMA_ISR);
-+ if (!dma_isr)
-+ goto isr_done;
-+
-+ DBGPR(" DMA_ISR = %08x\n", dma_isr);
-+
-+ for (i = 0; i < pdata->channel_count; i++) {
-+ if (!(dma_isr & (1 << i)))
-+ continue;
-+
-+ channel = pdata->channel + i;
-+
-+ dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR);
-+ DBGPR(" DMA_CH%u_ISR = %08x\n", i, dma_ch_isr);
-+
-+ /* The TI or RI interrupt bits may still be set even if using
-+ * per channel DMA interrupts. Check to be sure those are not
-+ * enabled before using the private data napi structure.
-+ */
-+ if (!pdata->per_channel_irq &&
-+ (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, TI) ||
-+ XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RI))) {
-+ if (napi_schedule_prep(&pdata->napi)) {
-+ /* Disable Tx and Rx interrupts */
-+ xgbe_disable_rx_tx_ints(pdata);
-+
-+ /* Turn on polling */
-+ __napi_schedule(&pdata->napi);
-+ }
-+ }
-+
-+ /* Restart the device on a Fatal Bus Error */
-+ if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, FBE))
-+ schedule_work(&pdata->restart_work);
-+
-+ /* Clear all interrupt signals */
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_ch_isr);
-+ }
-+
-+ if (XGMAC_GET_BITS(dma_isr, DMA_ISR, MACIS)) {
-+ mac_isr = XGMAC_IOREAD(pdata, MAC_ISR);
-+
-+ if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCTXIS))
-+ hw_if->tx_mmc_int(pdata);
-+
-+ if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCRXIS))
-+ hw_if->rx_mmc_int(pdata);
-+
-+ if (XGMAC_GET_BITS(mac_isr, MAC_ISR, TSIS)) {
-+ mac_tssr = XGMAC_IOREAD(pdata, MAC_TSSR);
-+
-+ if (XGMAC_GET_BITS(mac_tssr, MAC_TSSR, TXTSC)) {
-+ /* Read Tx Timestamp to clear interrupt */
-+ pdata->tx_tstamp =
-+ hw_if->get_tx_tstamp(pdata);
-+ schedule_work(&pdata->tx_tstamp_work);
-+ }
-+ }
-+ }
-+
-+ DBGPR(" DMA_ISR = %08x\n", XGMAC_IOREAD(pdata, DMA_ISR));
-+
-+isr_done:
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t xgbe_dma_isr(int irq, void *data)
-+{
-+ struct xgbe_channel *channel = data;
-+
-+ /* Per channel DMA interrupts are enabled, so we use the per
-+ * channel napi structure and not the private data napi structure
-+ */
-+ if (napi_schedule_prep(&channel->napi)) {
-+ /* Disable Tx and Rx interrupts */
-+ disable_irq_nosync(channel->dma_irq);
-+
-+ /* Turn on polling */
-+ __napi_schedule(&channel->napi);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
-+{
-+ struct xgbe_channel *channel = container_of(timer,
-+ struct xgbe_channel,
-+ tx_timer);
-+ struct xgbe_prv_data *pdata = channel->pdata;
-+ struct napi_struct *napi;
-+
-+ DBGPR("-->xgbe_tx_timer\n");
-+
-+ napi = (pdata->per_channel_irq) ? &channel->napi : &pdata->napi;
-+
-+ if (napi_schedule_prep(napi)) {
-+ /* Disable Tx and Rx interrupts */
-+ if (pdata->per_channel_irq)
-+ disable_irq(channel->dma_irq);
-+ else
-+ xgbe_disable_rx_tx_ints(pdata);
-+
-+ /* Turn on polling */
-+ __napi_schedule(napi);
-+ }
-+
-+ channel->tx_timer_active = 0;
-+
-+ DBGPR("<--xgbe_tx_timer\n");
-+
-+ return HRTIMER_NORESTART;
-+}
-+
-+static void xgbe_init_tx_timers(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ DBGPR("-->xgbe_init_tx_timers\n");
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ DBGPR(" %s adding tx timer\n", channel->name);
-+ hrtimer_init(&channel->tx_timer, CLOCK_MONOTONIC,
-+ HRTIMER_MODE_REL);
-+ channel->tx_timer.function = xgbe_tx_timer;
-+ }
-+
-+ DBGPR("<--xgbe_init_tx_timers\n");
-+}
-+
-+static void xgbe_stop_tx_timers(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ DBGPR("-->xgbe_stop_tx_timers\n");
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ break;
-+
-+ DBGPR(" %s deleting tx timer\n", channel->name);
-+ channel->tx_timer_active = 0;
-+ hrtimer_cancel(&channel->tx_timer);
-+ }
-+
-+ DBGPR("<--xgbe_stop_tx_timers\n");
-+}
-+
-+void xgbe_a0_get_all_hw_features(struct xgbe_prv_data *pdata)
-+{
-+ unsigned int mac_hfr0, mac_hfr1, mac_hfr2;
-+ struct xgbe_hw_features *hw_feat = &pdata->hw_feat;
-+
-+ DBGPR("-->xgbe_a0_get_all_hw_features\n");
-+
-+ mac_hfr0 = XGMAC_IOREAD(pdata, MAC_HWF0R);
-+ mac_hfr1 = XGMAC_IOREAD(pdata, MAC_HWF1R);
-+ mac_hfr2 = XGMAC_IOREAD(pdata, MAC_HWF2R);
-+
-+ memset(hw_feat, 0, sizeof(*hw_feat));
-+
-+ hw_feat->version = XGMAC_IOREAD(pdata, MAC_VR);
-+
-+ /* Hardware feature register 0 */
-+ hw_feat->gmii = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL);
-+ hw_feat->vlhash = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH);
-+ hw_feat->sma = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SMASEL);
-+ hw_feat->rwk = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RWKSEL);
-+ hw_feat->mgk = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MGKSEL);
-+ hw_feat->mmc = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MMCSEL);
-+ hw_feat->aoe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, ARPOFFSEL);
-+ hw_feat->ts = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSEL);
-+ hw_feat->eee = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, EEESEL);
-+ hw_feat->tx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TXCOESEL);
-+ hw_feat->rx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RXCOESEL);
-+ hw_feat->addn_mac = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R,
-+ ADDMACADRSEL);
-+ hw_feat->ts_src = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSTSSEL);
-+ hw_feat->sa_vlan_ins = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SAVLANINS);
-+
-+ /* Hardware feature register 1 */
-+ hw_feat->rx_fifo_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
-+ RXFIFOSIZE);
-+ hw_feat->tx_fifo_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
-+ TXFIFOSIZE);
-+ hw_feat->dcb = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN);
-+ hw_feat->sph = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
-+ hw_feat->tso = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
-+ hw_feat->dma_debug = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DBGMEMA);
-+ hw_feat->rss = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, RSSEN);
-+ hw_feat->tc_cnt = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, NUMTC);
-+ hw_feat->hash_table_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
-+ HASHTBLSZ);
-+ hw_feat->l3l4_filter_num = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
-+ L3L4FNUM);
-+
-+ /* Hardware feature register 2 */
-+ hw_feat->rx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXQCNT);
-+ hw_feat->tx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXQCNT);
-+ hw_feat->rx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXCHCNT);
-+ hw_feat->tx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXCHCNT);
-+ hw_feat->pps_out_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM);
-+ hw_feat->aux_snap_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, AUXSNAPNUM);
-+
-+ /* Translate the Hash Table size into actual number */
-+ switch (hw_feat->hash_table_size) {
-+ case 0:
-+ break;
-+ case 1:
-+ hw_feat->hash_table_size = 64;
-+ break;
-+ case 2:
-+ hw_feat->hash_table_size = 128;
-+ break;
-+ case 3:
-+ hw_feat->hash_table_size = 256;
-+ break;
-+ }
-+
-+ /* The Queue, Channel and TC counts are zero based so increment them
-+ * to get the actual number
-+ */
-+ hw_feat->rx_q_cnt++;
-+ hw_feat->tx_q_cnt++;
-+ hw_feat->rx_ch_cnt++;
-+ hw_feat->tx_ch_cnt++;
-+ hw_feat->tc_cnt++;
-+
-+#define XGBE_TC_CNT 2
-+ hw_feat->tc_cnt = XGBE_TC_CNT;
-+
-+ DBGPR("<--xgbe_a0_get_all_hw_features\n");
-+}
-+
-+static void xgbe_napi_enable(struct xgbe_prv_data *pdata, unsigned int add)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ if (pdata->per_channel_irq) {
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (add)
-+ netif_napi_add(pdata->netdev, &channel->napi,
-+ xgbe_one_poll, NAPI_POLL_WEIGHT);
-+
-+ napi_enable(&channel->napi);
-+ }
-+ } else {
-+ if (add)
-+ netif_napi_add(pdata->netdev, &pdata->napi,
-+ xgbe_all_poll, NAPI_POLL_WEIGHT);
-+
-+ napi_enable(&pdata->napi);
-+ }
-+}
-+
-+static void xgbe_napi_disable(struct xgbe_prv_data *pdata, unsigned int del)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ if (pdata->per_channel_irq) {
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ napi_disable(&channel->napi);
-+
-+ if (del)
-+ netif_napi_del(&channel->napi);
-+ }
-+ } else {
-+ napi_disable(&pdata->napi);
-+
-+ if (del)
-+ netif_napi_del(&pdata->napi);
-+ }
-+}
-+
-+static int xgbe_request_irqs(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ struct net_device *netdev = pdata->netdev;
-+ unsigned int i;
-+ int ret;
-+
-+ ret = devm_request_irq(pdata->dev, pdata->dev_irq, xgbe_isr, 0,
-+ netdev->name, pdata);
-+ if (ret) {
-+ netdev_alert(netdev, "error requesting irq %d\n",
-+ pdata->dev_irq);
-+ return ret;
-+ }
-+
-+ if (!pdata->per_channel_irq)
-+ return 0;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ snprintf(channel->dma_irq_name,
-+ sizeof(channel->dma_irq_name) - 1,
-+ "%s-TxRx-%u", netdev_name(netdev),
-+ channel->queue_index);
-+
-+ ret = devm_request_irq(pdata->dev, channel->dma_irq,
-+ xgbe_dma_isr, 0,
-+ channel->dma_irq_name, channel);
-+ if (ret) {
-+ netdev_alert(netdev, "error requesting irq %d\n",
-+ channel->dma_irq);
-+ goto err_irq;
-+ }
-+ }
-+
-+ return 0;
-+
-+err_irq:
-+ /* Using an unsigned int, 'i' will go to UINT_MAX and exit */
-+ for (i--, channel--; i < pdata->channel_count; i--, channel--)
-+ devm_free_irq(pdata->dev, channel->dma_irq, channel);
-+
-+ devm_free_irq(pdata->dev, pdata->dev_irq, pdata);
-+
-+ return ret;
-+}
-+
-+static void xgbe_free_irqs(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ devm_free_irq(pdata->dev, pdata->dev_irq, pdata);
-+
-+ if (!pdata->per_channel_irq)
-+ return;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++)
-+ devm_free_irq(pdata->dev, channel->dma_irq, channel);
-+}
-+
-+void xgbe_a0_init_tx_coalesce(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+
-+ DBGPR("-->xgbe_a0_init_tx_coalesce\n");
-+
-+ pdata->tx_usecs = XGMAC_INIT_DMA_TX_USECS;
-+ pdata->tx_frames = XGMAC_INIT_DMA_TX_FRAMES;
-+
-+ hw_if->config_tx_coalesce(pdata);
-+
-+ DBGPR("<--xgbe_a0_init_tx_coalesce\n");
-+}
-+
-+void xgbe_a0_init_rx_coalesce(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+
-+ DBGPR("-->xgbe_a0_init_rx_coalesce\n");
-+
-+ pdata->rx_riwt = hw_if->usec_to_riwt(pdata, XGMAC_INIT_DMA_RX_USECS);
-+ pdata->rx_frames = XGMAC_INIT_DMA_RX_FRAMES;
-+
-+ hw_if->config_rx_coalesce(pdata);
-+
-+ DBGPR("<--xgbe_a0_init_rx_coalesce\n");
-+}
-+
-+static void xgbe_free_tx_data(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
-+ struct xgbe_channel *channel;
-+ struct xgbe_ring *ring;
-+ struct xgbe_ring_data *rdata;
-+ unsigned int i, j;
-+
-+ DBGPR("-->xgbe_free_tx_data\n");
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ ring = channel->tx_ring;
-+ if (!ring)
-+ break;
-+
-+ for (j = 0; j < ring->rdesc_count; j++) {
-+ rdata = XGBE_GET_DESC_DATA(ring, j);
-+ desc_if->unmap_rdata(pdata, rdata);
-+ }
-+ }
-+
-+ DBGPR("<--xgbe_free_tx_data\n");
-+}
-+
-+static void xgbe_free_rx_data(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
-+ struct xgbe_channel *channel;
-+ struct xgbe_ring *ring;
-+ struct xgbe_ring_data *rdata;
-+ unsigned int i, j;
-+
-+ DBGPR("-->xgbe_free_rx_data\n");
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ ring = channel->rx_ring;
-+ if (!ring)
-+ break;
-+
-+ for (j = 0; j < ring->rdesc_count; j++) {
-+ rdata = XGBE_GET_DESC_DATA(ring, j);
-+ desc_if->unmap_rdata(pdata, rdata);
-+ }
-+ }
-+
-+ DBGPR("<--xgbe_free_rx_data\n");
-+}
-+
-+static void xgbe_adjust_link(struct net_device *netdev)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct phy_device *phydev = pdata->phydev;
-+ int new_state = 0;
-+
-+ if (!phydev)
-+ return;
-+
-+ if (phydev->link) {
-+ /* Flow control support */
-+ if (pdata->pause_autoneg) {
-+ if (phydev->pause || phydev->asym_pause) {
-+ pdata->tx_pause = 1;
-+ pdata->rx_pause = 1;
-+ } else {
-+ pdata->tx_pause = 0;
-+ pdata->rx_pause = 0;
-+ }
-+ }
-+
-+ if (pdata->tx_pause != pdata->phy_tx_pause) {
-+ hw_if->config_tx_flow_control(pdata);
-+ pdata->phy_tx_pause = pdata->tx_pause;
-+ }
-+
-+ if (pdata->rx_pause != pdata->phy_rx_pause) {
-+ hw_if->config_rx_flow_control(pdata);
-+ pdata->phy_rx_pause = pdata->rx_pause;
-+ }
-+
-+ /* Speed support */
-+ if (phydev->speed != pdata->phy_speed) {
-+ new_state = 1;
-+
-+ switch (phydev->speed) {
-+ case SPEED_10000:
-+ hw_if->set_xgmii_speed(pdata);
-+ break;
-+
-+ case SPEED_2500:
-+ hw_if->set_gmii_2500_speed(pdata);
-+ break;
-+
-+ case SPEED_1000:
-+ hw_if->set_gmii_speed(pdata);
-+ break;
-+ }
-+ pdata->phy_speed = phydev->speed;
-+ }
-+
-+ if (phydev->link != pdata->phy_link) {
-+ new_state = 1;
-+ pdata->phy_link = 1;
-+ }
-+ } else if (pdata->phy_link) {
-+ new_state = 1;
-+ pdata->phy_link = 0;
-+ pdata->phy_speed = SPEED_UNKNOWN;
-+ }
-+
-+ if (new_state)
-+ phy_print_status(phydev);
-+}
-+
-+static int xgbe_phy_init(struct xgbe_prv_data *pdata)
-+{
-+ struct net_device *netdev = pdata->netdev;
-+ struct phy_device *phydev = pdata->phydev;
-+ int ret;
-+
-+ pdata->phy_link = -1;
-+ pdata->phy_speed = SPEED_UNKNOWN;
-+ pdata->phy_tx_pause = pdata->tx_pause;
-+ pdata->phy_rx_pause = pdata->rx_pause;
-+
-+ ret = phy_connect_direct(netdev, phydev, &xgbe_adjust_link,
-+ pdata->phy_mode);
-+ if (ret) {
-+ netdev_err(netdev, "phy_connect_direct failed\n");
-+ return ret;
-+ }
-+
-+ if (!phydev->drv || (phydev->drv->phy_id == 0)) {
-+ netdev_err(netdev, "phy_id not valid\n");
-+ ret = -ENODEV;
-+ goto err_phy_connect;
-+ }
-+ DBGPR(" phy_connect_direct succeeded for PHY %s, link=%d\n",
-+ dev_name(&phydev->dev), phydev->link);
-+
-+ return 0;
-+
-+err_phy_connect:
-+ phy_disconnect(phydev);
-+
-+ return ret;
-+}
-+
-+static void xgbe_phy_exit(struct xgbe_prv_data *pdata)
-+{
-+ if (!pdata->phydev)
-+ return;
-+
-+ phy_disconnect(pdata->phydev);
-+}
-+
-+int xgbe_a0_powerdown(struct net_device *netdev, unsigned int caller)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ unsigned long flags;
-+
-+ DBGPR("-->xgbe_a0_powerdown\n");
-+
-+ if (!netif_running(netdev) ||
-+ (caller == XGMAC_IOCTL_CONTEXT && pdata->power_down)) {
-+ netdev_alert(netdev, "Device is already powered down\n");
-+ DBGPR("<--xgbe_a0_powerdown\n");
-+ return -EINVAL;
-+ }
-+
-+ spin_lock_irqsave(&pdata->lock, flags);
-+
-+ if (caller == XGMAC_DRIVER_CONTEXT)
-+ netif_device_detach(netdev);
-+
-+ netif_tx_stop_all_queues(netdev);
-+
-+ hw_if->powerdown_tx(pdata);
-+ hw_if->powerdown_rx(pdata);
-+
-+ xgbe_napi_disable(pdata, 0);
-+
-+ phy_stop(pdata->phydev);
-+
-+ pdata->power_down = 1;
-+
-+ spin_unlock_irqrestore(&pdata->lock, flags);
-+
-+ DBGPR("<--xgbe_a0_powerdown\n");
-+
-+ return 0;
-+}
-+
-+int xgbe_a0_powerup(struct net_device *netdev, unsigned int caller)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ unsigned long flags;
-+
-+ DBGPR("-->xgbe_a0_powerup\n");
-+
-+ if (!netif_running(netdev) ||
-+ (caller == XGMAC_IOCTL_CONTEXT && !pdata->power_down)) {
-+ netdev_alert(netdev, "Device is already powered up\n");
-+ DBGPR("<--xgbe_a0_powerup\n");
-+ return -EINVAL;
-+ }
-+
-+ spin_lock_irqsave(&pdata->lock, flags);
-+
-+ pdata->power_down = 0;
-+
-+ phy_start(pdata->phydev);
-+
-+ xgbe_napi_enable(pdata, 0);
-+
-+ hw_if->powerup_tx(pdata);
-+ hw_if->powerup_rx(pdata);
-+
-+ if (caller == XGMAC_DRIVER_CONTEXT)
-+ netif_device_attach(netdev);
-+
-+ netif_tx_start_all_queues(netdev);
-+
-+ spin_unlock_irqrestore(&pdata->lock, flags);
-+
-+ DBGPR("<--xgbe_a0_powerup\n");
-+
-+ return 0;
-+}
-+
-+static int xgbe_start(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct net_device *netdev = pdata->netdev;
-+ int ret;
-+
-+ DBGPR("-->xgbe_start\n");
-+
-+ xgbe_set_rx_mode(netdev);
-+
-+ hw_if->init(pdata);
-+
-+ phy_start(pdata->phydev);
-+
-+ xgbe_napi_enable(pdata, 1);
-+
-+ ret = xgbe_request_irqs(pdata);
-+ if (ret)
-+ goto err_napi;
-+
-+ hw_if->enable_tx(pdata);
-+ hw_if->enable_rx(pdata);
-+
-+ xgbe_init_tx_timers(pdata);
-+
-+ netif_tx_start_all_queues(netdev);
-+
-+ DBGPR("<--xgbe_start\n");
-+
-+ return 0;
-+
-+err_napi:
-+ xgbe_napi_disable(pdata, 1);
-+
-+ phy_stop(pdata->phydev);
-+
-+ hw_if->exit(pdata);
-+
-+ return ret;
-+}
-+
-+static void xgbe_stop(struct xgbe_prv_data *pdata)
-+{
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_channel *channel;
-+ struct net_device *netdev = pdata->netdev;
-+ struct netdev_queue *txq;
-+ unsigned int i;
-+
-+ DBGPR("-->xgbe_stop\n");
-+
-+ netif_tx_stop_all_queues(netdev);
-+
-+ xgbe_stop_tx_timers(pdata);
-+
-+ hw_if->disable_tx(pdata);
-+ hw_if->disable_rx(pdata);
-+
-+ xgbe_free_irqs(pdata);
-+
-+ xgbe_napi_disable(pdata, 1);
-+
-+ phy_stop(pdata->phydev);
-+
-+ hw_if->exit(pdata);
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ if (!channel->tx_ring)
-+ continue;
-+
-+ txq = netdev_get_tx_queue(netdev, channel->queue_index);
-+ netdev_tx_reset_queue(txq);
-+ }
-+
-+ DBGPR("<--xgbe_stop\n");
-+}
-+
-+static void xgbe_restart_dev(struct xgbe_prv_data *pdata)
-+{
-+ DBGPR("-->xgbe_restart_dev\n");
-+
-+ /* If not running, "restart" will happen on open */
-+ if (!netif_running(pdata->netdev))
-+ return;
-+
-+ xgbe_stop(pdata);
-+
-+ xgbe_free_tx_data(pdata);
-+ xgbe_free_rx_data(pdata);
-+
-+ xgbe_start(pdata);
-+
-+ DBGPR("<--xgbe_restart_dev\n");
-+}
-+
-+static void xgbe_restart(struct work_struct *work)
-+{
-+ struct xgbe_prv_data *pdata = container_of(work,
-+ struct xgbe_prv_data,
-+ restart_work);
-+
-+ rtnl_lock();
-+
-+ xgbe_restart_dev(pdata);
-+
-+ rtnl_unlock();
-+}
-+
-+static void xgbe_tx_tstamp(struct work_struct *work)
-+{
-+ struct xgbe_prv_data *pdata = container_of(work,
-+ struct xgbe_prv_data,
-+ tx_tstamp_work);
-+ struct skb_shared_hwtstamps hwtstamps;
-+ u64 nsec;
-+ unsigned long flags;
-+
-+ if (pdata->tx_tstamp) {
-+ nsec = timecounter_cyc2time(&pdata->tstamp_tc,
-+ pdata->tx_tstamp);
-+
-+ memset(&hwtstamps, 0, sizeof(hwtstamps));
-+ hwtstamps.hwtstamp = ns_to_ktime(nsec);
-+ skb_tstamp_tx(pdata->tx_tstamp_skb, &hwtstamps);
-+ }
-+
-+ dev_kfree_skb_any(pdata->tx_tstamp_skb);
-+
-+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
-+ pdata->tx_tstamp_skb = NULL;
-+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
-+}
-+
-+static int xgbe_get_hwtstamp_settings(struct xgbe_prv_data *pdata,
-+ struct ifreq *ifreq)
-+{
-+ if (copy_to_user(ifreq->ifr_data, &pdata->tstamp_config,
-+ sizeof(pdata->tstamp_config)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_hwtstamp_settings(struct xgbe_prv_data *pdata,
-+ struct ifreq *ifreq)
-+{
-+ struct hwtstamp_config config;
-+ unsigned int mac_tscr;
-+
-+ if (copy_from_user(&config, ifreq->ifr_data, sizeof(config)))
-+ return -EFAULT;
-+
-+ if (config.flags)
-+ return -EINVAL;
-+
-+ mac_tscr = 0;
-+
-+ switch (config.tx_type) {
-+ case HWTSTAMP_TX_OFF:
-+ break;
-+
-+ case HWTSTAMP_TX_ON:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ default:
-+ return -ERANGE;
-+ }
-+
-+ switch (config.rx_filter) {
-+ case HWTSTAMP_FILTER_NONE:
-+ break;
-+
-+ case HWTSTAMP_FILTER_ALL:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENALL, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ /* PTP v2, UDP, any kind of event packet */
-+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-+ /* PTP v1, UDP, any kind of event packet */
-+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ /* PTP v2, UDP, Sync packet */
-+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-+ /* PTP v1, UDP, Sync packet */
-+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ /* PTP v2, UDP, Delay_req packet */
-+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-+ /* PTP v1, UDP, Delay_req packet */
-+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ /* 802.AS1, Ethernet, any kind of event packet */
-+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ /* 802.AS1, Ethernet, Sync packet */
-+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ /* 802.AS1, Ethernet, Delay_req packet */
-+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ /* PTP v2/802.AS1, any layer, any kind of event packet */
-+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ /* PTP v2/802.AS1, any layer, Sync packet */
-+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ /* PTP v2/802.AS1, any layer, Delay_req packet */
-+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-+ break;
-+
-+ default:
-+ return -ERANGE;
-+ }
-+
-+ pdata->hw_if.config_tstamp(pdata, mac_tscr);
-+
-+ memcpy(&pdata->tstamp_config, &config, sizeof(config));
-+
-+ return 0;
-+}
-+
-+static void xgbe_prep_tx_tstamp(struct xgbe_prv_data *pdata,
-+ struct sk_buff *skb,
-+ struct xgbe_packet_data *packet)
-+{
-+ unsigned long flags;
-+
-+ if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP)) {
-+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
-+ if (pdata->tx_tstamp_skb) {
-+ /* Another timestamp in progress, ignore this one */
-+ XGMAC_SET_BITS(packet->attributes,
-+ TX_PACKET_ATTRIBUTES, PTP, 0);
-+ } else {
-+ pdata->tx_tstamp_skb = skb_get(skb);
-+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
-+ }
-+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
-+ }
-+
-+ if (!XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP))
-+ skb_tx_timestamp(skb);
-+}
-+
-+static void xgbe_prep_vlan(struct sk_buff *skb, struct xgbe_packet_data *packet)
-+{
-+ if (skb_vlan_tag_present(skb))
-+ packet->vlan_ctag = skb_vlan_tag_get(skb);
-+}
-+
-+static int xgbe_prep_tso(struct sk_buff *skb, struct xgbe_packet_data *packet)
-+{
-+ int ret;
-+
-+ if (!XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ TSO_ENABLE))
-+ return 0;
-+
-+ ret = skb_cow_head(skb, 0);
-+ if (ret)
-+ return ret;
-+
-+ packet->header_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-+ packet->tcp_header_len = tcp_hdrlen(skb);
-+ packet->tcp_payload_len = skb->len - packet->header_len;
-+ packet->mss = skb_shinfo(skb)->gso_size;
-+ DBGPR(" packet->header_len=%u\n", packet->header_len);
-+ DBGPR(" packet->tcp_header_len=%u, packet->tcp_payload_len=%u\n",
-+ packet->tcp_header_len, packet->tcp_payload_len);
-+ DBGPR(" packet->mss=%u\n", packet->mss);
-+
-+ /* Update the number of packets that will ultimately be transmitted
-+ * along with the extra bytes for each extra packet
-+ */
-+ packet->tx_packets = skb_shinfo(skb)->gso_segs;
-+ packet->tx_bytes += (packet->tx_packets - 1) * packet->header_len;
-+
-+ return 0;
-+}
-+
-+static int xgbe_is_tso(struct sk_buff *skb)
-+{
-+ if (skb->ip_summed != CHECKSUM_PARTIAL)
-+ return 0;
-+
-+ if (!skb_is_gso(skb))
-+ return 0;
-+
-+ DBGPR(" TSO packet to be processed\n");
-+
-+ return 1;
-+}
-+
-+static void xgbe_packet_info(struct xgbe_prv_data *pdata,
-+ struct xgbe_ring *ring, struct sk_buff *skb,
-+ struct xgbe_packet_data *packet)
-+{
-+ struct skb_frag_struct *frag;
-+ unsigned int context_desc;
-+ unsigned int len;
-+ unsigned int i;
-+
-+ packet->skb = skb;
-+
-+ context_desc = 0;
-+ packet->rdesc_count = 0;
-+
-+ packet->tx_packets = 1;
-+ packet->tx_bytes = skb->len;
-+
-+ if (xgbe_is_tso(skb)) {
-+ /* TSO requires an extra descriptor if mss is different */
-+ if (skb_shinfo(skb)->gso_size != ring->tx.cur_mss) {
-+ context_desc = 1;
-+ packet->rdesc_count++;
-+ }
-+
-+ /* TSO requires an extra descriptor for TSO header */
-+ packet->rdesc_count++;
-+
-+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ TSO_ENABLE, 1);
-+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ CSUM_ENABLE, 1);
-+ } else if (skb->ip_summed == CHECKSUM_PARTIAL)
-+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ CSUM_ENABLE, 1);
-+
-+ if (skb_vlan_tag_present(skb)) {
-+ /* VLAN requires an extra descriptor if tag is different */
-+ if (skb_vlan_tag_get(skb) != ring->tx.cur_vlan_ctag)
-+ /* We can share with the TSO context descriptor */
-+ if (!context_desc) {
-+ context_desc = 1;
-+ packet->rdesc_count++;
-+ }
-+
-+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ VLAN_CTAG, 1);
-+ }
-+
-+ if ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
-+ (pdata->tstamp_config.tx_type == HWTSTAMP_TX_ON))
-+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
-+ PTP, 1);
-+
-+ for (len = skb_headlen(skb); len;) {
-+ packet->rdesc_count++;
-+ len -= min_t(unsigned int, len, XGBE_TX_MAX_BUF_SIZE);
-+ }
-+
-+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+ frag = &skb_shinfo(skb)->frags[i];
-+ for (len = skb_frag_size(frag); len; ) {
-+ packet->rdesc_count++;
-+ len -= min_t(unsigned int, len, XGBE_TX_MAX_BUF_SIZE);
-+ }
-+ }
-+}
-+
-+static int xgbe_open(struct net_device *netdev)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
-+ int ret;
-+
-+ DBGPR("-->xgbe_open\n");
-+
-+ /* Initialize the phy */
-+ ret = xgbe_phy_init(pdata);
-+ if (ret)
-+ return ret;
-+
-+ /* Enable the clocks */
-+ ret = clk_prepare_enable(pdata->sysclk);
-+ if (ret) {
-+ netdev_alert(netdev, "dma clk_prepare_enable failed\n");
-+ goto err_phy_init;
-+ }
-+
-+ ret = clk_prepare_enable(pdata->ptpclk);
-+ if (ret) {
-+ netdev_alert(netdev, "ptp clk_prepare_enable failed\n");
-+ goto err_sysclk;
-+ }
-+
-+ /* Calculate the Rx buffer size before allocating rings */
-+ ret = xgbe_calc_rx_buf_size(netdev, netdev->mtu);
-+ if (ret < 0)
-+ goto err_ptpclk;
-+ pdata->rx_buf_size = ret;
-+
-+ /* Allocate the channel and ring structures */
-+ ret = xgbe_alloc_channels(pdata);
-+ if (ret)
-+ goto err_ptpclk;
-+
-+ /* Allocate the ring descriptors and buffers */
-+ ret = desc_if->alloc_ring_resources(pdata);
-+ if (ret)
-+ goto err_channels;
-+
-+ /* Initialize the device restart and Tx timestamp work struct */
-+ INIT_WORK(&pdata->restart_work, xgbe_restart);
-+ INIT_WORK(&pdata->tx_tstamp_work, xgbe_tx_tstamp);
-+
-+ ret = xgbe_start(pdata);
-+ if (ret)
-+ goto err_rings;
-+
-+ DBGPR("<--xgbe_open\n");
-+
-+ return 0;
-+
-+err_rings:
-+ desc_if->free_ring_resources(pdata);
-+
-+err_channels:
-+ xgbe_free_channels(pdata);
-+
-+err_ptpclk:
-+ clk_disable_unprepare(pdata->ptpclk);
-+
-+err_sysclk:
-+ clk_disable_unprepare(pdata->sysclk);
-+
-+err_phy_init:
-+ xgbe_phy_exit(pdata);
-+
-+ return ret;
-+}
-+
-+static int xgbe_close(struct net_device *netdev)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
-+
-+ DBGPR("-->xgbe_close\n");
-+
-+ /* Stop the device */
-+ xgbe_stop(pdata);
-+
-+ /* Free the ring descriptors and buffers */
-+ desc_if->free_ring_resources(pdata);
-+
-+ /* Free the channel and ring structures */
-+ xgbe_free_channels(pdata);
-+
-+ /* Disable the clocks */
-+ clk_disable_unprepare(pdata->ptpclk);
-+ clk_disable_unprepare(pdata->sysclk);
-+
-+ /* Release the phy */
-+ xgbe_phy_exit(pdata);
-+
-+ DBGPR("<--xgbe_close\n");
-+
-+ return 0;
-+}
-+
-+static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
-+ struct xgbe_channel *channel;
-+ struct xgbe_ring *ring;
-+ struct xgbe_packet_data *packet;
-+ struct netdev_queue *txq;
-+ int ret;
-+
-+ DBGPR("-->xgbe_xmit: skb->len = %d\n", skb->len);
-+
-+ channel = pdata->channel + skb->queue_mapping;
-+ txq = netdev_get_tx_queue(netdev, channel->queue_index);
-+ ring = channel->tx_ring;
-+ packet = &ring->packet_data;
-+
-+ ret = NETDEV_TX_OK;
-+
-+ if (skb->len == 0) {
-+ netdev_err(netdev, "empty skb received from stack\n");
-+ dev_kfree_skb_any(skb);
-+ goto tx_netdev_return;
-+ }
-+
-+ /* Calculate preliminary packet info */
-+ memset(packet, 0, sizeof(*packet));
-+ xgbe_packet_info(pdata, ring, skb, packet);
-+
-+ /* Check that there are enough descriptors available */
-+ ret = xgbe_maybe_stop_tx_queue(channel, ring, packet->rdesc_count);
-+ if (ret)
-+ goto tx_netdev_return;
-+
-+ ret = xgbe_prep_tso(skb, packet);
-+ if (ret) {
-+ netdev_err(netdev, "error processing TSO packet\n");
-+ dev_kfree_skb_any(skb);
-+ goto tx_netdev_return;
-+ }
-+ xgbe_prep_vlan(skb, packet);
-+
-+ if (!desc_if->map_tx_skb(channel, skb)) {
-+ dev_kfree_skb_any(skb);
-+ goto tx_netdev_return;
-+ }
-+
-+ xgbe_prep_tx_tstamp(pdata, skb, packet);
-+
-+ /* Report on the actual number of bytes (to be) sent */
-+ netdev_tx_sent_queue(txq, packet->tx_bytes);
-+
-+ /* Configure required descriptor fields for transmission */
-+ hw_if->dev_xmit(channel);
-+
-+#ifdef XGMAC_ENABLE_TX_PKT_DUMP
-+ xgbe_a0_print_pkt(netdev, skb, true);
-+#endif
-+
-+ /* Stop the queue in advance if there may not be enough descriptors */
-+ xgbe_maybe_stop_tx_queue(channel, ring, XGBE_TX_MAX_DESCS);
-+
-+ ret = NETDEV_TX_OK;
-+
-+tx_netdev_return:
-+ return ret;
-+}
-+
-+static void xgbe_set_rx_mode(struct net_device *netdev)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ unsigned int pr_mode, am_mode;
-+
-+ DBGPR("-->xgbe_set_rx_mode\n");
-+
-+ pr_mode = ((netdev->flags & IFF_PROMISC) != 0);
-+ am_mode = ((netdev->flags & IFF_ALLMULTI) != 0);
-+
-+ hw_if->set_promiscuous_mode(pdata, pr_mode);
-+ hw_if->set_all_multicast_mode(pdata, am_mode);
-+
-+ hw_if->add_mac_addresses(pdata);
-+
-+ DBGPR("<--xgbe_set_rx_mode\n");
-+}
-+
-+static int xgbe_set_mac_address(struct net_device *netdev, void *addr)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct sockaddr *saddr = addr;
-+
-+ DBGPR("-->xgbe_set_mac_address\n");
-+
-+ if (!is_valid_ether_addr(saddr->sa_data))
-+ return -EADDRNOTAVAIL;
-+
-+ memcpy(netdev->dev_addr, saddr->sa_data, netdev->addr_len);
-+
-+ hw_if->set_mac_address(pdata, netdev->dev_addr);
-+
-+ DBGPR("<--xgbe_set_mac_address\n");
-+
-+ return 0;
-+}
-+
-+static int xgbe_ioctl(struct net_device *netdev, struct ifreq *ifreq, int cmd)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ int ret;
-+
-+ switch (cmd) {
-+ case SIOCGHWTSTAMP:
-+ ret = xgbe_get_hwtstamp_settings(pdata, ifreq);
-+ break;
-+
-+ case SIOCSHWTSTAMP:
-+ ret = xgbe_set_hwtstamp_settings(pdata, ifreq);
-+ break;
-+
-+ default:
-+ ret = -EOPNOTSUPP;
-+ }
-+
-+ return ret;
-+}
-+
-+static int xgbe_change_mtu(struct net_device *netdev, int mtu)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ int ret;
-+
-+ DBGPR("-->xgbe_change_mtu\n");
-+
-+ ret = xgbe_calc_rx_buf_size(netdev, mtu);
-+ if (ret < 0)
-+ return ret;
-+
-+ pdata->rx_buf_size = ret;
-+ netdev->mtu = mtu;
-+
-+ xgbe_restart_dev(pdata);
-+
-+ DBGPR("<--xgbe_change_mtu\n");
-+
-+ return 0;
-+}
-+
-+static struct rtnl_link_stats64 *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;
-+
-+ DBGPR("-->%s\n", __func__);
-+
-+ pdata->hw_if.read_mmc_stats(pdata);
-+
-+ s->rx_packets = pstats->rxframecount_gb;
-+ s->rx_bytes = pstats->rxoctetcount_gb;
-+ s->rx_errors = pstats->rxframecount_gb -
-+ pstats->rxbroadcastframes_g -
-+ pstats->rxmulticastframes_g -
-+ pstats->rxunicastframes_g;
-+ s->multicast = pstats->rxmulticastframes_g;
-+ s->rx_length_errors = pstats->rxlengtherror;
-+ s->rx_crc_errors = pstats->rxcrcerror;
-+ s->rx_fifo_errors = pstats->rxfifooverflow;
-+
-+ s->tx_packets = pstats->txframecount_gb;
-+ s->tx_bytes = pstats->txoctetcount_gb;
-+ s->tx_errors = pstats->txframecount_gb - pstats->txframecount_g;
-+ 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,
-+ u16 vid)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+
-+ DBGPR("-->%s\n", __func__);
-+
-+ set_bit(vid, pdata->active_vlans);
-+ hw_if->update_vlan_hash_table(pdata);
-+
-+ DBGPR("<--%s\n", __func__);
-+
-+ return 0;
-+}
-+
-+static int xgbe_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto,
-+ u16 vid)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+
-+ DBGPR("-->%s\n", __func__);
-+
-+ clear_bit(vid, pdata->active_vlans);
-+ hw_if->update_vlan_hash_table(pdata);
-+
-+ DBGPR("<--%s\n", __func__);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+static void xgbe_poll_controller(struct net_device *netdev)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_channel *channel;
-+ unsigned int i;
-+
-+ DBGPR("-->xgbe_poll_controller\n");
-+
-+ if (pdata->per_channel_irq) {
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++)
-+ xgbe_dma_isr(channel->dma_irq, channel);
-+ } else {
-+ disable_irq(pdata->dev_irq);
-+ xgbe_isr(pdata->dev_irq, pdata);
-+ enable_irq(pdata->dev_irq);
-+ }
-+
-+ DBGPR("<--xgbe_poll_controller\n");
-+}
-+#endif /* End CONFIG_NET_POLL_CONTROLLER */
-+
-+static int xgbe_setup_tc(struct net_device *netdev, u8 tc)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ unsigned int offset, queue;
-+ u8 i;
-+
-+ if (tc && (tc != pdata->hw_feat.tc_cnt))
-+ return -EINVAL;
-+
-+ if (tc) {
-+ netdev_set_num_tc(netdev, tc);
-+ for (i = 0, queue = 0, offset = 0; i < tc; i++) {
-+ while ((queue < pdata->tx_q_count) &&
-+ (pdata->q2tc_map[queue] == i))
-+ queue++;
-+
-+ DBGPR(" TC%u using TXq%u-%u\n", i, offset, queue - 1);
-+ netdev_set_tc_queue(netdev, i, queue - offset, offset);
-+ offset = queue;
-+ }
-+ } else {
-+ netdev_reset_tc(netdev);
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_features(struct net_device *netdev,
-+ netdev_features_t features)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ netdev_features_t rxhash, rxcsum, rxvlan, rxvlan_filter;
-+ int ret = 0;
-+
-+ rxhash = pdata->netdev_features & NETIF_F_RXHASH;
-+ rxcsum = pdata->netdev_features & NETIF_F_RXCSUM;
-+ rxvlan = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX;
-+ rxvlan_filter = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_FILTER;
-+
-+ if ((features & NETIF_F_RXHASH) && !rxhash)
-+ ret = hw_if->enable_rss(pdata);
-+ else if (!(features & NETIF_F_RXHASH) && rxhash)
-+ ret = hw_if->disable_rss(pdata);
-+ if (ret)
-+ return ret;
-+
-+ if ((features & NETIF_F_RXCSUM) && !rxcsum)
-+ hw_if->enable_rx_csum(pdata);
-+ else if (!(features & NETIF_F_RXCSUM) && rxcsum)
-+ hw_if->disable_rx_csum(pdata);
-+
-+ if ((features & NETIF_F_HW_VLAN_CTAG_RX) && !rxvlan)
-+ hw_if->enable_rx_vlan_stripping(pdata);
-+ else if (!(features & NETIF_F_HW_VLAN_CTAG_RX) && rxvlan)
-+ hw_if->disable_rx_vlan_stripping(pdata);
-+
-+ if ((features & NETIF_F_HW_VLAN_CTAG_FILTER) && !rxvlan_filter)
-+ hw_if->enable_rx_vlan_filtering(pdata);
-+ else if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER) && rxvlan_filter)
-+ hw_if->disable_rx_vlan_filtering(pdata);
-+
-+ pdata->netdev_features = features;
-+
-+ DBGPR("<--xgbe_set_features\n");
-+
-+ return 0;
-+}
-+
-+static const struct net_device_ops xgbe_netdev_ops = {
-+ .ndo_open = xgbe_open,
-+ .ndo_stop = xgbe_close,
-+ .ndo_start_xmit = xgbe_xmit,
-+ .ndo_set_rx_mode = xgbe_set_rx_mode,
-+ .ndo_set_mac_address = xgbe_set_mac_address,
-+ .ndo_validate_addr = eth_validate_addr,
-+ .ndo_do_ioctl = xgbe_ioctl,
-+ .ndo_change_mtu = xgbe_change_mtu,
-+ .ndo_get_stats64 = xgbe_get_stats64,
-+ .ndo_vlan_rx_add_vid = xgbe_vlan_rx_add_vid,
-+ .ndo_vlan_rx_kill_vid = xgbe_vlan_rx_kill_vid,
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+ .ndo_poll_controller = xgbe_poll_controller,
-+#endif
-+ .ndo_setup_tc = xgbe_setup_tc,
-+ .ndo_set_features = xgbe_set_features,
-+};
-+
-+struct net_device_ops *xgbe_a0_get_netdev_ops(void)
-+{
-+ return (struct net_device_ops *)&xgbe_netdev_ops;
-+}
-+
-+static void xgbe_rx_refresh(struct xgbe_channel *channel)
-+{
-+ struct xgbe_prv_data *pdata = channel->pdata;
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
-+ struct xgbe_ring *ring = channel->rx_ring;
-+ struct xgbe_ring_data *rdata;
-+
-+ while (ring->dirty != ring->cur) {
-+ rdata = XGBE_GET_DESC_DATA(ring, ring->dirty);
-+
-+ /* Reset rdata values */
-+ desc_if->unmap_rdata(pdata, rdata);
-+
-+ if (desc_if->map_rx_buffer(pdata, ring, rdata))
-+ break;
-+
-+ hw_if->rx_desc_reset(rdata);
-+
-+ ring->dirty++;
-+ }
-+
-+ /* Update the Rx Tail Pointer Register with address of
-+ * the last cleaned entry */
-+ rdata = XGBE_GET_DESC_DATA(ring, ring->dirty - 1);
-+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
-+ lower_32_bits(rdata->rdesc_dma));
-+}
-+
-+static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
-+ struct xgbe_ring_data *rdata,
-+ unsigned int *len)
-+{
-+ struct net_device *netdev = pdata->netdev;
-+ struct sk_buff *skb;
-+ u8 *packet;
-+ unsigned int copy_len;
-+
-+ skb = netdev_alloc_skb_ip_align(netdev, rdata->rx.hdr.dma_len);
-+ if (!skb)
-+ return NULL;
-+
-+ packet = page_address(rdata->rx.hdr.pa.pages) +
-+ rdata->rx.hdr.pa.pages_offset;
-+ copy_len = (rdata->rx.hdr_len) ? rdata->rx.hdr_len : *len;
-+ copy_len = min(rdata->rx.hdr.dma_len, copy_len);
-+ skb_copy_to_linear_data(skb, packet, copy_len);
-+ skb_put(skb, copy_len);
-+
-+ *len -= copy_len;
-+
-+ return skb;
-+}
-+
-+static int xgbe_tx_poll(struct xgbe_channel *channel)
-+{
-+ struct xgbe_prv_data *pdata = channel->pdata;
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
-+ struct xgbe_ring *ring = channel->tx_ring;
-+ struct xgbe_ring_data *rdata;
-+ struct xgbe_ring_desc *rdesc;
-+ struct net_device *netdev = pdata->netdev;
-+ struct netdev_queue *txq;
-+ int processed = 0;
-+ unsigned int tx_packets = 0, tx_bytes = 0;
-+
-+ DBGPR("-->xgbe_tx_poll\n");
-+
-+ /* Nothing to do if there isn't a Tx ring for this channel */
-+ if (!ring)
-+ return 0;
-+
-+ txq = netdev_get_tx_queue(netdev, channel->queue_index);
-+
-+ while ((processed < XGBE_TX_DESC_MAX_PROC) &&
-+ (ring->dirty != ring->cur)) {
-+ rdata = XGBE_GET_DESC_DATA(ring, ring->dirty);
-+ rdesc = rdata->rdesc;
-+
-+ if (!hw_if->tx_complete(rdesc))
-+ break;
-+
-+ /* Make sure descriptor fields are read after reading the OWN
-+ * bit */
-+ rmb();
-+
-+#ifdef XGMAC_ENABLE_TX_DESC_DUMP
-+ xgbe_a0_dump_tx_desc(ring, ring->dirty, 1, 0);
-+#endif
-+
-+ if (hw_if->is_last_desc(rdesc)) {
-+ tx_packets += rdata->tx.packets;
-+ tx_bytes += rdata->tx.bytes;
-+ }
-+
-+ /* Free the SKB and reset the descriptor for re-use */
-+ desc_if->unmap_rdata(pdata, rdata);
-+ hw_if->tx_desc_reset(rdata);
-+
-+ processed++;
-+ ring->dirty++;
-+ }
-+
-+ if (!processed)
-+ return 0;
-+
-+ netdev_tx_completed_queue(txq, tx_packets, tx_bytes);
-+
-+ if ((ring->tx.queue_stopped == 1) &&
-+ (xgbe_tx_avail_desc(ring) > XGBE_TX_DESC_MIN_FREE)) {
-+ ring->tx.queue_stopped = 0;
-+ netif_tx_wake_queue(txq);
-+ }
-+
-+ DBGPR("<--xgbe_tx_poll: processed=%d\n", processed);
-+
-+ return processed;
-+}
-+
-+static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
-+{
-+ struct xgbe_prv_data *pdata = channel->pdata;
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ struct xgbe_ring *ring = channel->rx_ring;
-+ struct xgbe_ring_data *rdata;
-+ struct xgbe_packet_data *packet;
-+ struct net_device *netdev = pdata->netdev;
-+ struct napi_struct *napi;
-+ struct sk_buff *skb;
-+ struct skb_shared_hwtstamps *hwtstamps;
-+ unsigned int incomplete, error, context_next, context;
-+ unsigned int len, put_len, max_len;
-+ unsigned int received = 0;
-+ int packet_count = 0;
-+
-+ DBGPR("-->xgbe_rx_poll: budget=%d\n", budget);
-+
-+ /* Nothing to do if there isn't a Rx ring for this channel */
-+ if (!ring)
-+ return 0;
-+
-+ napi = (pdata->per_channel_irq) ? &channel->napi : &pdata->napi;
-+
-+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
-+ packet = &ring->packet_data;
-+ while (packet_count < budget) {
-+ DBGPR(" cur = %d\n", ring->cur);
-+
-+ /* First time in loop see if we need to restore state */
-+ if (!received && rdata->state_saved) {
-+ incomplete = rdata->state.incomplete;
-+ context_next = rdata->state.context_next;
-+ skb = rdata->state.skb;
-+ error = rdata->state.error;
-+ len = rdata->state.len;
-+ } else {
-+ memset(packet, 0, sizeof(*packet));
-+ incomplete = 0;
-+ context_next = 0;
-+ skb = NULL;
-+ error = 0;
-+ len = 0;
-+ }
-+
-+read_again:
-+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
-+
-+ if (xgbe_rx_dirty_desc(ring) > (XGBE_RX_DESC_CNT >> 3))
-+ xgbe_rx_refresh(channel);
-+
-+ if (hw_if->dev_read(channel))
-+ break;
-+
-+ received++;
-+ ring->cur++;
-+
-+ incomplete = XGMAC_GET_BITS(packet->attributes,
-+ RX_PACKET_ATTRIBUTES,
-+ INCOMPLETE);
-+ context_next = XGMAC_GET_BITS(packet->attributes,
-+ RX_PACKET_ATTRIBUTES,
-+ CONTEXT_NEXT);
-+ context = XGMAC_GET_BITS(packet->attributes,
-+ RX_PACKET_ATTRIBUTES,
-+ CONTEXT);
-+
-+ /* Earlier error, just drain the remaining data */
-+ if ((incomplete || context_next) && error)
-+ goto read_again;
-+
-+ if (error || packet->errors) {
-+ if (packet->errors)
-+ DBGPR("Error in received packet\n");
-+ dev_kfree_skb(skb);
-+ goto next_packet;
-+ }
-+
-+ if (!context) {
-+ put_len = rdata->rx.len - len;
-+ len += put_len;
-+
-+ if (!skb) {
-+ dma_sync_single_for_cpu(pdata->dev,
-+ rdata->rx.hdr.dma,
-+ rdata->rx.hdr.dma_len,
-+ DMA_FROM_DEVICE);
-+
-+ skb = xgbe_create_skb(pdata, rdata, &put_len);
-+ if (!skb) {
-+ error = 1;
-+ goto skip_data;
-+ }
-+ }
-+
-+ if (put_len) {
-+ dma_sync_single_for_cpu(pdata->dev,
-+ rdata->rx.buf.dma,
-+ rdata->rx.buf.dma_len,
-+ DMA_FROM_DEVICE);
-+
-+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
-+ rdata->rx.buf.pa.pages,
-+ rdata->rx.buf.pa.pages_offset,
-+ put_len, rdata->rx.buf.dma_len);
-+ rdata->rx.buf.pa.pages = NULL;
-+ }
-+ }
-+
-+skip_data:
-+ if (incomplete || context_next)
-+ goto read_again;
-+
-+ if (!skb)
-+ goto next_packet;
-+
-+ /* Be sure we don't exceed the configured MTU */
-+ max_len = netdev->mtu + ETH_HLEN;
-+ if (!(netdev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
-+ (skb->protocol == htons(ETH_P_8021Q)))
-+ max_len += VLAN_HLEN;
-+
-+ if (skb->len > max_len) {
-+ DBGPR("packet length exceeds configured MTU\n");
-+ dev_kfree_skb(skb);
-+ goto next_packet;
-+ }
-+
-+#ifdef XGMAC_ENABLE_RX_PKT_DUMP
-+ xgbe_a0_print_pkt(netdev, skb, false);
-+#endif
-+
-+ skb_checksum_none_assert(skb);
-+ if (XGMAC_GET_BITS(packet->attributes,
-+ RX_PACKET_ATTRIBUTES, CSUM_DONE))
-+ skb->ip_summed = CHECKSUM_UNNECESSARY;
-+
-+ if (XGMAC_GET_BITS(packet->attributes,
-+ RX_PACKET_ATTRIBUTES, VLAN_CTAG))
-+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-+ packet->vlan_ctag);
-+
-+ if (XGMAC_GET_BITS(packet->attributes,
-+ RX_PACKET_ATTRIBUTES, RX_TSTAMP)) {
-+ u64 nsec;
-+
-+ nsec = timecounter_cyc2time(&pdata->tstamp_tc,
-+ packet->rx_tstamp);
-+ hwtstamps = skb_hwtstamps(skb);
-+ hwtstamps->hwtstamp = ns_to_ktime(nsec);
-+ }
-+
-+ if (XGMAC_GET_BITS(packet->attributes,
-+ RX_PACKET_ATTRIBUTES, RSS_HASH))
-+ skb_set_hash(skb, packet->rss_hash,
-+ packet->rss_hash_type);
-+
-+ skb->dev = netdev;
-+ skb->protocol = eth_type_trans(skb, netdev);
-+ skb_record_rx_queue(skb, channel->queue_index);
-+ skb_mark_napi_id(skb, napi);
-+
-+ netdev->last_rx = jiffies;
-+ napi_gro_receive(napi, skb);
-+
-+next_packet:
-+ packet_count++;
-+ }
-+
-+ /* Check if we need to save state before leaving */
-+ if (received && (incomplete || context_next)) {
-+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
-+ rdata->state_saved = 1;
-+ rdata->state.incomplete = incomplete;
-+ rdata->state.context_next = context_next;
-+ rdata->state.skb = skb;
-+ rdata->state.len = len;
-+ rdata->state.error = error;
-+ }
-+
-+ DBGPR("<--xgbe_rx_poll: packet_count = %d\n", packet_count);
-+
-+ return packet_count;
-+}
-+
-+static int xgbe_one_poll(struct napi_struct *napi, int budget)
-+{
-+ struct xgbe_channel *channel = container_of(napi, struct xgbe_channel,
-+ napi);
-+ int processed = 0;
-+
-+ DBGPR("-->xgbe_one_poll: budget=%d\n", budget);
-+
-+ /* Cleanup Tx ring first */
-+ xgbe_tx_poll(channel);
-+
-+ /* Process Rx ring next */
-+ processed = xgbe_rx_poll(channel, budget);
-+
-+ /* If we processed everything, we are done */
-+ if (processed < budget) {
-+ /* Turn off polling */
-+ napi_complete(napi);
-+
-+ /* Enable Tx and Rx interrupts */
-+ enable_irq(channel->dma_irq);
-+ }
-+
-+ DBGPR("<--xgbe_one_poll: received = %d\n", processed);
-+
-+ return processed;
-+}
-+
-+static int xgbe_all_poll(struct napi_struct *napi, int budget)
-+{
-+ struct xgbe_prv_data *pdata = container_of(napi, struct xgbe_prv_data,
-+ napi);
-+ struct xgbe_channel *channel;
-+ int ring_budget;
-+ int processed, last_processed;
-+ unsigned int i;
-+
-+ DBGPR("-->xgbe_all_poll: budget=%d\n", budget);
-+
-+ processed = 0;
-+ ring_budget = budget / pdata->rx_ring_count;
-+ do {
-+ last_processed = processed;
-+
-+ channel = pdata->channel;
-+ for (i = 0; i < pdata->channel_count; i++, channel++) {
-+ /* Cleanup Tx ring first */
-+ xgbe_tx_poll(channel);
-+
-+ /* Process Rx ring next */
-+ if (ring_budget > (budget - processed))
-+ ring_budget = budget - processed;
-+ processed += xgbe_rx_poll(channel, ring_budget);
-+ }
-+ } while ((processed < budget) && (processed != last_processed));
-+
-+ /* If we processed everything, we are done */
-+ if (processed < budget) {
-+ /* Turn off polling */
-+ napi_complete(napi);
-+
-+ /* Enable Tx and Rx interrupts */
-+ xgbe_enable_rx_tx_ints(pdata);
-+ }
-+
-+ DBGPR("<--xgbe_all_poll: received = %d\n", processed);
-+
-+ return processed;
-+}
-+
-+void xgbe_a0_dump_tx_desc(struct xgbe_ring *ring, unsigned int idx,
-+ unsigned int count, unsigned int flag)
-+{
-+ struct xgbe_ring_data *rdata;
-+ struct xgbe_ring_desc *rdesc;
-+
-+ while (count--) {
-+ rdata = XGBE_GET_DESC_DATA(ring, idx);
-+ rdesc = rdata->rdesc;
-+ pr_alert("TX_NORMAL_DESC[%d %s] = %08x:%08x:%08x:%08x\n", idx,
-+ (flag == 1) ? "QUEUED FOR TX" : "TX BY DEVICE",
-+ le32_to_cpu(rdesc->desc0), le32_to_cpu(rdesc->desc1),
-+ le32_to_cpu(rdesc->desc2), le32_to_cpu(rdesc->desc3));
-+ idx++;
-+ }
-+}
-+
-+void xgbe_a0_dump_rx_desc(struct xgbe_ring *ring, struct xgbe_ring_desc *desc,
-+ unsigned int idx)
-+{
-+ pr_alert("RX_NORMAL_DESC[%d RX BY DEVICE] = %08x:%08x:%08x:%08x\n", idx,
-+ le32_to_cpu(desc->desc0), le32_to_cpu(desc->desc1),
-+ le32_to_cpu(desc->desc2), le32_to_cpu(desc->desc3));
-+}
-+
-+void xgbe_a0_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx)
-+{
-+ struct ethhdr *eth = (struct ethhdr *)skb->data;
-+ unsigned char *buf = skb->data;
-+ unsigned char buffer[128];
-+ unsigned int i, j;
-+
-+ netdev_alert(netdev, "\n************** SKB dump ****************\n");
-+
-+ netdev_alert(netdev, "%s packet of %d bytes\n",
-+ (tx_rx ? "TX" : "RX"), skb->len);
-+
-+ netdev_alert(netdev, "Dst MAC addr: %pM\n", eth->h_dest);
-+ netdev_alert(netdev, "Src MAC addr: %pM\n", eth->h_source);
-+ netdev_alert(netdev, "Protocol: 0x%04hx\n", ntohs(eth->h_proto));
-+
-+ for (i = 0, j = 0; i < skb->len;) {
-+ j += snprintf(buffer + j, sizeof(buffer) - j, "%02hhx",
-+ buf[i++]);
-+
-+ if ((i % 32) == 0) {
-+ netdev_alert(netdev, " 0x%04x: %s\n", i - 32, buffer);
-+ j = 0;
-+ } else if ((i % 16) == 0) {
-+ buffer[j++] = ' ';
-+ buffer[j++] = ' ';
-+ } else if ((i % 4) == 0) {
-+ buffer[j++] = ' ';
-+ }
-+ }
-+ if (i % 32)
-+ netdev_alert(netdev, " 0x%04x: %s\n", i - (i % 32), buffer);
-+
-+ netdev_alert(netdev, "\n************** SKB dump ****************\n");
-+}
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe-a0/xgbe-ethtool.c
-new file mode 100644
-index 0000000..165ff1c
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-ethtool.c
-@@ -0,0 +1,616 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/spinlock.h>
-+#include <linux/phy.h>
-+#include <linux/net_tstamp.h>
-+
-+#include "xgbe.h"
-+#include "xgbe-common.h"
-+
-+struct xgbe_stats {
-+ char stat_string[ETH_GSTRING_LEN];
-+ int stat_size;
-+ int stat_offset;
-+};
-+
-+#define XGMAC_MMC_STAT(_string, _var) \
-+ { _string, \
-+ FIELD_SIZEOF(struct xgbe_mmc_stats, _var), \
-+ offsetof(struct xgbe_prv_data, mmc_stats._var), \
-+ }
-+
-+static const struct xgbe_stats xgbe_gstring_stats[] = {
-+ XGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
-+ XGMAC_MMC_STAT("tx_packets", txframecount_gb),
-+ XGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb),
-+ XGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
-+ XGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
-+ XGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
-+ XGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
-+ XGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
-+ XGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
-+ XGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
-+ XGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
-+ XGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
-+ XGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror),
-+ XGMAC_MMC_STAT("tx_pause_frames", txpauseframes),
-+
-+ XGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb),
-+ XGMAC_MMC_STAT("rx_packets", rxframecount_gb),
-+ XGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g),
-+ XGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g),
-+ XGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g),
-+ XGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb),
-+ XGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb),
-+ XGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb),
-+ XGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb),
-+ XGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb),
-+ XGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb),
-+ XGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb),
-+ XGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g),
-+ XGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g),
-+ XGMAC_MMC_STAT("rx_crc_errors", rxcrcerror),
-+ XGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror),
-+ XGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror),
-+ XGMAC_MMC_STAT("rx_length_errors", rxlengtherror),
-+ XGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype),
-+ XGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
-+ XGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
-+ XGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
-+};
-+
-+#define XGBE_STATS_COUNT ARRAY_SIZE(xgbe_gstring_stats)
-+
-+static void xgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
-+{
-+ int i;
-+
-+ DBGPR("-->%s\n", __func__);
-+
-+ switch (stringset) {
-+ case ETH_SS_STATS:
-+ for (i = 0; i < XGBE_STATS_COUNT; i++) {
-+ memcpy(data, xgbe_gstring_stats[i].stat_string,
-+ ETH_GSTRING_LEN);
-+ data += ETH_GSTRING_LEN;
-+ }
-+ break;
-+ }
-+
-+ DBGPR("<--%s\n", __func__);
-+}
-+
-+static void xgbe_get_ethtool_stats(struct net_device *netdev,
-+ struct ethtool_stats *stats, u64 *data)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ u8 *stat;
-+ int i;
-+
-+ DBGPR("-->%s\n", __func__);
-+
-+ pdata->hw_if.read_mmc_stats(pdata);
-+ for (i = 0; i < XGBE_STATS_COUNT; i++) {
-+ stat = (u8 *)pdata + xgbe_gstring_stats[i].stat_offset;
-+ *data++ = *(u64 *)stat;
-+ }
-+
-+ DBGPR("<--%s\n", __func__);
-+}
-+
-+static int xgbe_get_sset_count(struct net_device *netdev, int stringset)
-+{
-+ int ret;
-+
-+ DBGPR("-->%s\n", __func__);
-+
-+ switch (stringset) {
-+ case ETH_SS_STATS:
-+ ret = XGBE_STATS_COUNT;
-+ break;
-+
-+ default:
-+ ret = -EOPNOTSUPP;
-+ }
-+
-+ DBGPR("<--%s\n", __func__);
-+
-+ return ret;
-+}
-+
-+static void xgbe_get_pauseparam(struct net_device *netdev,
-+ struct ethtool_pauseparam *pause)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+
-+ DBGPR("-->xgbe_get_pauseparam\n");
-+
-+ pause->autoneg = pdata->pause_autoneg;
-+ pause->tx_pause = pdata->tx_pause;
-+ pause->rx_pause = pdata->rx_pause;
-+
-+ DBGPR("<--xgbe_get_pauseparam\n");
-+}
-+
-+static int xgbe_set_pauseparam(struct net_device *netdev,
-+ struct ethtool_pauseparam *pause)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct phy_device *phydev = pdata->phydev;
-+ int ret = 0;
-+
-+ DBGPR("-->xgbe_set_pauseparam\n");
-+
-+ DBGPR(" autoneg = %d, tx_pause = %d, rx_pause = %d\n",
-+ pause->autoneg, pause->tx_pause, pause->rx_pause);
-+
-+ pdata->pause_autoneg = pause->autoneg;
-+ if (pause->autoneg) {
-+ phydev->advertising |= ADVERTISED_Pause;
-+ phydev->advertising |= ADVERTISED_Asym_Pause;
-+
-+ } else {
-+ phydev->advertising &= ~ADVERTISED_Pause;
-+ phydev->advertising &= ~ADVERTISED_Asym_Pause;
-+
-+ pdata->tx_pause = pause->tx_pause;
-+ pdata->rx_pause = pause->rx_pause;
-+ }
-+
-+ if (netif_running(netdev))
-+ ret = phy_start_aneg(phydev);
-+
-+ DBGPR("<--xgbe_set_pauseparam\n");
-+
-+ return ret;
-+}
-+
-+static int xgbe_get_settings(struct net_device *netdev,
-+ struct ethtool_cmd *cmd)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ int ret;
-+
-+ DBGPR("-->xgbe_get_settings\n");
-+
-+ if (!pdata->phydev)
-+ return -ENODEV;
-+
-+ ret = phy_ethtool_gset(pdata->phydev, cmd);
-+ cmd->transceiver = XCVR_EXTERNAL;
-+
-+ DBGPR("<--xgbe_get_settings\n");
-+
-+ return ret;
-+}
-+
-+static int xgbe_set_settings(struct net_device *netdev,
-+ struct ethtool_cmd *cmd)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct phy_device *phydev = pdata->phydev;
-+ u32 speed;
-+ int ret;
-+
-+ DBGPR("-->xgbe_set_settings\n");
-+
-+ if (!pdata->phydev)
-+ return -ENODEV;
-+
-+ speed = ethtool_cmd_speed(cmd);
-+
-+ if (cmd->phy_address != phydev->addr)
-+ return -EINVAL;
-+
-+ if ((cmd->autoneg != AUTONEG_ENABLE) &&
-+ (cmd->autoneg != AUTONEG_DISABLE))
-+ return -EINVAL;
-+
-+ if (cmd->autoneg == AUTONEG_DISABLE) {
-+ switch (speed) {
-+ case SPEED_10000:
-+ case SPEED_2500:
-+ case SPEED_1000:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (cmd->duplex != DUPLEX_FULL)
-+ return -EINVAL;
-+ }
-+
-+ cmd->advertising &= phydev->supported;
-+ if ((cmd->autoneg == AUTONEG_ENABLE) && !cmd->advertising)
-+ return -EINVAL;
-+
-+ ret = 0;
-+ phydev->autoneg = cmd->autoneg;
-+ phydev->speed = speed;
-+ phydev->duplex = cmd->duplex;
-+ phydev->advertising = cmd->advertising;
-+
-+ if (cmd->autoneg == AUTONEG_ENABLE)
-+ phydev->advertising |= ADVERTISED_Autoneg;
-+ else
-+ phydev->advertising &= ~ADVERTISED_Autoneg;
-+
-+ if (netif_running(netdev))
-+ ret = phy_start_aneg(phydev);
-+
-+ DBGPR("<--xgbe_set_settings\n");
-+
-+ return ret;
-+}
-+
-+static void xgbe_get_drvinfo(struct net_device *netdev,
-+ struct ethtool_drvinfo *drvinfo)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_features *hw_feat = &pdata->hw_feat;
-+
-+ strlcpy(drvinfo->driver, XGBE_DRV_NAME, sizeof(drvinfo->driver));
-+ strlcpy(drvinfo->version, XGBE_DRV_VERSION, sizeof(drvinfo->version));
-+ strlcpy(drvinfo->bus_info, dev_name(pdata->dev),
-+ sizeof(drvinfo->bus_info));
-+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d.%d.%d",
-+ XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER),
-+ XGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID),
-+ XGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER));
-+ drvinfo->n_stats = XGBE_STATS_COUNT;
-+}
-+
-+static int xgbe_get_coalesce(struct net_device *netdev,
-+ struct ethtool_coalesce *ec)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ unsigned int riwt;
-+
-+ DBGPR("-->xgbe_get_coalesce\n");
-+
-+ memset(ec, 0, sizeof(struct ethtool_coalesce));
-+
-+ riwt = pdata->rx_riwt;
-+ ec->rx_coalesce_usecs = hw_if->riwt_to_usec(pdata, riwt);
-+ ec->rx_max_coalesced_frames = pdata->rx_frames;
-+
-+ ec->tx_coalesce_usecs = pdata->tx_usecs;
-+ ec->tx_max_coalesced_frames = pdata->tx_frames;
-+
-+ DBGPR("<--xgbe_get_coalesce\n");
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_coalesce(struct net_device *netdev,
-+ struct ethtool_coalesce *ec)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ unsigned int rx_frames, rx_riwt, rx_usecs;
-+ unsigned int tx_frames, tx_usecs;
-+
-+ DBGPR("-->xgbe_set_coalesce\n");
-+
-+ /* Check for not supported parameters */
-+ if ((ec->rx_coalesce_usecs_irq) ||
-+ (ec->rx_max_coalesced_frames_irq) ||
-+ (ec->tx_coalesce_usecs_irq) ||
-+ (ec->tx_max_coalesced_frames_irq) ||
-+ (ec->stats_block_coalesce_usecs) ||
-+ (ec->use_adaptive_rx_coalesce) ||
-+ (ec->use_adaptive_tx_coalesce) ||
-+ (ec->pkt_rate_low) ||
-+ (ec->rx_coalesce_usecs_low) ||
-+ (ec->rx_max_coalesced_frames_low) ||
-+ (ec->tx_coalesce_usecs_low) ||
-+ (ec->tx_max_coalesced_frames_low) ||
-+ (ec->pkt_rate_high) ||
-+ (ec->rx_coalesce_usecs_high) ||
-+ (ec->rx_max_coalesced_frames_high) ||
-+ (ec->tx_coalesce_usecs_high) ||
-+ (ec->tx_max_coalesced_frames_high) ||
-+ (ec->rate_sample_interval))
-+ return -EOPNOTSUPP;
-+
-+ /* Can only change rx-frames when interface is down (see
-+ * rx_descriptor_init in xgbe-dev.c)
-+ */
-+ rx_frames = pdata->rx_frames;
-+ if (rx_frames != ec->rx_max_coalesced_frames && netif_running(netdev)) {
-+ netdev_alert(netdev,
-+ "interface must be down to change rx-frames\n");
-+ return -EINVAL;
-+ }
-+
-+ rx_riwt = hw_if->usec_to_riwt(pdata, ec->rx_coalesce_usecs);
-+ rx_frames = ec->rx_max_coalesced_frames;
-+
-+ /* Use smallest possible value if conversion resulted in zero */
-+ if (ec->rx_coalesce_usecs && !rx_riwt)
-+ rx_riwt = 1;
-+
-+ /* Check the bounds of values for Rx */
-+ if (rx_riwt > XGMAC_MAX_DMA_RIWT) {
-+ rx_usecs = hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT);
-+ netdev_alert(netdev, "rx-usec is limited to %d usecs\n",
-+ rx_usecs);
-+ return -EINVAL;
-+ }
-+ if (rx_frames > pdata->rx_desc_count) {
-+ netdev_alert(netdev, "rx-frames is limited to %d frames\n",
-+ pdata->rx_desc_count);
-+ return -EINVAL;
-+ }
-+
-+ tx_usecs = ec->tx_coalesce_usecs;
-+ tx_frames = ec->tx_max_coalesced_frames;
-+
-+ /* Check the bounds of values for Tx */
-+ if (tx_frames > pdata->tx_desc_count) {
-+ netdev_alert(netdev, "tx-frames is limited to %d frames\n",
-+ pdata->tx_desc_count);
-+ return -EINVAL;
-+ }
-+
-+ pdata->rx_riwt = rx_riwt;
-+ pdata->rx_frames = rx_frames;
-+ hw_if->config_rx_coalesce(pdata);
-+
-+ pdata->tx_usecs = tx_usecs;
-+ pdata->tx_frames = tx_frames;
-+ hw_if->config_tx_coalesce(pdata);
-+
-+ DBGPR("<--xgbe_set_coalesce\n");
-+
-+ return 0;
-+}
-+
-+static int xgbe_get_rxnfc(struct net_device *netdev,
-+ struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+
-+ switch (rxnfc->cmd) {
-+ case ETHTOOL_GRXRINGS:
-+ rxnfc->data = pdata->rx_ring_count;
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return 0;
-+}
-+
-+static u32 xgbe_get_rxfh_key_size(struct net_device *netdev)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+
-+ return sizeof(pdata->rss_key);
-+}
-+
-+static u32 xgbe_get_rxfh_indir_size(struct net_device *netdev)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+
-+ return ARRAY_SIZE(pdata->rss_table);
-+}
-+
-+static int xgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
-+ u8 *hfunc)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ unsigned int i;
-+
-+ if (indir) {
-+ for (i = 0; i < ARRAY_SIZE(pdata->rss_table); i++)
-+ indir[i] = XGMAC_GET_BITS(pdata->rss_table[i],
-+ MAC_RSSDR, DMCH);
-+ }
-+
-+ if (key)
-+ memcpy(key, pdata->rss_key, sizeof(pdata->rss_key));
-+
-+ if (hfunc)
-+ *hfunc = ETH_RSS_HASH_TOP;
-+
-+ return 0;
-+}
-+
-+static int xgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
-+ const u8 *key, const u8 hfunc)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ unsigned int ret;
-+
-+ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
-+ return -EOPNOTSUPP;
-+
-+ if (indir) {
-+ ret = hw_if->set_rss_lookup_table(pdata, indir);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ if (key) {
-+ ret = hw_if->set_rss_hash_key(pdata, key);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int xgbe_get_ts_info(struct net_device *netdev,
-+ struct ethtool_ts_info *ts_info)
-+{
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+
-+ ts_info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
-+ SOF_TIMESTAMPING_RX_SOFTWARE |
-+ SOF_TIMESTAMPING_SOFTWARE |
-+ SOF_TIMESTAMPING_TX_HARDWARE |
-+ SOF_TIMESTAMPING_RX_HARDWARE |
-+ SOF_TIMESTAMPING_RAW_HARDWARE;
-+
-+ if (pdata->ptp_clock)
-+ ts_info->phc_index = ptp_clock_index(pdata->ptp_clock);
-+ else
-+ ts_info->phc_index = -1;
-+
-+ ts_info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
-+ ts_info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
-+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
-+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
-+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
-+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
-+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
-+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
-+ (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
-+ (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
-+ (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
-+ (1 << HWTSTAMP_FILTER_ALL);
-+
-+ return 0;
-+}
-+
-+static const struct ethtool_ops xgbe_ethtool_ops = {
-+ .get_settings = xgbe_get_settings,
-+ .set_settings = xgbe_set_settings,
-+ .get_drvinfo = xgbe_get_drvinfo,
-+ .get_link = ethtool_op_get_link,
-+ .get_coalesce = xgbe_get_coalesce,
-+ .set_coalesce = xgbe_set_coalesce,
-+ .get_pauseparam = xgbe_get_pauseparam,
-+ .set_pauseparam = xgbe_set_pauseparam,
-+ .get_strings = xgbe_get_strings,
-+ .get_ethtool_stats = xgbe_get_ethtool_stats,
-+ .get_sset_count = xgbe_get_sset_count,
-+ .get_rxnfc = xgbe_get_rxnfc,
-+ .get_rxfh_key_size = xgbe_get_rxfh_key_size,
-+ .get_rxfh_indir_size = xgbe_get_rxfh_indir_size,
-+ .get_rxfh = xgbe_get_rxfh,
-+ .set_rxfh = xgbe_set_rxfh,
-+ .get_ts_info = xgbe_get_ts_info,
-+};
-+
-+struct ethtool_ops *xgbe_a0_get_ethtool_ops(void)
-+{
-+ return (struct ethtool_ops *)&xgbe_ethtool_ops;
-+}
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-main.c b/drivers/net/ethernet/amd/xgbe-a0/xgbe-main.c
-new file mode 100644
-index 0000000..deb8551
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-main.c
-@@ -0,0 +1,618 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/spinlock.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_net.h>
-+#include <linux/of_address.h>
-+#include <linux/clk.h>
-+#include <linux/property.h>
-+#include <linux/acpi.h>
-+
-+#include "xgbe.h"
-+#include "xgbe-common.h"
-+
-+MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>");
-+MODULE_LICENSE("Dual BSD/GPL");
-+MODULE_VERSION(XGBE_DRV_VERSION);
-+MODULE_DESCRIPTION(XGBE_DRV_DESC);
-+
-+unsigned int speed = 0;
-+module_param(speed, uint, 0444);
-+MODULE_PARM_DESC(speed, " Select operating speed (1=1GbE, 2=2.5GbE, 10=10GbE, any other value implies auto-negotiation");
-+
-+static void xgbe_default_config(struct xgbe_prv_data *pdata)
-+{
-+ DBGPR("-->xgbe_default_config\n");
-+
-+ pdata->pblx8 = DMA_PBL_X8_ENABLE;
-+ pdata->tx_sf_mode = MTL_TSF_ENABLE;
-+ pdata->tx_threshold = MTL_TX_THRESHOLD_64;
-+ pdata->tx_pbl = DMA_PBL_16;
-+ pdata->tx_osp_mode = DMA_OSP_ENABLE;
-+ pdata->rx_sf_mode = MTL_RSF_DISABLE;
-+ pdata->rx_threshold = MTL_RX_THRESHOLD_64;
-+ pdata->rx_pbl = DMA_PBL_16;
-+ pdata->pause_autoneg = 1;
-+ pdata->tx_pause = 1;
-+ pdata->rx_pause = 1;
-+ pdata->phy_speed = SPEED_UNKNOWN;
-+ pdata->power_down = 0;
-+
-+ if (speed == 10) {
-+ pdata->default_autoneg = AUTONEG_DISABLE;
-+ pdata->default_speed = SPEED_10000;
-+ } else if (speed == 2) {
-+ pdata->default_autoneg = AUTONEG_DISABLE;
-+ pdata->default_speed = SPEED_2500;
-+ } else if (speed == 1) {
-+ pdata->default_autoneg = AUTONEG_DISABLE;
-+ pdata->default_speed = SPEED_1000;
-+ } else {
-+ pdata->default_autoneg = AUTONEG_ENABLE;
-+ pdata->default_speed = SPEED_10000;
-+ }
-+
-+ DBGPR("<--xgbe_default_config\n");
-+}
-+
-+static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata)
-+{
-+ xgbe_a0_init_function_ptrs_dev(&pdata->hw_if);
-+ xgbe_a0_init_function_ptrs_desc(&pdata->desc_if);
-+}
-+
-+#ifdef CONFIG_ACPI
-+static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
-+{
-+ struct device *dev = pdata->dev;
-+ u32 property;
-+ int ret;
-+
-+ /* Obtain the system clock setting */
-+ ret = device_property_read_u32(dev, XGBE_ACPI_DMA_FREQ, &property);
-+ if (ret) {
-+ dev_err(dev, "unable to obtain %s property\n",
-+ XGBE_ACPI_DMA_FREQ);
-+ return ret;
-+ }
-+ pdata->sysclk_rate = property;
-+
-+ /* Obtain the PTP clock setting */
-+ ret = device_property_read_u32(dev, XGBE_ACPI_PTP_FREQ, &property);
-+ if (ret) {
-+ dev_err(dev, "unable to obtain %s property\n",
-+ XGBE_ACPI_PTP_FREQ);
-+ return ret;
-+ }
-+ pdata->ptpclk_rate = property;
-+
-+ return 0;
-+}
-+#else /* CONFIG_ACPI */
-+static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
-+{
-+ return -EINVAL;
-+}
-+#endif /* CONFIG_ACPI */
-+
-+#ifdef CONFIG_OF
-+static int xgbe_of_support(struct xgbe_prv_data *pdata)
-+{
-+ struct device *dev = pdata->dev;
-+
-+ /* Obtain the system clock setting */
-+ pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
-+ if (IS_ERR(pdata->sysclk)) {
-+ dev_err(dev, "dma devm_clk_get failed\n");
-+ return PTR_ERR(pdata->sysclk);
-+ }
-+ pdata->sysclk_rate = clk_get_rate(pdata->sysclk);
-+
-+ /* Obtain the PTP clock setting */
-+ pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
-+ if (IS_ERR(pdata->ptpclk)) {
-+ dev_err(dev, "ptp devm_clk_get failed\n");
-+ return PTR_ERR(pdata->ptpclk);
-+ }
-+ pdata->ptpclk_rate = clk_get_rate(pdata->ptpclk);
-+
-+ return 0;
-+}
-+#else /* CONFIG_OF */
-+static int xgbe_of_support(struct xgbe_prv_data *pdata)
-+{
-+ return -EINVAL;
-+}
-+#endif /*CONFIG_OF */
-+
-+static int xgbe_probe(struct platform_device *pdev)
-+{
-+ struct xgbe_prv_data *pdata;
-+ struct xgbe_hw_if *hw_if;
-+ struct xgbe_desc_if *desc_if;
-+ struct net_device *netdev;
-+ struct device *dev = &pdev->dev;
-+ struct resource *res;
-+ const char *phy_mode;
-+ unsigned int i;
-+ int ret;
-+
-+ DBGPR("--> xgbe_probe\n");
-+
-+ netdev = alloc_etherdev_mq(sizeof(struct xgbe_prv_data),
-+ XGBE_MAX_DMA_CHANNELS);
-+ if (!netdev) {
-+ dev_err(dev, "alloc_etherdev failed\n");
-+ ret = -ENOMEM;
-+ goto err_alloc;
-+ }
-+ SET_NETDEV_DEV(netdev, dev);
-+ pdata = netdev_priv(netdev);
-+ pdata->netdev = netdev;
-+ pdata->pdev = pdev;
-+ pdata->adev = ACPI_COMPANION(dev);
-+ pdata->dev = dev;
-+ platform_set_drvdata(pdev, netdev);
-+
-+ spin_lock_init(&pdata->lock);
-+ mutex_init(&pdata->xpcs_mutex);
-+ mutex_init(&pdata->rss_mutex);
-+ spin_lock_init(&pdata->tstamp_lock);
-+
-+ /* Check if we should use ACPI or DT */
-+ pdata->use_acpi = (!pdata->adev || acpi_disabled) ? 0 : 1;
-+
-+ /* Set and validate the number of descriptors for a ring */
-+ BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_TX_DESC_CNT);
-+ pdata->tx_desc_count = XGBE_TX_DESC_CNT;
-+ if (pdata->tx_desc_count & (pdata->tx_desc_count - 1)) {
-+ dev_err(dev, "tx descriptor count (%d) is not valid\n",
-+ pdata->tx_desc_count);
-+ ret = -EINVAL;
-+ goto err_io;
-+ }
-+ BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_RX_DESC_CNT);
-+ pdata->rx_desc_count = XGBE_RX_DESC_CNT;
-+ if (pdata->rx_desc_count & (pdata->rx_desc_count - 1)) {
-+ dev_err(dev, "rx descriptor count (%d) is not valid\n",
-+ pdata->rx_desc_count);
-+ ret = -EINVAL;
-+ goto err_io;
-+ }
-+
-+ /* Obtain the mmio areas for the device */
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ pdata->xgmac_regs = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(pdata->xgmac_regs)) {
-+ dev_err(dev, "xgmac ioremap failed\n");
-+ ret = PTR_ERR(pdata->xgmac_regs);
-+ goto err_io;
-+ }
-+ DBGPR(" xgmac_regs = %p\n", pdata->xgmac_regs);
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-+ pdata->xpcs_regs = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(pdata->xpcs_regs)) {
-+ dev_err(dev, "xpcs ioremap failed\n");
-+ ret = PTR_ERR(pdata->xpcs_regs);
-+ goto err_io;
-+ }
-+ DBGPR(" xpcs_regs = %p\n", pdata->xpcs_regs);
-+
-+ /* Retrieve the MAC address */
-+ ret = device_property_read_u8_array(dev, XGBE_MAC_ADDR_PROPERTY,
-+ pdata->mac_addr,
-+ sizeof(pdata->mac_addr));
-+ if (ret || !is_valid_ether_addr(pdata->mac_addr)) {
-+ dev_err(dev, "invalid %s property\n", XGBE_MAC_ADDR_PROPERTY);
-+ if (!ret)
-+ ret = -EINVAL;
-+ goto err_io;
-+ }
-+
-+ /* Retrieve the PHY mode - it must be "xgmii" */
-+ ret = device_property_read_string(dev, XGBE_PHY_MODE_PROPERTY,
-+ &phy_mode);
-+ if (ret || strcmp(phy_mode, phy_modes(PHY_INTERFACE_MODE_XGMII))) {
-+ dev_err(dev, "invalid %s property\n", XGBE_PHY_MODE_PROPERTY);
-+ if (!ret)
-+ ret = -EINVAL;
-+ goto err_io;
-+ }
-+ pdata->phy_mode = PHY_INTERFACE_MODE_XGMII;
-+
-+ /* Check for per channel interrupt support */
-+ if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY))
-+ pdata->per_channel_irq = 1;
-+
-+ /* Obtain device settings unique to ACPI/OF */
-+ if (pdata->use_acpi)
-+ ret = xgbe_acpi_support(pdata);
-+ else
-+ ret = xgbe_of_support(pdata);
-+ if (ret)
-+ goto err_io;
-+
-+ /* Set the DMA coherency values */
-+ pdata->coherent = device_dma_is_coherent(pdata->dev);
-+ if (pdata->coherent) {
-+ pdata->axdomain = XGBE_DMA_OS_AXDOMAIN;
-+ pdata->arcache = XGBE_DMA_OS_ARCACHE;
-+ pdata->awcache = XGBE_DMA_OS_AWCACHE;
-+ } else {
-+ pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN;
-+ pdata->arcache = XGBE_DMA_SYS_ARCACHE;
-+ pdata->awcache = XGBE_DMA_SYS_AWCACHE;
-+ }
-+
-+ /* Set the DMA mask */
-+ if (!dev->dma_mask)
-+ dev->dma_mask = &dev->coherent_dma_mask;
-+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
-+ if (ret) {
-+ dev_err(dev, "dma_set_mask_and_coherent failed\n");
-+ goto err_io;
-+ }
-+
-+ /* Get the device interrupt */
-+ ret = platform_get_irq(pdev, 0);
-+ if (ret < 0) {
-+ dev_err(dev, "platform_get_irq 0 failed\n");
-+ goto err_io;
-+ }
-+ pdata->dev_irq = ret;
-+
-+ netdev->irq = pdata->dev_irq;
-+ netdev->base_addr = (unsigned long)pdata->xgmac_regs;
-+ memcpy(netdev->dev_addr, pdata->mac_addr, netdev->addr_len);
-+
-+ /* Set all the function pointers */
-+ xgbe_init_all_fptrs(pdata);
-+ hw_if = &pdata->hw_if;
-+ desc_if = &pdata->desc_if;
-+
-+ /* Issue software reset to device */
-+ hw_if->exit(pdata);
-+
-+ /* Populate the hardware features */
-+ xgbe_a0_get_all_hw_features(pdata);
-+
-+ /* Set default configuration data */
-+ xgbe_default_config(pdata);
-+
-+ /* Calculate the number of Tx and Rx rings to be created
-+ * -Tx (DMA) Channels map 1-to-1 to Tx Queues so set
-+ * the number of Tx queues to the number of Tx channels
-+ * enabled
-+ * -Rx (DMA) Channels do not map 1-to-1 so use the actual
-+ * number of Rx queues
-+ */
-+ pdata->tx_ring_count = min_t(unsigned int, num_online_cpus(),
-+ pdata->hw_feat.tx_ch_cnt);
-+ pdata->tx_q_count = pdata->tx_ring_count;
-+ ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count);
-+ if (ret) {
-+ dev_err(dev, "error setting real tx queue count\n");
-+ goto err_io;
-+ }
-+
-+ pdata->rx_ring_count = min_t(unsigned int,
-+ netif_get_num_default_rss_queues(),
-+ pdata->hw_feat.rx_ch_cnt);
-+ pdata->rx_q_count = pdata->hw_feat.rx_q_cnt;
-+ ret = netif_set_real_num_rx_queues(netdev, pdata->rx_ring_count);
-+ if (ret) {
-+ dev_err(dev, "error setting real rx queue count\n");
-+ goto err_io;
-+ }
-+
-+ /* Initialize RSS hash key and lookup table */
-+ netdev_rss_key_fill(pdata->rss_key, sizeof(pdata->rss_key));
-+
-+ for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++)
-+ XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH,
-+ i % pdata->rx_ring_count);
-+
-+ XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1);
-+ XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1);
-+ XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
-+
-+ /* Prepare to regsiter with MDIO */
-+ pdata->mii_bus_id = kasprintf(GFP_KERNEL, "%s", pdev->name);
-+ if (!pdata->mii_bus_id) {
-+ dev_err(dev, "failed to allocate mii bus id\n");
-+ ret = -ENOMEM;
-+ goto err_io;
-+ }
-+ ret = xgbe_a0_mdio_register(pdata);
-+ if (ret)
-+ goto err_bus_id;
-+
-+ /* Set device operations */
-+ netdev->netdev_ops = xgbe_a0_get_netdev_ops();
-+ netdev->ethtool_ops = xgbe_a0_get_ethtool_ops();
-+#ifdef CONFIG_AMD_XGBE_DCB
-+ netdev->dcbnl_ops = xgbe_a0_get_dcbnl_ops();
-+#endif
-+
-+ /* Set device features */
-+ netdev->hw_features = NETIF_F_SG |
-+ NETIF_F_IP_CSUM |
-+ NETIF_F_IPV6_CSUM |
-+ NETIF_F_RXCSUM |
-+ NETIF_F_TSO |
-+ NETIF_F_TSO6 |
-+ NETIF_F_GRO |
-+ NETIF_F_HW_VLAN_CTAG_RX |
-+ NETIF_F_HW_VLAN_CTAG_TX |
-+ NETIF_F_HW_VLAN_CTAG_FILTER;
-+
-+ if (pdata->hw_feat.rss)
-+ netdev->hw_features |= NETIF_F_RXHASH;
-+
-+ netdev->vlan_features |= NETIF_F_SG |
-+ NETIF_F_IP_CSUM |
-+ NETIF_F_IPV6_CSUM |
-+ NETIF_F_TSO |
-+ NETIF_F_TSO6;
-+
-+ netdev->features |= netdev->hw_features;
-+ pdata->netdev_features = netdev->features;
-+
-+ netdev->priv_flags |= IFF_UNICAST_FLT;
-+
-+ xgbe_a0_init_rx_coalesce(pdata);
-+ xgbe_a0_init_tx_coalesce(pdata);
-+
-+ netif_carrier_off(netdev);
-+ ret = register_netdev(netdev);
-+ if (ret) {
-+ dev_err(dev, "net device registration failed\n");
-+ goto err_reg_netdev;
-+ }
-+
-+ xgbe_a0_ptp_register(pdata);
-+
-+ xgbe_a0_debugfs_init(pdata);
-+
-+ netdev_notice(netdev, "net device enabled\n");
-+
-+ DBGPR("<-- xgbe_probe\n");
-+
-+ return 0;
-+
-+err_reg_netdev:
-+ xgbe_a0_mdio_unregister(pdata);
-+
-+err_bus_id:
-+ kfree(pdata->mii_bus_id);
-+
-+err_io:
-+ free_netdev(netdev);
-+
-+err_alloc:
-+ dev_notice(dev, "net device not enabled\n");
-+
-+ return ret;
-+}
-+
-+static int xgbe_remove(struct platform_device *pdev)
-+{
-+ struct net_device *netdev = platform_get_drvdata(pdev);
-+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
-+
-+ DBGPR("-->xgbe_remove\n");
-+
-+ xgbe_a0_debugfs_exit(pdata);
-+
-+ xgbe_a0_ptp_unregister(pdata);
-+
-+ unregister_netdev(netdev);
-+
-+ xgbe_a0_mdio_unregister(pdata);
-+
-+ kfree(pdata->mii_bus_id);
-+
-+ free_netdev(netdev);
-+
-+ DBGPR("<--xgbe_remove\n");
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int xgbe_suspend(struct device *dev)
-+{
-+ struct net_device *netdev = dev_get_drvdata(dev);
-+ int ret;
-+
-+ DBGPR("-->xgbe_suspend\n");
-+
-+ if (!netif_running(netdev)) {
-+ DBGPR("<--xgbe_dev_suspend\n");
-+ return -EINVAL;
-+ }
-+
-+ ret = xgbe_a0_powerdown(netdev, XGMAC_DRIVER_CONTEXT);
-+
-+ DBGPR("<--xgbe_suspend\n");
-+
-+ return ret;
-+}
-+
-+static int xgbe_resume(struct device *dev)
-+{
-+ struct net_device *netdev = dev_get_drvdata(dev);
-+ int ret;
-+
-+ DBGPR("-->xgbe_resume\n");
-+
-+ if (!netif_running(netdev)) {
-+ DBGPR("<--xgbe_dev_resume\n");
-+ return -EINVAL;
-+ }
-+
-+ ret = xgbe_a0_powerup(netdev, XGMAC_DRIVER_CONTEXT);
-+
-+ DBGPR("<--xgbe_resume\n");
-+
-+ return ret;
-+}
-+#endif /* CONFIG_PM */
-+
-+#ifdef CONFIG_ACPI
-+static const struct acpi_device_id xgbe_a0_acpi_match[] = {
-+ { "AMDI8000", 0 },
-+ {},
-+};
-+
-+MODULE_DEVICE_TABLE(acpi, xgbe_a0_acpi_match);
-+#endif
-+
-+#ifdef CONFIG_OF
-+static const struct of_device_id xgbe_a0_of_match[] = {
-+ { .compatible = "amd,xgbe-seattle-v0a", },
-+ {},
-+};
-+
-+MODULE_DEVICE_TABLE(of, xgbe_a0_of_match);
-+#endif
-+
-+static SIMPLE_DEV_PM_OPS(xgbe_pm_ops, xgbe_suspend, xgbe_resume);
-+
-+static struct platform_driver xgbe_a0_driver = {
-+ .driver = {
-+ .name = "amd-xgbe-a0",
-+#ifdef CONFIG_ACPI
-+ .acpi_match_table = xgbe_a0_acpi_match,
-+#endif
-+#ifdef CONFIG_OF
-+ .of_match_table = xgbe_a0_of_match,
-+#endif
-+ .pm = &xgbe_pm_ops,
-+ },
-+ .probe = xgbe_probe,
-+ .remove = xgbe_remove,
-+};
-+
-+module_platform_driver(xgbe_a0_driver);
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe-a0/xgbe-mdio.c
-new file mode 100644
-index 0000000..b84d048
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-mdio.c
-@@ -0,0 +1,312 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kmod.h>
-+#include <linux/mdio.h>
-+#include <linux/phy.h>
-+#include <linux/of.h>
-+
-+#include "xgbe.h"
-+#include "xgbe-common.h"
-+
-+static int xgbe_mdio_read(struct mii_bus *mii, int prtad, int mmd_reg)
-+{
-+ struct xgbe_prv_data *pdata = mii->priv;
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ int mmd_data;
-+
-+ DBGPR_MDIO("-->xgbe_mdio_read: prtad=%#x mmd_reg=%#x\n",
-+ prtad, mmd_reg);
-+
-+ mmd_data = hw_if->read_mmd_regs(pdata, prtad, mmd_reg);
-+
-+ DBGPR_MDIO("<--xgbe_mdio_read: mmd_data=%#x\n", mmd_data);
-+
-+ return mmd_data;
-+}
-+
-+static int xgbe_mdio_write(struct mii_bus *mii, int prtad, int mmd_reg,
-+ u16 mmd_val)
-+{
-+ struct xgbe_prv_data *pdata = mii->priv;
-+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
-+ int mmd_data = mmd_val;
-+
-+ DBGPR_MDIO("-->xgbe_mdio_write: prtad=%#x mmd_reg=%#x mmd_data=%#x\n",
-+ prtad, mmd_reg, mmd_data);
-+
-+ hw_if->write_mmd_regs(pdata, prtad, mmd_reg, mmd_data);
-+
-+ DBGPR_MDIO("<--xgbe_mdio_write\n");
-+
-+ return 0;
-+}
-+
-+void xgbe_a0_dump_phy_registers(struct xgbe_prv_data *pdata)
-+{
-+ struct device *dev = pdata->dev;
-+ struct phy_device *phydev = pdata->mii->phy_map[XGBE_PRTAD];
-+ int i;
-+
-+ dev_alert(dev, "\n************* PHY Reg dump **********************\n");
-+
-+ dev_alert(dev, "PCS Control Reg (%#04x) = %#04x\n", MDIO_CTRL1,
-+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1));
-+ dev_alert(dev, "PCS Status Reg (%#04x) = %#04x\n", MDIO_STAT1,
-+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1));
-+ dev_alert(dev, "Phy Id (PHYS ID 1 %#04x)= %#04x\n", MDIO_DEVID1,
-+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVID1));
-+ dev_alert(dev, "Phy Id (PHYS ID 2 %#04x)= %#04x\n", MDIO_DEVID2,
-+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVID2));
-+ dev_alert(dev, "Devices in Package (%#04x)= %#04x\n", MDIO_DEVS1,
-+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVS1));
-+ dev_alert(dev, "Devices in Package (%#04x)= %#04x\n", MDIO_DEVS2,
-+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVS2));
-+
-+ dev_alert(dev, "Auto-Neg Control Reg (%#04x) = %#04x\n", MDIO_CTRL1,
-+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1));
-+ dev_alert(dev, "Auto-Neg Status Reg (%#04x) = %#04x\n", MDIO_STAT1,
-+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_STAT1));
-+ dev_alert(dev, "Auto-Neg Ad Reg 1 (%#04x) = %#04x\n",
-+ MDIO_AN_ADVERTISE,
-+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE));
-+ dev_alert(dev, "Auto-Neg Ad Reg 2 (%#04x) = %#04x\n",
-+ MDIO_AN_ADVERTISE + 1,
-+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1));
-+ dev_alert(dev, "Auto-Neg Ad Reg 3 (%#04x) = %#04x\n",
-+ MDIO_AN_ADVERTISE + 2,
-+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2));
-+ dev_alert(dev, "Auto-Neg Completion Reg (%#04x) = %#04x\n",
-+ MDIO_AN_COMP_STAT,
-+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_COMP_STAT));
-+
-+ dev_alert(dev, "MMD Device Mask = %#x\n",
-+ phydev->c45_ids.devices_in_package);
-+ for (i = 0; i < ARRAY_SIZE(phydev->c45_ids.device_ids); i++)
-+ dev_alert(dev, " MMD %d: ID = %#08x\n", i,
-+ phydev->c45_ids.device_ids[i]);
-+
-+ dev_alert(dev, "\n*************************************************\n");
-+}
-+
-+int xgbe_a0_mdio_register(struct xgbe_prv_data *pdata)
-+{
-+ struct mii_bus *mii;
-+ struct phy_device *phydev;
-+ int ret = 0;
-+
-+ DBGPR("-->xgbe_a0_mdio_register\n");
-+
-+ mii = mdiobus_alloc();
-+ if (!mii) {
-+ dev_err(pdata->dev, "mdiobus_alloc failed\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* Register on the MDIO bus (don't probe any PHYs) */
-+ mii->name = XGBE_PHY_NAME;
-+ mii->read = xgbe_mdio_read;
-+ mii->write = xgbe_mdio_write;
-+ snprintf(mii->id, sizeof(mii->id), "%s", pdata->mii_bus_id);
-+ mii->priv = pdata;
-+ mii->phy_mask = ~0;
-+ mii->parent = pdata->dev;
-+ ret = mdiobus_register(mii);
-+ if (ret) {
-+ dev_err(pdata->dev, "mdiobus_register failed\n");
-+ goto err_mdiobus_alloc;
-+ }
-+ DBGPR(" mdiobus_register succeeded for %s\n", pdata->mii_bus_id);
-+
-+ /* Probe the PCS using Clause 45 */
-+ phydev = get_phy_device(mii, XGBE_PRTAD, true);
-+ if (IS_ERR(phydev) || !phydev ||
-+ !phydev->c45_ids.device_ids[MDIO_MMD_PCS]) {
-+ dev_err(pdata->dev, "get_phy_device failed\n");
-+ ret = phydev ? PTR_ERR(phydev) : -ENOLINK;
-+ goto err_mdiobus_register;
-+ }
-+ request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT,
-+ MDIO_ID_ARGS(phydev->c45_ids.device_ids[MDIO_MMD_PCS]));
-+
-+ ret = phy_device_register(phydev);
-+ if (ret) {
-+ dev_err(pdata->dev, "phy_device_register failed\n");
-+ goto err_phy_device;
-+ }
-+ if (!phydev->dev.driver) {
-+ dev_err(pdata->dev, "phy driver probe failed\n");
-+ ret = -EIO;
-+ goto err_phy_device;
-+ }
-+
-+ /* Add a reference to the PHY driver so it can't be unloaded */
-+ pdata->phy_module = phydev->dev.driver->owner;
-+ if (!try_module_get(pdata->phy_module)) {
-+ dev_err(pdata->dev, "try_module_get failed\n");
-+ ret = -EIO;
-+ goto err_phy_device;
-+ }
-+
-+ pdata->mii = mii;
-+ pdata->mdio_mmd = MDIO_MMD_PCS;
-+
-+ phydev->autoneg = pdata->default_autoneg;
-+ if (phydev->autoneg == AUTONEG_DISABLE) {
-+ phydev->speed = pdata->default_speed;
-+ phydev->duplex = DUPLEX_FULL;
-+
-+ phydev->advertising &= ~ADVERTISED_Autoneg;
-+ }
-+
-+ pdata->phydev = phydev;
-+
-+ DBGPHY_REGS(pdata);
-+
-+ DBGPR("<--xgbe_a0_mdio_register\n");
-+
-+ return 0;
-+
-+err_phy_device:
-+ phy_device_free(phydev);
-+
-+err_mdiobus_register:
-+ mdiobus_unregister(mii);
-+
-+err_mdiobus_alloc:
-+ mdiobus_free(mii);
-+
-+ return ret;
-+}
-+
-+void xgbe_a0_mdio_unregister(struct xgbe_prv_data *pdata)
-+{
-+ DBGPR("-->xgbe_a0_mdio_unregister\n");
-+
-+ pdata->phydev = NULL;
-+
-+ module_put(pdata->phy_module);
-+ pdata->phy_module = NULL;
-+
-+ mdiobus_unregister(pdata->mii);
-+ pdata->mii->priv = NULL;
-+
-+ mdiobus_free(pdata->mii);
-+ pdata->mii = NULL;
-+
-+ DBGPR("<--xgbe_a0_mdio_unregister\n");
-+}
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe-ptp.c b/drivers/net/ethernet/amd/xgbe-a0/xgbe-ptp.c
-new file mode 100644
-index 0000000..1016aeb
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe-ptp.c
-@@ -0,0 +1,278 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clocksource.h>
-+#include <linux/ptp_clock_kernel.h>
-+#include <linux/net_tstamp.h>
-+
-+#include "xgbe.h"
-+#include "xgbe-common.h"
-+
-+static cycle_t xgbe_cc_read(const struct cyclecounter *cc)
-+{
-+ struct xgbe_prv_data *pdata = container_of(cc,
-+ struct xgbe_prv_data,
-+ tstamp_cc);
-+ u64 nsec;
-+
-+ nsec = pdata->hw_if.get_tstamp_time(pdata);
-+
-+ return nsec;
-+}
-+
-+static int xgbe_adjfreq(struct ptp_clock_info *info, s32 delta)
-+{
-+ struct xgbe_prv_data *pdata = container_of(info,
-+ struct xgbe_prv_data,
-+ ptp_clock_info);
-+ unsigned long flags;
-+ u64 adjust;
-+ u32 addend, diff;
-+ unsigned int neg_adjust = 0;
-+
-+ if (delta < 0) {
-+ neg_adjust = 1;
-+ delta = -delta;
-+ }
-+
-+ adjust = pdata->tstamp_addend;
-+ adjust *= delta;
-+ diff = div_u64(adjust, 1000000000UL);
-+
-+ addend = (neg_adjust) ? pdata->tstamp_addend - diff :
-+ pdata->tstamp_addend + diff;
-+
-+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
-+
-+ pdata->hw_if.update_tstamp_addend(pdata, addend);
-+
-+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
-+
-+ return 0;
-+}
-+
-+static int xgbe_adjtime(struct ptp_clock_info *info, s64 delta)
-+{
-+ struct xgbe_prv_data *pdata = container_of(info,
-+ struct xgbe_prv_data,
-+ ptp_clock_info);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
-+ timecounter_adjtime(&pdata->tstamp_tc, delta);
-+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
-+
-+ return 0;
-+}
-+
-+static int xgbe_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
-+{
-+ struct xgbe_prv_data *pdata = container_of(info,
-+ struct xgbe_prv_data,
-+ ptp_clock_info);
-+ unsigned long flags;
-+ u64 nsec;
-+
-+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
-+
-+ nsec = timecounter_read(&pdata->tstamp_tc);
-+
-+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
-+
-+ *ts = ns_to_timespec64(nsec);
-+
-+ return 0;
-+}
-+
-+static int xgbe_settime(struct ptp_clock_info *info, const struct timespec64 *ts)
-+{
-+ struct xgbe_prv_data *pdata = container_of(info,
-+ struct xgbe_prv_data,
-+ ptp_clock_info);
-+ unsigned long flags;
-+ u64 nsec;
-+
-+ nsec = timespec64_to_ns(ts);
-+
-+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
-+
-+ timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc, nsec);
-+
-+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
-+
-+ return 0;
-+}
-+
-+static int xgbe_enable(struct ptp_clock_info *info,
-+ struct ptp_clock_request *request, int on)
-+{
-+ return -EOPNOTSUPP;
-+}
-+
-+void xgbe_a0_ptp_register(struct xgbe_prv_data *pdata)
-+{
-+ struct ptp_clock_info *info = &pdata->ptp_clock_info;
-+ struct ptp_clock *clock;
-+ struct cyclecounter *cc = &pdata->tstamp_cc;
-+ u64 dividend;
-+
-+ snprintf(info->name, sizeof(info->name), "%s",
-+ netdev_name(pdata->netdev));
-+ info->owner = THIS_MODULE;
-+ info->max_adj = pdata->ptpclk_rate;
-+ info->adjfreq = xgbe_adjfreq;
-+ info->adjtime = xgbe_adjtime;
-+ info->gettime64 = xgbe_gettime;
-+ info->settime64 = xgbe_settime;
-+ info->enable = xgbe_enable;
-+
-+ clock = ptp_clock_register(info, pdata->dev);
-+ if (IS_ERR(clock)) {
-+ dev_err(pdata->dev, "ptp_clock_register failed\n");
-+ return;
-+ }
-+
-+ pdata->ptp_clock = clock;
-+
-+ /* Calculate the addend:
-+ * addend = 2^32 / (PTP ref clock / 50Mhz)
-+ * = (2^32 * 50Mhz) / PTP ref clock
-+ */
-+ dividend = 50000000;
-+ dividend <<= 32;
-+ pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate);
-+
-+ /* Setup the timecounter */
-+ cc->read = xgbe_cc_read;
-+ cc->mask = CLOCKSOURCE_MASK(64);
-+ cc->mult = 1;
-+ cc->shift = 0;
-+
-+ timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc,
-+ ktime_to_ns(ktime_get_real()));
-+
-+ /* Disable all timestamping to start */
-+ XGMAC_IOWRITE(pdata, MAC_TCR, 0);
-+ pdata->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
-+ pdata->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
-+}
-+
-+void xgbe_a0_ptp_unregister(struct xgbe_prv_data *pdata)
-+{
-+ if (pdata->ptp_clock)
-+ ptp_clock_unregister(pdata->ptp_clock);
-+}
-diff --git a/drivers/net/ethernet/amd/xgbe-a0/xgbe.h b/drivers/net/ethernet/amd/xgbe-a0/xgbe.h
-new file mode 100644
-index 0000000..04c00d2
---- /dev/null
-+++ b/drivers/net/ethernet/amd/xgbe-a0/xgbe.h
-@@ -0,0 +1,868 @@
-+/*
-+ * AMD 10Gb Ethernet driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
-+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
-+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
-+ * and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for Licensed
-+ * Product with Synopsys or any supplement thereto. Permission is hereby
-+ * granted, free of charge, to any person obtaining a copy of this software
-+ * annotated with this license and the Software, to deal in the Software
-+ * without restriction, including without limitation the rights to use,
-+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is furnished
-+ * to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#ifndef __XGBE_H__
-+#define __XGBE_H__
-+
-+#include <linux/dma-mapping.h>
-+#include <linux/netdevice.h>
-+#include <linux/workqueue.h>
-+#include <linux/phy.h>
-+#include <linux/if_vlan.h>
-+#include <linux/bitops.h>
-+#include <linux/ptp_clock_kernel.h>
-+#include <linux/timecounter.h>
-+#include <linux/net_tstamp.h>
-+#include <net/dcbnl.h>
-+
-+#define XGBE_DRV_NAME "amd-xgbe"
-+#define XGBE_DRV_VERSION "0.0.0-a"
-+#define XGBE_DRV_DESC "AMD 10 Gigabit Ethernet Driver"
-+
-+/* Descriptor related defines */
-+#define XGBE_TX_DESC_CNT 512
-+#define XGBE_TX_DESC_MIN_FREE (XGBE_TX_DESC_CNT >> 3)
-+#define XGBE_TX_DESC_MAX_PROC (XGBE_TX_DESC_CNT >> 1)
-+#define XGBE_RX_DESC_CNT 512
-+
-+#define XGBE_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1))
-+
-+/* Descriptors required for maximum contigous TSO/GSO packet */
-+#define XGBE_TX_MAX_SPLIT ((GSO_MAX_SIZE / XGBE_TX_MAX_BUF_SIZE) + 1)
-+
-+/* Maximum possible descriptors needed for an SKB:
-+ * - Maximum number of SKB frags
-+ * - Maximum descriptors for contiguous TSO/GSO packet
-+ * - Possible context descriptor
-+ * - Possible TSO header descriptor
-+ */
-+#define XGBE_TX_MAX_DESCS (MAX_SKB_FRAGS + XGBE_TX_MAX_SPLIT + 2)
-+
-+#define XGBE_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
-+#define XGBE_RX_BUF_ALIGN 64
-+#define XGBE_SKB_ALLOC_SIZE 256
-+#define XGBE_SPH_HDSMS_SIZE 2 /* Keep in sync with SKB_ALLOC_SIZE */
-+
-+#define XGBE_MAX_DMA_CHANNELS 16
-+#define XGBE_MAX_QUEUES 16
-+#define XGBE_DMA_STOP_TIMEOUT 5
-+
-+/* DMA cache settings - Outer sharable, write-back, write-allocate */
-+#define XGBE_DMA_OS_AXDOMAIN 0x2
-+#define XGBE_DMA_OS_ARCACHE 0xb
-+#define XGBE_DMA_OS_AWCACHE 0xf
-+
-+/* DMA cache settings - System, no caches used */
-+#define XGBE_DMA_SYS_AXDOMAIN 0x3
-+#define XGBE_DMA_SYS_ARCACHE 0x0
-+#define XGBE_DMA_SYS_AWCACHE 0x0
-+
-+#define XGBE_DMA_INTERRUPT_MASK 0x31c7
-+
-+#define XGMAC_MIN_PACKET 60
-+#define XGMAC_STD_PACKET_MTU 1500
-+#define XGMAC_MAX_STD_PACKET 1518
-+#define XGMAC_JUMBO_PACKET_MTU 9000
-+#define XGMAC_MAX_JUMBO_PACKET 9018
-+
-+/* MDIO bus phy name */
-+#define XGBE_PHY_NAME "amd_xgbe_phy_a0"
-+#define XGBE_PRTAD 0
-+
-+/* Common property names */
-+#define XGBE_MAC_ADDR_PROPERTY "mac-address"
-+#define XGBE_PHY_MODE_PROPERTY "phy-mode"
-+#define XGBE_DMA_IRQS_PROPERTY "amd,per-channel-interrupt"
-+
-+/* Device-tree clock names */
-+#define XGBE_DMA_CLOCK "dma_clk"
-+#define XGBE_PTP_CLOCK "ptp_clk"
-+
-+/* ACPI property names */
-+#define XGBE_ACPI_DMA_FREQ "amd,dma-freq"
-+#define XGBE_ACPI_PTP_FREQ "amd,ptp-freq"
-+
-+/* Timestamp support - values based on 50MHz PTP clock
-+ * 50MHz => 20 nsec
-+ */
-+#define XGBE_TSTAMP_SSINC 20
-+#define XGBE_TSTAMP_SNSINC 0
-+
-+/* Driver PMT macros */
-+#define XGMAC_DRIVER_CONTEXT 1
-+#define XGMAC_IOCTL_CONTEXT 2
-+
-+#define XGBE_FIFO_MAX 81920
-+#define XGBE_FIFO_SIZE_B(x) (x)
-+#define XGBE_FIFO_SIZE_KB(x) (x * 1024)
-+
-+#define XGBE_TC_MIN_QUANTUM 10
-+
-+/* Helper macro for descriptor handling
-+ * Always use XGBE_GET_DESC_DATA to access the descriptor data
-+ * since the index is free-running and needs to be and-ed
-+ * with the descriptor count value of the ring to index to
-+ * the proper descriptor data.
-+ */
-+#define XGBE_GET_DESC_DATA(_ring, _idx) \
-+ ((_ring)->rdata + \
-+ ((_idx) & ((_ring)->rdesc_count - 1)))
-+
-+/* Default coalescing parameters */
-+#define XGMAC_INIT_DMA_TX_USECS 50
-+#define XGMAC_INIT_DMA_TX_FRAMES 25
-+
-+#define XGMAC_MAX_DMA_RIWT 0xff
-+#define XGMAC_INIT_DMA_RX_USECS 30
-+#define XGMAC_INIT_DMA_RX_FRAMES 25
-+
-+/* Flow control queue count */
-+#define XGMAC_MAX_FLOW_CONTROL_QUEUES 8
-+
-+/* Maximum MAC address hash table size (256 bits = 8 bytes) */
-+#define XGBE_MAC_HASH_TABLE_SIZE 8
-+
-+/* Receive Side Scaling */
-+#define XGBE_RSS_HASH_KEY_SIZE 40
-+#define XGBE_RSS_MAX_TABLE_SIZE 256
-+#define XGBE_RSS_LOOKUP_TABLE_TYPE 0
-+#define XGBE_RSS_HASH_KEY_TYPE 1
-+
-+struct xgbe_prv_data;
-+
-+struct xgbe_packet_data {
-+ struct sk_buff *skb;
-+
-+ unsigned int attributes;
-+
-+ unsigned int errors;
-+
-+ unsigned int rdesc_count;
-+ unsigned int length;
-+
-+ unsigned int header_len;
-+ unsigned int tcp_header_len;
-+ unsigned int tcp_payload_len;
-+ unsigned short mss;
-+
-+ unsigned short vlan_ctag;
-+
-+ u64 rx_tstamp;
-+
-+ u32 rss_hash;
-+ enum pkt_hash_types rss_hash_type;
-+
-+ unsigned int tx_packets;
-+ unsigned int tx_bytes;
-+};
-+
-+/* Common Rx and Tx descriptor mapping */
-+struct xgbe_ring_desc {
-+ __le32 desc0;
-+ __le32 desc1;
-+ __le32 desc2;
-+ __le32 desc3;
-+};
-+
-+/* Page allocation related values */
-+struct xgbe_page_alloc {
-+ struct page *pages;
-+ unsigned int pages_len;
-+ unsigned int pages_offset;
-+
-+ dma_addr_t pages_dma;
-+};
-+
-+/* Ring entry buffer data */
-+struct xgbe_buffer_data {
-+ struct xgbe_page_alloc pa;
-+ struct xgbe_page_alloc pa_unmap;
-+
-+ dma_addr_t dma;
-+ unsigned int dma_len;
-+};
-+
-+/* Tx-related ring data */
-+struct xgbe_tx_ring_data {
-+ unsigned int packets; /* BQL packet count */
-+ unsigned int bytes; /* BQL byte count */
-+};
-+
-+/* Rx-related ring data */
-+struct xgbe_rx_ring_data {
-+ struct xgbe_buffer_data hdr; /* Header locations */
-+ struct xgbe_buffer_data buf; /* Payload locations */
-+
-+ unsigned short hdr_len; /* Length of received header */
-+ unsigned short len; /* Length of received packet */
-+};
-+
-+/* Structure used to hold information related to the descriptor
-+ * and the packet associated with the descriptor (always use
-+ * use the XGBE_GET_DESC_DATA macro to access this data from the ring)
-+ */
-+struct xgbe_ring_data {
-+ struct xgbe_ring_desc *rdesc; /* Virtual address of descriptor */
-+ dma_addr_t rdesc_dma; /* DMA address of descriptor */
-+
-+ struct sk_buff *skb; /* Virtual address of SKB */
-+ dma_addr_t skb_dma; /* DMA address of SKB data */
-+ unsigned int skb_dma_len; /* Length of SKB DMA area */
-+
-+ struct xgbe_tx_ring_data tx; /* Tx-related data */
-+ struct xgbe_rx_ring_data rx; /* Rx-related data */
-+
-+ unsigned int interrupt; /* Interrupt indicator */
-+
-+ unsigned int mapped_as_page;
-+
-+ /* Incomplete receive save location. If the budget is exhausted
-+ * or the last descriptor (last normal descriptor or a following
-+ * context descriptor) has not been DMA'd yet the current state
-+ * of the receive processing needs to be saved.
-+ */
-+ unsigned int state_saved;
-+ struct {
-+ unsigned int incomplete;
-+ unsigned int context_next;
-+ struct sk_buff *skb;
-+ unsigned int len;
-+ unsigned int error;
-+ } state;
-+};
-+
-+struct xgbe_ring {
-+ /* Ring lock - used just for TX rings at the moment */
-+ spinlock_t lock;
-+
-+ /* Per packet related information */
-+ struct xgbe_packet_data packet_data;
-+
-+ /* Virtual/DMA addresses and count of allocated descriptor memory */
-+ struct xgbe_ring_desc *rdesc;
-+ dma_addr_t rdesc_dma;
-+ unsigned int rdesc_count;
-+
-+ /* Array of descriptor data corresponding the descriptor memory
-+ * (always use the XGBE_GET_DESC_DATA macro to access this data)
-+ */
-+ struct xgbe_ring_data *rdata;
-+
-+ /* Page allocation for RX buffers */
-+ struct xgbe_page_alloc rx_hdr_pa;
-+ struct xgbe_page_alloc rx_buf_pa;
-+
-+ /* Ring index values
-+ * cur - Tx: index of descriptor to be used for current transfer
-+ * Rx: index of descriptor to check for packet availability
-+ * dirty - Tx: index of descriptor to check for transfer complete
-+ * Rx: index of descriptor to check for buffer reallocation
-+ */
-+ unsigned int cur;
-+ unsigned int dirty;
-+
-+ /* Coalesce frame count used for interrupt bit setting */
-+ unsigned int coalesce_count;
-+
-+ union {
-+ struct {
-+ unsigned int queue_stopped;
-+ unsigned int xmit_more;
-+ unsigned short cur_mss;
-+ unsigned short cur_vlan_ctag;
-+ } tx;
-+ };
-+} ____cacheline_aligned;
-+
-+/* Structure used to describe the descriptor rings associated with
-+ * a DMA channel.
-+ */
-+struct xgbe_channel {
-+ char name[16];
-+
-+ /* Address of private data area for device */
-+ struct xgbe_prv_data *pdata;
-+
-+ /* Queue index and base address of queue's DMA registers */
-+ unsigned int queue_index;
-+ void __iomem *dma_regs;
-+
-+ /* Per channel interrupt irq number */
-+ int dma_irq;
-+ char dma_irq_name[IFNAMSIZ + 32];
-+
-+ /* Netdev related settings */
-+ struct napi_struct napi;
-+
-+ unsigned int saved_ier;
-+
-+ unsigned int tx_timer_active;
-+ struct hrtimer tx_timer;
-+
-+ struct xgbe_ring *tx_ring;
-+ struct xgbe_ring *rx_ring;
-+} ____cacheline_aligned;
-+
-+enum xgbe_int {
-+ XGMAC_INT_DMA_CH_SR_TI,
-+ XGMAC_INT_DMA_CH_SR_TPS,
-+ XGMAC_INT_DMA_CH_SR_TBU,
-+ XGMAC_INT_DMA_CH_SR_RI,
-+ XGMAC_INT_DMA_CH_SR_RBU,
-+ XGMAC_INT_DMA_CH_SR_RPS,
-+ XGMAC_INT_DMA_CH_SR_TI_RI,
-+ XGMAC_INT_DMA_CH_SR_FBE,
-+ XGMAC_INT_DMA_ALL,
-+};
-+
-+enum xgbe_int_state {
-+ XGMAC_INT_STATE_SAVE,
-+ XGMAC_INT_STATE_RESTORE,
-+};
-+
-+enum xgbe_mtl_fifo_size {
-+ XGMAC_MTL_FIFO_SIZE_256 = 0x00,
-+ XGMAC_MTL_FIFO_SIZE_512 = 0x01,
-+ XGMAC_MTL_FIFO_SIZE_1K = 0x03,
-+ XGMAC_MTL_FIFO_SIZE_2K = 0x07,
-+ XGMAC_MTL_FIFO_SIZE_4K = 0x0f,
-+ XGMAC_MTL_FIFO_SIZE_8K = 0x1f,
-+ XGMAC_MTL_FIFO_SIZE_16K = 0x3f,
-+ XGMAC_MTL_FIFO_SIZE_32K = 0x7f,
-+ XGMAC_MTL_FIFO_SIZE_64K = 0xff,
-+ XGMAC_MTL_FIFO_SIZE_128K = 0x1ff,
-+ XGMAC_MTL_FIFO_SIZE_256K = 0x3ff,
-+};
-+
-+struct xgbe_mmc_stats {
-+ /* Tx Stats */
-+ u64 txoctetcount_gb;
-+ u64 txframecount_gb;
-+ u64 txbroadcastframes_g;
-+ u64 txmulticastframes_g;
-+ u64 tx64octets_gb;
-+ u64 tx65to127octets_gb;
-+ u64 tx128to255octets_gb;
-+ u64 tx256to511octets_gb;
-+ u64 tx512to1023octets_gb;
-+ u64 tx1024tomaxoctets_gb;
-+ u64 txunicastframes_gb;
-+ u64 txmulticastframes_gb;
-+ u64 txbroadcastframes_gb;
-+ u64 txunderflowerror;
-+ u64 txoctetcount_g;
-+ u64 txframecount_g;
-+ u64 txpauseframes;
-+ u64 txvlanframes_g;
-+
-+ /* Rx Stats */
-+ u64 rxframecount_gb;
-+ u64 rxoctetcount_gb;
-+ u64 rxoctetcount_g;
-+ u64 rxbroadcastframes_g;
-+ u64 rxmulticastframes_g;
-+ u64 rxcrcerror;
-+ u64 rxrunterror;
-+ u64 rxjabbererror;
-+ u64 rxundersize_g;
-+ u64 rxoversize_g;
-+ u64 rx64octets_gb;
-+ u64 rx65to127octets_gb;
-+ u64 rx128to255octets_gb;
-+ u64 rx256to511octets_gb;
-+ u64 rx512to1023octets_gb;
-+ u64 rx1024tomaxoctets_gb;
-+ u64 rxunicastframes_g;
-+ u64 rxlengtherror;
-+ u64 rxoutofrangetype;
-+ u64 rxpauseframes;
-+ u64 rxfifooverflow;
-+ u64 rxvlanframes_gb;
-+ u64 rxwatchdogerror;
-+};
-+
-+struct xgbe_hw_if {
-+ int (*tx_complete)(struct xgbe_ring_desc *);
-+
-+ int (*set_promiscuous_mode)(struct xgbe_prv_data *, unsigned int);
-+ int (*set_all_multicast_mode)(struct xgbe_prv_data *, unsigned int);
-+ int (*add_mac_addresses)(struct xgbe_prv_data *);
-+ int (*set_mac_address)(struct xgbe_prv_data *, u8 *addr);
-+
-+ int (*enable_rx_csum)(struct xgbe_prv_data *);
-+ int (*disable_rx_csum)(struct xgbe_prv_data *);
-+
-+ int (*enable_rx_vlan_stripping)(struct xgbe_prv_data *);
-+ int (*disable_rx_vlan_stripping)(struct xgbe_prv_data *);
-+ int (*enable_rx_vlan_filtering)(struct xgbe_prv_data *);
-+ int (*disable_rx_vlan_filtering)(struct xgbe_prv_data *);
-+ int (*update_vlan_hash_table)(struct xgbe_prv_data *);
-+
-+ int (*read_mmd_regs)(struct xgbe_prv_data *, int, int);
-+ void (*write_mmd_regs)(struct xgbe_prv_data *, int, int, int);
-+ int (*set_gmii_speed)(struct xgbe_prv_data *);
-+ int (*set_gmii_2500_speed)(struct xgbe_prv_data *);
-+ int (*set_xgmii_speed)(struct xgbe_prv_data *);
-+
-+ void (*enable_tx)(struct xgbe_prv_data *);
-+ void (*disable_tx)(struct xgbe_prv_data *);
-+ void (*enable_rx)(struct xgbe_prv_data *);
-+ void (*disable_rx)(struct xgbe_prv_data *);
-+
-+ void (*powerup_tx)(struct xgbe_prv_data *);
-+ void (*powerdown_tx)(struct xgbe_prv_data *);
-+ void (*powerup_rx)(struct xgbe_prv_data *);
-+ void (*powerdown_rx)(struct xgbe_prv_data *);
-+
-+ int (*init)(struct xgbe_prv_data *);
-+ int (*exit)(struct xgbe_prv_data *);
-+
-+ int (*enable_int)(struct xgbe_channel *, enum xgbe_int);
-+ int (*disable_int)(struct xgbe_channel *, enum xgbe_int);
-+ void (*dev_xmit)(struct xgbe_channel *);
-+ int (*dev_read)(struct xgbe_channel *);
-+ void (*tx_desc_init)(struct xgbe_channel *);
-+ void (*rx_desc_init)(struct xgbe_channel *);
-+ void (*rx_desc_reset)(struct xgbe_ring_data *);
-+ void (*tx_desc_reset)(struct xgbe_ring_data *);
-+ int (*is_last_desc)(struct xgbe_ring_desc *);
-+ int (*is_context_desc)(struct xgbe_ring_desc *);
-+ void (*tx_start_xmit)(struct xgbe_channel *, struct xgbe_ring *);
-+
-+ /* For FLOW ctrl */
-+ int (*config_tx_flow_control)(struct xgbe_prv_data *);
-+ int (*config_rx_flow_control)(struct xgbe_prv_data *);
-+
-+ /* For RX coalescing */
-+ int (*config_rx_coalesce)(struct xgbe_prv_data *);
-+ int (*config_tx_coalesce)(struct xgbe_prv_data *);
-+ unsigned int (*usec_to_riwt)(struct xgbe_prv_data *, unsigned int);
-+ unsigned int (*riwt_to_usec)(struct xgbe_prv_data *, unsigned int);
-+
-+ /* For RX and TX threshold config */
-+ int (*config_rx_threshold)(struct xgbe_prv_data *, unsigned int);
-+ int (*config_tx_threshold)(struct xgbe_prv_data *, unsigned int);
-+
-+ /* For RX and TX Store and Forward Mode config */
-+ int (*config_rsf_mode)(struct xgbe_prv_data *, unsigned int);
-+ int (*config_tsf_mode)(struct xgbe_prv_data *, unsigned int);
-+
-+ /* For TX DMA Operate on Second Frame config */
-+ int (*config_osp_mode)(struct xgbe_prv_data *);
-+
-+ /* For RX and TX PBL config */
-+ int (*config_rx_pbl_val)(struct xgbe_prv_data *);
-+ int (*get_rx_pbl_val)(struct xgbe_prv_data *);
-+ int (*config_tx_pbl_val)(struct xgbe_prv_data *);
-+ int (*get_tx_pbl_val)(struct xgbe_prv_data *);
-+ int (*config_pblx8)(struct xgbe_prv_data *);
-+
-+ /* For MMC statistics */
-+ void (*rx_mmc_int)(struct xgbe_prv_data *);
-+ void (*tx_mmc_int)(struct xgbe_prv_data *);
-+ void (*read_mmc_stats)(struct xgbe_prv_data *);
-+
-+ /* For Timestamp config */
-+ int (*config_tstamp)(struct xgbe_prv_data *, unsigned int);
-+ void (*update_tstamp_addend)(struct xgbe_prv_data *, unsigned int);
-+ void (*set_tstamp_time)(struct xgbe_prv_data *, unsigned int sec,
-+ unsigned int nsec);
-+ u64 (*get_tstamp_time)(struct xgbe_prv_data *);
-+ u64 (*get_tx_tstamp)(struct xgbe_prv_data *);
-+
-+ /* For Data Center Bridging config */
-+ void (*config_dcb_tc)(struct xgbe_prv_data *);
-+ void (*config_dcb_pfc)(struct xgbe_prv_data *);
-+
-+ /* For Receive Side Scaling */
-+ int (*enable_rss)(struct xgbe_prv_data *);
-+ int (*disable_rss)(struct xgbe_prv_data *);
-+ int (*set_rss_hash_key)(struct xgbe_prv_data *, const u8 *);
-+ int (*set_rss_lookup_table)(struct xgbe_prv_data *, const u32 *);
-+};
-+
-+struct xgbe_desc_if {
-+ int (*alloc_ring_resources)(struct xgbe_prv_data *);
-+ void (*free_ring_resources)(struct xgbe_prv_data *);
-+ int (*map_tx_skb)(struct xgbe_channel *, struct sk_buff *);
-+ int (*map_rx_buffer)(struct xgbe_prv_data *, struct xgbe_ring *,
-+ struct xgbe_ring_data *);
-+ void (*unmap_rdata)(struct xgbe_prv_data *, struct xgbe_ring_data *);
-+ void (*wrapper_tx_desc_init)(struct xgbe_prv_data *);
-+ void (*wrapper_rx_desc_init)(struct xgbe_prv_data *);
-+};
-+
-+/* This structure contains flags that indicate what hardware features
-+ * or configurations are present in the device.
-+ */
-+struct xgbe_hw_features {
-+ /* HW Version */
-+ unsigned int version;
-+
-+ /* HW Feature Register0 */
-+ unsigned int gmii; /* 1000 Mbps support */
-+ unsigned int vlhash; /* VLAN Hash Filter */
-+ unsigned int sma; /* SMA(MDIO) Interface */
-+ unsigned int rwk; /* PMT remote wake-up packet */
-+ unsigned int mgk; /* PMT magic packet */
-+ unsigned int mmc; /* RMON module */
-+ unsigned int aoe; /* ARP Offload */
-+ unsigned int ts; /* IEEE 1588-2008 Adavanced Timestamp */
-+ unsigned int eee; /* Energy Efficient Ethernet */
-+ unsigned int tx_coe; /* Tx Checksum Offload */
-+ unsigned int rx_coe; /* Rx Checksum Offload */
-+ unsigned int addn_mac; /* Additional MAC Addresses */
-+ unsigned int ts_src; /* Timestamp Source */
-+ unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */
-+
-+ /* HW Feature Register1 */
-+ unsigned int rx_fifo_size; /* MTL Receive FIFO Size */
-+ unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */
-+ unsigned int adv_ts_hi; /* Advance Timestamping High Word */
-+ unsigned int dcb; /* DCB Feature */
-+ unsigned int sph; /* Split Header Feature */
-+ unsigned int tso; /* TCP Segmentation Offload */
-+ unsigned int dma_debug; /* DMA Debug Registers */
-+ unsigned int rss; /* Receive Side Scaling */
-+ unsigned int tc_cnt; /* Number of Traffic Classes */
-+ unsigned int hash_table_size; /* Hash Table Size */
-+ unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */
-+
-+ /* HW Feature Register2 */
-+ unsigned int rx_q_cnt; /* Number of MTL Receive Queues */
-+ unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */
-+ unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */
-+ unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */
-+ unsigned int pps_out_num; /* Number of PPS outputs */
-+ unsigned int aux_snap_num; /* Number of Aux snapshot inputs */
-+};
-+
-+struct xgbe_prv_data {
-+ struct net_device *netdev;
-+ struct platform_device *pdev;
-+ struct acpi_device *adev;
-+ struct device *dev;
-+
-+ /* ACPI or DT flag */
-+ unsigned int use_acpi;
-+
-+ /* XGMAC/XPCS related mmio registers */
-+ void __iomem *xgmac_regs; /* XGMAC CSRs */
-+ void __iomem *xpcs_regs; /* XPCS MMD registers */
-+
-+ /* Overall device lock */
-+ spinlock_t lock;
-+
-+ /* XPCS indirect addressing mutex */
-+ struct mutex xpcs_mutex;
-+
-+ /* RSS addressing mutex */
-+ struct mutex rss_mutex;
-+
-+ int dev_irq;
-+ unsigned int per_channel_irq;
-+
-+ struct xgbe_hw_if hw_if;
-+ struct xgbe_desc_if desc_if;
-+
-+ /* AXI DMA settings */
-+ unsigned int coherent;
-+ unsigned int axdomain;
-+ unsigned int arcache;
-+ unsigned int awcache;
-+
-+ /* Rings for Tx/Rx on a DMA channel */
-+ struct xgbe_channel *channel;
-+ unsigned int channel_count;
-+ unsigned int tx_ring_count;
-+ unsigned int tx_desc_count;
-+ unsigned int rx_ring_count;
-+ unsigned int rx_desc_count;
-+
-+ unsigned int tx_q_count;
-+ unsigned int rx_q_count;
-+
-+ /* Tx/Rx common settings */
-+ unsigned int pblx8;
-+
-+ /* Tx settings */
-+ unsigned int tx_sf_mode;
-+ unsigned int tx_threshold;
-+ unsigned int tx_pbl;
-+ unsigned int tx_osp_mode;
-+
-+ /* Rx settings */
-+ unsigned int rx_sf_mode;
-+ unsigned int rx_threshold;
-+ unsigned int rx_pbl;
-+
-+ /* Tx coalescing settings */
-+ unsigned int tx_usecs;
-+ unsigned int tx_frames;
-+
-+ /* Rx coalescing settings */
-+ unsigned int rx_riwt;
-+ unsigned int rx_frames;
-+
-+ /* Current Rx buffer size */
-+ unsigned int rx_buf_size;
-+
-+ /* Flow control settings */
-+ unsigned int pause_autoneg;
-+ unsigned int tx_pause;
-+ unsigned int rx_pause;
-+
-+ /* Receive Side Scaling settings */
-+ u8 rss_key[XGBE_RSS_HASH_KEY_SIZE];
-+ u32 rss_table[XGBE_RSS_MAX_TABLE_SIZE];
-+ u32 rss_options;
-+
-+ /* MDIO settings */
-+ struct module *phy_module;
-+ char *mii_bus_id;
-+ struct mii_bus *mii;
-+ int mdio_mmd;
-+ struct phy_device *phydev;
-+ int default_autoneg;
-+ int default_speed;
-+
-+ /* Current PHY settings */
-+ phy_interface_t phy_mode;
-+ int phy_link;
-+ int phy_speed;
-+ unsigned int phy_tx_pause;
-+ unsigned int phy_rx_pause;
-+
-+ /* Netdev related settings */
-+ unsigned char mac_addr[ETH_ALEN];
-+ netdev_features_t netdev_features;
-+ struct napi_struct napi;
-+ struct xgbe_mmc_stats mmc_stats;
-+
-+ /* Filtering support */
-+ unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
-+
-+ /* Device clocks */
-+ struct clk *sysclk;
-+ unsigned long sysclk_rate;
-+ struct clk *ptpclk;
-+ unsigned long ptpclk_rate;
-+
-+ /* Timestamp support */
-+ spinlock_t tstamp_lock;
-+ struct ptp_clock_info ptp_clock_info;
-+ struct ptp_clock *ptp_clock;
-+ struct hwtstamp_config tstamp_config;
-+ struct cyclecounter tstamp_cc;
-+ struct timecounter tstamp_tc;
-+ unsigned int tstamp_addend;
-+ struct work_struct tx_tstamp_work;
-+ struct sk_buff *tx_tstamp_skb;
-+ u64 tx_tstamp;
-+
-+ /* DCB support */
-+ struct ieee_ets *ets;
-+ struct ieee_pfc *pfc;
-+ unsigned int q2tc_map[XGBE_MAX_QUEUES];
-+ unsigned int prio2q_map[IEEE_8021QAZ_MAX_TCS];
-+
-+ /* Hardware features of the device */
-+ struct xgbe_hw_features hw_feat;
-+
-+ /* Device restart work structure */
-+ struct work_struct restart_work;
-+
-+ /* Keeps track of power mode */
-+ unsigned int power_down;
-+
-+#ifdef CONFIG_DEBUG_FS
-+ struct dentry *xgbe_debugfs;
-+
-+ unsigned int debugfs_xgmac_reg;
-+
-+ unsigned int debugfs_xpcs_mmd;
-+ unsigned int debugfs_xpcs_reg;
-+#endif
-+};
-+
-+/* Function prototypes*/
-+
-+void xgbe_a0_init_function_ptrs_dev(struct xgbe_hw_if *);
-+void xgbe_a0_init_function_ptrs_desc(struct xgbe_desc_if *);
-+struct net_device_ops *xgbe_a0_get_netdev_ops(void);
-+struct ethtool_ops *xgbe_a0_get_ethtool_ops(void);
-+#ifdef CONFIG_AMD_XGBE_DCB
-+const struct dcbnl_rtnl_ops *xgbe_a0_get_dcbnl_ops(void);
-+#endif
-+
-+int xgbe_a0_mdio_register(struct xgbe_prv_data *);
-+void xgbe_a0_mdio_unregister(struct xgbe_prv_data *);
-+void xgbe_a0_dump_phy_registers(struct xgbe_prv_data *);
-+void xgbe_a0_ptp_register(struct xgbe_prv_data *);
-+void xgbe_a0_ptp_unregister(struct xgbe_prv_data *);
-+void xgbe_a0_dump_tx_desc(struct xgbe_ring *, unsigned int, unsigned int,
-+ unsigned int);
-+void xgbe_a0_dump_rx_desc(struct xgbe_ring *, struct xgbe_ring_desc *,
-+ unsigned int);
-+void xgbe_a0_print_pkt(struct net_device *, struct sk_buff *, bool);
-+void xgbe_a0_get_all_hw_features(struct xgbe_prv_data *);
-+int xgbe_a0_powerup(struct net_device *, unsigned int);
-+int xgbe_a0_powerdown(struct net_device *, unsigned int);
-+void xgbe_a0_init_rx_coalesce(struct xgbe_prv_data *);
-+void xgbe_a0_init_tx_coalesce(struct xgbe_prv_data *);
-+
-+#ifdef CONFIG_DEBUG_FS
-+void xgbe_a0_debugfs_init(struct xgbe_prv_data *);
-+void xgbe_a0_debugfs_exit(struct xgbe_prv_data *);
-+#else
-+static inline void xgbe_a0_debugfs_init(struct xgbe_prv_data *pdata) {}
-+static inline void xgbe_a0_debugfs_exit(struct xgbe_prv_data *pdata) {}
-+#endif /* CONFIG_DEBUG_FS */
-+
-+/* NOTE: Uncomment for TX and RX DESCRIPTOR DUMP in KERNEL LOG */
-+#if 0
-+#define XGMAC_ENABLE_TX_DESC_DUMP
-+#define XGMAC_ENABLE_RX_DESC_DUMP
-+#endif
-+
-+/* NOTE: Uncomment for TX and RX PACKET DUMP in KERNEL LOG */
-+#if 0
-+#define XGMAC_ENABLE_TX_PKT_DUMP
-+#define XGMAC_ENABLE_RX_PKT_DUMP
-+#endif
-+
-+/* NOTE: Uncomment for function trace log messages in KERNEL LOG */
-+#if 0
-+#define YDEBUG
-+#define YDEBUG_MDIO
-+#endif
-+
-+/* For debug prints */
-+#ifdef YDEBUG
-+#define DBGPR(x...) pr_alert(x)
-+#define DBGPHY_REGS(x...) xgbe_a0_dump_phy_registers(x)
-+#else
-+#define DBGPR(x...) do { } while (0)
-+#define DBGPHY_REGS(x...) do { } while (0)
-+#endif
-+
-+#ifdef YDEBUG_MDIO
-+#define DBGPR_MDIO(x...) pr_alert(x)
-+#else
-+#define DBGPR_MDIO(x...) do { } while (0)
-+#endif
-+
-+#endif
---
-2.4.5
-
diff --git a/amd-xgbe-phy-a0-Add-support-for-XGBE-PHY-on-A0.patch b/amd-xgbe-phy-a0-Add-support-for-XGBE-PHY-on-A0.patch
deleted file mode 100644
index c24edad0a..000000000
--- a/amd-xgbe-phy-a0-Add-support-for-XGBE-PHY-on-A0.patch
+++ /dev/null
@@ -1,1870 +0,0 @@
-From a3e660ae9fdeb53000eceeaf393e03cd087e37f7 Mon Sep 17 00:00:00 2001
-From: Tom Lendacky <thomas.lendacky@amd.com>
-Date: Tue, 17 Mar 2015 10:58:38 -0500
-Subject: [PATCH 2/2] amd-xgbe-phy-a0: Add support for XGBE PHY on A0
-
-Add XGBE phy driver support for A0 hardware.
-
-Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
-[Add back AMD_XGBE_PHY removed upstream for B0 driver]
-Signed-off-by: Mark Salter <msalter@redhat.com>
----
- drivers/net/phy/Kconfig | 7 +
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/amd-xgbe-phy-a0.c | 1814 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 1822 insertions(+)
- create mode 100644 drivers/net/phy/amd-xgbe-phy-a0.c
-
-diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
-index cb86d7a..a3138b1 100644
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -24,6 +24,13 @@ config AMD_PHY
- ---help---
- Currently supports the am79c874
-
-+config AMD_XGBE_PHY
-+ tristate "Driver for the AMD 10GbE (amd-xgbe) PHYs"
-+ depends on (OF || ACPI) && HAS_IOMEM
-+ depends on ARM64 || COMPILE_TEST
-+ ---help---
-+ Currently supports the AMD 10GbE PHY
-+
- config MARVELL_PHY
- tristate "Drivers for Marvell PHYs"
- ---help---
-diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
-index fcc25a0..6ebb9ba 100644
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -29,6 +29,7 @@ obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
- obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
- obj-$(CONFIG_AT803X_PHY) += at803x.o
- obj-$(CONFIG_AMD_PHY) += amd.o
-+obj-$(CONFIG_AMD_XGBE_PHY) += amd-xgbe-phy-a0.o
- obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o
- obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o
- obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o
-diff --git a/drivers/net/phy/amd-xgbe-phy-a0.c b/drivers/net/phy/amd-xgbe-phy-a0.c
-new file mode 100644
-index 0000000..c352d5c
---- /dev/null
-+++ b/drivers/net/phy/amd-xgbe-phy-a0.c
-@@ -0,0 +1,1814 @@
-+/*
-+ * AMD 10Gb Ethernet PHY driver
-+ *
-+ * This file is available to you under your choice of the following two
-+ * licenses:
-+ *
-+ * License 1: GPLv2
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ *
-+ * This file is free software; you may copy, redistribute and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ * This file is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ *
-+ * License 2: Modified BSD
-+ *
-+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * * Neither the name of Advanced Micro Devices, Inc. nor the
-+ * names of its contributors may be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/unistd.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/workqueue.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/mm.h>
-+#include <linux/module.h>
-+#include <linux/mii.h>
-+#include <linux/ethtool.h>
-+#include <linux/phy.h>
-+#include <linux/mdio.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/of_device.h>
-+#include <linux/uaccess.h>
-+#include <linux/bitops.h>
-+#include <linux/property.h>
-+#include <linux/acpi.h>
-+#include <linux/irq.h>
-+
-+MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>");
-+MODULE_LICENSE("Dual BSD/GPL");
-+MODULE_VERSION("0.0.0-a");
-+MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
-+
-+#define XGBE_PHY_ID 0x7996ced0
-+#define XGBE_PHY_MASK 0xfffffff0
-+
-+#define XGBE_PHY_SERDES_RETRY 32
-+#define XGBE_PHY_CHANNEL_PROPERTY "amd,serdes-channel"
-+#define XGBE_PHY_SPEEDSET_PROPERTY "amd,speed-set"
-+#define XGBE_PHY_BLWC_PROPERTY "amd,serdes-blwc"
-+#define XGBE_PHY_CDR_RATE_PROPERTY "amd,serdes-cdr-rate"
-+#define XGBE_PHY_PQ_SKEW_PROPERTY "amd,serdes-pq-skew"
-+#define XGBE_PHY_TX_AMP_PROPERTY "amd,serdes-tx-amp"
-+
-+#define XGBE_PHY_SPEEDS 3
-+#define XGBE_PHY_SPEED_1000 0
-+#define XGBE_PHY_SPEED_2500 1
-+#define XGBE_PHY_SPEED_10000 2
-+
-+#define XGBE_AN_INT_CMPLT 0x01
-+#define XGBE_AN_INC_LINK 0x02
-+#define XGBE_AN_PG_RCV 0x04
-+#define XGBE_AN_INT_MASK 0x07
-+
-+#define XNP_MCF_NULL_MESSAGE 0x001
-+#define XNP_ACK_PROCESSED BIT(12)
-+#define XNP_MP_FORMATTED BIT(13)
-+#define XNP_NP_EXCHANGE BIT(15)
-+
-+#define XGBE_PHY_RATECHANGE_COUNT 500
-+
-+#define XGBE_PHY_KR_TRAINING_START 0x01
-+#define XGBE_PHY_KR_TRAINING_ENABLE 0x02
-+
-+#define XGBE_PHY_FEC_ENABLE 0x01
-+#define XGBE_PHY_FEC_FORWARD 0x02
-+#define XGBE_PHY_FEC_MASK 0x03
-+
-+#ifndef MDIO_PMA_10GBR_PMD_CTRL
-+#define MDIO_PMA_10GBR_PMD_CTRL 0x0096
-+#endif
-+
-+#ifndef MDIO_PMA_10GBR_FEC_ABILITY
-+#define MDIO_PMA_10GBR_FEC_ABILITY 0x00aa
-+#endif
-+
-+#ifndef MDIO_PMA_10GBR_FEC_CTRL
-+#define MDIO_PMA_10GBR_FEC_CTRL 0x00ab
-+#endif
-+
-+#ifndef MDIO_AN_XNP
-+#define MDIO_AN_XNP 0x0016
-+#endif
-+
-+#ifndef MDIO_AN_LPX
-+#define MDIO_AN_LPX 0x0019
-+#endif
-+
-+#ifndef MDIO_AN_INTMASK
-+#define MDIO_AN_INTMASK 0x8001
-+#endif
-+
-+#ifndef MDIO_AN_INT
-+#define MDIO_AN_INT 0x8002
-+#endif
-+
-+#ifndef MDIO_AN_KR_CTRL
-+#define MDIO_AN_KR_CTRL 0x8003
-+#endif
-+
-+#ifndef MDIO_CTRL1_SPEED1G
-+#define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100)
-+#endif
-+
-+#ifndef MDIO_KR_CTRL_PDETECT
-+#define MDIO_KR_CTRL_PDETECT 0x01
-+#endif
-+
-+#define GET_BITS(_var, _index, _width) \
-+ (((_var) >> (_index)) & ((0x1 << (_width)) - 1))
-+
-+#define SET_BITS(_var, _index, _width, _val) \
-+do { \
-+ (_var) &= ~(((0x1 << (_width)) - 1) << (_index)); \
-+ (_var) |= (((_val) & ((0x1 << (_width)) - 1)) << (_index)); \
-+} while (0)
-+
-+#define XCMU_IOREAD(_priv, _reg) \
-+ ioread16((_priv)->cmu_regs + _reg)
-+
-+#define XCMU_IOWRITE(_priv, _reg, _val) \
-+ iowrite16((_val), (_priv)->cmu_regs + _reg)
-+
-+#define XRXTX_IOREAD(_priv, _reg) \
-+ ioread16((_priv)->rxtx_regs + _reg)
-+
-+#define XRXTX_IOREAD_BITS(_priv, _reg, _field) \
-+ GET_BITS(XRXTX_IOREAD((_priv), _reg), \
-+ _reg##_##_field##_INDEX, \
-+ _reg##_##_field##_WIDTH)
-+
-+#define XRXTX_IOWRITE(_priv, _reg, _val) \
-+ iowrite16((_val), (_priv)->rxtx_regs + _reg)
-+
-+#define XRXTX_IOWRITE_BITS(_priv, _reg, _field, _val) \
-+do { \
-+ u16 reg_val = XRXTX_IOREAD((_priv), _reg); \
-+ SET_BITS(reg_val, \
-+ _reg##_##_field##_INDEX, \
-+ _reg##_##_field##_WIDTH, (_val)); \
-+ XRXTX_IOWRITE((_priv), _reg, reg_val); \
-+} while (0)
-+
-+/* SerDes CMU register offsets */
-+#define CMU_REG15 0x003c
-+#define CMU_REG16 0x0040
-+
-+/* SerDes CMU register entry bit positions and sizes */
-+#define CMU_REG16_TX_RATE_CHANGE_BASE 15
-+#define CMU_REG16_RX_RATE_CHANGE_BASE 14
-+#define CMU_REG16_RATE_CHANGE_DECR 2
-+
-+/* SerDes RxTx register offsets */
-+#define RXTX_REG2 0x0008
-+#define RXTX_REG3 0x000c
-+#define RXTX_REG5 0x0014
-+#define RXTX_REG6 0x0018
-+#define RXTX_REG20 0x0050
-+#define RXTX_REG53 0x00d4
-+#define RXTX_REG114 0x01c8
-+#define RXTX_REG115 0x01cc
-+#define RXTX_REG142 0x0238
-+
-+/* SerDes RxTx register entry bit positions and sizes */
-+#define RXTX_REG2_RESETB_INDEX 15
-+#define RXTX_REG2_RESETB_WIDTH 1
-+#define RXTX_REG3_TX_DATA_RATE_INDEX 14
-+#define RXTX_REG3_TX_DATA_RATE_WIDTH 2
-+#define RXTX_REG3_TX_WORD_MODE_INDEX 11
-+#define RXTX_REG3_TX_WORD_MODE_WIDTH 3
-+#define RXTX_REG5_TXAMP_CNTL_INDEX 7
-+#define RXTX_REG5_TXAMP_CNTL_WIDTH 4
-+#define RXTX_REG6_RX_DATA_RATE_INDEX 9
-+#define RXTX_REG6_RX_DATA_RATE_WIDTH 2
-+#define RXTX_REG6_RX_WORD_MODE_INDEX 11
-+#define RXTX_REG6_RX_WORD_MODE_WIDTH 3
-+#define RXTX_REG20_BLWC_ENA_INDEX 2
-+#define RXTX_REG20_BLWC_ENA_WIDTH 1
-+#define RXTX_REG53_RX_PLLSELECT_INDEX 15
-+#define RXTX_REG53_RX_PLLSELECT_WIDTH 1
-+#define RXTX_REG53_TX_PLLSELECT_INDEX 14
-+#define RXTX_REG53_TX_PLLSELECT_WIDTH 1
-+#define RXTX_REG53_PI_SPD_SEL_CDR_INDEX 10
-+#define RXTX_REG53_PI_SPD_SEL_CDR_WIDTH 4
-+#define RXTX_REG114_PQ_REG_INDEX 9
-+#define RXTX_REG114_PQ_REG_WIDTH 7
-+#define RXTX_REG115_FORCE_LAT_CAL_START_INDEX 2
-+#define RXTX_REG115_FORCE_LAT_CAL_START_WIDTH 1
-+#define RXTX_REG115_FORCE_SUM_CAL_START_INDEX 1
-+#define RXTX_REG115_FORCE_SUM_CAL_START_WIDTH 1
-+#define RXTX_REG142_SUM_CALIB_DONE_INDEX 15
-+#define RXTX_REG142_SUM_CALIB_DONE_WIDTH 1
-+#define RXTX_REG142_SUM_CALIB_ERR_INDEX 14
-+#define RXTX_REG142_SUM_CALIB_ERR_WIDTH 1
-+#define RXTX_REG142_LAT_CALIB_DONE_INDEX 11
-+#define RXTX_REG142_LAT_CALIB_DONE_WIDTH 1
-+
-+#define RXTX_FULL_RATE 0x0
-+#define RXTX_HALF_RATE 0x1
-+#define RXTX_FIFTH_RATE 0x3
-+#define RXTX_66BIT_WORD 0x7
-+#define RXTX_10BIT_WORD 0x1
-+#define RXTX_10G_BLWC 0x0
-+#define RXTX_1G_BLWC 0x1
-+#define RXTX_10G_TX_AMP 0xa
-+#define RXTX_1G_TX_AMP 0xf
-+#define RXTX_10G_CDR 0x7
-+#define RXTX_1G_CDR 0x2
-+#define RXTX_10G_PLL 0x1
-+#define RXTX_1G_PLL 0x0
-+#define RXTX_10G_PQ 0x1e
-+#define RXTX_1G_PQ 0xa
-+
-+DEFINE_SPINLOCK(cmu_lock);
-+
-+static const u32 amd_xgbe_phy_serdes_blwc[] = {
-+ RXTX_1G_BLWC,
-+ RXTX_1G_BLWC,
-+ RXTX_10G_BLWC,
-+};
-+
-+static const u32 amd_xgbe_phy_serdes_cdr_rate[] = {
-+ RXTX_1G_CDR,
-+ RXTX_1G_CDR,
-+ RXTX_10G_CDR,
-+};
-+
-+static const u32 amd_xgbe_phy_serdes_pq_skew[] = {
-+ RXTX_1G_PQ,
-+ RXTX_1G_PQ,
-+ RXTX_10G_PQ,
-+};
-+
-+static const u32 amd_xgbe_phy_serdes_tx_amp[] = {
-+ RXTX_1G_TX_AMP,
-+ RXTX_1G_TX_AMP,
-+ RXTX_10G_TX_AMP,
-+};
-+
-+enum amd_xgbe_phy_an {
-+ AMD_XGBE_AN_READY = 0,
-+ AMD_XGBE_AN_PAGE_RECEIVED,
-+ AMD_XGBE_AN_INCOMPAT_LINK,
-+ AMD_XGBE_AN_COMPLETE,
-+ AMD_XGBE_AN_NO_LINK,
-+ AMD_XGBE_AN_ERROR,
-+};
-+
-+enum amd_xgbe_phy_rx {
-+ AMD_XGBE_RX_BPA = 0,
-+ AMD_XGBE_RX_XNP,
-+ AMD_XGBE_RX_COMPLETE,
-+ AMD_XGBE_RX_ERROR,
-+};
-+
-+enum amd_xgbe_phy_mode {
-+ AMD_XGBE_MODE_KR,
-+ AMD_XGBE_MODE_KX,
-+};
-+
-+enum amd_xgbe_phy_speedset {
-+ AMD_XGBE_PHY_SPEEDSET_1000_10000 = 0,
-+ AMD_XGBE_PHY_SPEEDSET_2500_10000,
-+};
-+
-+struct amd_xgbe_phy_priv {
-+ struct platform_device *pdev;
-+ struct acpi_device *adev;
-+ struct device *dev;
-+
-+ struct phy_device *phydev;
-+
-+ /* SerDes related mmio resources */
-+ struct resource *rxtx_res;
-+ struct resource *cmu_res;
-+
-+ /* SerDes related mmio registers */
-+ void __iomem *rxtx_regs; /* SerDes Rx/Tx CSRs */
-+ void __iomem *cmu_regs; /* SerDes CMU CSRs */
-+
-+ int an_irq;
-+ char an_irq_name[IFNAMSIZ + 32];
-+ struct work_struct an_irq_work;
-+ unsigned int an_irq_allocated;
-+
-+ unsigned int serdes_channel;
-+ unsigned int speed_set;
-+
-+ /* Maintain link status for re-starting auto-negotiation */
-+ unsigned int link;
-+
-+ /* SerDes UEFI configurable settings.
-+ * Switching between modes/speeds requires new values for some
-+ * SerDes settings. The values can be supplied as device
-+ * properties in array format. The first array entry is for
-+ * 1GbE, second for 2.5GbE and third for 10GbE
-+ */
-+ u32 serdes_blwc[XGBE_PHY_SPEEDS];
-+ u32 serdes_cdr_rate[XGBE_PHY_SPEEDS];
-+ u32 serdes_pq_skew[XGBE_PHY_SPEEDS];
-+ u32 serdes_tx_amp[XGBE_PHY_SPEEDS];
-+
-+ /* Auto-negotiation state machine support */
-+ struct mutex an_mutex;
-+ enum amd_xgbe_phy_an an_result;
-+ enum amd_xgbe_phy_an an_state;
-+ enum amd_xgbe_phy_rx kr_state;
-+ enum amd_xgbe_phy_rx kx_state;
-+ struct work_struct an_work;
-+ struct workqueue_struct *an_workqueue;
-+ unsigned int an_supported;
-+ unsigned int parallel_detect;
-+ unsigned int fec_ability;
-+
-+ unsigned int lpm_ctrl; /* CTRL1 for resume */
-+};
-+
-+static int amd_xgbe_an_disable_kr_training(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret &= ~XGBE_PHY_KR_TRAINING_ENABLE;
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, ret);
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_pcs_power_cycle(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret |= MDIO_CTRL1_LPOWER;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, ret);
-+
-+ usleep_range(75, 100);
-+
-+ ret &= ~MDIO_CTRL1_LPOWER;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, ret);
-+
-+ return 0;
-+}
-+
-+static void amd_xgbe_phy_serdes_start_ratechange(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ u16 val, mask;
-+
-+ /* Assert Rx and Tx ratechange in CMU_reg16 */
-+ val = XCMU_IOREAD(priv, CMU_REG16);
-+
-+ mask = (1 << (CMU_REG16_TX_RATE_CHANGE_BASE -
-+ (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR))) |
-+ (1 << (CMU_REG16_RX_RATE_CHANGE_BASE -
-+ (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR)));
-+ val |= mask;
-+
-+ XCMU_IOWRITE(priv, CMU_REG16, val);
-+}
-+
-+static void amd_xgbe_phy_serdes_complete_ratechange(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ u16 val, mask;
-+ unsigned int wait;
-+
-+ /* Release Rx and Tx ratechange for proper channel in CMU_reg16 */
-+ val = XCMU_IOREAD(priv, CMU_REG16);
-+
-+ mask = (1 << (CMU_REG16_TX_RATE_CHANGE_BASE -
-+ (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR))) |
-+ (1 << (CMU_REG16_RX_RATE_CHANGE_BASE -
-+ (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR)));
-+ val &= ~mask;
-+
-+ XCMU_IOWRITE(priv, CMU_REG16, val);
-+
-+ /* Wait for Rx and Tx ready in CMU_reg15 */
-+ mask = (1 << priv->serdes_channel) |
-+ (1 << (priv->serdes_channel + 8));
-+ wait = XGBE_PHY_RATECHANGE_COUNT;
-+ while (wait--) {
-+ udelay(50);
-+
-+ val = XCMU_IOREAD(priv, CMU_REG15);
-+ if ((val & mask) == mask)
-+ return;
-+ }
-+
-+ netdev_dbg(phydev->attached_dev, "SerDes rx/tx not ready (%#hx)\n",
-+ val);
-+}
-+
-+static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ int ret;
-+
-+ /* Disable KR training */
-+ ret = amd_xgbe_an_disable_kr_training(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Set PCS to KR/10G speed */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret &= ~MDIO_PCS_CTRL2_TYPE;
-+ ret |= MDIO_PCS_CTRL2_10GBR;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2, ret);
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret &= ~MDIO_CTRL1_SPEEDSEL;
-+ ret |= MDIO_CTRL1_SPEED10G;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, ret);
-+
-+ ret = amd_xgbe_phy_pcs_power_cycle(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Set SerDes to 10G speed */
-+ spin_lock(&cmu_lock);
-+
-+ amd_xgbe_phy_serdes_start_ratechange(phydev);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_DATA_RATE, RXTX_FULL_RATE);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_WORD_MODE, RXTX_66BIT_WORD);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG5, TXAMP_CNTL,
-+ priv->serdes_tx_amp[XGBE_PHY_SPEED_10000]);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_DATA_RATE, RXTX_FULL_RATE);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_WORD_MODE, RXTX_66BIT_WORD);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA,
-+ priv->serdes_blwc[XGBE_PHY_SPEED_10000]);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG53, RX_PLLSELECT, RXTX_10G_PLL);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG53, TX_PLLSELECT, RXTX_10G_PLL);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG53, PI_SPD_SEL_CDR,
-+ priv->serdes_cdr_rate[XGBE_PHY_SPEED_10000]);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG,
-+ priv->serdes_pq_skew[XGBE_PHY_SPEED_10000]);
-+
-+ amd_xgbe_phy_serdes_complete_ratechange(phydev);
-+
-+ spin_unlock(&cmu_lock);
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_gmii_2500_mode(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ int ret;
-+
-+ /* Disable KR training */
-+ ret = amd_xgbe_an_disable_kr_training(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Set PCS to KX/1G speed */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret &= ~MDIO_PCS_CTRL2_TYPE;
-+ ret |= MDIO_PCS_CTRL2_10GBX;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2, ret);
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret &= ~MDIO_CTRL1_SPEEDSEL;
-+ ret |= MDIO_CTRL1_SPEED1G;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, ret);
-+
-+ ret = amd_xgbe_phy_pcs_power_cycle(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Set SerDes to 2.5G speed */
-+ spin_lock(&cmu_lock);
-+
-+ amd_xgbe_phy_serdes_start_ratechange(phydev);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_DATA_RATE, RXTX_HALF_RATE);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_WORD_MODE, RXTX_10BIT_WORD);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG5, TXAMP_CNTL,
-+ priv->serdes_tx_amp[XGBE_PHY_SPEED_2500]);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_DATA_RATE, RXTX_HALF_RATE);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_WORD_MODE, RXTX_10BIT_WORD);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA,
-+ priv->serdes_blwc[XGBE_PHY_SPEED_2500]);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG53, RX_PLLSELECT, RXTX_1G_PLL);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG53, TX_PLLSELECT, RXTX_1G_PLL);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG53, PI_SPD_SEL_CDR,
-+ priv->serdes_cdr_rate[XGBE_PHY_SPEED_2500]);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG,
-+ priv->serdes_pq_skew[XGBE_PHY_SPEED_2500]);
-+
-+ amd_xgbe_phy_serdes_complete_ratechange(phydev);
-+
-+ spin_unlock(&cmu_lock);
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_gmii_mode(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ int ret;
-+
-+ /* Disable KR training */
-+ ret = amd_xgbe_an_disable_kr_training(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Set PCS to KX/1G speed */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret &= ~MDIO_PCS_CTRL2_TYPE;
-+ ret |= MDIO_PCS_CTRL2_10GBX;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2, ret);
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret &= ~MDIO_CTRL1_SPEEDSEL;
-+ ret |= MDIO_CTRL1_SPEED1G;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, ret);
-+
-+ ret = amd_xgbe_phy_pcs_power_cycle(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Set SerDes to 1G speed */
-+ spin_lock(&cmu_lock);
-+
-+ amd_xgbe_phy_serdes_start_ratechange(phydev);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_DATA_RATE, RXTX_FIFTH_RATE);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_WORD_MODE, RXTX_10BIT_WORD);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG5, TXAMP_CNTL,
-+ priv->serdes_tx_amp[XGBE_PHY_SPEED_1000]);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_DATA_RATE, RXTX_FIFTH_RATE);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_WORD_MODE, RXTX_10BIT_WORD);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA,
-+ priv->serdes_blwc[XGBE_PHY_SPEED_1000]);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG53, RX_PLLSELECT, RXTX_1G_PLL);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG53, TX_PLLSELECT, RXTX_1G_PLL);
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG53, PI_SPD_SEL_CDR,
-+ priv->serdes_cdr_rate[XGBE_PHY_SPEED_1000]);
-+
-+ XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG,
-+ priv->serdes_pq_skew[XGBE_PHY_SPEED_1000]);
-+
-+ amd_xgbe_phy_serdes_complete_ratechange(phydev);
-+
-+ spin_unlock(&cmu_lock);
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_cur_mode(struct phy_device *phydev,
-+ enum amd_xgbe_phy_mode *mode)
-+{
-+ int ret;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
-+ if (ret < 0)
-+ return ret;
-+
-+ if ((ret & MDIO_PCS_CTRL2_TYPE) == MDIO_PCS_CTRL2_10GBR)
-+ *mode = AMD_XGBE_MODE_KR;
-+ else
-+ *mode = AMD_XGBE_MODE_KX;
-+
-+ return 0;
-+}
-+
-+static bool amd_xgbe_phy_in_kr_mode(struct phy_device *phydev)
-+{
-+ enum amd_xgbe_phy_mode mode;
-+
-+ if (amd_xgbe_phy_cur_mode(phydev, &mode))
-+ return false;
-+
-+ return (mode == AMD_XGBE_MODE_KR);
-+}
-+
-+static int amd_xgbe_phy_switch_mode(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ int ret;
-+
-+ /* If we are in KR switch to KX, and vice-versa */
-+ if (amd_xgbe_phy_in_kr_mode(phydev)) {
-+ if (priv->speed_set == AMD_XGBE_PHY_SPEEDSET_1000_10000)
-+ ret = amd_xgbe_phy_gmii_mode(phydev);
-+ else
-+ ret = amd_xgbe_phy_gmii_2500_mode(phydev);
-+ } else {
-+ ret = amd_xgbe_phy_xgmii_mode(phydev);
-+ }
-+
-+ return ret;
-+}
-+
-+static int amd_xgbe_phy_set_mode(struct phy_device *phydev,
-+ enum amd_xgbe_phy_mode mode)
-+{
-+ enum amd_xgbe_phy_mode cur_mode;
-+ int ret;
-+
-+ ret = amd_xgbe_phy_cur_mode(phydev, &cur_mode);
-+ if (ret)
-+ return ret;
-+
-+ if (mode != cur_mode)
-+ ret = amd_xgbe_phy_switch_mode(phydev);
-+
-+ return ret;
-+}
-+
-+static int amd_xgbe_phy_set_an(struct phy_device *phydev, bool enable,
-+ bool restart)
-+{
-+ int ret;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret &= ~MDIO_AN_CTRL1_ENABLE;
-+
-+ if (enable)
-+ ret |= MDIO_AN_CTRL1_ENABLE;
-+
-+ if (restart)
-+ ret |= MDIO_AN_CTRL1_RESTART;
-+
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, ret);
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_restart_an(struct phy_device *phydev)
-+{
-+ return amd_xgbe_phy_set_an(phydev, true, true);
-+}
-+
-+static int amd_xgbe_phy_disable_an(struct phy_device *phydev)
-+{
-+ return amd_xgbe_phy_set_an(phydev, false, false);
-+}
-+
-+static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
-+ enum amd_xgbe_phy_rx *state)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ int ad_reg, lp_reg, ret;
-+
-+ *state = AMD_XGBE_RX_COMPLETE;
-+
-+ /* If we're not in KR mode then we're done */
-+ if (!amd_xgbe_phy_in_kr_mode(phydev))
-+ return AMD_XGBE_AN_PAGE_RECEIVED;
-+
-+ /* Enable/Disable FEC */
-+ ad_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
-+ if (ad_reg < 0)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ lp_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA + 2);
-+ if (lp_reg < 0)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FEC_CTRL);
-+ if (ret < 0)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ ret &= ~XGBE_PHY_FEC_MASK;
-+ if ((ad_reg & 0xc000) && (lp_reg & 0xc000))
-+ ret |= priv->fec_ability;
-+
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FEC_CTRL, ret);
-+
-+ /* Start KR training */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);
-+ if (ret < 0)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ if (ret & XGBE_PHY_KR_TRAINING_ENABLE) {
-+ ret |= XGBE_PHY_KR_TRAINING_START;
-+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL,
-+ ret);
-+ }
-+
-+ return AMD_XGBE_AN_PAGE_RECEIVED;
-+}
-+
-+static enum amd_xgbe_phy_an amd_xgbe_an_tx_xnp(struct phy_device *phydev,
-+ enum amd_xgbe_phy_rx *state)
-+{
-+ u16 msg;
-+
-+ *state = AMD_XGBE_RX_XNP;
-+
-+ msg = XNP_MCF_NULL_MESSAGE;
-+ msg |= XNP_MP_FORMATTED;
-+
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0);
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0);
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_XNP, msg);
-+
-+ return AMD_XGBE_AN_PAGE_RECEIVED;
-+}
-+
-+static enum amd_xgbe_phy_an amd_xgbe_an_rx_bpa(struct phy_device *phydev,
-+ enum amd_xgbe_phy_rx *state)
-+{
-+ unsigned int link_support;
-+ int ret, ad_reg, lp_reg;
-+
-+ /* Read Base Ability register 2 first */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA + 1);
-+ if (ret < 0)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ /* Check for a supported mode, otherwise restart in a different one */
-+ link_support = amd_xgbe_phy_in_kr_mode(phydev) ? 0x80 : 0x20;
-+ if (!(ret & link_support))
-+ return AMD_XGBE_AN_INCOMPAT_LINK;
-+
-+ /* Check Extended Next Page support */
-+ ad_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
-+ if (ad_reg < 0)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ lp_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA);
-+ if (lp_reg < 0)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ return ((ad_reg & XNP_NP_EXCHANGE) || (lp_reg & XNP_NP_EXCHANGE)) ?
-+ amd_xgbe_an_tx_xnp(phydev, state) :
-+ amd_xgbe_an_tx_training(phydev, state);
-+}
-+
-+static enum amd_xgbe_phy_an amd_xgbe_an_rx_xnp(struct phy_device *phydev,
-+ enum amd_xgbe_phy_rx *state)
-+{
-+ int ad_reg, lp_reg;
-+
-+ /* Check Extended Next Page support */
-+ ad_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_XNP);
-+ if (ad_reg < 0)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ lp_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPX);
-+ if (lp_reg < 0)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ return ((ad_reg & XNP_NP_EXCHANGE) || (lp_reg & XNP_NP_EXCHANGE)) ?
-+ amd_xgbe_an_tx_xnp(phydev, state) :
-+ amd_xgbe_an_tx_training(phydev, state);
-+}
-+
-+static enum amd_xgbe_phy_an amd_xgbe_an_page_received(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ enum amd_xgbe_phy_rx *state;
-+ int ret;
-+
-+ state = amd_xgbe_phy_in_kr_mode(phydev) ? &priv->kr_state
-+ : &priv->kx_state;
-+
-+ switch (*state) {
-+ case AMD_XGBE_RX_BPA:
-+ ret = amd_xgbe_an_rx_bpa(phydev, state);
-+ break;
-+
-+ case AMD_XGBE_RX_XNP:
-+ ret = amd_xgbe_an_rx_xnp(phydev, state);
-+ break;
-+
-+ default:
-+ ret = AMD_XGBE_AN_ERROR;
-+ }
-+
-+ return ret;
-+}
-+
-+static enum amd_xgbe_phy_an amd_xgbe_an_incompat_link(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ int ret;
-+
-+ /* Be sure we aren't looping trying to negotiate */
-+ if (amd_xgbe_phy_in_kr_mode(phydev)) {
-+ priv->kr_state = AMD_XGBE_RX_ERROR;
-+
-+ if (!(phydev->supported & SUPPORTED_1000baseKX_Full) &&
-+ !(phydev->supported & SUPPORTED_2500baseX_Full))
-+ return AMD_XGBE_AN_NO_LINK;
-+
-+ if (priv->kx_state != AMD_XGBE_RX_BPA)
-+ return AMD_XGBE_AN_NO_LINK;
-+ } else {
-+ priv->kx_state = AMD_XGBE_RX_ERROR;
-+
-+ if (!(phydev->supported & SUPPORTED_10000baseKR_Full))
-+ return AMD_XGBE_AN_NO_LINK;
-+
-+ if (priv->kr_state != AMD_XGBE_RX_BPA)
-+ return AMD_XGBE_AN_NO_LINK;
-+ }
-+
-+ ret = amd_xgbe_phy_disable_an(phydev);
-+ if (ret)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ ret = amd_xgbe_phy_switch_mode(phydev);
-+ if (ret)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ ret = amd_xgbe_phy_restart_an(phydev);
-+ if (ret)
-+ return AMD_XGBE_AN_ERROR;
-+
-+ return AMD_XGBE_AN_INCOMPAT_LINK;
-+}
-+
-+static irqreturn_t amd_xgbe_an_isr(int irq, void *data)
-+{
-+ struct amd_xgbe_phy_priv *priv = (struct amd_xgbe_phy_priv *)data;
-+
-+ /* Interrupt reason must be read and cleared outside of IRQ context */
-+ disable_irq_nosync(priv->an_irq);
-+
-+ queue_work(priv->an_workqueue, &priv->an_irq_work);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void amd_xgbe_an_irq_work(struct work_struct *work)
-+{
-+ struct amd_xgbe_phy_priv *priv = container_of(work,
-+ struct amd_xgbe_phy_priv,
-+ an_irq_work);
-+
-+ /* Avoid a race between enabling the IRQ and exiting the work by
-+ * waiting for the work to finish and then queueing it
-+ */
-+ flush_work(&priv->an_work);
-+ queue_work(priv->an_workqueue, &priv->an_work);
-+}
-+
-+static void amd_xgbe_an_state_machine(struct work_struct *work)
-+{
-+ struct amd_xgbe_phy_priv *priv = container_of(work,
-+ struct amd_xgbe_phy_priv,
-+ an_work);
-+ struct phy_device *phydev = priv->phydev;
-+ enum amd_xgbe_phy_an cur_state = priv->an_state;
-+ int int_reg, int_mask;
-+
-+ mutex_lock(&priv->an_mutex);
-+
-+ /* Read the interrupt */
-+ int_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT);
-+ if (!int_reg)
-+ goto out;
-+
-+next_int:
-+ if (int_reg < 0) {
-+ priv->an_state = AMD_XGBE_AN_ERROR;
-+ int_mask = XGBE_AN_INT_MASK;
-+ } else if (int_reg & XGBE_AN_PG_RCV) {
-+ priv->an_state = AMD_XGBE_AN_PAGE_RECEIVED;
-+ int_mask = XGBE_AN_PG_RCV;
-+ } else if (int_reg & XGBE_AN_INC_LINK) {
-+ priv->an_state = AMD_XGBE_AN_INCOMPAT_LINK;
-+ int_mask = XGBE_AN_INC_LINK;
-+ } else if (int_reg & XGBE_AN_INT_CMPLT) {
-+ priv->an_state = AMD_XGBE_AN_COMPLETE;
-+ int_mask = XGBE_AN_INT_CMPLT;
-+ } else {
-+ priv->an_state = AMD_XGBE_AN_ERROR;
-+ int_mask = 0;
-+ }
-+
-+ /* Clear the interrupt to be processed */
-+ int_reg &= ~int_mask;
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, int_reg);
-+
-+ priv->an_result = priv->an_state;
-+
-+again:
-+ cur_state = priv->an_state;
-+
-+ switch (priv->an_state) {
-+ case AMD_XGBE_AN_READY:
-+ priv->an_supported = 0;
-+ break;
-+
-+ case AMD_XGBE_AN_PAGE_RECEIVED:
-+ priv->an_state = amd_xgbe_an_page_received(phydev);
-+ priv->an_supported++;
-+ break;
-+
-+ case AMD_XGBE_AN_INCOMPAT_LINK:
-+ priv->an_supported = 0;
-+ priv->parallel_detect = 0;
-+ priv->an_state = amd_xgbe_an_incompat_link(phydev);
-+ break;
-+
-+ case AMD_XGBE_AN_COMPLETE:
-+ priv->parallel_detect = priv->an_supported ? 0 : 1;
-+ netdev_dbg(phydev->attached_dev, "%s successful\n",
-+ priv->an_supported ? "Auto negotiation"
-+ : "Parallel detection");
-+ break;
-+
-+ case AMD_XGBE_AN_NO_LINK:
-+ break;
-+
-+ default:
-+ priv->an_state = AMD_XGBE_AN_ERROR;
-+ }
-+
-+ if (priv->an_state == AMD_XGBE_AN_NO_LINK) {
-+ /* Disable auto-negotiation for now - it will be
-+ * re-enabled once a link is established
-+ */
-+ amd_xgbe_phy_disable_an(phydev);
-+
-+ int_reg = 0;
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
-+ } else if (priv->an_state == AMD_XGBE_AN_ERROR) {
-+ netdev_err(phydev->attached_dev,
-+ "error during auto-negotiation, state=%u\n",
-+ cur_state);
-+
-+ int_reg = 0;
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
-+ }
-+
-+ if (priv->an_state >= AMD_XGBE_AN_COMPLETE) {
-+ priv->an_result = priv->an_state;
-+ priv->an_state = AMD_XGBE_AN_READY;
-+ priv->kr_state = AMD_XGBE_RX_BPA;
-+ priv->kx_state = AMD_XGBE_RX_BPA;
-+ }
-+
-+ if (cur_state != priv->an_state)
-+ goto again;
-+
-+ if (int_reg)
-+ goto next_int;
-+
-+out:
-+ enable_irq(priv->an_irq);
-+
-+ mutex_unlock(&priv->an_mutex);
-+}
-+
-+static int amd_xgbe_an_init(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Set up Advertisement register 3 first */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (phydev->supported & SUPPORTED_10000baseR_FEC)
-+ ret |= 0xc000;
-+ else
-+ ret &= ~0xc000;
-+
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, ret);
-+
-+ /* Set up Advertisement register 2 next */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (phydev->supported & SUPPORTED_10000baseKR_Full)
-+ ret |= 0x80;
-+ else
-+ ret &= ~0x80;
-+
-+ if ((phydev->supported & SUPPORTED_1000baseKX_Full) ||
-+ (phydev->supported & SUPPORTED_2500baseX_Full))
-+ ret |= 0x20;
-+ else
-+ ret &= ~0x20;
-+
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, ret);
-+
-+ /* Set up Advertisement register 1 last */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (phydev->supported & SUPPORTED_Pause)
-+ ret |= 0x400;
-+ else
-+ ret &= ~0x400;
-+
-+ if (phydev->supported & SUPPORTED_Asym_Pause)
-+ ret |= 0x800;
-+ else
-+ ret &= ~0x800;
-+
-+ /* We don't intend to perform XNP */
-+ ret &= ~XNP_NP_EXCHANGE;
-+
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, ret);
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_soft_reset(struct phy_device *phydev)
-+{
-+ int count, ret;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret |= MDIO_CTRL1_RESET;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, ret);
-+
-+ count = 50;
-+ do {
-+ msleep(20);
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
-+ if (ret < 0)
-+ return ret;
-+ } while ((ret & MDIO_CTRL1_RESET) && --count);
-+
-+ if (ret & MDIO_CTRL1_RESET)
-+ return -ETIMEDOUT;
-+
-+ /* Disable auto-negotiation for now */
-+ ret = amd_xgbe_phy_disable_an(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Clear auto-negotiation interrupts */
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_config_init(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ struct net_device *netdev = phydev->attached_dev;
-+ int ret;
-+
-+ if (!priv->an_irq_allocated) {
-+ /* Allocate the auto-negotiation workqueue and interrupt */
-+ snprintf(priv->an_irq_name, sizeof(priv->an_irq_name) - 1,
-+ "%s-pcs", netdev_name(netdev));
-+
-+ priv->an_workqueue =
-+ create_singlethread_workqueue(priv->an_irq_name);
-+ if (!priv->an_workqueue) {
-+ netdev_err(netdev, "phy workqueue creation failed\n");
-+ return -ENOMEM;
-+ }
-+
-+ ret = devm_request_irq(priv->dev, priv->an_irq,
-+ amd_xgbe_an_isr, 0, priv->an_irq_name,
-+ priv);
-+ if (ret) {
-+ netdev_err(netdev, "phy irq request failed\n");
-+ destroy_workqueue(priv->an_workqueue);
-+ return ret;
-+ }
-+
-+ priv->an_irq_allocated = 1;
-+ }
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FEC_ABILITY);
-+ if (ret < 0)
-+ return ret;
-+ priv->fec_ability = ret & XGBE_PHY_FEC_MASK;
-+
-+ /* Initialize supported features */
-+ phydev->supported = SUPPORTED_Autoneg;
-+ phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
-+ phydev->supported |= SUPPORTED_Backplane;
-+ phydev->supported |= SUPPORTED_10000baseKR_Full;
-+ switch (priv->speed_set) {
-+ case AMD_XGBE_PHY_SPEEDSET_1000_10000:
-+ phydev->supported |= SUPPORTED_1000baseKX_Full;
-+ break;
-+ case AMD_XGBE_PHY_SPEEDSET_2500_10000:
-+ phydev->supported |= SUPPORTED_2500baseX_Full;
-+ break;
-+ }
-+
-+ if (priv->fec_ability & XGBE_PHY_FEC_ENABLE)
-+ phydev->supported |= SUPPORTED_10000baseR_FEC;
-+
-+ phydev->advertising = phydev->supported;
-+
-+ /* Set initial mode - call the mode setting routines
-+ * directly to insure we are properly configured
-+ */
-+ if (phydev->supported & SUPPORTED_10000baseKR_Full)
-+ ret = amd_xgbe_phy_xgmii_mode(phydev);
-+ else if (phydev->supported & SUPPORTED_1000baseKX_Full)
-+ ret = amd_xgbe_phy_gmii_mode(phydev);
-+ else if (phydev->supported & SUPPORTED_2500baseX_Full)
-+ ret = amd_xgbe_phy_gmii_2500_mode(phydev);
-+ else
-+ ret = -EINVAL;
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Set up advertisement registers based on current settings */
-+ ret = amd_xgbe_an_init(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* Enable auto-negotiation interrupts */
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07);
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_setup_forced(struct phy_device *phydev)
-+{
-+ int ret;
-+
-+ /* Disable auto-negotiation */
-+ ret = amd_xgbe_phy_disable_an(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Validate/Set specified speed */
-+ switch (phydev->speed) {
-+ case SPEED_10000:
-+ ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KR);
-+ break;
-+
-+ case SPEED_2500:
-+ case SPEED_1000:
-+ ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX);
-+ break;
-+
-+ default:
-+ ret = -EINVAL;
-+ }
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Validate duplex mode */
-+ if (phydev->duplex != DUPLEX_FULL)
-+ return -EINVAL;
-+
-+ phydev->pause = 0;
-+ phydev->asym_pause = 0;
-+
-+ return 0;
-+}
-+
-+static int __amd_xgbe_phy_config_aneg(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ u32 mmd_mask = phydev->c45_ids.devices_in_package;
-+ int ret;
-+
-+ if (phydev->autoneg != AUTONEG_ENABLE)
-+ return amd_xgbe_phy_setup_forced(phydev);
-+
-+ /* Make sure we have the AN MMD present */
-+ if (!(mmd_mask & MDIO_DEVS_AN))
-+ return -EINVAL;
-+
-+ /* Disable auto-negotiation interrupt */
-+ disable_irq(priv->an_irq);
-+
-+ /* Start auto-negotiation in a supported mode */
-+ if (phydev->supported & SUPPORTED_10000baseKR_Full)
-+ ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KR);
-+ else if ((phydev->supported & SUPPORTED_1000baseKX_Full) ||
-+ (phydev->supported & SUPPORTED_2500baseX_Full))
-+ ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX);
-+ else
-+ ret = -EINVAL;
-+ if (ret < 0) {
-+ enable_irq(priv->an_irq);
-+ return ret;
-+ }
-+
-+ /* Disable and stop any in progress auto-negotiation */
-+ ret = amd_xgbe_phy_disable_an(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Clear any auto-negotitation interrupts */
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
-+
-+ priv->an_result = AMD_XGBE_AN_READY;
-+ priv->an_state = AMD_XGBE_AN_READY;
-+ priv->kr_state = AMD_XGBE_RX_BPA;
-+ priv->kx_state = AMD_XGBE_RX_BPA;
-+
-+ /* Re-enable auto-negotiation interrupt */
-+ enable_irq(priv->an_irq);
-+
-+ /* Set up advertisement registers based on current settings */
-+ ret = amd_xgbe_an_init(phydev);
-+ if (ret)
-+ return ret;
-+
-+ /* Enable and start auto-negotiation */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret |= MDIO_KR_CTRL_PDETECT;
-+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL, ret);
-+
-+ return amd_xgbe_phy_restart_an(phydev);
-+}
-+
-+static int amd_xgbe_phy_config_aneg(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ int ret;
-+
-+ mutex_lock(&priv->an_mutex);
-+
-+ ret = __amd_xgbe_phy_config_aneg(phydev);
-+
-+ mutex_unlock(&priv->an_mutex);
-+
-+ return ret;
-+}
-+
-+static int amd_xgbe_phy_aneg_done(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+
-+ return (priv->an_result == AMD_XGBE_AN_COMPLETE);
-+}
-+
-+static int amd_xgbe_phy_update_link(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ unsigned int check_again, autoneg;
-+ int ret;
-+
-+ /* If we're doing auto-negotiation don't report link down */
-+ if (priv->an_state != AMD_XGBE_AN_READY) {
-+ phydev->link = 1;
-+ return 0;
-+ }
-+
-+ /* Since the device can be in the wrong mode when a link is
-+ * (re-)established (cable connected after the interface is
-+ * up, etc.), the link status may report no link. If there
-+ * is no link, try switching modes and checking the status
-+ * again if auto negotiation is enabled.
-+ */
-+ check_again = (phydev->autoneg == AUTONEG_ENABLE) ? 1 : 0;
-+again:
-+ /* Link status is latched low, so read once to clear
-+ * and then read again to get current state
-+ */
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_STAT1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_STAT1);
-+ if (ret < 0)
-+ return ret;
-+
-+ phydev->link = (ret & MDIO_STAT1_LSTATUS) ? 1 : 0;
-+
-+ if (!phydev->link) {
-+ if (check_again) {
-+ ret = amd_xgbe_phy_switch_mode(phydev);
-+ if (ret < 0)
-+ return ret;
-+ check_again = 0;
-+ goto again;
-+ }
-+ }
-+
-+ autoneg = (phydev->link && !priv->link) ? 1 : 0;
-+ priv->link = phydev->link;
-+ if (autoneg) {
-+ /* Link is (back) up, re-start auto-negotiation */
-+ ret = amd_xgbe_phy_config_aneg(phydev);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_read_status(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ u32 mmd_mask = phydev->c45_ids.devices_in_package;
-+ int ret, ad_ret, lp_ret;
-+
-+ ret = amd_xgbe_phy_update_link(phydev);
-+ if (ret)
-+ return ret;
-+
-+ if ((phydev->autoneg == AUTONEG_ENABLE) &&
-+ !priv->parallel_detect) {
-+ if (!(mmd_mask & MDIO_DEVS_AN))
-+ return -EINVAL;
-+
-+ if (!amd_xgbe_phy_aneg_done(phydev))
-+ return 0;
-+
-+ /* Compare Advertisement and Link Partner register 1 */
-+ ad_ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
-+ if (ad_ret < 0)
-+ return ad_ret;
-+ lp_ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA);
-+ if (lp_ret < 0)
-+ return lp_ret;
-+
-+ ad_ret &= lp_ret;
-+ phydev->pause = (ad_ret & 0x400) ? 1 : 0;
-+ phydev->asym_pause = (ad_ret & 0x800) ? 1 : 0;
-+
-+ /* Compare Advertisement and Link Partner register 2 */
-+ ad_ret = phy_read_mmd(phydev, MDIO_MMD_AN,
-+ MDIO_AN_ADVERTISE + 1);
-+ if (ad_ret < 0)
-+ return ad_ret;
-+ lp_ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA + 1);
-+ if (lp_ret < 0)
-+ return lp_ret;
-+
-+ ad_ret &= lp_ret;
-+ if (ad_ret & 0x80) {
-+ phydev->speed = SPEED_10000;
-+ ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KR);
-+ if (ret)
-+ return ret;
-+ } else {
-+ switch (priv->speed_set) {
-+ case AMD_XGBE_PHY_SPEEDSET_1000_10000:
-+ phydev->speed = SPEED_1000;
-+ break;
-+
-+ case AMD_XGBE_PHY_SPEEDSET_2500_10000:
-+ phydev->speed = SPEED_2500;
-+ break;
-+ }
-+
-+ ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ phydev->duplex = DUPLEX_FULL;
-+ } else {
-+ if (amd_xgbe_phy_in_kr_mode(phydev)) {
-+ phydev->speed = SPEED_10000;
-+ } else {
-+ switch (priv->speed_set) {
-+ case AMD_XGBE_PHY_SPEEDSET_1000_10000:
-+ phydev->speed = SPEED_1000;
-+ break;
-+
-+ case AMD_XGBE_PHY_SPEEDSET_2500_10000:
-+ phydev->speed = SPEED_2500;
-+ break;
-+ }
-+ }
-+ phydev->duplex = DUPLEX_FULL;
-+ phydev->pause = 0;
-+ phydev->asym_pause = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+static int amd_xgbe_phy_suspend(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ int ret;
-+
-+ mutex_lock(&phydev->lock);
-+
-+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
-+ if (ret < 0)
-+ goto unlock;
-+
-+ priv->lpm_ctrl = ret;
-+
-+ ret |= MDIO_CTRL1_LPOWER;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, ret);
-+
-+ ret = 0;
-+
-+unlock:
-+ mutex_unlock(&phydev->lock);
-+
-+ return ret;
-+}
-+
-+static int amd_xgbe_phy_resume(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+
-+ mutex_lock(&phydev->lock);
-+
-+ priv->lpm_ctrl &= ~MDIO_CTRL1_LPOWER;
-+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, priv->lpm_ctrl);
-+
-+ mutex_unlock(&phydev->lock);
-+
-+ return 0;
-+}
-+
-+static unsigned int amd_xgbe_phy_resource_count(struct platform_device *pdev,
-+ unsigned int type)
-+{
-+ unsigned int count;
-+ int i;
-+
-+ for (i = 0, count = 0; i < pdev->num_resources; i++) {
-+ struct resource *r = &pdev->resource[i];
-+
-+ if (type == resource_type(r))
-+ count++;
-+ }
-+
-+ return count;
-+}
-+
-+static int amd_xgbe_phy_probe(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv;
-+ struct platform_device *phy_pdev;
-+ struct device *dev, *phy_dev;
-+ unsigned int phy_resnum, phy_irqnum;
-+ int ret;
-+
-+ if (!phydev->bus || !phydev->bus->parent)
-+ return -EINVAL;
-+
-+ dev = phydev->bus->parent;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->pdev = to_platform_device(dev);
-+ priv->adev = ACPI_COMPANION(dev);
-+ priv->dev = dev;
-+ priv->phydev = phydev;
-+ mutex_init(&priv->an_mutex);
-+ INIT_WORK(&priv->an_irq_work, amd_xgbe_an_irq_work);
-+ INIT_WORK(&priv->an_work, amd_xgbe_an_state_machine);
-+
-+ if (!priv->adev || acpi_disabled) {
-+ struct device_node *bus_node;
-+ struct device_node *phy_node;
-+
-+ bus_node = priv->dev->of_node;
-+ phy_node = of_parse_phandle(bus_node, "phy-handle", 0);
-+ if (!phy_node) {
-+ dev_err(dev, "unable to parse phy-handle\n");
-+ ret = -EINVAL;
-+ goto err_priv;
-+ }
-+
-+ phy_pdev = of_find_device_by_node(phy_node);
-+ of_node_put(phy_node);
-+
-+ if (!phy_pdev) {
-+ dev_err(dev, "unable to obtain phy device\n");
-+ ret = -EINVAL;
-+ goto err_priv;
-+ }
-+
-+ phy_resnum = 0;
-+ phy_irqnum = 0;
-+ } else {
-+ /* In ACPI, the XGBE and PHY resources are the grouped
-+ * together with the PHY resources at the end
-+ */
-+ phy_pdev = priv->pdev;
-+ phy_resnum = amd_xgbe_phy_resource_count(phy_pdev,
-+ IORESOURCE_MEM) - 2;
-+ phy_irqnum = amd_xgbe_phy_resource_count(phy_pdev,
-+ IORESOURCE_IRQ) - 1;
-+ }
-+ phy_dev = &phy_pdev->dev;
-+
-+ /* Get the device mmio areas */
-+ priv->rxtx_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
-+ phy_resnum++);
-+ priv->rxtx_regs = devm_ioremap_resource(dev, priv->rxtx_res);
-+ if (IS_ERR(priv->rxtx_regs)) {
-+ dev_err(dev, "rxtx ioremap failed\n");
-+ ret = PTR_ERR(priv->rxtx_regs);
-+ goto err_put;
-+ }
-+
-+ /* All xgbe phy devices share the CMU registers so retrieve
-+ * the resource and do the ioremap directly rather than
-+ * the devm_ioremap_resource call
-+ */
-+ priv->cmu_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
-+ phy_resnum++);
-+ if (!priv->cmu_res) {
-+ dev_err(dev, "cmu invalid resource\n");
-+ ret = -EINVAL;
-+ goto err_rxtx;
-+ }
-+ priv->cmu_regs = devm_ioremap_nocache(dev, priv->cmu_res->start,
-+ resource_size(priv->cmu_res));
-+ if (!priv->cmu_regs) {
-+ dev_err(dev, "cmu ioremap failed\n");
-+ ret = -ENOMEM;
-+ goto err_rxtx;
-+ }
-+
-+ /* Get the auto-negotiation interrupt */
-+ ret = platform_get_irq(phy_pdev, phy_irqnum);
-+ if (ret < 0) {
-+ dev_err(dev, "platform_get_irq failed\n");
-+ goto err_cmu;
-+ }
-+ if (priv->adev && !acpi_disabled && !phy_irqnum) {
-+ struct irq_data *d = irq_get_irq_data(ret);
-+ if (!d) {
-+ dev_err(dev, "unable to set AN interrupt\n");
-+ ret = -EINVAL;
-+ goto err_cmu;
-+ }
-+
-+#ifdef CONFIG_ACPI
-+ ret = acpi_register_gsi(dev, d->hwirq - 2,
-+ ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
-+#else
-+ ret = -EINVAL;
-+#endif
-+ if (ret < 0) {
-+ dev_err(dev, "unable to set AN interrupt\n");
-+ goto err_cmu;
-+ }
-+ }
-+ priv->an_irq = ret;
-+
-+ /* Get the device serdes channel property */
-+ ret = device_property_read_u32(phy_dev, XGBE_PHY_CHANNEL_PROPERTY,
-+ &priv->serdes_channel);
-+ if (ret) {
-+ dev_err(dev, "invalid %s property\n",
-+ XGBE_PHY_CHANNEL_PROPERTY);
-+ goto err_cmu;
-+ }
-+
-+ /* Get the device speed set property */
-+ ret = device_property_read_u32(phy_dev, XGBE_PHY_SPEEDSET_PROPERTY,
-+ &priv->speed_set);
-+ if (ret) {
-+ dev_err(dev, "invalid %s property\n",
-+ XGBE_PHY_SPEEDSET_PROPERTY);
-+ goto err_cmu;
-+ }
-+
-+ switch (priv->speed_set) {
-+ case AMD_XGBE_PHY_SPEEDSET_1000_10000:
-+ case AMD_XGBE_PHY_SPEEDSET_2500_10000:
-+ break;
-+ default:
-+ dev_err(dev, "invalid %s property\n",
-+ XGBE_PHY_SPEEDSET_PROPERTY);
-+ ret = -EINVAL;
-+ goto err_cmu;
-+ }
-+
-+ if (device_property_present(phy_dev, XGBE_PHY_BLWC_PROPERTY)) {
-+ ret = device_property_read_u32_array(phy_dev,
-+ XGBE_PHY_BLWC_PROPERTY,
-+ priv->serdes_blwc,
-+ XGBE_PHY_SPEEDS);
-+ if (ret) {
-+ dev_err(dev, "invalid %s property\n",
-+ XGBE_PHY_BLWC_PROPERTY);
-+ goto err_cmu;
-+ }
-+ } else {
-+ memcpy(priv->serdes_blwc, amd_xgbe_phy_serdes_blwc,
-+ sizeof(priv->serdes_blwc));
-+ }
-+
-+ if (device_property_present(phy_dev, XGBE_PHY_CDR_RATE_PROPERTY)) {
-+ ret = device_property_read_u32_array(phy_dev,
-+ XGBE_PHY_CDR_RATE_PROPERTY,
-+ priv->serdes_cdr_rate,
-+ XGBE_PHY_SPEEDS);
-+ if (ret) {
-+ dev_err(dev, "invalid %s property\n",
-+ XGBE_PHY_CDR_RATE_PROPERTY);
-+ goto err_cmu;
-+ }
-+ } else {
-+ memcpy(priv->serdes_cdr_rate, amd_xgbe_phy_serdes_cdr_rate,
-+ sizeof(priv->serdes_cdr_rate));
-+ }
-+
-+ if (device_property_present(phy_dev, XGBE_PHY_PQ_SKEW_PROPERTY)) {
-+ ret = device_property_read_u32_array(phy_dev,
-+ XGBE_PHY_PQ_SKEW_PROPERTY,
-+ priv->serdes_pq_skew,
-+ XGBE_PHY_SPEEDS);
-+ if (ret) {
-+ dev_err(dev, "invalid %s property\n",
-+ XGBE_PHY_PQ_SKEW_PROPERTY);
-+ goto err_cmu;
-+ }
-+ } else {
-+ memcpy(priv->serdes_pq_skew, amd_xgbe_phy_serdes_pq_skew,
-+ sizeof(priv->serdes_pq_skew));
-+ }
-+
-+ if (device_property_present(phy_dev, XGBE_PHY_TX_AMP_PROPERTY)) {
-+ ret = device_property_read_u32_array(phy_dev,
-+ XGBE_PHY_TX_AMP_PROPERTY,
-+ priv->serdes_tx_amp,
-+ XGBE_PHY_SPEEDS);
-+ if (ret) {
-+ dev_err(dev, "invalid %s property\n",
-+ XGBE_PHY_TX_AMP_PROPERTY);
-+ goto err_cmu;
-+ }
-+ } else {
-+ memcpy(priv->serdes_tx_amp, amd_xgbe_phy_serdes_tx_amp,
-+ sizeof(priv->serdes_tx_amp));
-+ }
-+
-+ priv->link = 1;
-+
-+ phydev->priv = priv;
-+
-+ if (!priv->adev || acpi_disabled)
-+ platform_device_put(phy_pdev);
-+
-+ return 0;
-+
-+err_cmu:
-+ devm_iounmap(dev, priv->cmu_regs);
-+
-+err_rxtx:
-+ devm_iounmap(dev, priv->rxtx_regs);
-+ devm_release_mem_region(dev, priv->rxtx_res->start,
-+ resource_size(priv->rxtx_res));
-+
-+err_put:
-+ if (!priv->adev || acpi_disabled)
-+ platform_device_put(phy_pdev);
-+
-+err_priv:
-+ devm_kfree(dev, priv);
-+
-+ return ret;
-+}
-+
-+static void amd_xgbe_phy_remove(struct phy_device *phydev)
-+{
-+ struct amd_xgbe_phy_priv *priv = phydev->priv;
-+ struct device *dev = priv->dev;
-+
-+ if (priv->an_irq_allocated) {
-+ devm_free_irq(dev, priv->an_irq, priv);
-+
-+ flush_workqueue(priv->an_workqueue);
-+ destroy_workqueue(priv->an_workqueue);
-+ }
-+
-+ devm_iounmap(dev, priv->cmu_regs);
-+
-+ devm_iounmap(dev, priv->rxtx_regs);
-+ devm_release_mem_region(dev, priv->rxtx_res->start,
-+ resource_size(priv->rxtx_res));
-+
-+ devm_kfree(dev, priv);
-+}
-+
-+static int amd_xgbe_match_phy_device(struct phy_device *phydev)
-+{
-+ return phydev->c45_ids.device_ids[MDIO_MMD_PCS] == XGBE_PHY_ID;
-+}
-+
-+static struct phy_driver amd_xgbe_phy_a0_driver[] = {
-+ {
-+ .phy_id = XGBE_PHY_ID,
-+ .phy_id_mask = XGBE_PHY_MASK,
-+ .name = "AMD XGBE PHY A0",
-+ .features = 0,
-+ .probe = amd_xgbe_phy_probe,
-+ .remove = amd_xgbe_phy_remove,
-+ .soft_reset = amd_xgbe_phy_soft_reset,
-+ .config_init = amd_xgbe_phy_config_init,
-+ .suspend = amd_xgbe_phy_suspend,
-+ .resume = amd_xgbe_phy_resume,
-+ .config_aneg = amd_xgbe_phy_config_aneg,
-+ .aneg_done = amd_xgbe_phy_aneg_done,
-+ .read_status = amd_xgbe_phy_read_status,
-+ .match_phy_device = amd_xgbe_match_phy_device,
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+module_phy_driver(amd_xgbe_phy_a0_driver);
-+
-+static struct mdio_device_id __maybe_unused amd_xgbe_phy_a0_ids[] = {
-+ { XGBE_PHY_ID, XGBE_PHY_MASK },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(mdio, amd_xgbe_phy_a0_ids);
---
-2.4.5
-
diff --git a/arm64-avoid-needing-console-to-enable-serial-console.patch b/arm64-avoid-needing-console-to-enable-serial-console.patch
index 47d09c2a7..e8cc7bbe0 100644
--- a/arm64-avoid-needing-console-to-enable-serial-console.patch
+++ b/arm64-avoid-needing-console-to-enable-serial-console.patch
@@ -1,3 +1,4 @@
+From ede02df9a481ba07348e6fd4393ba2e273ef16d8 Mon Sep 17 00:00:00 2001
From: Mark Salter <msalter@redhat.com>
Date: Wed, 25 Mar 2015 14:17:50 -0400
Subject: [PATCH] arm64: avoid needing console= to enable serial console
@@ -14,13 +15,13 @@ Signed-off-by: Mark Salter <msalter@redhat.com>
1 file changed, 19 insertions(+)
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
-index f3067d4d4e35..6f8d814c4e5c 100644
+index 8119479..ea9ff80 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
-@@ -568,3 +568,22 @@ const struct seq_operations cpuinfo_op = {
- .stop = c_stop,
- .show = c_show
- };
+@@ -381,3 +381,22 @@ static int __init topology_init(void)
+ return 0;
+ }
+ subsys_initcall(topology_init);
+
+/*
+ * Temporary hack to avoid need for console= on command line
@@ -40,3 +41,6 @@ index f3067d4d4e35..6f8d814c4e5c 100644
+ return 0;
+}
+early_initcall(arm64_console_setup);
+--
+2.5.0
+
diff --git a/btrfs-handle-invalid-num_stripes-in-sys_array.patch b/btrfs-handle-invalid-num_stripes-in-sys_array.patch
deleted file mode 100644
index 20bf403bc..000000000
--- a/btrfs-handle-invalid-num_stripes-in-sys_array.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From 43d10880aa4ac713cf73dbac428be9671ef1bf9d Mon Sep 17 00:00:00 2001
-From: David Sterba <dsterba@suse.com>
-Date: Mon, 30 Nov 2015 17:27:06 +0100
-Subject: [PATCH 1/2] btrfs: handle invalid num_stripes in sys_array
-
-We can handle the special case of num_stripes == 0 directly inside
-btrfs_read_sys_array. The BUG_ON in btrfs_chunk_item_size is there to
-catch other unhandled cases where we fail to validate external data.
-
-A crafted or corrupted image crashes at mount time:
-
-BTRFS: device fsid 9006933e-2a9a-44f0-917f-514252aeec2c devid 1 transid 7 /dev/loop0
-BTRFS info (device loop0): disk space caching is enabled
-BUG: failure at fs/btrfs/ctree.h:337/btrfs_chunk_item_size()!
-Kernel panic - not syncing: BUG!
-CPU: 0 PID: 313 Comm: mount Not tainted 4.2.5-00657-ge047887-dirty #25
-Stack:
- 637af890 60062489 602aeb2e 604192ba
- 60387961 00000011 637af8a0 6038a835
- 637af9c0 6038776b 634ef32b 00000000
-Call Trace:
- [<6001c86d>] show_stack+0xfe/0x15b
- [<6038a835>] dump_stack+0x2a/0x2c
- [<6038776b>] panic+0x13e/0x2b3
- [<6020f099>] btrfs_read_sys_array+0x25d/0x2ff
- [<601cfbbe>] open_ctree+0x192d/0x27af
- [<6019c2c1>] btrfs_mount+0x8f5/0xb9a
- [<600bc9a7>] mount_fs+0x11/0xf3
- [<600d5167>] vfs_kern_mount+0x75/0x11a
- [<6019bcb0>] btrfs_mount+0x2e4/0xb9a
- [<600bc9a7>] mount_fs+0x11/0xf3
- [<600d5167>] vfs_kern_mount+0x75/0x11a
- [<600d710b>] do_mount+0xa35/0xbc9
- [<600d7557>] SyS_mount+0x95/0xc8
- [<6001e884>] handle_syscall+0x6b/0x8e
-
-Reported-by: Jiri Slaby <jslaby@suse.com>
-Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
-CC: stable@vger.kernel.org # 3.19+
-Signed-off-by: David Sterba <dsterba@suse.com>
----
- fs/btrfs/volumes.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
-index 6fc735869c18..b816b3a2e118 100644
---- a/fs/btrfs/volumes.c
-+++ b/fs/btrfs/volumes.c
-@@ -6399,6 +6399,14 @@ int btrfs_read_sys_array(struct btrfs_root *root)
- goto out_short_read;
-
- num_stripes = btrfs_chunk_num_stripes(sb, chunk);
-+ if (!num_stripes) {
-+ printk(KERN_ERR
-+ "BTRFS: invalid number of stripes %u in sys_array at offset %u\n",
-+ num_stripes, cur_offset);
-+ ret = -EIO;
-+ break;
-+ }
-+
- len = btrfs_chunk_item_size(num_stripes);
- if (cur_offset + len > array_size)
- goto out_short_read;
---
-2.5.0
-
diff --git a/config-arm-generic b/config-arm-generic
index c8984594e..399bfaf23 100644
--- a/config-arm-generic
+++ b/config-arm-generic
@@ -7,8 +7,8 @@ CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST=y
CONFIG_FB_SSD1307=m
CONFIG_HW_PERF_EVENTS=y
CONFIG_NFS_FS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
-CONFIG_CRASH=m
CONFIG_CC_STACKPROTECTOR=y
# CONFIG_PID_IN_CONTEXTIDR is not set
@@ -94,6 +94,35 @@ CONFIG_CLKSRC_VERSATILE=y
CONFIG_POWER_RESET_VERSATILE=y
# CONFIG_ARM_CHARLCD is not set
+# Rockchips
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_I2C_RK3X=m
+CONFIG_SPI_ROCKCHIP=m
+CONFIG_PWM_ROCKCHIP=m
+CONFIG_ROCKCHIP_SARADC=m
+CONFIG_ROCKCHIP_IODOMAIN=m
+CONFIG_MMC_DW_ROCKCHIP=m
+CONFIG_EMAC_ROCKCHIP=m
+CONFIG_MFD_RK808=m
+CONFIG_COMMON_CLK_RK808=m
+CONFIG_REGULATOR_RK808=m
+CONFIG_RTC_DRV_RK808=m
+CONFIG_RTC_DRV_HYM8563=m
+CONFIG_ROCKCHIP_SARADC=m
+CONFIG_ROCKCHIP_IOMMU=y
+CONFIG_ROCKCHIP_THERMAL=m
+CONFIG_DRM_ROCKCHIP=m
+CONFIG_ROCKCHIP_DW_HDMI=m
+CONFIG_PHY_ROCKCHIP_USB=m
+CONFIG_DWMAC_ROCKCHIP=m
+CONFIG_SND_SOC_ROCKCHIP=m
+CONFIG_SND_SOC_ROCKCHIP_I2S=m
+CONFIG_SND_SOC_ROCKCHIP_MAX98090=m
+CONFIG_SND_SOC_ROCKCHIP_RT5645=m
+CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
+CONFIG_REGULATOR_ACT8865=m
+CONFIG_ROCKCHIP_PM_DOMAINS=y
+
# Tegra
# CONFIG_TEGRA_AHB is not set
@@ -136,6 +165,7 @@ CONFIG_THERMAL_OF=y
CONFIG_MAILBOX=y
CONFIG_ARM_MHU=m
# CONFIG_PL320_MBOX is not set
+CONFIG_ARM_SCPI_PROTOCOL=m
# USB
CONFIG_USB_OHCI_HCD_PLATFORM=m
@@ -144,6 +174,7 @@ CONFIG_USB_XHCI_PLATFORM=m
# MMC/SD
CONFIG_MMC_SPI=m
+CONFIG_MMC_SDHCI_OF_ARASAN=m
# Designware (used by numerous devices)
CONFIG_MMC_DW=m
@@ -170,6 +201,9 @@ CONFIG_USB_DWC3_ULPI=y
CONFIG_DW_WATCHDOG=m
CONFIG_PCIE_DW=y
# CONFIG_MMC_DW_EXYNOS is not set
+CONFIG_I2C_DESIGNWARE_CORE=m
+CONFIG_I2C_DESIGNWARE_PLATFORM=m
+CONFIG_GPIO_DWAPB=m
# External Connectors
CONFIG_EXTCON=m
@@ -210,6 +244,13 @@ CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_RESTART=y
# CONFIG_GPIO_74XX_MMIO is not set
+# Pin stuff
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_PINCTRL_SINGLE=m
+
#i2c
CONFIG_I2C_ARB_GPIO_CHALLENGE=m
CONFIG_I2C_BOARDINFO=y
@@ -227,6 +268,7 @@ CONFIG_SPI_PL022=m
# Sensors
CONFIG_SENSORS_IIO_HWMON=m
CONFIG_IIO_SYSFS_TRIGGER=m
+CONFIG_SENSORS_ARM_SCPI=m
# PHY framework
CONFIG_GENERIC_PHY=y
@@ -279,6 +321,7 @@ CONFIG_VFIO_AMBA=m
# CONFIG_COMMON_CLK_SI570 is not set
# CONFIG_COMMON_CLK_QCOM is not set
+CONFIG_COMMON_CLK_SCPI=m
# CONFIG_ARM_PTDUMP is not set
@@ -305,6 +348,7 @@ CONFIG_VFIO_AMBA=m
# netdrv
+CONFIG_NET_VENDOR_MELLANOX=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_ADAPTEC is not set
# CONFIG_NET_VENDOR_BROADCOM is not set
@@ -314,7 +358,6 @@ CONFIG_VFIO_AMBA=m
# CONFIG_NET_VENDOR_DEC is not set
# CONFIG_NET_VENDOR_EMULEX is not set
# CONFIG_NET_VENDOR_EXAR is not set
-# CONFIG_NET_VENDOR_MELLANOX is not set
# CONFIG_NET_VENDOR_QLOGIC is not set
# CONFIG_NET_VENDOR_SUN is not set
# CONFIG_NET_VENDOR_WIZNET is not set
@@ -352,11 +395,15 @@ CONFIG_VFIO_AMBA=m
# CONFIG_DEBUG_SET_MODULE_RONX is not set
# CONFIG_CORESIGHT is not set
-
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_BMP085_SPI is not set
# CONFIG_TI_DAC7512 is not set
-# CONFIG_SPI_ROCKCHIP is not set
# https://fedoraproject.org/wiki/Features/Checkpoint_Restore
CONFIG_CHECKPOINT_RESTORE=y
+
+# Bad Intel shit we don't care about
+# CONFIG_PINCTRL_BAYTRAIL is not set
+# CONFIG_PINCTRL_CHERRYVIEW is not set
+# CONFIG_PINCTRL_BROXTON is not set
+# CONFIG_PINCTRL_SUNRISEPOINT is not set
diff --git a/config-arm64 b/config-arm64
index 31f4d51c6..d2a723230 100644
--- a/config-arm64
+++ b/config-arm64
@@ -10,18 +10,18 @@ CONFIG_SCHED_SMT=y
CONFIG_ARCH_HISI=y
CONFIG_ARCH_SEATTLE=y
CONFIG_ARCH_XGENE=y
-# CONFIG_ARCH_THUNDER is not set
+# CONFIG_ARCH_BCM_IPROC is not set
+# CONFIG_ARCH_BERLIN is not set
# CONFIG_ARCH_EXYNOS7 is not set
# CONFIG_ARCH_FSL_LS2085A is not set
+# CONFIG_ARCH_LAYERSCAPE is not set
# CONFIG_ARCH_MEDIATEK is not set
-# CONFIG_ARCH_TEGRA is not set
# CONFIG_ARCH_QCOM is not set
# CONFIG_ARCH_SPRD is not set
+# CONFIG_ARCH_STRATIX10 is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_THUNDER is not set
# CONFIG_ARCH_ZYNQMP is not set
-# CONFIG_ARCH_BCM_IPROC is not set
-# CONFIG_ARCH_BERLIN is not set
-# CONFIG_ARCH_ROCKCHIP is not set
-
# Erratum
CONFIG_ARM64_ERRATUM_826319=y
@@ -29,8 +29,10 @@ CONFIG_ARM64_ERRATUM_827319=y
CONFIG_ARM64_ERRATUM_824069=y
CONFIG_ARM64_ERRATUM_819472=y
CONFIG_ARM64_ERRATUM_832075=y
-CONFIG_ARM64_ERRATUM_834220=y
CONFIG_ARM64_ERRATUM_843419=y
+CONFIG_ARM64_ERRATUM_834220=y
+CONFIG_CAVIUM_ERRATUM_22375=y
+CONFIG_CAVIUM_ERRATUM_23154=y
# AMBA / VExpress
# CONFIG_RTC_DRV_PL030 is not set
@@ -57,17 +59,17 @@ CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_HAVE_64BIT_ALIGNED_ACCESS=y
CONFIG_HVC_DRIVER=y
+# CONFIG_HVC_DCC is not set
CONFIG_HZ=100
CONFIG_KVM=y
-CONFIG_KVM_ARM_MAX_VCPUS=8
+CONFIG_KVM_ARM_MAX_VCPUS=16
CONFIG_RCU_FANOUT=64
CONFIG_SPARSE_IRQ=y
CONFIG_SPARSEMEM_VMEMMAP=y
# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_THERMAL is not set
CONFIG_EFI=y
CONFIG_EFI_VARS=y
@@ -89,6 +91,11 @@ CONFIG_ACPI_CUSTOM_METHOD=m
CONFIG_ACPI_NFIT=m
# CONFIG_ACPI_NFIT_DEBUG is not set
CONFIG_PCC=y
+CONFIG_ACPI_CPPC_CPUFREQ=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_I2C_SCMI=m
+CONFIG_SENSORS_ACPI_POWER=m
CONFIG_ARM64_CRYPTO=y
CONFIG_CRYPTO_SHA1_ARM64_CE=y
@@ -106,7 +113,6 @@ CONFIG_CRYPTO_DEV_CCP_CRYPTO=m
# APM Xgene
CONFIG_POWER_RESET_XGENE=y
CONFIG_COMMON_CLK_XGENE=y
-
CONFIG_AHCI_XGENE=y
CONFIG_PHY_XGENE=y
CONFIG_NET_XGENE=y
@@ -116,6 +122,9 @@ CONFIG_GPIO_XGENE=y
CONFIG_GPIO_XGENE_SB=m
CONFIG_XGENE_DMA=m
CONFIG_EDAC_XGENE=m
+CONFIG_PCI_XGENE=y
+CONFIG_PCI_XGENE_MSI=y
+CONFIG_I2C_XGENE_SLIMPRO=m
# busted build for various reasons
# uses pci_* for some reason to allocate DMA buffers
@@ -126,36 +135,29 @@ CONFIG_EDAC_XGENE=m
# CONFIG_PARPORT_PC is not set
# CONFIG_VGA_CONSOLE is not set
-CONFIG_PCI_XGENE=y
-CONFIG_PCI_XGENE_MSI=y
# CONFIG_HOTPLUG_PCI_SHPC is not set
# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set
# CONFIG_PNP_DEBUG_MESSAGES is not set
-CONFIG_I2C_SCMI=m
-CONFIG_I2C_XGENE_SLIMPRO=m
-CONFIG_SENSORS_ACPI_POWER=m
# AMD Seattle
CONFIG_NET_SB1000=y
CONFIG_AMD_XGBE=m
CONFIG_AMD_XGBE_PHY=m
# CONFIG_AMD_XGBE_DCB is not set
+# CONFIG_VFIO_PLATFORM_AMDXGBE_RESET is not set
+CONFIG_PINCTRL_AMD=y
# HiSilicon
CONFIG_POWER_RESET_HISI=y
CONFIG_HISI_THERMAL=m
CONFIG_STUB_CLK_HI6220=y
+CONFIG_PCI_HISI=y
# ThunderX
# CONFIG_MDIO_OCTEON is not set
-CONFIG_NET_VENDOR_MELLANOX=y
-CONFIG_MLX4_EN=m
-CONFIG_MLX4_EN_DCB=y
-CONFIG_MLX4_EN_VXLAN=y
-
# CONFIG_IMX_THERMAL is not set
CONFIG_DMI=y
diff --git a/config-armv7 b/config-armv7
index 7c81e1d70..eaa6d4ebf 100644
--- a/config-armv7
+++ b/config-armv7
@@ -5,7 +5,6 @@
CONFIG_ARCH_MXC=y
CONFIG_ARCH_OMAP3=y
CONFIG_ARCH_OMAP4=y
-CONFIG_ARCH_PICOXCELL=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_TEGRA=y
CONFIG_ARCH_U8500=y
@@ -22,7 +21,7 @@ CONFIG_ARCH_OMAP2PLUS_TYPICAL=y
CONFIG_SOC_OMAP5=y
# CONFIG_SOC_DRA7XX is not set
CONFIG_SOC_OMAP3430=y
-CONFIG_SOC_TI81XX=y
+# CONFIG_SOC_TI81XX is not set
# CONFIG_MACH_NOKIA_RX51 is not set
# CONFIG_MACH_OMAP_LDP is not set
# CONFIG_MACH_OMAP3517EVM is not set
@@ -63,9 +62,9 @@ CONFIG_TWL4030_MADC=m
CONFIG_TWL4030_POWER=y
CONFIG_TWL4030_WATCHDOG=m
CONFIG_BATTERY_TWL4030_MADC=m
-CONFIG_BATTERY_BQ27x00=m
-CONFIG_BATTERY_BQ27X00_I2C=y
-CONFIG_BATTERY_BQ27X00_PLATFORM=y
+CONFIG_BATTERY_BQ27XXX=m
+CONFIG_BATTERY_BQ27XXX_I2C=y
+CONFIG_BATTERY_BQ27XXX_PLATFORM=y
CONFIG_OMAP_USB2=m
CONFIG_OMAP_CONTROL_PHY=m
CONFIG_TI_PIPE3=m
@@ -84,9 +83,9 @@ CONFIG_USB_EHCI_HCD_OMAP=m
CONFIG_USB_OHCI_HCD_OMAP3=m
CONFIG_USB_MUSB_AM35X=m
CONFIG_USB_MUSB_OMAP2PLUS=m
+CONFIG_USB_INVENTRA_DMA=y
CONFIG_USB_DWC3_OMAP=m
CONFIG_MMC_OMAP=m
-CONFIG_MMC_OMAP_HS=m
CONFIG_RTC_DRV_MAX8907=m
# CONFIG_RTC_DRV_TWL92330 is not set
CONFIG_RTC_DRV_TWL4030=y
@@ -240,8 +239,6 @@ CONFIG_TI_CPSW=m
CONFIG_TI_CPSW_PHY_SEL=y
CONFIG_TI_CPSW_ALE=m
CONFIG_TI_CPTS=y
-# Builtin needed for BBone White
-CONFIG_REGULATOR_TPS65217=y
CONFIG_TI_EMIF=m
CONFIG_DRM_TILCDC=m
# We only need this until the BBB dts is actually updated
@@ -265,6 +262,13 @@ CONFIG_VIDEO_AM437X_VPFE=m
CONFIG_UIO_PRUSS=m
CONFIG_WKUP_M3_RPROC=m
+# Builtin needed for BBone White
+CONFIG_MFD_TPS65217=y
+CONFIG_REGULATOR_TPS65217=y
+CONFOG_CHARGER_TPS65217=m
+CONFIG_BACKLIGHT_TPS65217=m
+CONFIG_REGULATOR_TPS65217=m
+
CONFIG_CAN_C_CAN=m
CONFIG_CAN_C_CAN_PLATFORM=m
@@ -351,6 +355,7 @@ CONFIG_REGULATOR_QCOM_SMD_RPM=m
CONFIG_SOC_IMX50=y
CONFIG_SOC_IMX51=y
CONFIG_SOC_IMX53=y
+CONFIG_SOC_IMX6=y
CONFIG_SOC_IMX6Q=y
CONFIG_SOC_IMX6SL=y
CONFIG_SOC_IMX6SX=y
@@ -408,6 +413,7 @@ CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=m
CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=m
CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=m
# CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG is not set
+# CONFIG_CRYPTO_DEV_MXS_DCP is not set
CONFIG_RTC_DRV_SNVS=m
CONFIG_FB_MXS=m
# CONFIG_FB_MX3 is not set
@@ -546,17 +552,6 @@ CONFIG_SENSORS_AB8500=m
CONFIG_STE_MODEM_RPROC=m
CONFIG_STIH415_RESET=y
-CONFIG_IIO_ST_GYRO_I2C_3AXIS=m
-CONFIG_IIO_ST_GYRO_SPI_3AXIS=m
-CONFIG_IIO_ST_MAGN_I2C_3AXIS=m
-CONFIG_IIO_ST_MAGN_SPI_3AXIS=m
-CONFIG_IIO_ST_PRESS=m
-CONFIG_IIO_ST_PRESS_I2C=m
-CONFIG_IIO_ST_PRESS_SPI=m
-CONFIG_IIO_ST_SENSORS_I2C=m
-CONFIG_IIO_ST_SENSORS_SPI=m
-CONFIG_IIO_ST_SENSORS_CORE=m
-
# Allwinner
CONFIG_MACH_SUN4I=y
CONFIG_MACH_SUN5I=y
@@ -609,7 +604,6 @@ CONFIG_GPIO_ZYNQ=m
CONFIG_I2C_XILINX=m
CONFIG_SPI_XILINX=m
CONFIG_SPI_CADENCE=m
-CONFIG_MMC_SDHCI_OF_ARASAN=m
CONFIG_I2C_CADENCE=m
CONFIG_XILINX_WATCHDOG=m
CONFIG_XILINX_XADC=m
diff --git a/config-armv7-generic b/config-armv7-generic
index 1fcaa9662..285b4dca0 100644
--- a/config-armv7-generic
+++ b/config-armv7-generic
@@ -50,7 +50,6 @@ CONFIG_CPU_SW_DOMAIN_PAN=y
# Platforms enabled/disabled globally on ARMv7
CONFIG_ARCH_EXYNOS=y
CONFIG_ARCH_HIGHBANK=y
-CONFIG_ARCH_ROCKCHIP=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_TEGRA=y
CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
@@ -76,6 +75,7 @@ CONFIG_ARCH_VIRT=y
# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_UNIPHIER is not set
# CONFIG_ARCH_ZX is not set
+# CONFIG_SOC_BRCMSTB is not set
# errata
# v5/v6
@@ -126,6 +126,7 @@ CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARM_PSCI=y
CONFIG_THERMAL=y
CONFIG_CLOCK_THERMAL=y
+# CONFIG_DEVFREQ_THERMAL is not set
CONFIG_CPUFREQ_DT=m
# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set
CONFIG_PM_DEVFREQ=y
@@ -200,11 +201,12 @@ CONFIG_GPIO_PCA953X=m
CONFIG_GPIO_PCF857X=m
CONFIG_TOUCHSCREEN_SUN4I=m
CONFIG_MFD_AXP20X=y
+CONFIG_AXP20X_POWER=m
+CONFIG_INPUT_AXP20X_PEK=m
+CONFIG_REGULATOR_AXP20X=m
CONFIG_AXP288_FUEL_GAUGE=m
CONFIG_AXP288_ADC=m
CONFIG_EXTCON_AXP288=m
-CONFIG_INPUT_AXP20X_PEK=m
-CONFIG_REGULATOR_AXP20X=m
CONFIG_AXP288_CHARGER=m
CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=m
CONFIG_IR_SUNXI=m
@@ -218,6 +220,8 @@ CONFIG_KEYBOARD_SUN4I_LRADC=m
CONFIG_PWM_SUN4I=m
CONFIG_USB_MUSB_SUNXI=m
CONFIG_CRYPTO_DEV_SUN4I_SS=m
+CONFIG_SND_SUN4I_CODEC=m
+CONFIG_SUNXI_RSB=m
# Exynos
CONFIG_ARCH_EXYNOS3=y
@@ -287,6 +291,7 @@ CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_EXYNOS_IPP=y
CONFIG_DRM_EXYNOS_ROTATOR=y
CONFIG_DRM_EXYNOS_VIDI=y
+CONFIG_DRM_EXYNOS_MIXER=y
CONFIG_PHY_EXYNOS_DP_VIDEO=m
# CONFIG_FB_S3C is not set
CONFIG_PHY_EXYNOS_MIPI_VIDEO=m
@@ -329,34 +334,8 @@ CONFIG_LEDS_MAX8997=m
CONFIG_RTC_DRV_MAX8997=m
CONFIG_RTC_DRV_MAX77686=m
CONFIG_RTC_DRV_MAX77802=m
-CONFIG_RTC_DRV_RK808=m
CONFIG_EXTCON_MAX8997=m
-# Rockchips
-CONFIG_I2C_RK3X=m
-CONFIG_SPI_ROCKCHIP=m
-CONFIG_PWM_ROCKCHIP=m
-CONFIG_ROCKCHIP_SARADC=m
-CONFIG_ROCKCHIP_IODOMAIN=m
-CONFIG_MMC_DW_ROCKCHIP=m
-CONFIG_EMAC_ROCKCHIP=m
-CONFIG_MFD_RK808=m
-CONFIG_COMMON_CLK_RK808=m
-CONFIG_REGULATOR_RK808=m
-CONFIG_RTC_DRV_HYM8563=m
-CONFIG_ROCKCHIP_SARADC=m
-CONFIG_ROCKCHIP_IOMMU=y
-CONFIG_SND_SOC_ROCKCHIP=m
-CONFIG_SND_SOC_ROCKCHIP_I2S=m
-CONFIG_ROCKCHIP_THERMAL=m
-CONFIG_DRM_ROCKCHIP=m
-CONFIG_ROCKCHIP_DW_HDMI=m
-CONFIG_PHY_ROCKCHIP_USB=m
-CONFIG_DWMAC_ROCKCHIP=m
-CONFIG_SND_SOC_ROCKCHIP_MAX98090=m
-CONFIG_SND_SOC_ROCKCHIP_RT5645=m
-CONFIG_REGULATOR_ACT8865=m
-
# Tegra
CONFIG_ARCH_TEGRA_114_SOC=y
CONFIG_ARCH_TEGRA_124_SOC=y
@@ -410,6 +389,8 @@ CONFIG_RTC_DRV_AS3722=y
# TI Generic
CONFIG_TI_SOC_THERMAL=m
CONFIG_TI_THERMAL=y
+# CONFIG_OMAP3_THERMAL is not set
+CONFIG_MMC_OMAP_HS=m
# mvebu
CONFIG_ARCH_MVEBU=y
@@ -475,6 +456,7 @@ CONFIG_DRM_PANEL_LG_LG4573=m
CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
CONFIG_DRM_DW_HDMI=m
+# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set
# regmap
CONFIG_REGMAP_SPI=m
@@ -496,8 +478,7 @@ CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
CONFIG_USB_MUSB_HDRC=m
CONFIG_USB_MUSB_DUAL_ROLE=y
CONFIG_USB_MUSB_DSPS=m
-# Use PIO on musb as upstream doesn't support multiple DMA engines yet :-/
-CONFIG_MUSB_PIO_ONLY=y
+# CONFIG_MUSB_PIO_ONLY is not set
# CONFIG_USB_MUSB_TUSB6010 is not set
# CONFIG_USB_MUSB_UX500 is not set
CONFIG_USB_GPIO_VBUS=m
@@ -541,7 +522,6 @@ CONFIG_USB_CONFIGFS_SERIAL=y
# Multifunction Devices
CONFIG_MFD_TPS65090=y
-CONFIG_MFD_TPS65217=y
CONFIG_MFD_TPS65910=y
CONFIG_MFD_TPS65912=y
CONFIG_MFD_TPS65912_I2C=y
@@ -562,11 +542,6 @@ CONFIG_MFD_TPS65912_SPI=y
#
# Pin stuff
-CONFIG_PINMUX=y
-CONFIG_PINCONF=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_SINGLE=y
-CONFIG_GENERIC_PINCONF=y
# CONFIG_PINCTRL_AMD is not set
# CONFIG_PINCTRL_SAMSUNG is not set
# CONFIG_PINCTRL_MSM8X74 is not set
@@ -619,8 +594,6 @@ CONFIG_SPI_XCOMM=m
CONFIG_NFC_NCI_SPI=y
# i2c
-CONFIG_I2C_DESIGNWARE_CORE=m
-CONFIG_I2C_DESIGNWARE_PLATFORM=m
CONFIG_I2C_MV64XXX=m
# HW crypto and rng
@@ -668,9 +641,6 @@ CONFIG_SND_ARM=y
CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC_AC97_CODEC=y
-# Displays
-CONFIG_BACKLIGHT_TPS65217=m
-
# RTC
CONFIG_RTC_DRV_DS1305=m
CONFIG_RTC_DRV_DS1390=m
@@ -747,11 +717,11 @@ CONFIG_TMP006=m
CONFIG_BMP085=y
CONFIG_BMP085_I2C=m
CONFIG_BMP085_SPI=m
-CONFIG_DHT11=m
-CONFIG_MPL3115=m
+CONFIG_BMP280=m
CONFIG_SENSORS_AD7314=m
CONFIG_SENSORS_ADCXX=m
CONFIG_SENSORS_ADS7871=m
+CONFIG_SENSORS_BH1780=m
CONFIG_SENSORS_GPIO_FAN=m
CONFIG_SENSORS_HTU21=m
CONFIG_SENSORS_ISL29018=m
@@ -759,11 +729,12 @@ CONFIG_SENSORS_ISL29028=m
CONFIG_SENSORS_LIS3_SPI=m
CONFIG_SENSORS_LM70=m
CONFIG_SENSORS_MAX1111=m
+CONFIG_MPL115=m
CONFIG_MPL3115=m
+CONFIG_DHT11=m
CONFIG_SI7005=m
CONFIG_SI7020=m
-# LCD panels
CONFIG_LCD_L4F00242T03=m
CONFIG_LCD_LMS283GF05=m
CONFIG_LCD_LTV350QV=m
@@ -902,7 +873,6 @@ CONFIG_R8188EU=m
# CONFIG_SCSI_ACARD is not set
# CONFIG_SFC is not set
# CONFIG_SND_ALI5451 is not set
-# CONFIG_MLX4_EN is not set
# CONFIG_POWER_RESET_QNAP is not set
# CONFIG_MMC_TMIO is not set
# CONFIG_PINCTRL_IMX35 is not set
@@ -936,3 +906,8 @@ CONFIG_R8188EU=m
# CONFIG_CRYPTO_DEV_UX500_DEBUG is not set
# CONFIG_AB8500_DEBUG is not set
# CONFIG_ARM_KERNMEM_PERMS is not set
+
+# CONFIG_VFIO_PLATFORM_AMDXGBE_RESET is not set
+
+# Altera?
+# CONFIG_PCIE_ALTERA is not set
diff --git a/config-debug b/config-debug
index d57a218ea..d733183a2 100644
--- a/config-debug
+++ b/config-debug
@@ -31,7 +31,7 @@ CONFIG_LOCK_STAT=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_ACPI_DEBUG=y
-
+# CONFIG_ACPI_DEBUGGER is not set
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_PI_LIST=y
diff --git a/config-generic b/config-generic
index bc0e2970c..508543b4f 100644
--- a/config-generic
+++ b/config-generic
@@ -160,7 +160,7 @@ CONFIG_MMC_MTK=m
# CONFIG_MMC_SDHCI_OF_ARASAN is not set
# CONFIG_MMC_SDHCI_F_SDH30 is not set
# CONFIG_MMC_USDHI6ROL0 is not set
-
+# CONFIG_MMC_SDHCI_OF_ESDHC is not set
CONFIG_CB710_CORE=m
# CONFIG_CB710_DEBUG is not set
@@ -189,14 +189,12 @@ CONFIG_INFINIBAND_CXGB4=m
CONFIG_SCSI_CXGB3_ISCSI=m
CONFIG_SCSI_CXGB4_ISCSI=m
# CONFIG_INFINIBAND_CXGB3_DEBUG is not set
-CONFIG_MLX4_INFINIBAND=m
-CONFIG_MLX5_INFINIBAND=m
CONFIG_INFINIBAND_NES=m
# CONFIG_INFINIBAND_NES_DEBUG is not set
CONFIG_INFINIBAND_QIB=m
CONFIG_INFINIBAND_QIB_DCA=y
-# CONFIG_INFINIBAND_OCRDMA is not set
-# CONFIG_INFINIBAND_USNIC is not set
+CONFIG_INFINIBAND_OCRDMA=m
+CONFIG_INFINIBAND_USNIC=m
#
# Executable file formats
@@ -360,6 +358,8 @@ CONFIG_HOTPLUG_PCI_ACPI_IBM=m
# CONFIG_NVMEM is not set
+# CONFIG_FPGA is not set
+
#
# Block devices
#
@@ -585,6 +585,8 @@ CONFIG_FCOE_FNIC=m
CONFIG_SCSI_SNIC=m
# CONFIG_SCSI_SNIC_DEBUG_FS is not set
+# CONFIG_NVM is not set
+
CONFIG_ATA=y
CONFIG_ATA_BMDMA=y
CONFIG_ATA_VERBOSE_ERROR=y
@@ -897,6 +899,7 @@ CONFIG_NETFILTER_NETLINK_ACCT=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_QUEUE_CT=y
CONFIG_NETFILTER_NETLINK_LOG=m
+# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set
CONFIG_NETFILTER_XTABLES=y
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_MARK=m
@@ -1428,7 +1431,8 @@ CONFIG_CHELSIO_T1_1G=y
CONFIG_CHELSIO_T3=m
CONFIG_CHELSIO_T4=m
CONFIG_CHELSIO_T4VF=m
-# CONFIG_CHELSIO_T4_DCB is not set
+CONFIG_CHELSIO_T4_DCB=y
+# CONFIG_CHELSIO_T4_FCOE is not set
CONFIG_NET_VENDOR_CISCO=y
CONFIG_ENIC=m
@@ -1544,6 +1548,8 @@ CONFIG_QLCNIC_VXLAN=y
CONFIG_QLCNIC_HWMON=y
CONFIG_QLGE=m
CONFIG_NETXEN_NIC=m
+CONFIG_QED=m
+CONFIG_QEDE=m
# CONFIG_NET_VENDOR_QUALCOMM is not set
@@ -1673,12 +1679,20 @@ CONFIG_JME=m
#
# Ethernet (10000 Mbit)
+# CONFIG_NET_VENDOR_AURORA is not set
+
#
# CONFIG_IP1000 is not set
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX4_EN_VXLAN is not set
-# CONFIG_MLX5_CORE is not set
+CONFIG_MLX4_CORE=m
+CONFIG_MLX4_EN=m
+CONFIG_MLX4_EN_DCB=y
+CONFIG_MLX4_EN_VXLAN=y
+CONFIG_MLX4_INFINIBAND=m
+CONFIG_MLX5_CORE=m
+CONFIG_MLX5_CORE_EN=y
+CONFIG_MLX5_INFINIBAND=m
# CONFIG_MLXSW_CORE is not set
+# CONFIG_MLX4_DEBUG is not set
# CONFIG_SFC is not set
# CONFIG_FDDI is not set
@@ -1832,6 +1846,8 @@ CONFIG_LIBERTAS_SDIO=m
# CONFIG_LIBERTAS_THINFIRM is not set
# CONFIG_LIBERTAS_SPI is not set
CONFIG_LIBERTAS_MESH=y
+CONFIG_BNXT=m
+CONFIG_BNXT_SRIOV=y
CONFIG_IWLWIFI=m
CONFIG_IWLDVM=m
@@ -1913,6 +1929,9 @@ CONFIG_RTL8723AE=m
CONFIG_RTL8723BE=m
CONFIG_RTL8188EE=m
CONFIG_RTL8821AE=m
+CONFIG_RTL8XXXU=m
+# Untested is intentionally disabled in stable branches
+# CONFIG_RTL8XXXU_UNTESTED is not set
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
@@ -1928,6 +1947,8 @@ CONFIG_IEEE802154_ATUSB=m
CONFIG_IEEE802154_CC2520=m
# CONFIG_IEEE802154_AT86RF230 is not set
# CONFIG_IEEE802154_MRF24J40 is not set
+# CONFIG_IEEE802154_NL802154_EXPERIMENTAL is not set
+# CONFIG_IEEE802154_AT86RF230_DEBUGFS is not set
CONFIG_MAC802154=m
CONFIG_NET_MPLS_GSO=m
@@ -2010,6 +2031,7 @@ CONFIG_CAN_GS_USB=m
CONFIG_CAN_8DEV_USB=m
CONFIG_CAN_SOFTING=m
# CONFIG_CAN_SOFTING_CS is not set
+CONFIG_CAN_SUN4I=m
CONFIG_NETROM=m
CONFIG_ROSE=m
@@ -2050,7 +2072,9 @@ CONFIG_NFC_ST21NFCA_I2C=m
# CONFIG_NFC_NCI_UART is not set
# CONFIG_NFC_ST_NCI is not set
# CONFIG_NFC_S3FWRN5_I2C is not set
-
+# CONFIG_NFC_FDP is not set
+# CONFIG_NFC_MRVL_I2C is not set
+# CONFIG_NFC_MRVL_SPI is not set
#
# IrDA (infrared) support
@@ -2264,6 +2288,8 @@ CONFIG_GIGASET_M105=m
#
# CONFIG_PHONE is not set
+# CONFIG_NET_L3_MASTER_DEV is not set
+
#
# Input device support
#
@@ -2328,6 +2354,7 @@ CONFIG_SERIO_ARC_PS2=m
# CONFIG_SERIO_PARKBD is not set
# CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_USERIO is not set
#
# Input Device Drivers
@@ -2457,6 +2484,9 @@ CONFIG_TOUCHSCREEN_ZFORCE=m
# CONFIG_TOUCHSCREEN_SX8654 is not set
# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set
# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set
+# CONFIG_TOUCHSCREEN_FT6236 is not set
+# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
+# CONFIG_TOUCHSCREEN_TSC2004 is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_E3X0_BUTTON=m
@@ -2528,6 +2558,8 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_DW=y
# CONFIG_SERIAL_8250_INGENIC is not set
+CONFIG_SERIAL_8250_RT288X=y
+CONFIG_SERIAL_8250_MID=y
CONFIG_CYCLADES=m
# CONFIG_CYZ_INTR is not set
# CONFIG_MOXA_INTELLIO is not set
@@ -2581,7 +2613,7 @@ CONFIG_I2C_CHARDEV=m
# CONFIG_I2C_MUX_PCA9541 is not set
# CONFIG_I2C_MUX_PINCTRL is not set
# CONFIG_I2C_MUX_REG is not set
-#
+# CONFIG_I2C_CADENCE is not set
#
# I2C Algorithms
@@ -2808,6 +2840,7 @@ CONFIG_SENSORS_MAX34440=m
CONFIG_SENSORS_MAX8688=m
CONFIG_SENSORS_MAX1668=m
CONFIG_SENSORS_MAX197=m
+CONFIG_SENSORS_MAX31790=m
CONFIG_SENSORS_TPS40422=m
# CONFIG_NTB is not set
@@ -2931,6 +2964,18 @@ CONFIG_PA12203001=m
# CONFIG_T5403 is not set
# CONFIG_MCP4922 is not set
# CONFIG_MAX1027 is not set
+# CONFIG_MXC4005 is not set
+# CONFIG_VZ89X is not set
+# CONFIG_HDC100X is not set
+# CONFIG_HTU21 is not set
+# CONFIG_APDS9960 is not set
+# CONFIG_US5182D is not set
+# CONFIG_MCP4531 is not set
+# CONFIG_MS5637 is not set
+# CONFIG_LIDAR_LITE_V2 is not set
+# CONFIG_TSYS01 is not set
+# CONFIG_TSYS02D is not set
+# CONFIG_HI8435 is not set
# staging IIO drivers
# CONFIG_AD7291 is not set
@@ -3065,6 +3110,7 @@ CONFIG_WM831X_WATCHDOG=m
# CONFIG_GPIO_WATCHDOG is not set
# CONFIG_XILINX_WATCHDOG is not set
# CONFIG_CADENCE_WATCHDOG is not set
+# CONFIG_BCM7038_WDT is not set
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=m
@@ -3151,6 +3197,7 @@ CONFIG_RTC_DRV_PCF85063=m
# CONFIG_RTC_DRV_XGENE is not set
# CONFIG_RTC_DRV_ABB5ZES3 is not set
# CONFIG_RTC_DRV_ZYNQMP is not set
+# CONFIG_RTC_DRV_RV8803 is not set
CONFIG_R3964=m
# CONFIG_APPLICOM is not set
@@ -3577,6 +3624,7 @@ CONFIG_FB_EFI=y
# CONFIG_FB_GOLDFISH is not set
# CONFIG_FB_OPENCORES is not set
# CONFIG_FB_SM712 is not set
+# CONFIG_FB_IBM_GXT4500 is not set
# CONFIG_FIRMWARE_EDID is not set
@@ -3767,6 +3815,8 @@ CONFIG_SND_DICE=m
CONFIG_SND_OXFW=m
CONFIG_SND_FIREWORKS=m
CONFIG_SND_BEBOB=m
+CONFIG_SND_FIREWIRE_DIGI00X=m
+CONFIG_SND_FIREWIRE_TASCAM=m
#
# Open Sound System
@@ -3803,7 +3853,6 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760 is not set
CONFIG_USB_ISP1362_HCD=m
-CONFIG_USB_FUSBH200_HCD=m
# CONFIG_USB_FOTG210_HCD is not set
# CONFIG_USB_GR_UDC is not set
CONFIG_USB_OHCI_HCD=y
@@ -3949,7 +3998,8 @@ CONFIG_HID_BELKIN=m
CONFIG_HID_APPLEIR=m
# CONFIG_HID_CP2112 is not set
CONFIG_HID_LENOVO=m
-
+CONFIG_HID_CORSAIR=m
+CONFIG_HID_GFRM=m
#
# USB Imaging devices
@@ -4239,6 +4289,7 @@ CONFIG_SSB_PCMCIAHOST=y
# CONFIG_SSB_DEBUG is not set
CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_SSB_DRIVER_GPIO=y
+CONFIG_SSB_HOST_SOC=y
# Multifunction USB devices
# CONFIG_MFD_PCF50633 is not set
@@ -4318,7 +4369,7 @@ CONFIG_MFD_VIPERBOARD=m
# CONFIG_MFD_DA9062 is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_INTEL_SOC_PMIC is not set
-
+# CONFIG_MFD_ATMEL_FLEXCOM is not set
#
# File systems
@@ -4552,6 +4603,7 @@ CONFIG_GFS2_FS_LOCKING_DLM=y
CONFIG_UBIFS_FS=m
# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_ATIME_SUPPORT=y
#
# Partition Types
@@ -4704,6 +4756,7 @@ CONFIG_MEMORY_FAILURE=y
CONFIG_HWPOISON_INJECT=m
CONFIG_CROSS_MEMORY_ATTACH=y
# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
# CONFIG_BACKTRACE_SELF_TEST is not set
CONFIG_LATENCYTOP=y
# CONFIG_COMPAT_BRK is not set
@@ -4711,8 +4764,8 @@ CONFIG_LATENCYTOP=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
CONFIG_EARLY_PRINTK_DBGP=y
# CONFIG_PAGE_POISONING is not set
-# CONFIG_CRASH_DUMP is not set
-# CONFIG_CRASH is not set
+CONFIG_CRASH=m
+CONFIG_CRASH_DUMP=y
# CONFIG_GCOV_KERNEL is not set
CONFIG_KGDB=y
@@ -4838,7 +4891,7 @@ CONFIG_CRYPTO_CHACHA20=m
CONFIG_CRYPTO_842=m
CONFIG_CRYPTO_DRBG_HASH=y
CONFIG_CRYPTO_DRBG_CTR=y
-
+CONFIG_CRYPTO_KEYWRAP=m
@@ -5059,6 +5112,7 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
# CONFIG_SND_SOC_AK4554 is not set
# CONFIG_SND_SOC_AK4642 is not set
# CONFIG_SND_SOC_AK5386 is not set
+# CONFIG_SND_SOC_AK4613 is not set
# CONFIG_SND_SOC_CS42L52 is not set
# CONFIG_SND_SOC_CS42L73 is not set
# CONFIG_SND_SOC_CS4270 is not set
@@ -5201,6 +5255,7 @@ CONFIG_ASYNC_TX_DMA=y
# CONFIG_HSU_DMA is not set
# CONFIG_HSU_DMA_PCI is not set
# CONFIG_XGENE_DMA is not set
+# CONFIG_INTEL_IDMA64 is not set
CONFIG_UNUSED_SYMBOLS=y
@@ -5222,6 +5277,7 @@ CONFIG_FUNCTION_PROFILER=y
CONFIG_RING_BUFFER_BENCHMARK=m
# CONFIG_RING_BUFFER_STARTUP_TEST is not set
# CONFIG_TRACE_ENUM_MAP_FILE is not set
+# CONFIG_TRACING_EVENTS_GPIO is not set
# CONFIG_RBTREE_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not set
CONFIG_FUNCTION_TRACER=y
@@ -5265,7 +5321,7 @@ CONFIG_APM_POWER=m
# CONFIG_BATTERY_DS2782 is not set
# CONFIG_BATTERY_SBS is not set
# CONFIG_BATTERY_DS2780 is not set
-# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_BQ27XXX is not set
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_BATTERY_MAX17042 is not set
# CONFIG_BATTERY_GOLDFISH is not set
@@ -5281,6 +5337,9 @@ CONFIG_APM_POWER=m
# CONFIG_CHARGER_BQ24257 is not set
# CONFIG_CHARGER_BQ25890 is not set
# CONFIG_CHARGER_RT9455 is not set
+# CONFIG_CHARGER_QCOM_SMBB is not set
+# CONFIG_CHARGER_TPS65217 is not set
+# CONFIG_AXP20X_POWER is not set
CONFIG_POWER_RESET=y
# CONFIG_POWER_RESET_LTC2952 is not set
@@ -5308,7 +5367,7 @@ CONFIG_UIO_PCI_GENERIC=m
CONFIG_VFIO=m
CONFIG_VFIO_IOMMU_TYPE1=m
CONFIG_VFIO_PCI=m
-
+# CONFIG_VFIO_NOIOMMU is not set
# LIRC
CONFIG_LIRC_STAGING=y
@@ -5470,6 +5529,7 @@ CONFIG_USBIP_HOST=m
# CONFIG_FB_TFT is not set
# CONFIG_FB_SM750 is not set
# CONFIG_STAGING_RDMA is not set
+# CONFIG_WILC1000_DRIVER is not set
# END OF STAGING
#
@@ -5597,6 +5657,9 @@ CONFIG_GPIO_VIPERBOARD=m
# CONFIG_GPIO_XILINX is not set
# CONFIG_GPIO_ALTERA is not set
# CONFIG_GPIO_ZX is not set
+# CONFIG_GPIO_AMDPT is not set
+# CONFIG_GPIO_104_IDIO_16 is not set
+# CONFIG_GPIO_IT87 is not set
# FIXME: Why?
@@ -5638,6 +5701,7 @@ CONFIG_PSTORE_RAM=m
# CONFIG_TEST_HEXDUMP is not set
# CONFIG_TEST_RHASHTABLE is not set
# CONFIG_TEST_STATIC_KEYS is not set
+# CONFIG_TEST_PRINTF is not set
# CONFIG_AVERAGE is not set
# CONFIG_VMXNET3 is not set
@@ -5663,6 +5727,7 @@ CONFIG_IOMMU_SUPPORT=y
# CONFIG_MAILBOX is not set
# CONFIG_ALTERA_MBOX is not set
+# CONFIG_MAILBOX_TEST is not set
# CONFIG_RESET_CONTROLLER is not set
@@ -5711,3 +5776,12 @@ CONFIG_POWERCAP=y
# set in x86-generic presently
# CONFIG_TOUCHSCREEN_GOODIX is not set
+
+# CONFIG_INTEL_TH is not set
+# CONFIG_STM is not set
+# CONFIG_STM_DUMMY is not set
+# CONFIG_STM_SOURCE_CONSOLE is not set
+
+# CONFIG_AHCI_QORIQ is not set
+# CONFIG_COMMON_CLK_SI514 is not set
+# CONFIG_CLK_QORIQ is not set
diff --git a/config-nodebug b/config-nodebug
index 15af3c7a1..65e8accd1 100644
--- a/config-nodebug
+++ b/config-nodebug
@@ -31,6 +31,7 @@ CONFIG_CPUMASK_OFFSTACK=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_DEBUGGER is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_PI_LIST is not set
diff --git a/config-powerpc64-generic b/config-powerpc64-generic
index 7f0b10585..b543cfbb6 100644
--- a/config-powerpc64-generic
+++ b/config-powerpc64-generic
@@ -64,8 +64,6 @@ CONFIG_CGROUP_HUGETLB=y
CONFIG_RCU_FANOUT=64
CONFIG_RCU_FANOUT_LEAF=16
-CONFIG_CRASH=m
-CONFIG_CRASH_DUMP=y
CONFIG_FA_DUMP=y
CONFIG_RELOCATABLE=y
@@ -166,6 +164,7 @@ CONFIG_SCSI_IPR_TRACE=y
CONFIG_SCSI_IPR_DUMP=y
CONFIG_SERIAL_ICOM=m
+# CONFIG_SERIAL_8250 is not set
# Things we might want to review for newer architectures
# CONFIG_PCIEPORTBUS is not set
@@ -260,10 +259,6 @@ CONFIG_SND_PPC=y
CONFIG_NET_VENDOR_IBM=y
-CONFIG_MLX4_EN=m
-CONFIG_MLX4_EN_DCB=y
-CONFIG_MLX4_EN_VXLAN=y
-
# CONFIG_SERIO_XILINX_XPS_PS2 is not set
# CONFIG_PPC_SMLPAR is not set
@@ -316,8 +311,6 @@ CONFIG_PPC_EMULATED_STATS=y
CONFIG_SWIOTLB=y
-# CONFIG_RDS is not set
-
CONFIG_PPC_DISABLE_WERROR=y
# CONFIG_STRICT_MM_TYPECHECKS is not set
@@ -337,7 +330,6 @@ CONFIG_GPIO_WM831X=m
# CONFIG_MFD_TPS65912_I2C is not set
# CONFIG_MFD_WL1273_CORE is not set
# CONFIG_XPS_USB_HCD_XILINX is not set
-# CONFIG_MMC_SDHCI_OF_ESDHC is not set
# CONFIG_MMC_SDHCI_OF_HLWD is not set
# CONFIG_MFD_AAT2870_CORE is not set
diff --git a/config-s390x b/config-s390x
index ae94aa82d..a41d95ac4 100644
--- a/config-s390x
+++ b/config-s390x
@@ -14,6 +14,8 @@ CONFIG_HZ_100=y
CONFIG_LOG_BUF_SHIFT=16
+CONFIG_IRQ_DOMAIN_DEBUG=y
+
#
# I/O subsystem configuration
#
@@ -127,10 +129,12 @@ CONFIG_MSDOS_PARTITION=y
#
# S390 crypto hw
#
+CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_DES_S390=m
+CONFIG_CRYPTO_GHASH_S390=m
CONFIG_CRYPTO_SHA1_S390=m
CONFIG_CRYPTO_SHA256_S390=m
-CONFIG_CRYPTO_DES_S390=m
-CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_SHA512_S390=m
#
# Kernel hacking
@@ -170,7 +174,7 @@ CONFIG_S390_VMUR=m
CONFIG_CTCM=m
CONFIG_QETH_L2=m
CONFIG_QETH_L3=m
-CONFIG_CRYPTO_SHA512_S390=m
+
CONFIG_KVM=m
# CONFIG_KVM_S390_UCONTROL is not set
CONFIG_S390_GUEST=y
@@ -205,8 +209,6 @@ CONFIG_SCHED_TOPOLOGY=y
# CONFIG_WARN_DYNAMIC_STACK is not set
-CONFIG_CRYPTO_GHASH_S390=m
-
# CONFIG_TRANSPARENT_HUGEPAGE is not set
CONFIG_SCM_BUS=y
CONFIG_EADM_SCH=m
@@ -292,20 +294,5 @@ CONFIG_HOTPLUG_PCI_S390=y
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_IEEE802154_DRIVERS is not set
# CONFIG_MDIO_OCTEON is not set
-
# CONFIG_FMC is not set
-
# CONFIG_OF is not set
-
-CONFIG_MLX4_EN=m
-CONFIG_MLX4_EN_DCB=y
-CONFIG_MLX4_EN_VXLAN=y
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_ACCESS=m
-CONFIG_MLX4_INFINIBAND=m
-CONFIG_RDS=m
-CONFIG_RDS_RDMA=m
-CONFIG_RDS_TCP=m
-CONFIG_IRQ_DOMAIN_DEBUG=y
-
-CONFIG_CRASH=m
diff --git a/config-x86-generic b/config-x86-generic
index 807f6025d..646378bb7 100644
--- a/config-x86-generic
+++ b/config-x86-generic
@@ -48,6 +48,7 @@ CONFIG_EFI_PCDP=y
CONFIG_FB_EFI=y
CONFIG_EARLY_PRINTK_EFI=y
CONFIG_EFI_RUNTIME_MAP=y
+# CONFIG_EFI_FAKE_MEMMAP is not set
# needs FB_SIMPLE to work correctly
# CONFIG_X86_SYSFB is not set
@@ -57,6 +58,7 @@ CONFIG_EFI_RUNTIME_MAP=y
CONFIG_INTEL_IOMMU=y
CONFIG_INTEL_IOMMU_FLOPPY_WA=y
# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set
+CONFIG_INTEL_IOMMU_SVM=y
CONFIG_SCSI_ADVANSYS=m
CONFIG_CAPI_EICON=y
@@ -70,6 +72,8 @@ CONFIG_MMIOTRACE=y
# CONFIG_MMIOTRACE_TEST is not set
# CONFIG_DEBUG_PER_CPU_MAPS is not set
CONFIG_DEBUG_RODATA=y
+# Generating too many warnings while waiting for fixes
+# CONFIG_DEBUG_WX is not set
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_ACPI=y
@@ -102,7 +106,7 @@ CONFIG_ACPI_IPMI=m
CONFIG_ACPI_CUSTOM_METHOD=m
CONFIG_ACPI_BGRT=y
# CONFIG_ACPI_EXTLOG is not set
-CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y
+# CONFIG_ACPI_REV_OVERRIDE_POSSIBLE is not set
CONFIG_INTEL_SOC_PMIC=y
CONFIG_PMIC_OPREGION=y
@@ -263,9 +267,7 @@ CONFIG_TOUCHSCREEN_GOODIX=m
CONFIG_VIA_WDT=m
CONFIG_IE6XX_WDT=m
-CONFIG_CRASH_DUMP=y
CONFIG_PROC_VMCORE=y
-CONFIG_CRASH=m
CONFIG_KVM=m
CONFIG_KVM_INTEL=m
@@ -314,7 +316,14 @@ CONFIG_XEN_ACPI_PROCESSOR=m
# CONFIG_XEN_SCSI_BACKEND is not set
CONFIG_XEN_SYMS=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
CONFIG_SPI_PXA2XX=m
+# CONFIG_CAN_MCP251X is not set
+# CONFIG_SPI_CADENCE is not set
+# CONFIG_SPI_ZYNQMP_GQSPI is not set
+# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
+# CONFIG_DRM_PANEL_LG_LG4573 is not set
CONFIG_MTD_ESB2ROM=m
CONFIG_MTD_CK804XROM=m
@@ -342,6 +351,7 @@ CONFIG_ISCSI_IBFT=m
CONFIG_DMADEVICES=y
CONFIG_INTEL_IOATDMA=m
+CONFIG_INTEL_IDMA64=m
CONFIG_SENSORS_I5K_AMB=m
CONFIG_SENSORS_FAM15H_POWER=m
@@ -394,6 +404,7 @@ CONFIG_ACPI_CMPC=m
CONFIG_MSI_WMI=m
CONFIG_TOSHIBA_BT_RFKILL=m
CONFIG_TOSHIBA_HAPS=m
+CONFIG_TOSHIBA_WMI=m
CONFIG_VGA_SWITCHEROO=y
CONFIG_LPC_SCH=m
@@ -520,9 +531,10 @@ CONFIG_PWM_LPSS_PCI=m
CONFIG_PWM_LPSS_PLATFORM=m
CONFIG_PINCTRL=y
CONFIG_PINCTRL_BAYTRAIL=y
-CONFIG_PINCTRL_CHERRYVIEW=m
+CONFIG_PINCTRL_CHERRYVIEW=y
# CONFIG_PINCTRL_AMD is not set
CONFIG_PINCTRL_SUNRISEPOINT=m
+CONFIG_PINCTRL_BROXTON=m
#baytrail/cherrytrail stuff
CONFIG_KEYBOARD_GPIO=m
@@ -538,9 +550,10 @@ CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH=m
CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH=m
CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH=m
CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH=m
+CONFIG_SND_SOC_INTEL_SKL_RT286_MACH=m
CONFIG_SND_SOC_AC97_CODEC=m
# CONFIG_SND_SOC_TAS571X is not set
-
+# CONFIG_SND_SUN4I_CODEC is not set
# CONFIG_INTEL_POWERCLAMP is not set
CONFIG_X86_PKG_TEMP_THERMAL=m
diff --git a/config-x86_64-generic b/config-x86_64-generic
index 272999819..9d13391fc 100644
--- a/config-x86_64-generic
+++ b/config-x86_64-generic
@@ -61,6 +61,7 @@ CONFIG_INTEL_MIC_HOST=m
CONFIG_INTEL_MIC_CARD=m
CONFIG_INTEL_MIC_BUS=m
CONFIG_INTEL_MIC_X100_DMA=m
+CONFIG_MIC_COSM=m
# SHPC has half-arsed PCI probing, which makes it load on too many systems
CONFIG_HOTPLUG_PCI_SHPC=m
@@ -135,7 +136,7 @@ CONFIG_XEN_DEV_EVTCHN=m
CONFIG_XEN_SYS_HYPERVISOR=y
# CONFIG_XEN_MCE_LOG is not set
# CONFIG_XEN_STUB is not set
-# CONFIG_XEN_PVH is not set
+CONFIG_XEN_PVH=y
CONFIG_XEN_512GB=y
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
@@ -183,10 +184,6 @@ CONFIG_NTB_TRANSPORT=m
# 10GigE
#
CONFIG_IP1000=m
-CONFIG_MLX4_EN=m
-CONFIG_MLX4_EN_DCB=y
-CONFIG_MLX4_EN_VXLAN=y
-# CONFIG_MLX4_DEBUG is not set
CONFIG_SFC=m
CONFIG_SFC_MCDI_MON=y
CONFIG_SFC_SRIOV=y
@@ -209,3 +206,9 @@ CONFIG_NO_HZ_FULL=y
# CONFIG_NO_HZ_FULL_ALL is not set
# CONFIG_NO_HZ_FULL_SYSIDLE is not set
# CONFIG_CONTEXT_TRACKING_FORCE is not set
+
+# Turn on CONFIG_CMA for THP
+CONFIG_CMA=y
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+CONFIG_CMA_AREAS=7
diff --git a/drm-i915-shut-up-gen8-SDE-irq-dmesg-noise-again.patch b/drm-i915-shut-up-gen8-SDE-irq-dmesg-noise-again.patch
new file mode 100644
index 000000000..cd53bf71c
--- /dev/null
+++ b/drm-i915-shut-up-gen8-SDE-irq-dmesg-noise-again.patch
@@ -0,0 +1,68 @@
+From 41ed5ee704b784a4fca02787311d59c243563013 Mon Sep 17 00:00:00 2001
+From: Jani Nikula <jani.nikula@intel.com>
+Date: Thu, 7 Jan 2016 10:29:10 +0200
+Subject: [PATCH] drm/i915: shut up gen8+ SDE irq dmesg noise, again
+
+We still keep getting
+
+[ 4.249930] [drm:gen8_irq_handler [i915]] *ERROR* The master control interrupt lied (SDE)!
+
+This reverts
+
+commit 820da7ae46332fa709b171eb7ba57cbd023fa6df
+Author: Jani Nikula <jani.nikula@intel.com>
+Date: Wed Nov 25 16:47:23 2015 +0200
+
+ Revert "drm/i915: shut up gen8+ SDE irq dmesg noise"
+
+which in itself is a revert, so this is just doing
+
+commit 97e5ed1111dcc5300a0f59a55248cd243937a8ab
+Author: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Fri Oct 23 10:56:12 2015 +0200
+
+ drm/i915: shut up gen8+ SDE irq dmesg noise
+
+all over again. I'll stop pretending I understand what's going on like I
+did when I thought I'd fixed this for good in
+
+commit 6a39d7c986be4fd18eb019e9cdbf774ec36c9f77
+Author: Jani Nikula <jani.nikula@intel.com>
+Date: Wed Nov 25 16:47:22 2015 +0200
+
+ drm/i915: fix the SDE irq dmesg warnings properly
+
+Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
+Reference: http://mid.gmane.org/20151213124945.GA5715@nuc-i3427.alporthouse.com
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92084
+Cc: drm-intel-fixes@lists.freedesktop.org
+Fixes: 820da7ae4633 ("Revert "drm/i915: shut up gen8+ SDE irq dmesg noise"")
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+---
+ drivers/gpu/drm/i915/i915_irq.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
+index 0d228f909dcb..0f42a2782afc 100644
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -2354,9 +2354,13 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
+ spt_irq_handler(dev, pch_iir);
+ else
+ cpt_irq_handler(dev, pch_iir);
+- } else
+- DRM_ERROR("The master control interrupt lied (SDE)!\n");
+-
++ } else {
++ /*
++ * Like on previous PCH there seems to be something
++ * fishy going on with forwarding PCH interrupts.
++ */
++ DRM_DEBUG_DRIVER("The master control interrupt lied (SDE)!\n");
++ }
+ }
+
+ I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
+--
+2.5.0
+
diff --git a/drm-mgag200-fix-kernel-hang-in-cursor-code.patch b/drm-mgag200-fix-kernel-hang-in-cursor-code.patch
deleted file mode 100644
index 075c06241..000000000
--- a/drm-mgag200-fix-kernel-hang-in-cursor-code.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From f6619ef7508261be2ba3ded313ccc46ce670d0d3 Mon Sep 17 00:00:00 2001
-From: "Wang, Rui Y" <rui.y.wang@intel.com>
-Date: Wed, 18 Nov 2015 23:00:53 +0800
-Subject: [PATCH] drm/mgag200: fix kernel hang in cursor code.
-
-The machine hang completely with the following message on the console:
-
-[ 487.777538] BUG: unable to handle kernel NULL pointer dereference at 0000000000000060
-[ 487.777554] IP: [<ffffffff8158aaee>] _raw_spin_lock+0xe/0x30
-[ 487.777557] PGD 42e9f7067 PUD 42f2fa067 PMD 0
-[ 487.777560] Oops: 0002 [#1] SMP
-...
-[ 487.777618] CPU: 21 PID: 3190 Comm: Xorg Tainted: G E 4.4.0-rc1-3-default+ #6
-[ 487.777620] Hardware name: Intel Corporation BRICKLAND/BRICKLAND, BIOS BRHSXSD1.86B.0059.R00.1501081238 01/08/2015
-[ 487.777621] task: ffff880853ae4680 ti: ffff8808696d4000 task.ti: ffff8808696d4000
-[ 487.777625] RIP: 0010:[<ffffffff8158aaee>] [<ffffffff8158aaee>] _raw_spin_lock+0xe/0x30
-[ 487.777627] RSP: 0018:ffff8808696d79c0 EFLAGS: 00010246
-[ 487.777628] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
-[ 487.777629] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000060
-[ 487.777630] RBP: ffff8808696d79e0 R08: 0000000000000000 R09: ffff88086924a780
-[ 487.777631] R10: 000000000001bb40 R11: 0000000000003246 R12: 0000000000000000
-[ 487.777632] R13: ffff880463a27360 R14: ffff88046ca50218 R15: 0000000000000080
-[ 487.777634] FS: 00007f3f81c5a8c0(0000) GS:ffff88086f060000(0000) knlGS:0000000000000000
-[ 487.777635] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
-[ 487.777636] CR2: 0000000000000060 CR3: 000000042e678000 CR4: 00000000001406e0
-[ 487.777638] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
-[ 487.777639] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
-[ 487.777639] Stack:
-[ 487.777642] ffffffffa00eb5fa ffff8808696d7b60 ffff88086b87d800 0000000000000000
-[ 487.777644] ffff8808696d7ac8 ffffffffa01694b6 ffff8808696d7ae8 ffffffff8109c8d5
-[ 487.777647] ffff880469158740 ffff880463a27000 ffff88086b87d800 ffff88086b87d800
-[ 487.777647] Call Trace:
-[ 487.777674] [<ffffffffa00eb5fa>] ? drm_gem_object_lookup+0x1a/0xa0 [drm]
-[ 487.777681] [<ffffffffa01694b6>] mga_crtc_cursor_set+0xc6/0xb60 [mgag200]
-[ 487.777691] [<ffffffff8109c8d5>] ? find_busiest_group+0x35/0x4a0
-[ 487.777696] [<ffffffff81086294>] ? __might_sleep+0x44/0x80
-[ 487.777699] [<ffffffff815888c2>] ? __ww_mutex_lock+0x22/0x9c
-[ 487.777722] [<ffffffffa0104f64>] ? drm_modeset_lock+0x34/0xf0 [drm]
-[ 487.777733] [<ffffffffa0148d9e>] restore_fbdev_mode+0xee/0x2a0 [drm_kms_helper]
-[ 487.777742] [<ffffffffa014afce>] drm_fb_helper_restore_fbdev_mode_unlocked+0x2e/0x70 [drm_kms_helper]
-[ 487.777748] [<ffffffffa014b037>] drm_fb_helper_set_par+0x27/0x50 [drm_kms_helper]
-[ 487.777752] [<ffffffff8134560c>] fb_set_var+0x18c/0x3f0
-[ 487.777777] [<ffffffffa02a9b0a>] ? __ext4_handle_dirty_metadata+0x8a/0x210 [ext4]
-[ 487.777783] [<ffffffff8133cb97>] fbcon_blank+0x1b7/0x2b0
-[ 487.777790] [<ffffffff813be2a3>] do_unblank_screen+0xb3/0x1c0
-[ 487.777795] [<ffffffff813b5aba>] vt_ioctl+0x118a/0x1210
-[ 487.777801] [<ffffffff813a8fe0>] tty_ioctl+0x3f0/0xc90
-[ 487.777808] [<ffffffff81172018>] ? kzfree+0x28/0x30
-[ 487.777813] [<ffffffff811e053f>] ? mntput+0x1f/0x30
-[ 487.777817] [<ffffffff811d3f5d>] do_vfs_ioctl+0x30d/0x570
-[ 487.777822] [<ffffffff8107ed3a>] ? task_work_run+0x8a/0xa0
-[ 487.777825] [<ffffffff811d4234>] SyS_ioctl+0x74/0x80
-[ 487.777829] [<ffffffff8158aeae>] entry_SYSCALL_64_fastpath+0x12/0x71
-[ 487.777851] Code: 65 ff 0d ce 02 a8 7e 5d c3 ba 01 00 00 00 f0 0f b1 17 85 c0 75 e8 b0 01 5d c3 0f 1f 00 65 ff 05 b1 02 a8 7e 31 c0 ba 01 00 00 00 <f0> 0f b1 17 85 c0 75 01 c3 55 89 c6 48 89 e5 e8 4e f5 b1 ff 5d
-[ 487.777854] RIP [<ffffffff8158aaee>] _raw_spin_lock+0xe/0x30
-[ 487.777855] RSP <ffff8808696d79c0>
-[ 487.777856] CR2: 0000000000000060
-[ 487.777860] ---[ end trace 672a2cd555e0ebd3 ]---
-
-The cursor code may be entered with file_priv == NULL && handle == NULL.
-The problem was introduced by:
-
-"bf89209 drm/mga200g: Hold a proper reference for cursor_set"
-
-which calls drm_gem_object_lookup(dev, file_priv...). Previously this wasn't
-a problem because we checked the handle. Move the check early in the function
-can fix the problem.
-
-Signed-off-by: Rui Wang <rui.y.wang@intel.com>
-Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Signed-off-by: Dave Airlie <airlied@redhat.com>
----
- drivers/gpu/drm/mgag200/mgag200_cursor.c | 11 +++++------
- 1 file changed, 5 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c
-index 4f2068fe5d88..a7bf6a90eae5 100644
---- a/drivers/gpu/drm/mgag200/mgag200_cursor.c
-+++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c
-@@ -70,6 +70,11 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
- BUG_ON(pixels_2 != pixels_current && pixels_2 != pixels_prev);
- BUG_ON(pixels_current == pixels_prev);
-
-+ if (!handle || !file_priv) {
-+ mga_hide_cursor(mdev);
-+ return 0;
-+ }
-+
- obj = drm_gem_object_lookup(dev, file_priv, handle);
- if (!obj)
- return -ENOENT;
-@@ -88,12 +93,6 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
- goto out_unreserve1;
- }
-
-- if (!handle) {
-- mga_hide_cursor(mdev);
-- ret = 0;
-- goto out1;
-- }
--
- /* Move cursor buffers into VRAM if they aren't already */
- if (!pixels_1->pin_count) {
- ret = mgag200_bo_pin(pixels_1, TTM_PL_FLAG_VRAM,
---
-2.5.0
-
diff --git a/drm-nouveau-Fix-pre-nv50-pageflip-events-v4.patch b/drm-nouveau-Fix-pre-nv50-pageflip-events-v4.patch
deleted file mode 100644
index 49bcefbf0..000000000
--- a/drm-nouveau-Fix-pre-nv50-pageflip-events-v4.patch
+++ /dev/null
@@ -1,204 +0,0 @@
-From 424f582d0ec7f206dcc59d34c9a2fa1c8087a8aa Mon Sep 17 00:00:00 2001
-From: Daniel Vetter <daniel.vetter@ffwll.ch>
-Date: Tue, 10 Nov 2015 17:37:31 +0100
-Subject: [PATCH] drm/nouveau: Fix pre-nv50 pageflip events (v4)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Apparently pre-nv50 pageflip events happen before the actual vblank
-period. Therefore that functionality got semi-disabled in
-
-commit af4870e406126b7ac0ae7c7ce5751f25ebe60f28
-Author: Mario Kleiner <mario.kleiner.de@gmail.com>
-Date: Tue May 13 00:42:08 2014 +0200
-
- drm/nouveau/kms/nv04-nv40: fix pageflip events via special case.
-
-Unfortunately that hack got uprooted in
-
-commit cc1ef118fc099295ae6aabbacc8af94d8d8885eb
-Author: Thierry Reding <treding@nvidia.com>
-Date: Wed Aug 12 17:00:31 2015 +0200
-
- drm/irq: Make pipe unsigned and name consistent
-
-Triggering a warning when trying to sample the vblank timestamp for a
-non-existing pipe. There's a few ways to fix this:
-
-- Open-code the old behaviour, which just enshrines this slight
- breakage of the userspace ABI.
-
-- Revert Mario's commit and again inflict broken timestamps, again not
- pretty.
-
-- Fix this for real by delaying the pageflip TS until the next vblank
- interrupt, thereby making it accurate.
-
-This patch implements the third option. Since having a page flip
-interrupt that happens when the pageflip gets armed and not when it
-completes in the next vblank seems to be fairly common (older i915 hw
-works very similarly) create a new helper to arm vblank events for
-such drivers.
-
-v2 (Mario Kleiner):
-- Fix function prototypes in drmP.h
-- Add missing vblank_put() for pageflip completion without
- pageflip event.
-- Initialize sequence number for queued pageflip event to avoid
- trouble in drm_handle_vblank_events().
-- Remove dead code and spelling fix.
-
-v3 (Mario Kleiner):
-- Add a signed-off-by and cc stable tag per Ilja's advice.
-
-v4 (Thierry Reding):
-- Fix kerneldoc typo, discovered by Michel Dänzer
-- Rearrange tags and changelog
-
-Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=106431
-Cc: Thierry Reding <treding@nvidia.com>
-Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
-Acked-by: Ben Skeggs <bskeggs@redhat.com>
-Cc: Ilia Mirkin <imirkin@alum.mit.edu>
-Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
-Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
-Cc: stable@vger.kernel.org # v4.3
-Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
-Signed-off-by: Thierry Reding <treding@nvidia.com>
-Signed-off-by: Dave Airlie <airlied@redhat.com>
----
- drivers/gpu/drm/drm_irq.c | 54 ++++++++++++++++++++++++++++++-
- drivers/gpu/drm/nouveau/nouveau_display.c | 19 ++++++-----
- include/drm/drmP.h | 4 +++
- 3 files changed, 68 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
-index 22d207e211e7..c5f20e41dcc6 100644
---- a/drivers/gpu/drm/drm_irq.c
-+++ b/drivers/gpu/drm/drm_irq.c
-@@ -944,7 +944,8 @@ static void send_vblank_event(struct drm_device *dev,
- struct drm_pending_vblank_event *e,
- unsigned long seq, struct timeval *now)
- {
-- WARN_ON_SMP(!spin_is_locked(&dev->event_lock));
-+ assert_spin_locked(&dev->event_lock);
-+
- e->event.sequence = seq;
- e->event.tv_sec = now->tv_sec;
- e->event.tv_usec = now->tv_usec;
-@@ -957,6 +958,57 @@ static void send_vblank_event(struct drm_device *dev,
- }
-
- /**
-+ * drm_arm_vblank_event - arm vblank event after pageflip
-+ * @dev: DRM device
-+ * @pipe: CRTC index
-+ * @e: the event to prepare to send
-+ *
-+ * A lot of drivers need to generate vblank events for the very next vblank
-+ * interrupt. For example when the page flip interrupt happens when the page
-+ * flip gets armed, but not when it actually executes within the next vblank
-+ * period. This helper function implements exactly the required vblank arming
-+ * behaviour.
-+ *
-+ * Caller must hold event lock. Caller must also hold a vblank reference for
-+ * the event @e, which will be dropped when the next vblank arrives.
-+ *
-+ * This is the legacy version of drm_crtc_arm_vblank_event().
-+ */
-+void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe,
-+ struct drm_pending_vblank_event *e)
-+{
-+ assert_spin_locked(&dev->event_lock);
-+
-+ e->pipe = pipe;
-+ e->event.sequence = drm_vblank_count(dev, pipe);
-+ list_add_tail(&e->base.link, &dev->vblank_event_list);
-+}
-+EXPORT_SYMBOL(drm_arm_vblank_event);
-+
-+/**
-+ * drm_crtc_arm_vblank_event - arm vblank event after pageflip
-+ * @crtc: the source CRTC of the vblank event
-+ * @e: the event to send
-+ *
-+ * A lot of drivers need to generate vblank events for the very next vblank
-+ * interrupt. For example when the page flip interrupt happens when the page
-+ * flip gets armed, but not when it actually executes within the next vblank
-+ * period. This helper function implements exactly the required vblank arming
-+ * behaviour.
-+ *
-+ * Caller must hold event lock. Caller must also hold a vblank reference for
-+ * the event @e, which will be dropped when the next vblank arrives.
-+ *
-+ * This is the native KMS version of drm_arm_vblank_event().
-+ */
-+void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
-+ struct drm_pending_vblank_event *e)
-+{
-+ drm_arm_vblank_event(crtc->dev, drm_crtc_index(crtc), e);
-+}
-+EXPORT_SYMBOL(drm_crtc_arm_vblank_event);
-+
-+/**
- * drm_send_vblank_event - helper to send vblank event after pageflip
- * @dev: DRM device
- * @pipe: CRTC index
-diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
-index e905c00acf1a..54183bcca48f 100644
---- a/drivers/gpu/drm/nouveau/nouveau_display.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
-@@ -827,7 +827,6 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
- struct drm_device *dev = drm->dev;
- struct nouveau_page_flip_state *s;
- unsigned long flags;
-- int crtcid = -1;
-
- spin_lock_irqsave(&dev->event_lock, flags);
-
-@@ -839,15 +838,19 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
-
- s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
- if (s->event) {
-- /* Vblank timestamps/counts are only correct on >= NV-50 */
-- if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA)
-- crtcid = s->crtc;
-+ if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
-+ drm_arm_vblank_event(dev, s->crtc, s->event);
-+ } else {
-+ drm_send_vblank_event(dev, s->crtc, s->event);
-
-- drm_send_vblank_event(dev, crtcid, s->event);
-+ /* Give up ownership of vblank for page-flipped crtc */
-+ drm_vblank_put(dev, s->crtc);
-+ }
-+ }
-+ else {
-+ /* Give up ownership of vblank for page-flipped crtc */
-+ drm_vblank_put(dev, s->crtc);
- }
--
-- /* Give up ownership of vblank for page-flipped crtc */
-- drm_vblank_put(dev, s->crtc);
-
- list_del(&s->head);
- if (ps)
-diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index 8b5ce7c5d9bb..c98f01046bd0 100644
---- a/include/drm/drmP.h
-+++ b/include/drm/drmP.h
-@@ -932,6 +932,10 @@ extern void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe,
- struct drm_pending_vblank_event *e);
- extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
- struct drm_pending_vblank_event *e);
-+extern void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe,
-+ struct drm_pending_vblank_event *e);
-+extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
-+ struct drm_pending_vblank_event *e);
- extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
- extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
- extern int drm_vblank_get(struct drm_device *dev, unsigned int pipe);
---
-2.5.0
-
diff --git a/efi-Add-EFI_SECURE_BOOT-bit.patch b/efi-Add-EFI_SECURE_BOOT-bit.patch
index 94f7fe768..89b9664c7 100644
--- a/efi-Add-EFI_SECURE_BOOT-bit.patch
+++ b/efi-Add-EFI_SECURE_BOOT-bit.patch
@@ -1,4 +1,4 @@
-From b4467813ec088c13bd8c9f1eafb7c29d889d7c8f Mon Sep 17 00:00:00 2001
+From c01ff700ea4192ae04b306fef725d62189550236 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@fedoraproject.org>
Date: Tue, 27 Aug 2013 13:33:03 -0400
Subject: [PATCH 13/20] efi: Add EFI_SECURE_BOOT bit
@@ -13,10 +13,10 @@ Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
2 files changed, 3 insertions(+)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
-index 1ac118146e90..f93826b8522c 100644
+index f3b804f..a401ff8 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
-@@ -1137,7 +1137,9 @@ void __init setup_arch(char **cmdline_p)
+@@ -1145,7 +1145,9 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_EFI_SECURE_BOOT_SIG_ENFORCE
if (boot_params.secure_boot) {
@@ -27,17 +27,17 @@ index 1ac118146e90..f93826b8522c 100644
#endif
diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 85ef051ac6fb..de3e45088d4a 100644
+index 569b5a8..4dc970e 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
-@@ -959,6 +959,7 @@ extern int __init efi_setup_pcdp_console(char *);
- #define EFI_PARAVIRT 6 /* Access is via a paravirt interface */
+@@ -980,6 +980,7 @@ extern int __init efi_setup_pcdp_console(char *);
#define EFI_ARCH_1 7 /* First arch-specific bit */
#define EFI_DBG 8 /* Print additional debug info at runtime */
-+#define EFI_SECURE_BOOT 9 /* Are we in Secure Boot mode? */
+ #define EFI_NX_PE_DATA 9 /* Can runtime data regions be mapped non-executable? */
++#define EFI_SECURE_BOOT 10 /* Are we in Secure Boot mode? */
#ifdef CONFIG_EFI
/*
--
-2.4.3
+2.5.0
diff --git a/fs-hugetlbfs-inode.c-fix-bugs-in-hugetlb_vmtruncate_.patch b/fs-hugetlbfs-inode.c-fix-bugs-in-hugetlb_vmtruncate_.patch
deleted file mode 100644
index 90bf05310..000000000
--- a/fs-hugetlbfs-inode.c-fix-bugs-in-hugetlb_vmtruncate_.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 9aacdd354d197ad64685941b36d28ea20ab88757 Mon Sep 17 00:00:00 2001
-From: Mike Kravetz <mike.kravetz@oracle.com>
-Date: Fri, 15 Jan 2016 16:57:37 -0800
-Subject: [PATCH] fs/hugetlbfs/inode.c: fix bugs in hugetlb_vmtruncate_list()
-
-Hillf Danton noticed bugs in the hugetlb_vmtruncate_list routine. The
-argument end is of type pgoff_t. It was being converted to a vaddr
-offset and passed to unmap_hugepage_range. However, end was also being
-used as an argument to the vma_interval_tree_foreach controlling loop.
-In addition, the conversion of end to vaddr offset was incorrect.
-
-hugetlb_vmtruncate_list is called as part of a file truncate or
-fallocate hole punch operation.
-
-When truncating a hugetlbfs file, this bug could prevent some pages from
-being unmapped. This is possible if there are multiple vmas mapping the
-file, and there is a sufficiently sized hole between the mappings. The
-size of the hole between two vmas (A,B) must be such that the starting
-virtual address of B is greater than (ending virtual address of A <<
-PAGE_SHIFT). In this case, the pages in B would not be unmapped. If
-pages are not properly unmapped during truncate, the following BUG is
-hit:
-
- kernel BUG at fs/hugetlbfs/inode.c:428!
-
-In the fallocate hole punch case, this bug could prevent pages from
-being unmapped as in the truncate case. However, for hole punch the
-result is that unmapped pages will not be removed during the operation.
-For hole punch, it is also possible that more pages than desired will be
-unmapped. This unnecessary unmapping will cause page faults to
-reestablish the mappings on subsequent page access.
-
-Fixes: 1bfad99ab (" hugetlbfs: hugetlb_vmtruncate_list() needs to take a range")Reported-by: Hillf Danton <hillf.zj@alibaba-inc.com>
-Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
-Cc: Hugh Dickins <hughd@google.com>
-Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
-Cc: Davidlohr Bueso <dave@stgolabs.net>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: <stable@vger.kernel.org> [4.3]
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
- fs/hugetlbfs/inode.c | 19 +++++++++++--------
- 1 file changed, 11 insertions(+), 8 deletions(-)
-
-diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
-index bbc333b01ca3..9c07d2d754c9 100644
---- a/fs/hugetlbfs/inode.c
-+++ b/fs/hugetlbfs/inode.c
-@@ -463,6 +463,7 @@ hugetlb_vmdelete_list(struct rb_root *root, pgoff_t start, pgoff_t end)
- */
- vma_interval_tree_foreach(vma, root, start, end ? end : ULONG_MAX) {
- unsigned long v_offset;
-+ unsigned long v_end;
-
- /*
- * Can the expression below overflow on 32-bit arches?
-@@ -475,15 +476,17 @@ hugetlb_vmdelete_list(struct rb_root *root, pgoff_t start, pgoff_t end)
- else
- v_offset = 0;
-
-- if (end) {
-- end = ((end - start) << PAGE_SHIFT) +
-- vma->vm_start + v_offset;
-- if (end > vma->vm_end)
-- end = vma->vm_end;
-- } else
-- end = vma->vm_end;
-+ if (!end)
-+ v_end = vma->vm_end;
-+ else {
-+ v_end = ((end - vma->vm_pgoff) << PAGE_SHIFT)
-+ + vma->vm_start;
-+ if (v_end > vma->vm_end)
-+ v_end = vma->vm_end;
-+ }
-
-- unmap_hugepage_range(vma, vma->vm_start + v_offset, end, NULL);
-+ unmap_hugepage_range(vma, vma->vm_start + v_offset, v_end,
-+ NULL);
- }
- }
-
---
-2.5.0
-
diff --git a/i915-stable-backports.patch b/i915-stable-backports.patch
deleted file mode 100644
index f366fda66..000000000
--- a/i915-stable-backports.patch
+++ /dev/null
@@ -1,1962 +0,0 @@
-From 5c19e5ee394c36652c59c247855a3c7e5a83a015 Mon Sep 17 00:00:00 2001
-From: Jani Nikula <jani.nikula@intel.com>
-Date: Thu, 7 Jan 2016 10:29:10 +0200
-Subject: [PATCH 01/26] drm/i915: shut up gen8+ SDE irq dmesg noise, again
-
-We still keep getting
-
-[ 4.249930] [drm:gen8_irq_handler [i915]] *ERROR* The master control interrupt lied (SDE)!
-
-This reverts
-
-commit 820da7ae46332fa709b171eb7ba57cbd023fa6df
-Author: Jani Nikula <jani.nikula@intel.com>
-Date: Wed Nov 25 16:47:23 2015 +0200
-
- Revert "drm/i915: shut up gen8+ SDE irq dmesg noise"
-
-which in itself is a revert, so this is just doing
-
-commit 97e5ed1111dcc5300a0f59a55248cd243937a8ab
-Author: Daniel Vetter <daniel.vetter@ffwll.ch>
-Date: Fri Oct 23 10:56:12 2015 +0200
-
- drm/i915: shut up gen8+ SDE irq dmesg noise
-
-all over again. I'll stop pretending I understand what's going on like I
-did when I thought I'd fixed this for good in
-
-commit 6a39d7c986be4fd18eb019e9cdbf774ec36c9f77
-Author: Jani Nikula <jani.nikula@intel.com>
-Date: Wed Nov 25 16:47:22 2015 +0200
-
- drm/i915: fix the SDE irq dmesg warnings properly
-
-Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
-Reference: http://mid.gmane.org/20151213124945.GA5715@nuc-i3427.alporthouse.com
-Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92084
-Cc: drm-intel-fixes@lists.freedesktop.org
-Fixes: 820da7ae4633 ("Revert "drm/i915: shut up gen8+ SDE irq dmesg noise"")
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-
-[Backported to 4.3.y by Josh Boyer <jwboyer@fedoraproject.org>]
----
- drivers/gpu/drm/i915/i915_irq.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
-index 39d73dbc1c47..fa7f82d54762 100644
---- a/drivers/gpu/drm/i915/i915_irq.c
-+++ b/drivers/gpu/drm/i915/i915_irq.c
-@@ -2168,8 +2168,13 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
- I915_WRITE(SDEIIR, pch_iir);
- ret = IRQ_HANDLED;
- cpt_irq_handler(dev, pch_iir);
-- } else
-- DRM_ERROR("The master control interrupt lied (SDE)!\n");
-+ } else {
-+ /*
-+ * Like on previous PCH there seems to be something
-+ * fishy going on with forwarding PCH interrupts.
-+ */
-+ DRM_DEBUG_DRIVER("The master control interrupt lied (SDE)!\n");
-+ }
-
- }
-
---
-2.5.0
-
-
-From 65dcf0f52e9705d0094e76a9225bbe770329c96d Mon Sep 17 00:00:00 2001
-From: Chris Wilson <chris@chris-wilson.co.uk>
-Date: Thu, 1 Oct 2015 12:34:46 +0100
-Subject: [PATCH 02/26] drm/i915: Fix userptr deadlock with aliased GTT
- mmappings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Upstream commit e4b946bfe1e36680e27a5f39163980979fa61a5d
-
-Michał Winiarski found a really evil way to trigger a struct_mutex
-deadlock with userptr. He found that if he allocated a userptr bo and
-then GTT mmaped another bo, or even itself, at the same address as the
-userptr using MAP_FIXED, he could then cause a deadlock any time we then
-had to invalidate the GTT mmappings (so at will). Tvrtko then found by
-repeatedly allocating GTT mmappings he could alias with an old userptr
-mmap and also trigger the deadlock.
-
-To counter act the deadlock, we make the observation that we only need
-to take the struct_mutex if the object has any pages to revoke, and that
-before userspace can alias with the userptr address space, it must have
-invalidated the userptr->pages. Thus if we can check for those pages
-outside of the struct_mutex, we can avoid the deadlock. To do so we
-introduce a separate flag for userptr objects that we can inspect from
-the mmu-notifier underneath its spinlock.
-
-The patch makes one eye-catching change. That is the removal serial=0
-after detecting a to-be-freed object inside the invalidate walker. I
-felt setting serial=0 was a questionable pessimisation: it denies us the
-chance to reuse the current iterator for the next loop (before it is
-freed) and being explicit makes the reader question the validity of the
-locking (since the object-free race could occur elsewhere). The
-serialisation of the iterator is through the spinlock, if the object is
-freed before the next loop then the notifier.serial will be incremented
-and we start the walk from the beginning as we detect the invalid cache.
-
-To try and tame the error paths and interactions with the userptr->active
-flag, we have to do a fair amount of rearranging of get_pages_userptr().
-
-v2: Grammar fixes
-v3: Reorder set-active so that it is only set when obj->pages is set
-(and so needs cancellation). Only the order of setting obj->pages and
-the active-flag is crucial. Calling gup after invalidate-range begin
-means the userptr sees the new set of backing storage (and so will not
-need to invalidate its new pages), but we have to be careful not to set
-the active-flag prior to successfully establishing obj->pages.
-v4: Take the active->flag early so we know in the mmu-notifier when we
-have to cancel a pending gup-worker.
-v5: Rearrange the error path so that is not so convoluted
-v6: Set pinned to 0 when negative before calling release_pages()
-
-Reported-by: Michał Winiarski <michal.winiarski@intel.com>
-Testcase: igt/gem_userptr_blits/map-fixed*
-Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-Cc: Michał Winiarski <michal.winiarski@intel.com>
-Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
-Cc: stable@vger.kernel.org
-Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
----
- drivers/gpu/drm/i915/i915_gem_userptr.c | 176 ++++++++++++++++++++------------
- 1 file changed, 110 insertions(+), 66 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
-index a96b9006a51e..ba321f0c41c5 100644
---- a/drivers/gpu/drm/i915/i915_gem_userptr.c
-+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
-@@ -59,6 +59,7 @@ struct i915_mmu_object {
- struct interval_tree_node it;
- struct list_head link;
- struct drm_i915_gem_object *obj;
-+ bool active;
- bool is_linear;
- };
-
-@@ -114,7 +115,8 @@ restart:
-
- obj = mo->obj;
-
-- if (!kref_get_unless_zero(&obj->base.refcount))
-+ if (!mo->active ||
-+ !kref_get_unless_zero(&obj->base.refcount))
- continue;
-
- spin_unlock(&mn->lock);
-@@ -151,7 +153,8 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
- else
- it = interval_tree_iter_first(&mn->objects, start, end);
- if (it != NULL) {
-- obj = container_of(it, struct i915_mmu_object, it)->obj;
-+ struct i915_mmu_object *mo =
-+ container_of(it, struct i915_mmu_object, it);
-
- /* The mmu_object is released late when destroying the
- * GEM object so it is entirely possible to gain a
-@@ -160,11 +163,9 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
- * the struct_mutex - and consequently use it after it
- * is freed and then double free it.
- */
-- if (!kref_get_unless_zero(&obj->base.refcount)) {
-- spin_unlock(&mn->lock);
-- serial = 0;
-- continue;
-- }
-+ if (mo->active &&
-+ kref_get_unless_zero(&mo->obj->base.refcount))
-+ obj = mo->obj;
-
- serial = mn->serial;
- }
-@@ -566,6 +567,30 @@ __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj,
- }
-
- static void
-+__i915_gem_userptr_set_active(struct drm_i915_gem_object *obj,
-+ bool value)
-+{
-+ /* During mm_invalidate_range we need to cancel any userptr that
-+ * overlaps the range being invalidated. Doing so requires the
-+ * struct_mutex, and that risks recursion. In order to cause
-+ * recursion, the user must alias the userptr address space with
-+ * a GTT mmapping (possible with a MAP_FIXED) - then when we have
-+ * to invalidate that mmaping, mm_invalidate_range is called with
-+ * the userptr address *and* the struct_mutex held. To prevent that
-+ * we set a flag under the i915_mmu_notifier spinlock to indicate
-+ * whether this object is valid.
-+ */
-+#if defined(CONFIG_MMU_NOTIFIER)
-+ if (obj->userptr.mmu_object == NULL)
-+ return;
-+
-+ spin_lock(&obj->userptr.mmu_object->mn->lock);
-+ obj->userptr.mmu_object->active = value;
-+ spin_unlock(&obj->userptr.mmu_object->mn->lock);
-+#endif
-+}
-+
-+static void
- __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
- {
- struct get_pages_work *work = container_of(_work, typeof(*work), work);
-@@ -612,6 +637,9 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
-
- pinned = 0;
- }
-+ obj->userptr.work = ERR_PTR(ret);
-+ if (ret)
-+ __i915_gem_userptr_set_active(obj, false);
- }
-
- obj->userptr.work = ERR_PTR(ret);
-@@ -627,11 +655,60 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
- }
-
- static int
-+__i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj,
-+ bool *active)
-+{
-+ struct get_pages_work *work;
-+
-+ /* Spawn a worker so that we can acquire the
-+ * user pages without holding our mutex. Access
-+ * to the user pages requires mmap_sem, and we have
-+ * a strict lock ordering of mmap_sem, struct_mutex -
-+ * we already hold struct_mutex here and so cannot
-+ * call gup without encountering a lock inversion.
-+ *
-+ * Userspace will keep on repeating the operation
-+ * (thanks to EAGAIN) until either we hit the fast
-+ * path or the worker completes. If the worker is
-+ * cancelled or superseded, the task is still run
-+ * but the results ignored. (This leads to
-+ * complications that we may have a stray object
-+ * refcount that we need to be wary of when
-+ * checking for existing objects during creation.)
-+ * If the worker encounters an error, it reports
-+ * that error back to this function through
-+ * obj->userptr.work = ERR_PTR.
-+ */
-+ if (obj->userptr.workers >= I915_GEM_USERPTR_MAX_WORKERS)
-+ return -EAGAIN;
-+
-+ work = kmalloc(sizeof(*work), GFP_KERNEL);
-+ if (work == NULL)
-+ return -ENOMEM;
-+
-+ obj->userptr.work = &work->work;
-+ obj->userptr.workers++;
-+
-+ work->obj = obj;
-+ drm_gem_object_reference(&obj->base);
-+
-+ work->task = current;
-+ get_task_struct(work->task);
-+
-+ INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker);
-+ schedule_work(&work->work);
-+
-+ *active = true;
-+ return -EAGAIN;
-+}
-+
-+static int
- i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
- {
- const int num_pages = obj->base.size >> PAGE_SHIFT;
- struct page **pvec;
- int pinned, ret;
-+ bool active;
-
- /* If userspace should engineer that these pages are replaced in
- * the vma between us binding this page into the GTT and completion
-@@ -649,6 +726,18 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
- * to the vma (discard or cloning) which should prevent the more
- * egregious cases from causing harm.
- */
-+ if (IS_ERR(obj->userptr.work)) {
-+ /* active flag will have been dropped already by the worker */
-+ ret = PTR_ERR(obj->userptr.work);
-+ obj->userptr.work = NULL;
-+ return ret;
-+ }
-+ if (obj->userptr.work)
-+ /* active flag should still be held for the pending work */
-+ return -EAGAIN;
-+
-+ /* Let the mmu-notifier know that we have begun and need cancellation */
-+ __i915_gem_userptr_set_active(obj, true);
-
- pvec = NULL;
- pinned = 0;
-@@ -657,73 +746,27 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
- GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
- if (pvec == NULL) {
- pvec = drm_malloc_ab(num_pages, sizeof(struct page *));
-- if (pvec == NULL)
-+ if (pvec == NULL) {
-+ __i915_gem_userptr_set_active(obj, false);
- return -ENOMEM;
-+ }
- }
-
- pinned = __get_user_pages_fast(obj->userptr.ptr, num_pages,
- !obj->userptr.read_only, pvec);
- }
-- if (pinned < num_pages) {
-- if (pinned < 0) {
-- ret = pinned;
-- pinned = 0;
-- } else {
-- /* Spawn a worker so that we can acquire the
-- * user pages without holding our mutex. Access
-- * to the user pages requires mmap_sem, and we have
-- * a strict lock ordering of mmap_sem, struct_mutex -
-- * we already hold struct_mutex here and so cannot
-- * call gup without encountering a lock inversion.
-- *
-- * Userspace will keep on repeating the operation
-- * (thanks to EAGAIN) until either we hit the fast
-- * path or the worker completes. If the worker is
-- * cancelled or superseded, the task is still run
-- * but the results ignored. (This leads to
-- * complications that we may have a stray object
-- * refcount that we need to be wary of when
-- * checking for existing objects during creation.)
-- * If the worker encounters an error, it reports
-- * that error back to this function through
-- * obj->userptr.work = ERR_PTR.
-- */
-- ret = -EAGAIN;
-- if (obj->userptr.work == NULL &&
-- obj->userptr.workers < I915_GEM_USERPTR_MAX_WORKERS) {
-- struct get_pages_work *work;
--
-- work = kmalloc(sizeof(*work), GFP_KERNEL);
-- if (work != NULL) {
-- obj->userptr.work = &work->work;
-- obj->userptr.workers++;
--
-- work->obj = obj;
-- drm_gem_object_reference(&obj->base);
--
-- work->task = current;
-- get_task_struct(work->task);
--
-- INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker);
-- schedule_work(&work->work);
-- } else
-- ret = -ENOMEM;
-- } else {
-- if (IS_ERR(obj->userptr.work)) {
-- ret = PTR_ERR(obj->userptr.work);
-- obj->userptr.work = NULL;
-- }
-- }
-- }
-- } else {
-+
-+ active = false;
-+ if (pinned < 0)
-+ ret = pinned, pinned = 0;
-+ else if (pinned < num_pages)
-+ ret = __i915_gem_userptr_get_pages_schedule(obj, &active);
-+ else
- ret = __i915_gem_userptr_set_pages(obj, pvec, num_pages);
-- if (ret == 0) {
-- obj->userptr.work = NULL;
-- pinned = 0;
-- }
-+ if (ret) {
-+ __i915_gem_userptr_set_active(obj, active);
-+ release_pages(pvec, pinned, 0);
- }
--
-- release_pages(pvec, pinned, 0);
- drm_free_large(pvec);
- return ret;
- }
-@@ -734,6 +777,7 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj)
- struct sg_page_iter sg_iter;
-
- BUG_ON(obj->userptr.work != NULL);
-+ __i915_gem_userptr_set_active(obj, false);
-
- if (obj->madv != I915_MADV_WILLNEED)
- obj->dirty = 0;
---
-2.5.0
-
-
-From d9cc6dc69e3a5f7f68e22227baf0e0f7743e448c Mon Sep 17 00:00:00 2001
-From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-Date: Thu, 22 Oct 2015 13:56:34 +0200
-Subject: [PATCH 03/26] drm/i915/skl: Prevent unclaimed register writes on
- skylake.
-
-Upstream commit b10f1b20171945b49988b2b1fe68cb312cc36d32
-
-I'm getting unclaimed register writes when checking the WM registers
-after the crtc is disabled. So I would imagine those are guarded by
-the crtc power well. Fix this by not reading out wm state when the
-power well is off.
-
-Cc: stable@vger.kernel.org # v4.3
-Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92181
-Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/intel_pm.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
-index ddbb7ed0a193..5e91e795fd99 100644
---- a/drivers/gpu/drm/i915/intel_pm.c
-+++ b/drivers/gpu/drm/i915/intel_pm.c
-@@ -2899,7 +2899,12 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
- int plane;
- u32 val;
-
-+ memset(ddb, 0, sizeof(*ddb));
-+
- for_each_pipe(dev_priv, pipe) {
-+ if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe)))
-+ continue;
-+
- for_each_plane(dev_priv, pipe, plane) {
- val = I915_READ(PLANE_BUF_CFG(pipe, plane));
- skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane],
---
-2.5.0
-
-
-From 0ee1dd6b04a4e8eb34f948842fe4385c09695270 Mon Sep 17 00:00:00 2001
-From: Jani Nikula <jani.nikula@intel.com>
-Date: Fri, 30 Oct 2015 14:50:24 +0200
-Subject: [PATCH 04/26] drm/i915: add quirk to enable backlight on Dell
- Chromebook 11 (2015)
-
-Upstream commit 9be64eee3a87dc03218ca9a12834d1150a57b8a8
-
-Reported-by: Keith Webb <khwebb@gmail.com>
-Suggested-by: Keith Webb <khwebb@gmail.com>
-Cc: stable@vger.kernel.org
-Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=106671
-Reviewed-by: Clint Taylor <Clinton.A.Taylor@intel.com>
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-Link: http://patchwork.freedesktop.org/patch/msgid/1446209424-28801-1-git-send-email-jani.nikula@intel.com
----
- drivers/gpu/drm/i915/intel_display.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index 1d2ff8e6fb4a..8f258092cada 100644
---- a/drivers/gpu/drm/i915/intel_display.c
-+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -14678,6 +14678,9 @@ static struct intel_quirk intel_quirks[] = {
-
- /* Dell Chromebook 11 */
- { 0x0a06, 0x1028, 0x0a35, quirk_backlight_present },
-+
-+ /* Dell Chromebook 11 (2015 version) */
-+ { 0x0a16, 0x1028, 0x0a35, quirk_backlight_present },
- };
-
- static void intel_init_quirks(struct drm_device *dev)
---
-2.5.0
-
-
-From 06d7e7fe18b63244ec4e6e633fc40dd5bea39099 Mon Sep 17 00:00:00 2001
-From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-Date: Tue, 3 Nov 2015 08:31:41 +0100
-Subject: [PATCH 05/26] drm/i915: Extend DSL readout fix to BDW and SKL.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Upstream commit b291681926a142958112eedde62823230d6afb84
-
-Those platforms have the same bug as haswell, and the same fix applies
-to them.
-
-The original HSW fix that this extends is
-
-commit 41b578fb0e8b930f2470d3f673b0fa279e77a7b8
-Author: Jesse Barnes <jbarnes@virtuousgeek.org>
-Date: Tue Sep 22 12:15:54 2015 -0700
-
- drm/i915: workaround bad DSL readout v3
-
-Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
-Cc: stable@vger.kernel.org # v4.3
-Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91579
-Link: http://patchwork.freedesktop.org/patch/msgid/1446535913-31970-3-git-send-email-maarten.lankhorst@linux.intel.com
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/i915_irq.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
-index fa7f82d54762..d83d12eeb3fe 100644
---- a/drivers/gpu/drm/i915/i915_irq.c
-+++ b/drivers/gpu/drm/i915/i915_irq.c
-@@ -651,7 +651,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
- * problem. We may need to extend this to include other platforms,
- * but so far testing only shows the problem on HSW.
- */
-- if (IS_HASWELL(dev) && !position) {
-+ if (HAS_DDI(dev) && !position) {
- int i, temp;
-
- for (i = 0; i < 100; i++) {
---
-2.5.0
-
-
-From f5268273f194155f0a5f3cbfa7bf271774a7a9d6 Mon Sep 17 00:00:00 2001
-From: Jani Nikula <jani.nikula@intel.com>
-Date: Thu, 5 Nov 2015 11:49:59 +0200
-Subject: [PATCH 06/26] drm/i915: quirk backlight present on Macbook 4, 1
-
-Upstream commit 1b9448b071caa7d10bb2569fabe3020a2c25ae59
-
-Unsurprisingly macbooks have backlights, just the VBT doesn't seem to
-know it in this case.
-
-Reported-and-tested-by: Daniel Nicoletti <dantti12@gmail.com>
-Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88325
-Fixes: c675949ec58c ("drm/i915: do not setup backlight if not available according to VBT")
-Cc: stable@vger.kernel.org # v3.15+
-Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-Link: http://patchwork.freedesktop.org/patch/msgid/1446716999-1796-1-git-send-email-jani.nikula@intel.com
----
- drivers/gpu/drm/i915/intel_display.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index 8f258092cada..2e348788ecaa 100644
---- a/drivers/gpu/drm/i915/intel_display.c
-+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -14670,6 +14670,9 @@ static struct intel_quirk intel_quirks[] = {
- /* Apple Macbook 2,1 (Core 2 T7400) */
- { 0x27a2, 0x8086, 0x7270, quirk_backlight_present },
-
-+ /* Apple Macbook 4,1 */
-+ { 0x2a02, 0x106b, 0x00a1, quirk_backlight_present },
-+
- /* Toshiba CB35 Chromebook (Celeron 2955U) */
- { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
-
---
-2.5.0
-
-
-From dddd84b8b5f7f8c0b0037a1bb53f81f5bc70115b Mon Sep 17 00:00:00 2001
-From: Imre Deak <imre.deak@intel.com>
-Date: Wed, 4 Nov 2015 21:25:32 +0200
-Subject: [PATCH 07/26] drm/i915: get runtime PM reference around GEM
- set_caching IOCTL
-
-Upstream commit fd0fe6acf1dd88aabfbf383f7e4c16315387a7b7
-
-After Damien's D3 fix I started to get runtime suspend residency for the
-first time and that revealed a breakage on the set_caching IOCTL path
-that accesses the HW but doesn't take an RPM ref. Fix this up.
-
-Signed-off-by: Imre Deak <imre.deak@intel.com>
-Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
-Cc: stable@vger.kernel.org
-Link: http://patchwork.freedesktop.org/patch/msgid/1446665132-22491-1-git-send-email-imre.deak@intel.com
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/i915_gem.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
-index 4d631a946481..dee065c2b6d8 100644
---- a/drivers/gpu/drm/i915/i915_gem.c
-+++ b/drivers/gpu/drm/i915/i915_gem.c
-@@ -3728,6 +3728,7 @@ int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
- int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
- {
-+ struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_i915_gem_caching *args = data;
- struct drm_i915_gem_object *obj;
- enum i915_cache_level level;
-@@ -3747,9 +3748,11 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
- return -EINVAL;
- }
-
-+ intel_runtime_pm_get(dev_priv);
-+
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
-- return ret;
-+ goto rpm_put;
-
- obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
- if (&obj->base == NULL) {
-@@ -3762,6 +3765,9 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
- drm_gem_object_unreference(&obj->base);
- unlock:
- mutex_unlock(&dev->struct_mutex);
-+rpm_put:
-+ intel_runtime_pm_put(dev_priv);
-+
- return ret;
- }
-
---
-2.5.0
-
-
-From df79b28d6a73835c70222506405bdb54774395c9 Mon Sep 17 00:00:00 2001
-From: Maarten Lankhorst <maarten@mblankhorst.nl>
-Date: Mon, 16 Nov 2015 12:49:14 +0100
-Subject: [PATCH 08/26] drm/i915: Clear intel_crtc->atomic before updating it.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Upstream commit ba8af3e592f7175b5f9a92d2cfcc00b82097d1be
-
-If an atomic update fails intel_crtc->atomic may have have some values left
-from the last atomic check. One example is atomic->wait_for_vblank,
-which results in spurious errors in kms_flip.
-
-[ 1551.892708] ------------[ cut here ]------------
-[ 1551.892721] WARNING: CPU: 3 PID: 4179 at ../drivers/gpu/drm/drm_irq.c:1199 drm_wait_one_vblank+0x197/0x1a0 [drm]()
-[ 1551.892722] vblank not available on crtc 2, ret=-22
-[ 1551.892751] Modules linked in: snd_hda_intel i915 drm_kms_helper drm
-intel_gtt i2c_algo_bit cfbfillrect syscopyarea cfbimgblt sysfillrect
-sysimgblt fb_sys_fops cfbcopyarea agpgart cfg80211 binfmt_misc
-snd_hda_codec_hdmi intel_rapl iosf_mbi x86_pkg_temp_thermal coretemp
-kvm_intel snd_hda_codec_realtek kvm snd_hda_codec_generic iTCO_wdt
-aesni_intel aes_x86_64 glue_helper lrw snd_hda_codec gf128mul
-ablk_helper cryptd snd_hwdep psmouse snd_hda_core pcspkr snd_pcm
-snd_timer snd lpc_ich i2c_i801 mfd_core soundcore wmi evdev [last
-unloaded: drm]
-[ 1551.892753] CPU: 3 PID: 4179 Comm: kms_pipe_crc_ba Tainted: G U W 4.3.0-reg+ #6
-[ 1551.892754] Hardware name: /DZ77BH-55K, BIOS BHZ7710H.86A.0100.2013.0517.0942 05/17/2013
-[ 1551.892758] ffffffffa03128d8 ffff8800cec73890 ffffffff812c0f3c ffff8800cec738d8
-[ 1551.892760] ffff8800cec738c8 ffffffff8104ff36 ffff880116ae2290 0000000000000002
-[ 1551.892762] ffff8800d39fcda0 ffff8800d038b4d0 ffff8800d42b5550 ffff8800cec73928
-[ 1551.892763] Call Trace:
-[ 1551.892768] [<ffffffff812c0f3c>] dump_stack+0x4e/0x82
-[ 1551.892771] [<ffffffff8104ff36>] warn_slowpath_common+0x86/0xc0
-[ 1551.892773] [<ffffffff8104ffbc>] warn_slowpath_fmt+0x4c/0x50
-[ 1551.892781] [<ffffffffa02e6708>] ? drm_vblank_get+0x78/0xd0 [drm]
-[ 1551.892787] [<ffffffffa02e6d47>] drm_wait_one_vblank+0x197/0x1a0 [drm]
-[ 1551.892813] [<ffffffffa03d052f>] intel_post_plane_update+0xef/0x120 [i915]
-[ 1551.892832] [<ffffffffa03d11d2>] intel_atomic_commit+0x4c2/0x1600 [i915]
-[ 1551.892862] [<ffffffffa02ff0c7>] ? drm_atomic_check_only+0x147/0x5e0 [drm]
-[ 1551.892872] [<ffffffffa02feeb7>] ? drm_atomic_add_affected_connectors+0x27/0xf0 [drm]
-[ 1551.892881] [<ffffffffa02ff597>] drm_atomic_commit+0x37/0x60 [drm]
-[ 1551.892887] [<ffffffffa034301a>] restore_fbdev_mode+0x28a/0x2c0 [drm_kms_helper]
-[ 1551.892895] [<ffffffffa0345253>] drm_fb_helper_restore_fbdev_mode_unlocked+0x33/0x80 [drm_kms_helper]
-[ 1551.892900] [<ffffffffa03452cd>] drm_fb_helper_set_par+0x2d/0x50 [drm_kms_helper]
-[ 1551.892920] [<ffffffffa03e7a9a>] intel_fbdev_set_par+0x1a/0x60 [i915]
-[ 1551.892923] [<ffffffff8131a5a7>] fb_set_var+0x1a7/0x3f0
-[ 1551.892927] [<ffffffff8109732f>] ? trace_hardirqs_on_caller+0x12f/0x1c0
-[ 1551.892931] [<ffffffff81314f32>] fbcon_blank+0x212/0x2f0
-[ 1551.892935] [<ffffffff81373f4a>] do_unblank_screen+0xba/0x1d0
-[ 1551.892937] [<ffffffff8136b725>] vt_ioctl+0x13d5/0x1450
-[ 1551.892940] [<ffffffff8107cdd1>] ? preempt_count_sub+0x41/0x50
-[ 1551.892943] [<ffffffff8135d8a3>] tty_ioctl+0x423/0xe30
-[ 1551.892947] [<ffffffff8119f721>] do_vfs_ioctl+0x301/0x560
-[ 1551.892949] [<ffffffff8119b1e3>] ? putname+0x53/0x60
-[ 1551.892952] [<ffffffff811ab376>] ? __fget_light+0x66/0x90
-[ 1551.892955] [<ffffffff8119f9f9>] SyS_ioctl+0x79/0x90
-[ 1551.892958] [<ffffffff81552e97>] entry_SYSCALL_64_fastpath+0x12/0x6f
-[ 1551.892961] ---[ end trace 3e764d4b6628c91c ]---
-
-Testcase: kms_flip
-Reported-and-tested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
-Cc: stable@vger.kernel.org #v4.3
-Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-Reviewed-by: Daniel Stone <daniels@collabora.com>
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-Link: http://patchwork.freedesktop.org/patch/msgid/5649C2BA.6080300@mblankhorst.nl
----
- drivers/gpu/drm/i915/intel_display.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index 2e348788ecaa..7e13bea3b4d5 100644
---- a/drivers/gpu/drm/i915/intel_display.c
-+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -13005,6 +13005,9 @@ static int intel_atomic_check(struct drm_device *dev,
- struct intel_crtc_state *pipe_config =
- to_intel_crtc_state(crtc_state);
-
-+ memset(&to_intel_crtc(crtc)->atomic, 0,
-+ sizeof(struct intel_crtc_atomic_commit));
-+
- /* Catch I915_MODE_FLAG_INHERITED */
- if (crtc_state->mode.private_flags != crtc->state->mode.private_flags)
- crtc_state->mode_changed = true;
---
-2.5.0
-
-
-From eb02e7a4b15ec47b50fd7447471ac3bb75cce53f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
-Date: Wed, 11 Nov 2015 19:11:28 +0200
-Subject: [PATCH 09/26] drm/i915: Don't clobber the addfb2 ioctl params
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Upstream commit 76dc3769d7c3cdcfa7c4c7768a7cb87cd91af12f
-
-We try to convert the old way of of specifying fb tiling (obj->tiling)
-into the new fb modifiers. We store the result in the passed in mode_cmd
-structure. But that structure comes directly from the addfb2 ioctl, and
-gets copied back out to userspace, which means we're clobbering the
-modifiers that the user provided (all 0 since the DRM_MODE_FB_MODIFIERS
-flag wasn't even set by the user). Hence if the user reuses the struct
-for another addfb2, the ioctl will be rejected since it's now asking for
-some modifiers w/o the flag set.
-
-Fix the problem by making a copy of the user provided structure. We can
-play any games we want with the copy.
-
-IGT-Version: 1.12-git (x86_64) (Linux: 4.4.0-rc1-stereo+ x86_64)
-...
-Subtest basic-X-tiled: SUCCESS (0.001s)
-Test assertion failure function pitch_tests, file kms_addfb_basic.c:167:
-Failed assertion: drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0
-Last errno: 22, Invalid argument
-Stack trace:
- #0 [__igt_fail_assert+0x101]
- #1 [pitch_tests+0x619]
- #2 [__real_main426+0x2f]
- #3 [main+0x23]
- #4 [__libc_start_main+0xf0]
- #5 [_start+0x29]
- #6 [<unknown>+0x29]
- Subtest framebuffer-vs-set-tiling failed.
- **** DEBUG ****
- Test assertion failure function pitch_tests, file kms_addfb_basic.c:167:
- Failed assertion: drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &f) == 0
- Last errno: 22, Invalid argument
- **** END ****
- Subtest framebuffer-vs-set-tiling: FAIL (0.003s)
- ...
-
-IGT-Version: 1.12-git (x86_64) (Linux: 4.4.0-rc1-stereo+ x86_64)
-Subtest framebuffer-vs-set-tiling: SUCCESS (0.000s)
-
-Cc: stable@vger.kernel.org # v4.1+
-Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
-Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
-Fixes: 2a80eada326f ("drm/i915: Add fb format modifier support")
-Testcase: igt/kms_addfb_basic/clobbered-modifier
-Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
-Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-Link: http://patchwork.freedesktop.org/patch/msgid/1447261890-3960-1-git-send-email-ville.syrjala@linux.intel.com
----
- drivers/gpu/drm/i915/intel_display.c | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index 7e13bea3b4d5..d07d98aeb72c 100644
---- a/drivers/gpu/drm/i915/intel_display.c
-+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -14330,16 +14330,17 @@ static int intel_framebuffer_init(struct drm_device *dev,
- static struct drm_framebuffer *
- intel_user_framebuffer_create(struct drm_device *dev,
- struct drm_file *filp,
-- struct drm_mode_fb_cmd2 *mode_cmd)
-+ struct drm_mode_fb_cmd2 *user_mode_cmd)
- {
- struct drm_i915_gem_object *obj;
-+ struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
-
- obj = to_intel_bo(drm_gem_object_lookup(dev, filp,
-- mode_cmd->handles[0]));
-+ mode_cmd.handles[0]));
- if (&obj->base == NULL)
- return ERR_PTR(-ENOENT);
-
-- return intel_framebuffer_create(dev, mode_cmd, obj);
-+ return intel_framebuffer_create(dev, &mode_cmd, obj);
- }
-
- #ifndef CONFIG_DRM_FBDEV_EMULATION
---
-2.5.0
-
-
-From 687b4f4810c6a23420994e9cf4bb2d420a80217d Mon Sep 17 00:00:00 2001
-From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
-Date: Tue, 17 Nov 2015 18:14:26 +0200
-Subject: [PATCH 10/26] drm/i915: Fix gpu frequency change tracing
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Upstream commit 0f94592efd36213c961145fe1ab0c3bc323ec053
-
-With gen < 9 we have had always 50Mhz units as our hw
-ratio. With gen >= 9 the hw ratio changed to 16.667Mhz (50/3).
-The result was that our gpu frequency tracing started to output
-values 3 times larger than expected due to hardcoded scaling
-value. Fix this by using Use intel_gpu_freq() when generating Mhz
-value from ratio for 'intel_gpu_freq_change' trace event.
-
-Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92591
-Cc: stable@vger.kernel.org # v4.3+
-Reported-by: Eero Tamminen <eero.t.tamminen@intel.com>
-Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
-Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-Link: http://patchwork.freedesktop.org/patch/msgid/1447776866-29384-1-git-send-email-mika.kuoppala@intel.com
----
- drivers/gpu/drm/i915/intel_pm.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
-index 5e91e795fd99..2a689522cd89 100644
---- a/drivers/gpu/drm/i915/intel_pm.c
-+++ b/drivers/gpu/drm/i915/intel_pm.c
-@@ -4503,7 +4503,7 @@ static void gen6_set_rps(struct drm_device *dev, u8 val)
- POSTING_READ(GEN6_RPNSWREQ);
-
- dev_priv->rps.cur_freq = val;
-- trace_intel_gpu_freq_change(val * 50);
-+ trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
- }
-
- static void valleyview_set_rps(struct drm_device *dev, u8 val)
---
-2.5.0
-
-
-From efee83c75bf454e745ebaddd96b9fe741c706317 Mon Sep 17 00:00:00 2001
-From: Chris Wilson <chris@chris-wilson.co.uk>
-Date: Thu, 19 Nov 2015 09:58:05 +0000
-Subject: [PATCH 11/26] drm/i915: Mark uneven memory banks on gen4 desktop as
- unknown swizzling
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Upstream commit 0b466dc238cb660bbdb9ef6e121e1757057484c3
-
-We have varied reports of swizzling corruption on gen4 desktop, and
-confirmation that one at least is triggered by uneven memory banks
-(L-shaped memory). The implication is that the swizzling varies between
-the paired channels and the remainder of memory on the single channel. As
-the object then has unpredictable swizzling (it will vary depending on
-exact page allocation and may even change during the object's lifetime as
-the pages are replaced), we have to report to userspace that the swizzling
-is unknown.
-
-However, some existing userspace is buggy when it meets an unknown
-swizzling configuration and so we need to tell another white lie and
-mark the swizzling as NONE but report it as UNKNOWN through the extended
-get-tiling-ioctl. See
-
-commit 5eb3e5a5e11d14f9deb2a4b83555443b69ab9940
-Author: Chris Wilson <chris@chris-wilson.co.uk>
-Date: Sun Jun 28 09:19:26 2015 +0100
-
- drm/i915: Declare the swizzling unknown for L-shaped configurations
-
-for the previous example where we found that telling the truth to
-userspace just ends up in a world of hurt.
-
-Also since we don't truly know what the swizzling is on the pages, we
-need to keep them pinned to prevent swapping as the reports also
-suggest that some gen4 devices have previously undetected bit17
-swizzling.
-
-v2: Combine unknown + quirk patches to prevent userspace ever seeing
-unknown swizzling through the normal get-tiling-ioctl. Also use the same
-path for the existing uneven bank detection for mobile gen4.
-
-Reported-by: Matti Hämäläinen <ccr@tnsp.org>
-Tested-by: Matti Hämäläinen <ccr@tnsp.org>
-References: https://bugs.freedesktop.org/show_bug.cgi?id=90725
-Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-Cc: Matti Hämäläinen <ccr@tnsp.org>
-Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
-Cc: Jani Nikula <jani.nikula@intel.com>
-Cc: stable@vger.kernel.org
-Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Link: http://patchwork.freedesktop.org/patch/msgid/1447927085-31726-1-git-send-email-chris@chris-wilson.co.uk
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/i915_gem_fence.c | 36 ++++++++++++++++++++++++++---------
- 1 file changed, 27 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
-index af1f8c461060..716c3d8f027c 100644
---- a/drivers/gpu/drm/i915/i915_gem_fence.c
-+++ b/drivers/gpu/drm/i915/i915_gem_fence.c
-@@ -647,11 +647,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
- }
-
- /* check for L-shaped memory aka modified enhanced addressing */
-- if (IS_GEN4(dev)) {
-- uint32_t ddc2 = I915_READ(DCC2);
--
-- if (!(ddc2 & DCC2_MODIFIED_ENHANCED_DISABLE))
-- dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
-+ if (IS_GEN4(dev) &&
-+ !(I915_READ(DCC2) & DCC2_MODIFIED_ENHANCED_DISABLE)) {
-+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
-+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
- }
-
- if (dcc == 0xffffffff) {
-@@ -680,16 +679,35 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
- * matching, which was the case for the swizzling required in
- * the table above, or from the 1-ch value being less than
- * the minimum size of a rank.
-+ *
-+ * Reports indicate that the swizzling actually
-+ * varies depending upon page placement inside the
-+ * channels, i.e. we see swizzled pages where the
-+ * banks of memory are paired and unswizzled on the
-+ * uneven portion, so leave that as unknown.
- */
-- if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
-- swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-- swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-- } else {
-+ if (I915_READ16(C0DRB3) == I915_READ16(C1DRB3)) {
- swizzle_x = I915_BIT_6_SWIZZLE_9_10;
- swizzle_y = I915_BIT_6_SWIZZLE_9;
- }
- }
-
-+ if (swizzle_x == I915_BIT_6_SWIZZLE_UNKNOWN ||
-+ swizzle_y == I915_BIT_6_SWIZZLE_UNKNOWN) {
-+ /* Userspace likes to explode if it sees unknown swizzling,
-+ * so lie. We will finish the lie when reporting through
-+ * the get-tiling-ioctl by reporting the physical swizzle
-+ * mode as unknown instead.
-+ *
-+ * As we don't strictly know what the swizzling is, it may be
-+ * bit17 dependent, and so we need to also prevent the pages
-+ * from being moved.
-+ */
-+ dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
-+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
-+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-+ }
-+
- dev_priv->mm.bit_6_swizzle_x = swizzle_x;
- dev_priv->mm.bit_6_swizzle_y = swizzle_y;
- }
---
-2.5.0
-
-
-From b9aa6e409916793c7b2c6302df80f9a8c36ddcf2 Mon Sep 17 00:00:00 2001
-From: Takashi Iwai <tiwai@suse.de>
-Date: Wed, 25 Nov 2015 15:26:47 +0100
-Subject: [PATCH 12/26] drm/i915: Don't compare has_drrs strictly in pipe
- config
-
-Upstream commit 13b13dfaaa39ab52b0f433c6744f4638793cbf7b
-
-The commit [cfb23ed622d0: drm/i915: Allow fuzzy matching in
-pipe_config_compare, v2] relaxed the way to compare the pipe
-configurations, but one new comparison sneaked in there: it added the
-strict has_drrs value check. This causes a regression on many
-machines, typically HP laptops with a docking port, where the kernel
-spews warnings and eventually fails to set the mode properly like:
- [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in has_drrs (expected 1, found 0)
- ------------[ cut here ]------------
- WARNING: CPU: 0 PID: 79 at drivers/gpu/drm/i915/intel_display.c:12700 intel_modeset_check_state+0x5aa/0x870 [i915]()
- pipe state doesn't match!
- ....
-
-This patch just removes the check again for fixing the regression.
-
-Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=104041
-Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92456
-Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=956397
-Fixes: cfb23ed622d0 ('drm/i915: Allow fuzzy matching in pipe_config_compare, v2')
-Cc: <stable@vger.kernel.org> # v4.3+
-Reported-and-tested-by: Max Lin <mlin@suse.com>
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Link: http://patchwork.freedesktop.org/patch/msgid/1448461607-16868-1-git-send-email-tiwai@suse.de
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/intel_display.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index d07d98aeb72c..58e08fb47d1f 100644
---- a/drivers/gpu/drm/i915/intel_display.c
-+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -12427,7 +12427,6 @@ intel_pipe_config_compare(struct drm_device *dev,
- if (INTEL_INFO(dev)->gen < 8) {
- PIPE_CONF_CHECK_M_N(dp_m_n);
-
-- PIPE_CONF_CHECK_I(has_drrs);
- if (current_config->has_drrs)
- PIPE_CONF_CHECK_M_N(dp_m2_n2);
- } else
---
-2.5.0
-
-
-From 17e09098ed89ccc44a9420b0eee361b2e4f1f58c Mon Sep 17 00:00:00 2001
-From: Takashi Iwai <tiwai@suse.de>
-Date: Thu, 19 Nov 2015 12:09:56 +0100
-Subject: [PATCH 13/26] drm/i915: Don't override output type for DDI HDMI
-
-Upstream commit 2540058f7a9d9a843b4d9a28d4f8168dd034d030
-
-Currently a DDI port may register the DP hotplug handler even though
-it's used with HDMI, and the DP HPD handler overrides the encoder
-type forcibly to DP. This caused the inconsistency on a machine
-connected with a HDMI monitor; upon a hotplug event, the DDI port is
-suddenly switched to be handled as a DP although the same monitor is
-kept connected, and this leads to the erroneous blank output.
-
-This patch papers over the bug by excluding the previous HDMI encoder
-type from this override. This should be fixed more fundamentally,
-e.g. by moving the encoder type reset from the HPD or by having
-individual encoder objects for HDMI and DP. But since the bug has
-been present for a long time (3.17), it's better to have a
-quick-n-dirty fix for now, and keep working on a cleaner fix.
-
-Bugzilla: http://bugzilla.opensuse.org/show_bug.cgi?id=955190
-Fixes: 0e32b39ceed6 ('drm/i915: add DP 1.2 MST support (v0.7)')
-Cc: <stable@vger.kernel.org> # v3.17+
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Link: http://patchwork.freedesktop.org/patch/msgid/1447931396-19147-1-git-send-email-tiwai@suse.de
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/intel_dp.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
-index 0a2e33fbf20d..a7b7a64d8d27 100644
---- a/drivers/gpu/drm/i915/intel_dp.c
-+++ b/drivers/gpu/drm/i915/intel_dp.c
-@@ -4921,7 +4921,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
- enum intel_display_power_domain power_domain;
- enum irqreturn ret = IRQ_NONE;
-
-- if (intel_dig_port->base.type != INTEL_OUTPUT_EDP)
-+ if (intel_dig_port->base.type != INTEL_OUTPUT_EDP &&
-+ intel_dig_port->base.type != INTEL_OUTPUT_HDMI)
- intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
-
- if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
---
-2.5.0
-
-
-From 5cbff55f4355dc1cec8124c8741fdfd98f644c73 Mon Sep 17 00:00:00 2001
-From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Date: Sat, 12 Sep 2015 10:17:50 +0530
-Subject: [PATCH 14/26] drm/i915: Add IS_SKL_GT3 and IS_SKL_GT4 macro.
-
-Upstream commit 7a58bad0e63295dfa803973efcebc80cb730c7bd
-
-It will be usefull to specify w/a that affects only SKL GT3 and GT4.
-
-Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Reviewed-by: Alex Dai <yu.dai@intel.com>
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
----
- drivers/gpu/drm/i915/i915_drv.h | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
-index e1db8de52851..3c16f6237251 100644
---- a/drivers/gpu/drm/i915/i915_drv.h
-+++ b/drivers/gpu/drm/i915/i915_drv.h
-@@ -2475,6 +2475,11 @@ struct drm_i915_cmd_table {
- #define IS_SKL_ULX(dev) (INTEL_DEVID(dev) == 0x190E || \
- INTEL_DEVID(dev) == 0x1915 || \
- INTEL_DEVID(dev) == 0x191E)
-+#define IS_SKL_GT3(dev) (IS_SKYLAKE(dev) && \
-+ (INTEL_DEVID(dev) & 0x00F0) == 0x0020)
-+#define IS_SKL_GT4(dev) (IS_SKYLAKE(dev) && \
-+ (INTEL_DEVID(dev) & 0x00F0) == 0x0030)
-+
- #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
-
- #define SKL_REVID_A0 (0x0)
---
-2.5.0
-
-
-From baed978880f2c32e82587cc514227aad82daecd5 Mon Sep 17 00:00:00 2001
-From: Arun Siluvery <arun.siluvery@linux.intel.com>
-Date: Fri, 18 Sep 2015 17:52:47 +0100
-Subject: [PATCH 15/26] drm/i915/bxt: Update revision id for BXT C0
-
-Upstream commit 5ca4163a612068d8f942c454218d3d631f22af1b
-
-Cc: Nick Hoath <nicholas.hoath@intel.com>
-Cc: Imre Deak <imre.deak@intel.com>
-Signed-off-by: Arun Siluvery <arun.siluvery@linux.intel.com>
-Reviewed-by: Imre Deak <imre.deak@intel.com>
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
----
- drivers/gpu/drm/i915/i915_drv.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
-index 3c16f6237251..475b03e9d584 100644
---- a/drivers/gpu/drm/i915/i915_drv.h
-+++ b/drivers/gpu/drm/i915/i915_drv.h
-@@ -2491,7 +2491,7 @@ struct drm_i915_cmd_table {
-
- #define BXT_REVID_A0 (0x0)
- #define BXT_REVID_B0 (0x3)
--#define BXT_REVID_C0 (0x6)
-+#define BXT_REVID_C0 (0x9)
-
- /*
- * The genX designation typically refers to the render engine, so render
---
-2.5.0
-
-
-From c80bd95bfeb85ce970c5f7711718a274e4b38b55 Mon Sep 17 00:00:00 2001
-From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Date: Sat, 12 Sep 2015 10:17:51 +0530
-Subject: [PATCH 16/26] drm/i915: WaRsDisableCoarsePowerGating
-
-Upstream commit f2d2fe95072acd5404f8051b8bf1195c61a47fb5
-
-WaRsDisableCoarsePowerGating: Coarse Power Gating (CPG) needs to be
-disabled for platforms prior to BXT B0 and SKL GT3/GT4 till E0.
-
-v2: Added GT3/GT4 Check.
-
-Change-Id: Ia3c4c16e050c88d3e259f601054875c812d69c3a
-Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Reviewed-by: Alex Dai <yu.dai@intel.com>
-[danvet: Align continuation properly.]
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
----
- drivers/gpu/drm/i915/intel_pm.c | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
-index 2a689522cd89..56a5568ffeb7 100644
---- a/drivers/gpu/drm/i915/intel_pm.c
-+++ b/drivers/gpu/drm/i915/intel_pm.c
-@@ -4851,11 +4851,14 @@ static void gen9_enable_rc6(struct drm_device *dev)
-
- /*
- * 3b: Enable Coarse Power Gating only when RC6 is enabled.
-- * WaDisableRenderPowerGating:skl,bxt - Render PG need to be disabled with RC6.
-+ * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6.
- */
-- I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
-- GEN9_MEDIA_PG_ENABLE : 0);
--
-+ if ((IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) ||
-+ ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_E0)))
-+ I915_WRITE(GEN9_PG_ENABLE, 0);
-+ else
-+ I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
-+ (GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE) : 0);
-
- intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
-
---
-2.5.0
-
-
-From c6b1dd5d44c09a9c0032066415ccf8539efb5856 Mon Sep 17 00:00:00 2001
-From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Date: Sat, 12 Sep 2015 10:17:52 +0530
-Subject: [PATCH 17/26] drm/i915: WaRsUseTimeoutMode
-
-Upstream commit e3429cd240b06c79df3ea90f28065a7e011744cd
-
-Enable TO mode for RC6 for SKL till D0 and BXT till A0.
-
-Cc: Tom O'Rourke <Tom.O'Rourke@intel.com>
-Cc: Akash Goel <akash.goel@intel.com>
-Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Reviewed-by: Alex Dai <yu.dai@intel.com>
-[danvet: Fixup line continuation alignment.]
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
----
- drivers/gpu/drm/i915/intel_pm.c | 13 ++++++++++---
- 1 file changed, 10 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
-index 56a5568ffeb7..ab54c645c2ee 100644
---- a/drivers/gpu/drm/i915/intel_pm.c
-+++ b/drivers/gpu/drm/i915/intel_pm.c
-@@ -4845,9 +4845,16 @@ static void gen9_enable_rc6(struct drm_device *dev)
- rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
- DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
- "on" : "off");
-- I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
-- GEN6_RC_CTL_EI_MODE(1) |
-- rc6_mask);
-+
-+ if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) ||
-+ (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0))
-+ I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
-+ GEN7_RC_CTL_TO_MODE |
-+ rc6_mask);
-+ else
-+ I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
-+ GEN6_RC_CTL_EI_MODE(1) |
-+ rc6_mask);
-
- /*
- * 3b: Enable Coarse Power Gating only when RC6 is enabled.
---
-2.5.0
-
-
-From a7af36dfaaa2136be0454787130f73d207c2f34d Mon Sep 17 00:00:00 2001
-From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Date: Sat, 12 Sep 2015 10:17:53 +0530
-Subject: [PATCH 18/26] drm/i915: WaRsDoubleRc6WrlWithCoarsePowerGating
-
-Upstream commit 63a4dec2c168b74a39df1eac494501f0f6bf3708
-
-Cc: Tom O'Rourke <Tom.O'Rourke@intel.com>
-Cc: Akash Goel <akash.goel@intel.com>
-Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Reviewed-by: Alex Dai <yu.dai@intel.com>
-[danvet: Fix continuation alignment.]
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
----
- drivers/gpu/drm/i915/intel_pm.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
-index ab54c645c2ee..7c7b6386121f 100644
---- a/drivers/gpu/drm/i915/intel_pm.c
-+++ b/drivers/gpu/drm/i915/intel_pm.c
-@@ -4828,7 +4828,13 @@ static void gen9_enable_rc6(struct drm_device *dev)
- I915_WRITE(GEN6_RC_CONTROL, 0);
-
- /* 2b: Program RC6 thresholds.*/
-- I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
-+
-+ /* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */
-+ if (IS_SKYLAKE(dev) && !((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) &&
-+ (INTEL_REVID(dev) <= SKL_REVID_E0)))
-+ I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
-+ else
-+ I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
- I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
- I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
- for_each_ring(ring, dev_priv, unused)
---
-2.5.0
-
-
-From b925cfd49203fc37c491fa28310221be23a2634d Mon Sep 17 00:00:00 2001
-From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
-Date: Mon, 7 Dec 2015 18:29:44 +0200
-Subject: [PATCH 19/26] drm/i915/skl: Disable coarse power gating up until F0
-
-Upstream commit 344df9809f4521c8c11d67c5ef18764b54358950
-
-There is conflicting info between E0 and F0 steppings
-for this workarounds. Trust more authoritative source and
-be conservative and extend also for F0.
-
-This prevents numerous (>50) gpu hangs with SKL GT4e
-during piglit run.
-
-References: HSD: gen9lp/2134184
-Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
-Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Link: http://patchwork.freedesktop.org/patch/msgid/1449505785-20812-1-git-send-email-mika.kuoppala@intel.com
-(cherry picked from commit 6686ece19f7446f0e29c77d9e0402e1d0ce10c48)
-Cc: stable@vger.kernel.org # v4.3+
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/intel_pm.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
-index 7c7b6386121f..d04f123f4ccf 100644
---- a/drivers/gpu/drm/i915/intel_pm.c
-+++ b/drivers/gpu/drm/i915/intel_pm.c
-@@ -4867,7 +4867,7 @@ static void gen9_enable_rc6(struct drm_device *dev)
- * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6.
- */
- if ((IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) ||
-- ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_E0)))
-+ ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && (INTEL_REVID(dev) <= SKL_REVID_F0)))
- I915_WRITE(GEN9_PG_ENABLE, 0);
- else
- I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
---
-2.5.0
-
-
-From 302e759f64e1c4bed49f31459329acbb2cddce8a Mon Sep 17 00:00:00 2001
-From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
-Date: Mon, 7 Dec 2015 18:29:45 +0200
-Subject: [PATCH 20/26] drm/i915/skl: Double RC6 WRL always on
-
-Upstream commit 6704d45528537ea6088aeea0667d87b605b82d51
-
-WaRsDoubleRc6WrlWithCoarsePowerGating should
-be enabled for all Skylakes. Make it so.
-
-Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
-Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
-Link: http://patchwork.freedesktop.org/patch/msgid/1449505785-20812-2-git-send-email-mika.kuoppala@intel.com
-(cherry picked from commit e7674b8c31717dd0c58b3a9493d43249722071eb)
-Cc: stable@vger.kernel.org # v4.3+
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/intel_pm.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
-index d04f123f4ccf..33db474fae02 100644
---- a/drivers/gpu/drm/i915/intel_pm.c
-+++ b/drivers/gpu/drm/i915/intel_pm.c
-@@ -4830,8 +4830,7 @@ static void gen9_enable_rc6(struct drm_device *dev)
- /* 2b: Program RC6 thresholds.*/
-
- /* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */
-- if (IS_SKYLAKE(dev) && !((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) &&
-- (INTEL_REVID(dev) <= SKL_REVID_E0)))
-+ if (IS_SKYLAKE(dev))
- I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
- else
- I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
---
-2.5.0
-
-
-From c4c390176eaf6b4321c1f90065107711845e9aff Mon Sep 17 00:00:00 2001
-From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-Date: Mon, 23 Nov 2015 10:25:28 +0100
-Subject: [PATCH 21/26] drm/i915: Do a better job at disabling primary plane in
- the noatomic case.
-
-Upstream commit 634b3a4a476e96816d5d6cd5bb9f8900a53f56ba
-
-When disable_noatomic is called plane_mask is not correct yet, and
-plane_state->visible = true is left as true after disabling the primary
-plane.
-
-Other planes are already disabled as part of crtc sanitization, only the
-primary is left active. But the plane_mask is not updated here. It gets
-updated during fb takeover in modeset_gem_init, or set to the new value
-on resume.
-
-This means that to disable the primary plane 1 << drm_plane_index(primary)
-needs to be used.
-
-Afterwards because the crtc is no longer active it's forbidden to keep
-plane_state->visible set, or a WARN_ON in
-intel_plane_atomic_calc_changes triggers. There are other code points
-that rely on accurate plane_state->visible too, so make sure the bool is
-cleared.
-
-The other planes are already disabled in intel_sanitize_crtc, so they
-don't have to be handled here.
-
-Cc: stable@vger.kernel.org #v4.3, v4.2?
-Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92655
-Tested-by: Tomas Mezzadra <tmezzadra@gmail.com>
-Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Link: http://patchwork.freedesktop.org/patch/msgid/5652DB88.9070208@linux.intel.com
-(cherry picked from commit 54a4196188eab82e6f0a5f05716626e9f18b8fb6)
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/intel_display.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index 58e08fb47d1f..35fad110cc26 100644
---- a/drivers/gpu/drm/i915/intel_display.c
-+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -6225,9 +6225,11 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
- if (to_intel_plane_state(crtc->primary->state)->visible) {
- intel_crtc_wait_for_pending_flips(crtc);
- intel_pre_disable_primary(crtc);
-+
-+ intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
-+ to_intel_plane_state(crtc->primary->state)->visible = false;
- }
-
-- intel_crtc_disable_planes(crtc, crtc->state->plane_mask);
- dev_priv->display.crtc_disable(crtc);
- intel_disable_shared_dpll(intel_crtc);
-
---
-2.5.0
-
-
-From 42ab5c413c7cf61fab4b2fbce9cb4ab7f7be6356 Mon Sep 17 00:00:00 2001
-From: Chris Wilson <chris@chris-wilson.co.uk>
-Date: Fri, 11 Dec 2015 11:32:57 +0000
-Subject: [PATCH 22/26] drm/i915: Break busywaiting for requests on pending
- signals
-
-Upstream commit e7571f7fd66c77a760338340adbe41d994fe93ac
-
-The busywait in __i915_spin_request() does not respect pending signals
-and so may consume the entire timeslice for the task instead of
-returning to userspace to handle the signal.
-
-In the worst case this could cause a delay in signal processing of 20ms,
-which would be a noticeable jitter in cursor tracking. If a higher
-resolution signal was being used, for example to provide fairness of a
-server timeslices between clients, we could expect to detect some
-unfairness between clients (i.e. some windows not updating as fast as
-others). This issue was noticed when inspecting a report of poor
-interactivity resulting from excessively high __i915_spin_request usage.
-
-Fixes regression from
-commit 2def4ad99befa25775dd2f714fdd4d92faec6e34 [v4.2]
-Author: Chris Wilson <chris@chris-wilson.co.uk>
-Date: Tue Apr 7 16:20:41 2015 +0100
-
- drm/i915: Optimistically spin for the request completion
-
-v2: Try to assess the impact of the bug
-
-Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
-Cc: Jens Axboe <axboe@kernel.dk>
-Cc; "Rogozhkin, Dmitry V" <dmitry.v.rogozhkin@intel.com>
-Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
-Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
-Cc: Eero Tamminen <eero.t.tamminen@intel.com>
-Cc: "Rantala, Valtteri" <valtteri.rantala@intel.com>
-Cc: stable@vger.kernel.org
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Link: http://patchwork.freedesktop.org/patch/msgid/1449833608-22125-2-git-send-email-chris@chris-wilson.co.uk
-(cherry picked from commit 91b0c352ace9afec1fb51590c7b8bd60e0eb9fbd)
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/i915_gem.c | 13 ++++++++-----
- 1 file changed, 8 insertions(+), 5 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
-index dee065c2b6d8..c6e3ab72882f 100644
---- a/drivers/gpu/drm/i915/i915_gem.c
-+++ b/drivers/gpu/drm/i915/i915_gem.c
-@@ -1144,7 +1144,7 @@ static bool missed_irq(struct drm_i915_private *dev_priv,
- return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings);
- }
-
--static int __i915_spin_request(struct drm_i915_gem_request *req)
-+static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
- {
- unsigned long timeout;
-
-@@ -1156,6 +1156,9 @@ static int __i915_spin_request(struct drm_i915_gem_request *req)
- if (i915_gem_request_completed(req, true))
- return 0;
-
-+ if (signal_pending_state(state, current))
-+ break;
-+
- if (time_after_eq(jiffies, timeout))
- break;
-
-@@ -1195,6 +1198,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
- struct drm_i915_private *dev_priv = dev->dev_private;
- const bool irq_test_in_progress =
- ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
-+ int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
- DEFINE_WAIT(wait);
- unsigned long timeout_expire;
- s64 before, now;
-@@ -1219,7 +1223,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
- before = ktime_get_raw_ns();
-
- /* Optimistic spin for the next jiffie before touching IRQs */
-- ret = __i915_spin_request(req);
-+ ret = __i915_spin_request(req, state);
- if (ret == 0)
- goto out;
-
-@@ -1231,8 +1235,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
- for (;;) {
- struct timer_list timer;
-
-- prepare_to_wait(&ring->irq_queue, &wait,
-- interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
-+ prepare_to_wait(&ring->irq_queue, &wait, state);
-
- /* We need to check whether any gpu reset happened in between
- * the caller grabbing the seqno and now ... */
-@@ -1250,7 +1253,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
- break;
- }
-
-- if (interruptible && signal_pending(current)) {
-+ if (signal_pending_state(state, current)) {
- ret = -ERESTARTSYS;
- break;
- }
---
-2.5.0
-
-
-From 8cbf415a2aadd85cf9dfab28296a821ffea96d87 Mon Sep 17 00:00:00 2001
-From: Chris Wilson <chris@chris-wilson.co.uk>
-Date: Fri, 11 Dec 2015 11:32:58 +0000
-Subject: [PATCH 23/26] drm/i915: Limit the busy wait on requests to 5us not
- 10ms!
-
-Upstream commit f87a780f07b22b6dc4642dbaf44af65112076cb8
-
-When waiting for high frequency requests, the finite amount of time
-required to set up the irq and wait upon it limits the response rate. By
-busywaiting on the request completion for a short while we can service
-the high frequency waits as quick as possible. However, if it is a slow
-request, we want to sleep as quickly as possible. The tradeoff between
-waiting and sleeping is roughly the time it takes to sleep on a request,
-on the order of a microsecond. Based on measurements of synchronous
-workloads from across big core and little atom, I have set the limit for
-busywaiting as 10 microseconds. In most of the synchronous cases, we can
-reduce the limit down to as little as 2 miscroseconds, but that leaves
-quite a few test cases regressing by factors of 3 and more.
-
-The code currently uses the jiffie clock, but that is far too coarse (on
-the order of 10 milliseconds) and results in poor interactivity as the
-CPU ends up being hogged by slow requests. To get microsecond resolution
-we need to use a high resolution timer. The cheapest of which is polling
-local_clock(), but that is only valid on the same CPU. If we switch CPUs
-because the task was preempted, we can also use that as an indicator that
- the system is too busy to waste cycles on spinning and we should sleep
-instead.
-
-__i915_spin_request was introduced in
-commit 2def4ad99befa25775dd2f714fdd4d92faec6e34 [v4.2]
-Author: Chris Wilson <chris@chris-wilson.co.uk>
-Date: Tue Apr 7 16:20:41 2015 +0100
-
- drm/i915: Optimistically spin for the request completion
-
-v2: Drop full u64 for unsigned long - the timer is 32bit wraparound safe,
-so we can use native register sizes on smaller architectures. Mention
-the approximate microseconds units for elapsed time and add some extra
-comments describing the reason for busywaiting.
-
-v3: Raise the limit to 10us
-v4: Now 5us.
-
-Reported-by: Jens Axboe <axboe@kernel.dk>
-Link: https://lkml.org/lkml/2015/11/12/621
-Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
-Cc: "Rogozhkin, Dmitry V" <dmitry.v.rogozhkin@intel.com>
-Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
-Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
-Cc: Eero Tamminen <eero.t.tamminen@intel.com>
-Cc: "Rantala, Valtteri" <valtteri.rantala@intel.com>
-Cc: stable@vger.kernel.org
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Link: http://patchwork.freedesktop.org/patch/msgid/1449833608-22125-3-git-send-email-chris@chris-wilson.co.uk
-(cherry picked from commit ca5b721e238226af1d767103ac852aeb8e4c0764)
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/i915_gem.c | 47 +++++++++++++++++++++++++++++++++++++++--
- 1 file changed, 45 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
-index c6e3ab72882f..205316d056f1 100644
---- a/drivers/gpu/drm/i915/i915_gem.c
-+++ b/drivers/gpu/drm/i915/i915_gem.c
-@@ -1144,14 +1144,57 @@ static bool missed_irq(struct drm_i915_private *dev_priv,
- return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings);
- }
-
-+static unsigned long local_clock_us(unsigned *cpu)
-+{
-+ unsigned long t;
-+
-+ /* Cheaply and approximately convert from nanoseconds to microseconds.
-+ * The result and subsequent calculations are also defined in the same
-+ * approximate microseconds units. The principal source of timing
-+ * error here is from the simple truncation.
-+ *
-+ * Note that local_clock() is only defined wrt to the current CPU;
-+ * the comparisons are no longer valid if we switch CPUs. Instead of
-+ * blocking preemption for the entire busywait, we can detect the CPU
-+ * switch and use that as indicator of system load and a reason to
-+ * stop busywaiting, see busywait_stop().
-+ */
-+ *cpu = get_cpu();
-+ t = local_clock() >> 10;
-+ put_cpu();
-+
-+ return t;
-+}
-+
-+static bool busywait_stop(unsigned long timeout, unsigned cpu)
-+{
-+ unsigned this_cpu;
-+
-+ if (time_after(local_clock_us(&this_cpu), timeout))
-+ return true;
-+
-+ return this_cpu != cpu;
-+}
-+
- static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
- {
- unsigned long timeout;
-+ unsigned cpu;
-+
-+ /* When waiting for high frequency requests, e.g. during synchronous
-+ * rendering split between the CPU and GPU, the finite amount of time
-+ * required to set up the irq and wait upon it limits the response
-+ * rate. By busywaiting on the request completion for a short while we
-+ * can service the high frequency waits as quick as possible. However,
-+ * if it is a slow request, we want to sleep as quickly as possible.
-+ * The tradeoff between waiting and sleeping is roughly the time it
-+ * takes to sleep on a request, on the order of a microsecond.
-+ */
-
- if (i915_gem_request_get_ring(req)->irq_refcount)
- return -EBUSY;
-
-- timeout = jiffies + 1;
-+ timeout = local_clock_us(&cpu) + 5;
- while (!need_resched()) {
- if (i915_gem_request_completed(req, true))
- return 0;
-@@ -1159,7 +1202,7 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
- if (signal_pending_state(state, current))
- break;
-
-- if (time_after_eq(jiffies, timeout))
-+ if (busywait_stop(timeout, cpu))
- break;
-
- cpu_relax_lowlatency();
---
-2.5.0
-
-
-From 7b94b8683d8d2ac4b29099e24e351e03f163e462 Mon Sep 17 00:00:00 2001
-From: Chris Wilson <chris@chris-wilson.co.uk>
-Date: Fri, 11 Dec 2015 11:32:59 +0000
-Subject: [PATCH 24/26] drm/i915: Only spin whilst waiting on the current
- request
-
-Upstream commit 0f0cd472062eca6f9fac8be0cd5585f9a2df1ab2
-
-Limit busywaiting only to the request currently being processed by the
-GPU. If the request is not currently being processed by the GPU, there
-is a very low likelihood of it being completed within the 2 microsecond
-spin timeout and so we will just be wasting CPU cycles.
-
-v2: Check for logical inversion when rebasing - we were incorrectly
-checking for this request being active, and instead busywaiting for
-when the GPU was not yet processing the request of interest.
-
-v3: Try another colour for the seqno names.
-v4: Another colour for the function names.
-
-v5: Remove the forced coherency when checking for the active request. On
-reflection and plenty of recent experimentation, the issue is not a
-cache coherency problem - but an irq/seqno ordering problem (timing issue).
-Here, we do not need the w/a to force ordering of the read with an
-interrupt.
-
-Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
-Cc: "Rogozhkin, Dmitry V" <dmitry.v.rogozhkin@intel.com>
-Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
-Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
-Cc: Eero Tamminen <eero.t.tamminen@intel.com>
-Cc: "Rantala, Valtteri" <valtteri.rantala@intel.com>
-Cc: stable@vger.kernel.org
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Link: http://patchwork.freedesktop.org/patch/msgid/1449833608-22125-4-git-send-email-chris@chris-wilson.co.uk
-(cherry picked from commit 821485dc2ad665f136c57ee589bf7a8210160fe2)
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/i915_drv.h | 27 +++++++++++++++++++--------
- drivers/gpu/drm/i915/i915_gem.c | 8 +++++++-
- 2 files changed, 26 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
-index 475b03e9d584..bd6df685ae61 100644
---- a/drivers/gpu/drm/i915/i915_drv.h
-+++ b/drivers/gpu/drm/i915/i915_drv.h
-@@ -2178,8 +2178,17 @@ struct drm_i915_gem_request {
- struct drm_i915_private *i915;
- struct intel_engine_cs *ring;
-
-- /** GEM sequence number associated with this request. */
-- uint32_t seqno;
-+ /** GEM sequence number associated with the previous request,
-+ * when the HWS breadcrumb is equal to this the GPU is processing
-+ * this request.
-+ */
-+ u32 previous_seqno;
-+
-+ /** GEM sequence number associated with this request,
-+ * when the HWS breadcrumb is equal or greater than this the GPU
-+ * has finished processing this request.
-+ */
-+ u32 seqno;
-
- /** Position in the ringbuffer of the start of the request */
- u32 head;
-@@ -2880,15 +2889,17 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
- return (int32_t)(seq1 - seq2) >= 0;
- }
-
-+static inline bool i915_gem_request_started(struct drm_i915_gem_request *req,
-+ bool lazy_coherency)
-+{
-+ u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
-+ return i915_seqno_passed(seqno, req->previous_seqno);
-+}
-+
- static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
- bool lazy_coherency)
- {
-- u32 seqno;
--
-- BUG_ON(req == NULL);
--
-- seqno = req->ring->get_seqno(req->ring, lazy_coherency);
--
-+ u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency);
- return i915_seqno_passed(seqno, req->seqno);
- }
-
-diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
-index 205316d056f1..1bf658dc6553 100644
---- a/drivers/gpu/drm/i915/i915_gem.c
-+++ b/drivers/gpu/drm/i915/i915_gem.c
-@@ -1191,9 +1191,13 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
- * takes to sleep on a request, on the order of a microsecond.
- */
-
-- if (i915_gem_request_get_ring(req)->irq_refcount)
-+ if (req->ring->irq_refcount)
- return -EBUSY;
-
-+ /* Only spin if we know the GPU is processing this request */
-+ if (!i915_gem_request_started(req, true))
-+ return -EAGAIN;
-+
- timeout = local_clock_us(&cpu) + 5;
- while (!need_resched()) {
- if (i915_gem_request_completed(req, true))
-@@ -1207,6 +1211,7 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state)
-
- cpu_relax_lowlatency();
- }
-+
- if (i915_gem_request_completed(req, false))
- return 0;
-
-@@ -2591,6 +2596,7 @@ void __i915_add_request(struct drm_i915_gem_request *request,
- request->batch_obj = obj;
-
- request->emitted_jiffies = jiffies;
-+ request->previous_seqno = ring->last_submitted_seqno;
- ring->last_submitted_seqno = request->seqno;
- list_add_tail(&request->list, &ring->request_list);
-
---
-2.5.0
-
-
-From bf0176f1bb4bb6316102f4ca4d9314a20c228098 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
-Date: Fri, 18 Dec 2015 19:24:39 +0200
-Subject: [PATCH 25/26] drm/i915: Workaround CHV pipe C cursor fail
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Upstream commit ef8dd37af85a8f37ca3a29074647511e52c56181
-
-Turns out CHV pipe C was glued on somewhat poorly, and there's something
-wrong with the cursor. If the cursor straddles the left screen edge,
-and is then moved away from the edge or disabled, the pipe will often
-underrun. If enough underruns are triggered quickly enough the pipe
-will fall over and die (it just scans out a solid color and reports
-a constant underrun). We need to turn the disp2d power well off and
-on again to recover the pipe.
-
-None of that is very nice for the user, so let's just refuse to place
-the cursor in the compromised position. The ddx appears to fall back
-to swcursor when the ioctl returns an error, so theoretically there's
-no loss of functionality for the user (discounting swcursor bugs).
-I suppose most cursors images actually have the hotspot not exactly
-at 0,0 so under typical conditions the fallback will in fact kick in
-as soon as the cursor touches the left edge of the screen.
-
-Any atomic compositor should anyway be prepared to fall back to
-GPU composition when things don't work out, so there should be no
-problem with those.
-
-Other things that I tried to solve this include flipping all
-display related clock gating knobs I could find, increasing the
-minimum gtt alignment all the way up to 512k. I also tried to see
-if there are more specific screen coordinates that hit the bug, but
-the findings were somewhat inconclusive. Sometimes the failures
-happen almost across the whole left edge, sometimes more at the very
-top and around the bottom half. I wasn't able to find any real pattern
-to these variations, so it seems our only choice is to just refuse
-to straddle the left screen edge at all.
-
-Cc: stable@vger.kernel.org
-Cc: Jason Plum <max@warheads.net>
-Testcase: igt/kms_chv_cursor_fail
-Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92826
-Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
-Link: http://patchwork.freedesktop.org/patch/msgid/1450459479-16286-1-git-send-email-ville.syrjala@linux.intel.com
-Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-(cherry picked from commit b29ec92c4f5e6d45d8bae8194e664427a01c6687)
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index 35fad110cc26..c70a6cb8914f 100644
---- a/drivers/gpu/drm/i915/intel_display.c
-+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -13614,6 +13614,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
- struct drm_crtc *crtc = crtc_state->base.crtc;
- struct drm_framebuffer *fb = state->base.fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-+ enum pipe pipe = to_intel_plane(plane)->pipe;
- unsigned stride;
- int ret;
-
-@@ -13647,6 +13648,22 @@ intel_check_cursor_plane(struct drm_plane *plane,
- return -EINVAL;
- }
-
-+ /*
-+ * There's something wrong with the cursor on CHV pipe C.
-+ * If it straddles the left edge of the screen then
-+ * moving it away from the edge or disabling it often
-+ * results in a pipe underrun, and often that can lead to
-+ * dead pipe (constant underrun reported, and it scans
-+ * out just a solid color). To recover from that, the
-+ * display power well must be turned off and on again.
-+ * Refuse the put the cursor into that compromised position.
-+ */
-+ if (IS_CHERRYVIEW(plane->dev) && pipe == PIPE_C &&
-+ state->visible && state->base.crtc_x < 0) {
-+ DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
-+ return -EINVAL;
-+ }
-+
- return 0;
- }
-
---
-2.5.0
-
-
-From 036933da945df1526e0b5ee17fe8a8a77c1380e7 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
-Date: Thu, 10 Dec 2015 18:22:31 +0200
-Subject: [PATCH 26/26] drm/i915: Unbreak check_digital_port_conflicts()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Upstream commit ae35b56e367b9fef7f5de701cf8c1c3dd954dded
-
-Atomic changes broke check_digital_port_conflicts(). It needs to look
-at the global situation instead of just trying to find a conflict
-within the current atomic state.
-
-This bug made my HSW explode spectacularly after I had split the DDI
-encoders into separate DP and HDMI encoders. With the fix, things
-seem much more solid.
-
-I hope holding the connection_mutex is enough protection that we can
-actually walk the connectors even if they're not part of the current
-atomic state...
-
-v2: Regenerate the patch so that it actually applies (Jani)
-
-Cc: stable@vger.kernel.org
-Cc: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
-Fixes: 5448a00d3f06 ("drm/i915: Don't use staged config in check_digital_port_conflicts()")
-Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
-Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-Link: http://patchwork.freedesktop.org/patch/msgid/1449764551-12466-1-git-send-email-ville.syrjala@linux.intel.com
-(cherry picked from commit 0bff4858653312a10c83709e0009c3adb87e6f1e)
-Signed-off-by: Jani Nikula <jani.nikula@intel.com>
----
- drivers/gpu/drm/i915/intel_display.c | 12 ++++++++----
- 1 file changed, 8 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index c70a6cb8914f..aafe3e3de3ae 100644
---- a/drivers/gpu/drm/i915/intel_display.c
-+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -12026,18 +12026,22 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
- static bool check_digital_port_conflicts(struct drm_atomic_state *state)
- {
- struct drm_device *dev = state->dev;
-- struct intel_encoder *encoder;
- struct drm_connector *connector;
-- struct drm_connector_state *connector_state;
- unsigned int used_ports = 0;
-- int i;
-
- /*
- * Walk the connector list instead of the encoder
- * list to detect the problem on ddi platforms
- * where there's just one encoder per digital port.
- */
-- for_each_connector_in_state(state, connector, connector_state, i) {
-+ drm_for_each_connector(connector, dev) {
-+ struct drm_connector_state *connector_state;
-+ struct intel_encoder *encoder;
-+
-+ connector_state = drm_atomic_get_existing_connector_state(state, connector);
-+ if (!connector_state)
-+ connector_state = connector->state;
-+
- if (!connector_state->best_encoder)
- continue;
-
---
-2.5.0
-
diff --git a/ideapad-laptop-Add-Lenovo-Yoga-700-to-no_hw_rfkill-d.patch b/ideapad-laptop-Add-Lenovo-Yoga-700-to-no_hw_rfkill-d.patch
deleted file mode 100644
index da0c82750..000000000
--- a/ideapad-laptop-Add-Lenovo-Yoga-700-to-no_hw_rfkill-d.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 90da345613c5c0910b54b72019664e0b2ada19f9 Mon Sep 17 00:00:00 2001
-From: Josh Boyer <jwboyer@fedoraproject.org>
-Date: Tue, 12 Jan 2016 07:54:39 -0500
-Subject: [PATCH] ideapad-laptop: Add Lenovo Yoga 700 to no_hw_rfkill dmi list
-
-Like the Yoga 900 models the Lenovo Yoga 700 does not have a
-hw rfkill switch, and trying to read the hw rfkill switch through the
-ideapad module causes it to always reported blocking breaking wifi.
-
-This commit adds the Lenovo Yoga 700 to the no_hw_rfkill dmi list, fixing
-the wifi breakage.
-
-BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1295272
-Cc: stable@vger.kernel.org
-Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
----
- drivers/platform/x86/ideapad-laptop.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
-index d28db0e793df..51178626305d 100644
---- a/drivers/platform/x86/ideapad-laptop.c
-+++ b/drivers/platform/x86/ideapad-laptop.c
-@@ -900,6 +900,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
- },
- },
- {
-+ .ident = "Lenogo Yoga 700",
-+ .matches = {
-+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 700"),
-+ },
-+ },
-+ {
- .ident = "Lenovo Yoga 900",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
---
-2.5.0
-
diff --git a/ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch b/ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch
deleted file mode 100644
index 9f6e5db1c..000000000
--- a/ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 332faabbaab64876396be48f1a1cf72b31d53a9d Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Mon, 9 Nov 2015 17:09:05 +0100
-Subject: [PATCH] ideapad-laptop: Add Lenovo Yoga 900 to no_hw_rfkill dmi list
-
-Like some of the other Yoga models the Lenovo Yoga 900 does not have a
-hw rfkill switch, and trying to read the hw rfkill switch through the
-ideapad module causes it to always reported blocking breaking wifi.
-
-This commit adds the Lenovo Yoga 900 to the no_hw_rfkill dmi list, fixing
-the wifi breakage.
-
-BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1275490
-Cc: stable@vger.kernel.org
-Reported-and-tested-by: Kevin Fenzi <kevin@scrye.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/platform/x86/ideapad-laptop.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
-index fce49f3c6ed6..d4a48b4d161a 100644
---- a/drivers/platform/x86/ideapad-laptop.c
-+++ b/drivers/platform/x86/ideapad-laptop.c
-@@ -873,6 +873,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
- DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3 Pro-1370"),
- },
- },
-+ {
-+ .ident = "Lenovo Yoga 900",
-+ .matches = {
-+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 900"),
-+ },
-+ },
- {}
- };
-
---
-2.4.3
-
diff --git a/iommu-fix.patch b/iommu-fix.patch
new file mode 100644
index 000000000..08cdafd1a
--- /dev/null
+++ b/iommu-fix.patch
@@ -0,0 +1,92 @@
+From b91309eedd77374fdecc379942c44f903e2dedff Mon Sep 17 00:00:00 2001
+From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
+Date: Tue, 23 Feb 2016 13:03:30 +0100
+Subject: [PATCH] iommu/amd: Fix boot warning when device 00:00.0 is not iommu
+ covered
+
+The setup code for the performance counters in the AMD IOMMU driver
+tests whether the counters can be written. It tests to setup a counter
+for device 00:00.0, which fails on systems where this particular device
+is not covered by the IOMMU.
+
+Fix this by not relying on device 00:00.0 but only on the IOMMU being
+present.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/amd_iommu_init.c | 34 ++++++++++++++++++++++------------
+ 1 file changed, 22 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
+index 013bdff..d06a6d9 100644
+--- a/drivers/iommu/amd_iommu_init.c
++++ b/drivers/iommu/amd_iommu_init.c
+@@ -228,6 +228,10 @@ static int amd_iommu_enable_interrupts(void);
+ static int __init iommu_go_to_state(enum iommu_init_state state);
+ static void init_device_table_dma(void);
+
++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu,
++ u8 bank, u8 cntr, u8 fxn,
++ u64 *value, bool is_write);
++
+ static inline void update_last_devid(u16 devid)
+ {
+ if (devid > amd_iommu_last_bdf)
+@@ -1142,8 +1146,8 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu)
+ amd_iommu_pc_present = true;
+
+ /* Check if the performance counters can be written to */
+- if ((0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val, true)) ||
+- (0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val2, false)) ||
++ if ((0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val, true)) ||
++ (0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val2, false)) ||
+ (val != val2)) {
+ pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n");
+ amd_iommu_pc_present = false;
+@@ -2283,22 +2287,15 @@ u8 amd_iommu_pc_get_max_counters(u16 devid)
+ }
+ EXPORT_SYMBOL(amd_iommu_pc_get_max_counters);
+
+-int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu,
++ u8 bank, u8 cntr, u8 fxn,
+ u64 *value, bool is_write)
+ {
+- struct amd_iommu *iommu;
+ u32 offset;
+ u32 max_offset_lim;
+
+- /* Make sure the IOMMU PC resource is available */
+- if (!amd_iommu_pc_present)
+- return -ENODEV;
+-
+- /* Locate the iommu associated with the device ID */
+- iommu = amd_iommu_rlookup_table[devid];
+-
+ /* Check for valid iommu and pc register indexing */
+- if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7)))
++ if (WARN_ON((fxn > 0x28) || (fxn & 7)))
+ return -ENODEV;
+
+ offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn);
+@@ -2322,3 +2319,16 @@ int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
+ return 0;
+ }
+ EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val);
++
++int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
++ u64 *value, bool is_write)
++{
++ struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
++
++ /* Make sure the IOMMU PC resource is available */
++ if (!amd_iommu_pc_present || iommu == NULL)
++ return -ENODEV;
++
++ return iommu_pc_get_set_reg_val(iommu, bank, cntr, fxn,
++ value, is_write);
++}
+--
+1.8.4.5
diff --git a/kbuild-AFTER_LINK.patch b/kbuild-AFTER_LINK.patch
index 7a18fd241..805b6eef8 100644
--- a/kbuild-AFTER_LINK.patch
+++ b/kbuild-AFTER_LINK.patch
@@ -1,4 +1,4 @@
-From 7877d76b409181af38d307b98d8fed1024f3c9c2 Mon Sep 17 00:00:00 2001
+From a9488dbeccf188f0bd83b9d5704892f2c0f97fdc Mon Sep 17 00:00:00 2001
From: Roland McGrath <roland@redhat.com>
Date: Mon, 6 Oct 2008 23:03:03 -0700
Subject: [PATCH] kbuild: AFTER_LINK
@@ -21,10 +21,10 @@ Signed-off-by: Roland McGrath <roland@redhat.com>
7 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
-index f6fe17d88da5..eb6ddbf37f30 100644
+index b467fd0..feeff5e 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
-@@ -52,7 +52,8 @@ $(obj-vdso): %.o: %.S FORCE
+@@ -55,7 +55,8 @@ $(obj-vdso): %.o: %.S FORCE
# Actual build commands
quiet_cmd_vdsold = VDSOL $@
@@ -35,7 +35,7 @@ index f6fe17d88da5..eb6ddbf37f30 100644
cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile
-index 53e6c9b979ec..e427844e9bb0 100644
+index 6abffb7..7b103bb 100644
--- a/arch/powerpc/kernel/vdso32/Makefile
+++ b/arch/powerpc/kernel/vdso32/Makefile
@@ -43,7 +43,8 @@ $(obj-vdso32): %.o: %.S
@@ -49,7 +49,7 @@ index 53e6c9b979ec..e427844e9bb0 100644
cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $<
diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
-index effca9404b17..713891a92d23 100644
+index 8c8f2ae..a743ebe 100644
--- a/arch/powerpc/kernel/vdso64/Makefile
+++ b/arch/powerpc/kernel/vdso64/Makefile
@@ -36,7 +36,8 @@ $(obj-vdso64): %.o: %.S
@@ -63,7 +63,7 @@ index effca9404b17..713891a92d23 100644
cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
-index ee8a18e50a25..63e33fa049f8 100644
+index ee8a18e..63e33fa 100644
--- a/arch/s390/kernel/vdso32/Makefile
+++ b/arch/s390/kernel/vdso32/Makefile
@@ -43,7 +43,8 @@ $(obj-vdso32): %.o: %.S
@@ -77,7 +77,7 @@ index ee8a18e50a25..63e33fa049f8 100644
cmd_vdso32as = $(CC) $(a_flags) -c -o $@ $<
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
-index c4b03f9ed228..550450fc2f95 100644
+index c4b03f9..550450f 100644
--- a/arch/s390/kernel/vdso64/Makefile
+++ b/arch/s390/kernel/vdso64/Makefile
@@ -43,7 +43,8 @@ $(obj-vdso64): %.o: %.S
@@ -91,10 +91,10 @@ index c4b03f9ed228..550450fc2f95 100644
cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
-index a3d0767a6b29..078c9be1db8f 100644
+index 265c0ed..fd90c7d 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
-@@ -172,8 +172,9 @@ $(vdso32-images:%=$(obj)/%.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
+@@ -159,8 +159,9 @@ $(obj)/vdso32.so.dbg: FORCE \
quiet_cmd_vdso = VDSO $@
cmd_vdso = $(CC) -nostdlib -o $@ \
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
@@ -107,11 +107,11 @@ index a3d0767a6b29..078c9be1db8f 100644
VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=both) \
$(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS)
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
-index 1a10d8ac8162..092d0c0cf72c 100755
+index dacf71a..72cbefd 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -65,6 +65,10 @@ vmlinux_link()
- -lutil ${1}
+ -lutil -lrt ${1}
rm -f linux
fi
+ if [ -n "${AFTER_LINK}" ]; then
@@ -122,5 +122,5 @@ index 1a10d8ac8162..092d0c0cf72c 100755
--
-2.4.3
+2.5.0
diff --git a/kernel.spec b/kernel.spec
index fe8efafd9..b0f69fdc6 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -49,7 +49,7 @@ Summary: The Linux kernel
# base_sublevel is the kernel version we're starting with and patching
# on top of -- for example, 3.1-rc7-git1 starts with a 3.0 base,
# which yields a base_sublevel of 0.
-%define base_sublevel 3
+%define base_sublevel 4
## If this is a released kernel ##
%if 0%{?released_kernel}
@@ -58,7 +58,7 @@ Summary: The Linux kernel
%define stable_rc 0
# Do we have a -stable update to apply?
-%define stable_update 6
+%define stable_update 3
# Set rpm version accordingly
%if 0%{?stable_update}
%define stablerev %{stable_update}
@@ -521,22 +521,12 @@ Patch05: kbuild-AFTER_LINK.patch
Patch451: lib-cpumask-Make-CPUMASK_OFFSTACK-usable-without-deb.patch
-Patch452: amd-xgbe-a0-Add-support-for-XGBE-on-A0.patch
-
-Patch453: amd-xgbe-phy-a0-Add-support-for-XGBE-PHY-on-A0.patch
-
Patch454: arm64-avoid-needing-console-to-enable-serial-console.patch
-Patch455: usb-make-xhci-platform-driver-use-64-bit-or-32-bit-D.patch
-
Patch456: arm64-acpi-drop-expert-patch.patch
Patch457: ARM-tegra-usb-no-reset.patch
-Patch458: ARM-dts-Add-am335x-bonegreen.patch
-
-Patch459: 0001-watchdog-omap_wdt-fix-null-pointer-dereference.patch
-
Patch460: mfd-wm8994-Ensure-that-the-whole-MFD-is-built-into-a.patch
Patch463: arm-i.MX6-Utilite-device-dtb.patch
@@ -617,26 +607,9 @@ Patch503: drm-i915-turn-off-wc-mmaps.patch
Patch508: kexec-uefi-copy-secure_boot-flag-in-boot-params.patch
-#rhbz 1269300
-Patch552: megaraid_sas-Do-not-use-PAGE_SIZE-for-max_sectors.patch
-
-#rhbz 1275490
-Patch553: ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch
-
-#rhbz 1279189
-Patch556: netfilter-ipset-Fix-extension-alignment.patch
-Patch557: netfilter-ipset-Fix-hash-type-expiration.patch
-Patch558: netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch
-
-#rhbz 1284059
-Patch566: KEYS-Fix-handling-of-stored-error-in-a-negatively-in.patch
-
#CVE-2015-7833 rhbz 1270158 1270160
Patch567: usbvision-fix-crash-on-detecting-device-with-invalid.patch
-#CVE-2015-7515 rhbz 1285326 1285331
-Patch568: Input-aiptek-fix-crash-on-detecting-device-without-e.patch
-
#rhbz 1287819
Patch570: HID-multitouch-enable-palm-rejection-if-device-imple.patch
@@ -646,43 +619,11 @@ Patch571: ideapad-laptop-Add-Lenovo-ideapad-Y700-17ISK-to-no_h.patch
#rhbz 1288687
Patch572: alua_fix.patch
-#CVE-XXXX-XXXX rhbz 1291329 1291332
-Patch574: ovl-fix-permission-checking-for-setattr.patch
-
-#CVE-2015-8709 rhbz 1295287 1295288
-Patch603: ptrace-being-capable-wrt-a-process-requires-mapped-u.patch
-
-#CVE-2015-7513 rhbz 1284847 1296142
-Patch605: KVM-x86-Reload-pit-counters-for-all-channels-when-re.patch
-
-#rhbz 1281368
-Patch607: drm-nouveau-Fix-pre-nv50-pageflip-events-v4.patch
+Patch604: drm-i915-shut-up-gen8-SDE-irq-dmesg-noise-again.patch
#rhbz 1083853
Patch610: PNP-Add-Broadwell-to-Intel-MCH-size-workaround.patch
-#rhbz 1298192
-Patch626: selinux-fix-bug-in-conditional-rules-handling.patch
-
-#rhbz 1295272
-Patch627: ideapad-laptop-Add-Lenovo-Yoga-700-to-no_hw_rfkill-d.patch
-
-Patch628: i915-stable-backports.patch
-Patch635: nouveau-stable-backports.patch
-
-#rhbz 1299810
-Patch629: SCSI-refactor-device-matching-code-in-scsi_devinfo.c.patch
-Patch630: SCSI-fix-bug-in-scsi_dev_info_list-matching.patch
-
-Patch631: btrfs-handle-invalid-num_stripes-in-sys_array.patch
-Patch632: Btrfs-fix-fitrim-discarding-device-area-reserved-for.patch
-
-#rhbz 1279653
-Patch638: rtlwifi-rtl8821ae-Fix-5G-failure-when-EEPROM-is-inco.patch
-
-#CVE-XXXX-XXXX rhbz 1300731 1300732
-Patch639: netfilter-nf_nat_redirect-add-missing-NULL-pointer-c.patch
-
#rhbz 1300955
Patch640: PNP-Add-Haswell-ULT-to-Intel-MCH-size-workaround.patch
@@ -696,24 +637,25 @@ Patch645: cfg80211-wext-fix-message-ordering.patch
#rhbz 1255325
Patch646: HID-sony-do-not-bail-out-when-the-sixaxis-refuses-th.patch
-#rhbz 1303270
-Patch647: rtlwifi-fix-memory-leak-for-USB-device.patch
-
-#CVE-2016-0617 rhbz 1305803 1305804
-Patch648: fs-hugetlbfs-inode.c-fix-bugs-in-hugetlb_vmtruncate_.patch
-
#CVE-2016-2383 rhbz 1308452 1308453
Patch650: bpf-fix-branch-offset-adjustment-on-backjumps-after-.patch
-#rhbz 1306987
-Patch651: Input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch
-
-#rhbz 1305181 1299901
-Patch652: drm-mgag200-fix-kernel-hang-in-cursor-code.patch
-
#CVE-2015-8812 rhbz 1303532 1309548
Patch653: iw_cxgb3-Fix-incorrectly-returning-error-on-success.patch
+#Known use after free, possibly rhbz 1310579
+Patch654: 0001-usb-hub-fix-panic-in-usb_reset_and_verify_device.patch
+
+#rhbz 1310258
+Patch655: iommu-fix.patch
+
+#CVE-2016-2550 rhbz 1311517 1311518
+Patch656: unix-correctly-track-in-flight-fds-in-sending-proces.patch
+
+#rhbz 1310682
+Patch657: 0001-Test-ata-fix.patch
+
+Patch658: nouveau-displayoff-fix.patch
# END OF PATCH DEFINITIONS
%endif
@@ -1283,22 +1225,12 @@ ApplyPatch kbuild-AFTER_LINK.patch
ApplyPatch lib-cpumask-Make-CPUMASK_OFFSTACK-usable-without-deb.patch
-ApplyPatch amd-xgbe-a0-Add-support-for-XGBE-on-A0.patch
-
-ApplyPatch amd-xgbe-phy-a0-Add-support-for-XGBE-PHY-on-A0.patch
-
ApplyPatch arm64-avoid-needing-console-to-enable-serial-console.patch
-ApplyPatch usb-make-xhci-platform-driver-use-64-bit-or-32-bit-D.patch
-
ApplyPatch arm64-acpi-drop-expert-patch.patch
ApplyPatch ARM-tegra-usb-no-reset.patch
-ApplyPatch ARM-dts-Add-am335x-bonegreen.patch
-
-ApplyPatch 0001-watchdog-omap_wdt-fix-null-pointer-dereference.patch
-
ApplyPatch mfd-wm8994-Ensure-that-the-whole-MFD-is-built-into-a.patch
ApplyPatch arm-i.MX6-Utilite-device-dtb.patch
@@ -1379,26 +1311,9 @@ ApplyPatch drm-i915-turn-off-wc-mmaps.patch
ApplyPatch kexec-uefi-copy-secure_boot-flag-in-boot-params.patch
-#rhbz 1269300
-ApplyPatch megaraid_sas-Do-not-use-PAGE_SIZE-for-max_sectors.patch
-
-#rhbz 1275490
-ApplyPatch ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch
-
-#rhbz 1279189
-ApplyPatch netfilter-ipset-Fix-extension-alignment.patch
-ApplyPatch netfilter-ipset-Fix-hash-type-expiration.patch
-ApplyPatch netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch
-
-#rhbz 1284059
-ApplyPatch KEYS-Fix-handling-of-stored-error-in-a-negatively-in.patch
-
#CVE-2015-7833 rhbz 1270158 1270160
ApplyPatch usbvision-fix-crash-on-detecting-device-with-invalid.patch
-#CVE-2015-7515 rhbz 1285326 1285331
-ApplyPatch Input-aiptek-fix-crash-on-detecting-device-without-e.patch
-
#rhbz 1287819
ApplyPatch HID-multitouch-enable-palm-rejection-if-device-imple.patch
@@ -1408,43 +1323,9 @@ ApplyPatch ideapad-laptop-Add-Lenovo-ideapad-Y700-17ISK-to-no_h.patch
#rhbz 1288687
ApplyPatch alua_fix.patch
-#CVE-XXXX-XXXX rhbz 1291329 1291332
-ApplyPatch ovl-fix-permission-checking-for-setattr.patch
-
-#CVE-2015-8709 rhbz 1295287 1295288
-ApplyPatch ptrace-being-capable-wrt-a-process-requires-mapped-u.patch
-
-#CVE-2015-7513 rhbz 1284847 1296142
-ApplyPatch KVM-x86-Reload-pit-counters-for-all-channels-when-re.patch
-
-#rhbz 1281368
-ApplyPatch drm-nouveau-Fix-pre-nv50-pageflip-events-v4.patch
-
#rhbz 1083853
ApplyPatch PNP-Add-Broadwell-to-Intel-MCH-size-workaround.patch
-#rhbz 1298192
-ApplyPatch selinux-fix-bug-in-conditional-rules-handling.patch
-
-#rhbz 1295272
-ApplyPatch ideapad-laptop-Add-Lenovo-Yoga-700-to-no_hw_rfkill-d.patch
-
-ApplyPatch i915-stable-backports.patch
-ApplyPatch nouveau-stable-backports.patch
-
-#rhbz 1299810
-ApplyPatch SCSI-refactor-device-matching-code-in-scsi_devinfo.c.patch
-ApplyPatch SCSI-fix-bug-in-scsi_dev_info_list-matching.patch
-
-ApplyPatch btrfs-handle-invalid-num_stripes-in-sys_array.patch
-ApplyPatch Btrfs-fix-fitrim-discarding-device-area-reserved-for.patch
-
-#rhbz 1279653
-ApplyPatch rtlwifi-rtl8821ae-Fix-5G-failure-when-EEPROM-is-inco.patch
-
-#CVE-XXXX-XXXX rhbz 1300731 1300732
-ApplyPatch netfilter-nf_nat_redirect-add-missing-NULL-pointer-c.patch
-
#rhbz 1300955
ApplyPatch PNP-Add-Haswell-ULT-to-Intel-MCH-size-workaround.patch
@@ -1458,24 +1339,25 @@ ApplyPatch cfg80211-wext-fix-message-ordering.patch
#rhbz 1255325
ApplyPatch HID-sony-do-not-bail-out-when-the-sixaxis-refuses-th.patch
-#rhbz 1303270
-ApplyPatch rtlwifi-fix-memory-leak-for-USB-device.patch
-
-#CVE-2016-0617 rhbz 1305803 1305804
-ApplyPatch fs-hugetlbfs-inode.c-fix-bugs-in-hugetlb_vmtruncate_.patch
-
#CVE-2016-2383 rhbz 1308452 1308453
ApplyPatch bpf-fix-branch-offset-adjustment-on-backjumps-after-.patch
-#rhbz 1306987
-ApplyPatch Input-elantech-mark-protocols-v2-and-v3-as-semi-mt.patch
-
-#rhbz 1305181 1299901
-ApplyPatch drm-mgag200-fix-kernel-hang-in-cursor-code.patch
-
#CVE-2015-8812 rhbz 1303532 1309548
ApplyPatch iw_cxgb3-Fix-incorrectly-returning-error-on-success.patch
+#Known use after free, possibly rhbz 1310579
+ApplyPatch 0001-usb-hub-fix-panic-in-usb_reset_and_verify_device.patch
+
+#rhbz 1310258
+ApplyPatch iommu-fix.patch
+
+#CVE-2016-2550 rhbz 1311517 1311518
+ApplyPatch unix-correctly-track-in-flight-fds-in-sending-proces.patch
+
+#rhbz 1310682
+ApplyPatch 0001-Test-ata-fix.patch
+
+ApplyPatch nouveau-displayoff-fix.patch
# END OF PATCH APPLICATIONS
%endif
@@ -2325,6 +2207,15 @@ fi
#
#
%changelog
+* Fri Feb 26 2016 Laura Abbott <labbott@fedoraproject.org> - 4.4.3-200
+- Linux v4.4.3
+
+* Wed Feb 24 2016 Josh Boyer <jwboyer@fedoraproject.org>
+- CVE-2016-2550 af_unix: incorrect accounting on in-flight fds (rhbz 1311517 1311518)
+
+* Mon Feb 22 2016 Josh Boyer <jwboyer@fedoraproject.org> - 4.3.6-201
+- Revert broken usb patch
+
* Sat Feb 20 2016 Josh Boyer <jwboyer@fedoraproject.org> - 4.3.6-200
- Linux v4.3.6
diff --git a/megaraid_sas-Do-not-use-PAGE_SIZE-for-max_sectors.patch b/megaraid_sas-Do-not-use-PAGE_SIZE-for-max_sectors.patch
deleted file mode 100644
index 769337dfa..000000000
--- a/megaraid_sas-Do-not-use-PAGE_SIZE-for-max_sectors.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From c6f081c88ab76d5a40365b94c1f5839e099b2b2b Mon Sep 17 00:00:00 2001
-From: "sumit.saxena@avagotech.com" <sumit.saxena@avagotech.com>
-Date: Thu, 15 Oct 2015 13:40:04 +0530
-Subject: [PATCH] megaraid_sas: Do not use PAGE_SIZE for max_sectors
-
-Do not use PAGE_SIZE marco to calculate max_sectors per I/O
-request. Driver code assumes PAGE_SIZE will be always 4096 which can
-lead to wrongly calculated value if PAGE_SIZE is not 4096. This issue
-was reported in Ubuntu Bugzilla Bug #1475166.
-
-Cc: <stable@vger.kernel.org>
-Signed-off-by: Sumit Saxena <sumit.saxena@avagotech.com>
-Signed-off-by: Kashyap Desai <kashyap.desai@avagotech.com>
-Reviewed-by: Tomas Henzl <thenzl@redhat.com>
-Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
----
- drivers/scsi/megaraid/megaraid_sas.h | 2 ++
- drivers/scsi/megaraid/megaraid_sas_base.c | 2 +-
- 2 files changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
-index 20c37541963f..ebf821b94cb6 100644
---- a/drivers/scsi/megaraid/megaraid_sas.h
-+++ b/drivers/scsi/megaraid/megaraid_sas.h
-@@ -364,6 +364,8 @@ enum MR_EVT_ARGS {
- MR_EVT_ARGS_GENERIC,
- };
-
-+
-+#define SGE_BUFFER_SIZE 4096
- /*
- * define constants for device list query options
- */
-diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
-index eaa81e552fd2..a9eb10ebc6ed 100644
---- a/drivers/scsi/megaraid/megaraid_sas_base.c
-+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
-@@ -4752,7 +4752,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
-
-
- instance->max_sectors_per_req = instance->max_num_sge *
-- PAGE_SIZE / 512;
-+ SGE_BUFFER_SIZE / 512;
- if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
- instance->max_sectors_per_req = tmp_sectors;
-
---
-2.4.3
-
diff --git a/netfilter-ipset-Fix-extension-alignment.patch b/netfilter-ipset-Fix-extension-alignment.patch
deleted file mode 100644
index 0a955e246..000000000
--- a/netfilter-ipset-Fix-extension-alignment.patch
+++ /dev/null
@@ -1,481 +0,0 @@
-From 55301931f78c0fdbb8f76dfdb3f914e9eef1f273 Mon Sep 17 00:00:00 2001
-From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-Date: Sat, 7 Nov 2015 11:21:47 +0100
-Subject: [PATCH 1/3] netfilter: ipset: Fix extension alignment
-
-The data extensions in ipset lacked the proper memory alignment and
-thus could lead to kernel crash on several architectures. Therefore
-the structures have been reorganized and alignment attributes added
-where needed. The patch was tested on armv7h by Gerhard Wiesinger and
-on x86_64, sparc64 by Jozsef Kadlecsik.
-
-Reported-by: Gerhard Wiesinger <lists@wiesinger.com>
-Tested-by: Gerhard Wiesinger <lists@wiesinger.com>
-Tested-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
----
- include/linux/netfilter/ipset/ip_set.h | 2 +-
- net/netfilter/ipset/ip_set_bitmap_gen.h | 17 +++-----
- net/netfilter/ipset/ip_set_bitmap_ip.c | 14 ++-----
- net/netfilter/ipset/ip_set_bitmap_ipmac.c | 64 ++++++++++++++-----------------
- net/netfilter/ipset/ip_set_bitmap_port.c | 18 ++++-----
- net/netfilter/ipset/ip_set_core.c | 14 ++++---
- net/netfilter/ipset/ip_set_hash_gen.h | 11 ++++--
- net/netfilter/ipset/ip_set_list_set.c | 5 ++-
- 8 files changed, 65 insertions(+), 80 deletions(-)
-
-diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
-index 48bb01edcf30..0e1f433cc4b7 100644
---- a/include/linux/netfilter/ipset/ip_set.h
-+++ b/include/linux/netfilter/ipset/ip_set.h
-@@ -421,7 +421,7 @@ extern void ip_set_free(void *members);
- extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr);
- extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr);
- extern size_t ip_set_elem_len(struct ip_set *set, struct nlattr *tb[],
-- size_t len);
-+ size_t len, size_t align);
- extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
- struct ip_set_ext *ext);
-
-diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h
-index d05e759ed0fa..b0bc475f641e 100644
---- a/net/netfilter/ipset/ip_set_bitmap_gen.h
-+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
-@@ -33,7 +33,7 @@
- #define mtype_gc IPSET_TOKEN(MTYPE, _gc)
- #define mtype MTYPE
-
--#define get_ext(set, map, id) ((map)->extensions + (set)->dsize * (id))
-+#define get_ext(set, map, id) ((map)->extensions + ((set)->dsize * (id)))
-
- static void
- mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
-@@ -67,12 +67,9 @@ mtype_destroy(struct ip_set *set)
- del_timer_sync(&map->gc);
-
- ip_set_free(map->members);
-- if (set->dsize) {
-- if (set->extensions & IPSET_EXT_DESTROY)
-- mtype_ext_cleanup(set);
-- ip_set_free(map->extensions);
-- }
-- kfree(map);
-+ if (set->dsize && set->extensions & IPSET_EXT_DESTROY)
-+ mtype_ext_cleanup(set);
-+ ip_set_free(map);
-
- set->data = NULL;
- }
-@@ -92,16 +89,14 @@ mtype_head(struct ip_set *set, struct sk_buff *skb)
- {
- const struct mtype *map = set->data;
- struct nlattr *nested;
-+ size_t memsize = sizeof(*map) + map->memsize;
-
- nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
- if (!nested)
- goto nla_put_failure;
- if (mtype_do_head(skb, map) ||
- nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
-- nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
-- htonl(sizeof(*map) +
-- map->memsize +
-- set->dsize * map->elements)))
-+ nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
- goto nla_put_failure;
- if (unlikely(ip_set_put_flags(skb, set)))
- goto nla_put_failure;
-diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c
-index 64a564334418..4783efff0bde 100644
---- a/net/netfilter/ipset/ip_set_bitmap_ip.c
-+++ b/net/netfilter/ipset/ip_set_bitmap_ip.c
-@@ -41,7 +41,6 @@ MODULE_ALIAS("ip_set_bitmap:ip");
- /* Type structure */
- struct bitmap_ip {
- void *members; /* the set members */
-- void *extensions; /* data extensions */
- u32 first_ip; /* host byte order, included in range */
- u32 last_ip; /* host byte order, included in range */
- u32 elements; /* number of max elements in the set */
-@@ -49,6 +48,8 @@ struct bitmap_ip {
- size_t memsize; /* members size */
- u8 netmask; /* subnet netmask */
- struct timer_list gc; /* garbage collection */
-+ unsigned char extensions[0] /* data extensions */
-+ __aligned(__alignof__(u64));
- };
-
- /* ADT structure for generic function args */
-@@ -224,13 +225,6 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
- map->members = ip_set_alloc(map->memsize);
- if (!map->members)
- return false;
-- if (set->dsize) {
-- map->extensions = ip_set_alloc(set->dsize * elements);
-- if (!map->extensions) {
-- kfree(map->members);
-- return false;
-- }
-- }
- map->first_ip = first_ip;
- map->last_ip = last_ip;
- map->elements = elements;
-@@ -316,13 +310,13 @@ bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
- pr_debug("hosts %u, elements %llu\n",
- hosts, (unsigned long long)elements);
-
-- map = kzalloc(sizeof(*map), GFP_KERNEL);
-+ set->dsize = ip_set_elem_len(set, tb, 0, 0);
-+ map = ip_set_alloc(sizeof(*map) + elements * set->dsize);
- if (!map)
- return -ENOMEM;
-
- map->memsize = bitmap_bytes(0, elements - 1);
- set->variant = &bitmap_ip;
-- set->dsize = ip_set_elem_len(set, tb, 0);
- if (!init_map_ip(set, map, first_ip, last_ip,
- elements, hosts, netmask)) {
- kfree(map);
-diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
-index 1430535118fb..29dde208381d 100644
---- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
-+++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
-@@ -47,24 +47,26 @@ enum {
- /* Type structure */
- struct bitmap_ipmac {
- void *members; /* the set members */
-- void *extensions; /* MAC + data extensions */
- u32 first_ip; /* host byte order, included in range */
- u32 last_ip; /* host byte order, included in range */
- u32 elements; /* number of max elements in the set */
- size_t memsize; /* members size */
- struct timer_list gc; /* garbage collector */
-+ unsigned char extensions[0] /* MAC + data extensions */
-+ __aligned(__alignof__(u64));
- };
-
- /* ADT structure for generic function args */
- struct bitmap_ipmac_adt_elem {
-+ unsigned char ether[ETH_ALEN] __aligned(2);
- u16 id;
-- unsigned char *ether;
-+ u16 add_mac;
- };
-
- struct bitmap_ipmac_elem {
- unsigned char ether[ETH_ALEN];
- unsigned char filled;
--} __attribute__ ((aligned));
-+} __aligned(__alignof__(u64));
-
- static inline u32
- ip_to_id(const struct bitmap_ipmac *m, u32 ip)
-@@ -72,11 +74,11 @@ ip_to_id(const struct bitmap_ipmac *m, u32 ip)
- return ip - m->first_ip;
- }
-
--static inline struct bitmap_ipmac_elem *
--get_elem(void *extensions, u16 id, size_t dsize)
--{
-- return (struct bitmap_ipmac_elem *)(extensions + id * dsize);
--}
-+#define get_elem(extensions, id, dsize) \
-+ (struct bitmap_ipmac_elem *)(extensions + (id) * (dsize))
-+
-+#define get_const_elem(extensions, id, dsize) \
-+ (const struct bitmap_ipmac_elem *)(extensions + (id) * (dsize))
-
- /* Common functions */
-
-@@ -88,10 +90,9 @@ bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e,
-
- if (!test_bit(e->id, map->members))
- return 0;
-- elem = get_elem(map->extensions, e->id, dsize);
-- if (elem->filled == MAC_FILLED)
-- return !e->ether ||
-- ether_addr_equal(e->ether, elem->ether);
-+ elem = get_const_elem(map->extensions, e->id, dsize);
-+ if (e->add_mac && elem->filled == MAC_FILLED)
-+ return ether_addr_equal(e->ether, elem->ether);
- /* Trigger kernel to fill out the ethernet address */
- return -EAGAIN;
- }
-@@ -103,7 +104,7 @@ bitmap_ipmac_gc_test(u16 id, const struct bitmap_ipmac *map, size_t dsize)
-
- if (!test_bit(id, map->members))
- return 0;
-- elem = get_elem(map->extensions, id, dsize);
-+ elem = get_const_elem(map->extensions, id, dsize);
- /* Timer not started for the incomplete elements */
- return elem->filled == MAC_FILLED;
- }
-@@ -133,7 +134,7 @@ bitmap_ipmac_add_timeout(unsigned long *timeout,
- * and we can reuse it later when MAC is filled out,
- * possibly by the kernel
- */
-- if (e->ether)
-+ if (e->add_mac)
- ip_set_timeout_set(timeout, t);
- else
- *timeout = t;
-@@ -150,7 +151,7 @@ bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e,
- elem = get_elem(map->extensions, e->id, dsize);
- if (test_bit(e->id, map->members)) {
- if (elem->filled == MAC_FILLED) {
-- if (e->ether &&
-+ if (e->add_mac &&
- (flags & IPSET_FLAG_EXIST) &&
- !ether_addr_equal(e->ether, elem->ether)) {
- /* memcpy isn't atomic */
-@@ -159,7 +160,7 @@ bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e,
- ether_addr_copy(elem->ether, e->ether);
- }
- return IPSET_ADD_FAILED;
-- } else if (!e->ether)
-+ } else if (!e->add_mac)
- /* Already added without ethernet address */
- return IPSET_ADD_FAILED;
- /* Fill the MAC address and trigger the timer activation */
-@@ -168,7 +169,7 @@ bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e,
- ether_addr_copy(elem->ether, e->ether);
- elem->filled = MAC_FILLED;
- return IPSET_ADD_START_STORED_TIMEOUT;
-- } else if (e->ether) {
-+ } else if (e->add_mac) {
- /* We can store MAC too */
- ether_addr_copy(elem->ether, e->ether);
- elem->filled = MAC_FILLED;
-@@ -191,7 +192,7 @@ bitmap_ipmac_do_list(struct sk_buff *skb, const struct bitmap_ipmac *map,
- u32 id, size_t dsize)
- {
- const struct bitmap_ipmac_elem *elem =
-- get_elem(map->extensions, id, dsize);
-+ get_const_elem(map->extensions, id, dsize);
-
- return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
- htonl(map->first_ip + id)) ||
-@@ -213,7 +214,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
- {
- struct bitmap_ipmac *map = set->data;
- ipset_adtfn adtfn = set->variant->adt[adt];
-- struct bitmap_ipmac_adt_elem e = { .id = 0 };
-+ struct bitmap_ipmac_adt_elem e = { .id = 0, .add_mac = 1 };
- struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
- u32 ip;
-
-@@ -231,7 +232,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
- return -EINVAL;
-
- e.id = ip_to_id(map, ip);
-- e.ether = eth_hdr(skb)->h_source;
-+ memcpy(e.ether, eth_hdr(skb)->h_source, ETH_ALEN);
-
- return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
- }
-@@ -265,11 +266,10 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
- return -IPSET_ERR_BITMAP_RANGE;
-
- e.id = ip_to_id(map, ip);
-- if (tb[IPSET_ATTR_ETHER])
-- e.ether = nla_data(tb[IPSET_ATTR_ETHER]);
-- else
-- e.ether = NULL;
--
-+ if (tb[IPSET_ATTR_ETHER]) {
-+ memcpy(e.ether, nla_data(tb[IPSET_ATTR_ETHER]), ETH_ALEN);
-+ e.add_mac = 1;
-+ }
- ret = adtfn(set, &e, &ext, &ext, flags);
-
- return ip_set_eexist(ret, flags) ? 0 : ret;
-@@ -300,13 +300,6 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
- map->members = ip_set_alloc(map->memsize);
- if (!map->members)
- return false;
-- if (set->dsize) {
-- map->extensions = ip_set_alloc(set->dsize * elements);
-- if (!map->extensions) {
-- kfree(map->members);
-- return false;
-- }
-- }
- map->first_ip = first_ip;
- map->last_ip = last_ip;
- map->elements = elements;
-@@ -361,14 +354,15 @@ bitmap_ipmac_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
- if (elements > IPSET_BITMAP_MAX_RANGE + 1)
- return -IPSET_ERR_BITMAP_RANGE_SIZE;
-
-- map = kzalloc(sizeof(*map), GFP_KERNEL);
-+ set->dsize = ip_set_elem_len(set, tb,
-+ sizeof(struct bitmap_ipmac_elem),
-+ __alignof__(struct bitmap_ipmac_elem));
-+ map = ip_set_alloc(sizeof(*map) + elements * set->dsize);
- if (!map)
- return -ENOMEM;
-
- map->memsize = bitmap_bytes(0, elements - 1);
- set->variant = &bitmap_ipmac;
-- set->dsize = ip_set_elem_len(set, tb,
-- sizeof(struct bitmap_ipmac_elem));
- if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
- kfree(map);
- return -ENOMEM;
-diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c
-index 5338ccd5da46..7f0c733358a4 100644
---- a/net/netfilter/ipset/ip_set_bitmap_port.c
-+++ b/net/netfilter/ipset/ip_set_bitmap_port.c
-@@ -35,12 +35,13 @@ MODULE_ALIAS("ip_set_bitmap:port");
- /* Type structure */
- struct bitmap_port {
- void *members; /* the set members */
-- void *extensions; /* data extensions */
- u16 first_port; /* host byte order, included in range */
- u16 last_port; /* host byte order, included in range */
- u32 elements; /* number of max elements in the set */
- size_t memsize; /* members size */
- struct timer_list gc; /* garbage collection */
-+ unsigned char extensions[0] /* data extensions */
-+ __aligned(__alignof__(u64));
- };
-
- /* ADT structure for generic function args */
-@@ -209,13 +210,6 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
- map->members = ip_set_alloc(map->memsize);
- if (!map->members)
- return false;
-- if (set->dsize) {
-- map->extensions = ip_set_alloc(set->dsize * map->elements);
-- if (!map->extensions) {
-- kfree(map->members);
-- return false;
-- }
-- }
- map->first_port = first_port;
- map->last_port = last_port;
- set->timeout = IPSET_NO_TIMEOUT;
-@@ -232,6 +226,7 @@ bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
- {
- struct bitmap_port *map;
- u16 first_port, last_port;
-+ u32 elements;
-
- if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
- !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) ||
-@@ -248,14 +243,15 @@ bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
- last_port = tmp;
- }
-
-- map = kzalloc(sizeof(*map), GFP_KERNEL);
-+ elements = last_port - first_port + 1;
-+ set->dsize = ip_set_elem_len(set, tb, 0, 0);
-+ map = ip_set_alloc(sizeof(*map) + elements * set->dsize);
- if (!map)
- return -ENOMEM;
-
-- map->elements = last_port - first_port + 1;
-+ map->elements = elements;
- map->memsize = bitmap_bytes(0, map->elements);
- set->variant = &bitmap_port;
-- set->dsize = ip_set_elem_len(set, tb, 0);
- if (!init_map_port(set, map, first_port, last_port)) {
- kfree(map);
- return -ENOMEM;
-diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
-index 338b4047776f..cab4bc06cddd 100644
---- a/net/netfilter/ipset/ip_set_core.c
-+++ b/net/netfilter/ipset/ip_set_core.c
-@@ -364,25 +364,27 @@ add_extension(enum ip_set_ext_id id, u32 flags, struct nlattr *tb[])
- }
-
- size_t
--ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len)
-+ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len,
-+ size_t align)
- {
- enum ip_set_ext_id id;
-- size_t offset = len;
- u32 cadt_flags = 0;
-
- if (tb[IPSET_ATTR_CADT_FLAGS])
- cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
- if (cadt_flags & IPSET_FLAG_WITH_FORCEADD)
- set->flags |= IPSET_CREATE_FLAG_FORCEADD;
-+ if (!align)
-+ align = 1;
- for (id = 0; id < IPSET_EXT_ID_MAX; id++) {
- if (!add_extension(id, cadt_flags, tb))
- continue;
-- offset = ALIGN(offset, ip_set_extensions[id].align);
-- set->offset[id] = offset;
-+ len = ALIGN(len, ip_set_extensions[id].align);
-+ set->offset[id] = len;
- set->extensions |= ip_set_extensions[id].type;
-- offset += ip_set_extensions[id].len;
-+ len += ip_set_extensions[id].len;
- }
-- return offset;
-+ return ALIGN(len, align);
- }
- EXPORT_SYMBOL_GPL(ip_set_elem_len);
-
-diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
-index 691b54fcaf2a..4ff22194ce55 100644
---- a/net/netfilter/ipset/ip_set_hash_gen.h
-+++ b/net/netfilter/ipset/ip_set_hash_gen.h
-@@ -72,8 +72,9 @@ struct hbucket {
- DECLARE_BITMAP(used, AHASH_MAX_TUNED);
- u8 size; /* size of the array */
- u8 pos; /* position of the first free entry */
-- unsigned char value[0]; /* the array of the values */
--} __attribute__ ((aligned));
-+ unsigned char value[0] /* the array of the values */
-+ __aligned(__alignof__(u64));
-+};
-
- /* The hash table: the table size stored here in order to make resizing easy */
- struct htable {
-@@ -1323,12 +1324,14 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
- #endif
- set->variant = &IPSET_TOKEN(HTYPE, 4_variant);
- set->dsize = ip_set_elem_len(set, tb,
-- sizeof(struct IPSET_TOKEN(HTYPE, 4_elem)));
-+ sizeof(struct IPSET_TOKEN(HTYPE, 4_elem)),
-+ __alignof__(struct IPSET_TOKEN(HTYPE, 4_elem)));
- #ifndef IP_SET_PROTO_UNDEF
- } else {
- set->variant = &IPSET_TOKEN(HTYPE, 6_variant);
- set->dsize = ip_set_elem_len(set, tb,
-- sizeof(struct IPSET_TOKEN(HTYPE, 6_elem)));
-+ sizeof(struct IPSET_TOKEN(HTYPE, 6_elem)),
-+ __alignof__(struct IPSET_TOKEN(HTYPE, 6_elem)));
- }
- #endif
- if (tb[IPSET_ATTR_TIMEOUT]) {
-diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
-index 5a30ce6e8c90..bbede95c9f68 100644
---- a/net/netfilter/ipset/ip_set_list_set.c
-+++ b/net/netfilter/ipset/ip_set_list_set.c
-@@ -31,7 +31,7 @@ struct set_elem {
- struct rcu_head rcu;
- struct list_head list;
- ip_set_id_t id;
--};
-+} __aligned(__alignof__(u64));
-
- struct set_adt_elem {
- ip_set_id_t id;
-@@ -618,7 +618,8 @@ list_set_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
- size = IP_SET_LIST_MIN_SIZE;
-
- set->variant = &set_variant;
-- set->dsize = ip_set_elem_len(set, tb, sizeof(struct set_elem));
-+ set->dsize = ip_set_elem_len(set, tb, sizeof(struct set_elem),
-+ __alignof__(struct set_elem));
- if (!init_list_set(net, set, size))
- return -ENOMEM;
- if (tb[IPSET_ATTR_TIMEOUT]) {
---
-2.4.3
-
diff --git a/netfilter-ipset-Fix-hash-type-expiration.patch b/netfilter-ipset-Fix-hash-type-expiration.patch
deleted file mode 100644
index 16ba4387f..000000000
--- a/netfilter-ipset-Fix-hash-type-expiration.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 7210b25e452780f0792e04dd9f84f3a02c582ab7 Mon Sep 17 00:00:00 2001
-From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-Date: Sat, 7 Nov 2015 11:23:34 +0100
-Subject: [PATCH 2/3] netfilter: ipset: Fix hash:* type expiration
-
-Incorrect index was used when the data blob was shrinked at expiration,
-which could lead to falsely expired entries and memory leak when
-the comment extension was used too.
-
-Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
----
- net/netfilter/ipset/ip_set_hash_gen.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
-index 4ff22194ce55..fa4f6374bb73 100644
---- a/net/netfilter/ipset/ip_set_hash_gen.h
-+++ b/net/netfilter/ipset/ip_set_hash_gen.h
-@@ -523,7 +523,7 @@ mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize)
- continue;
- data = ahash_data(n, j, dsize);
- memcpy(tmp->value + d * dsize, data, dsize);
-- set_bit(j, tmp->used);
-+ set_bit(d, tmp->used);
- d++;
- }
- tmp->pos = d;
---
-2.4.3
-
diff --git a/netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch b/netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch
deleted file mode 100644
index 1f0d86373..000000000
--- a/netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 03fdcf282c8fe212efae0d1229fb8594ffe60b17 Mon Sep 17 00:00:00 2001
-From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-Date: Sat, 7 Nov 2015 11:24:51 +0100
-Subject: [PATCH 3/3] netfilter: ipset: Fix hash type expire: release empty
- hash bucket block
-
-When all entries are expired/all slots are empty, release the bucket.
-
-Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
----
- net/netfilter/ipset/ip_set_hash_gen.h | 13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
-diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
-index fa4f6374bb73..e5336ab36d67 100644
---- a/net/netfilter/ipset/ip_set_hash_gen.h
-+++ b/net/netfilter/ipset/ip_set_hash_gen.h
-@@ -476,7 +476,7 @@ static void
- mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize)
- {
- struct htable *t;
-- struct hbucket *n;
-+ struct hbucket *n, *tmp;
- struct mtype_elem *data;
- u32 i, j, d;
- #ifdef IP_SET_HASH_WITH_NETS
-@@ -511,9 +511,14 @@ mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize)
- }
- }
- if (d >= AHASH_INIT_SIZE) {
-- struct hbucket *tmp = kzalloc(sizeof(*tmp) +
-- (n->size - AHASH_INIT_SIZE) * dsize,
-- GFP_ATOMIC);
-+ if (d >= n->size) {
-+ rcu_assign_pointer(hbucket(t, i), NULL);
-+ kfree_rcu(n, rcu);
-+ continue;
-+ }
-+ tmp = kzalloc(sizeof(*tmp) +
-+ (n->size - AHASH_INIT_SIZE) * dsize,
-+ GFP_ATOMIC);
- if (!tmp)
- /* Still try to delete expired elements */
- continue;
---
-2.4.3
-
diff --git a/netfilter-nf_nat_redirect-add-missing-NULL-pointer-c.patch b/netfilter-nf_nat_redirect-add-missing-NULL-pointer-c.patch
deleted file mode 100644
index 3b2031981..000000000
--- a/netfilter-nf_nat_redirect-add-missing-NULL-pointer-c.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From f9688b8f6755c3c2eb5c7e2e22ab168d0cb97644 Mon Sep 17 00:00:00 2001
-From: Munehisa Kamata <kamatam@amazon.com>
-Date: Mon, 26 Oct 2015 19:10:52 -0700
-Subject: [PATCH] netfilter: nf_nat_redirect: add missing NULL pointer check
-
-Upstream commit 94f9cd81436c85d8c3a318ba92e236ede73752fc
-
-Commit 8b13eddfdf04cbfa561725cfc42d6868fe896f56 ("netfilter: refactor NAT
-redirect IPv4 to use it from nf_tables") has introduced a trivial logic
-change which can result in the following crash.
-
-BUG: unable to handle kernel NULL pointer dereference at 0000000000000030
-IP: [<ffffffffa033002d>] nf_nat_redirect_ipv4+0x2d/0xa0 [nf_nat_redirect]
-PGD 3ba662067 PUD 3ba661067 PMD 0
-Oops: 0000 [#1] SMP
-Modules linked in: ipv6(E) xt_REDIRECT(E) nf_nat_redirect(E) xt_tcpudp(E) iptable_nat(E) nf_conntrack_ipv4(E) nf_defrag_ipv4(E) nf_nat_ipv4(E) nf_nat(E) nf_conntrack(E) ip_tables(E) x_tables(E) binfmt_misc(E) xfs(E) libcrc32c(E) evbug(E) evdev(E) psmouse(E) i2c_piix4(E) i2c_core(E) acpi_cpufreq(E) button(E) ext4(E) crc16(E) jbd2(E) mbcache(E) dm_mirror(E) dm_region_hash(E) dm_log(E) dm_mod(E)
-CPU: 0 PID: 2536 Comm: ip Tainted: G E 4.1.7-15.23.amzn1.x86_64 #1
-Hardware name: Xen HVM domU, BIOS 4.2.amazon 05/06/2015
-task: ffff8800eb438000 ti: ffff8803ba664000 task.ti: ffff8803ba664000
-[...]
-Call Trace:
- <IRQ>
- [<ffffffffa0334065>] redirect_tg4+0x15/0x20 [xt_REDIRECT]
- [<ffffffffa02e2e99>] ipt_do_table+0x2b9/0x5e1 [ip_tables]
- [<ffffffffa0328045>] iptable_nat_do_chain+0x25/0x30 [iptable_nat]
- [<ffffffffa031777d>] nf_nat_ipv4_fn+0x13d/0x1f0 [nf_nat_ipv4]
- [<ffffffffa0328020>] ? iptable_nat_ipv4_fn+0x20/0x20 [iptable_nat]
- [<ffffffffa031785e>] nf_nat_ipv4_in+0x2e/0x90 [nf_nat_ipv4]
- [<ffffffffa03280a5>] iptable_nat_ipv4_in+0x15/0x20 [iptable_nat]
- [<ffffffff81449137>] nf_iterate+0x57/0x80
- [<ffffffff814491f7>] nf_hook_slow+0x97/0x100
- [<ffffffff814504d4>] ip_rcv+0x314/0x400
-
-unsigned int
-nf_nat_redirect_ipv4(struct sk_buff *skb,
-...
-{
-...
- rcu_read_lock();
- indev = __in_dev_get_rcu(skb->dev);
- if (indev != NULL) {
- ifa = indev->ifa_list;
- newdst = ifa->ifa_local; <---
- }
- rcu_read_unlock();
-...
-}
-
-Before the commit, 'ifa' had been always checked before access. After the
-commit, however, it could be accessed even if it's NULL. Interestingly,
-this was once fixed in 2003.
-
-http://marc.info/?l=netfilter-devel&m=106668497403047&w=2
-
-In addition to the original one, we have seen the crash when packets that
-need to be redirected somehow arrive on an interface which hasn't been
-yet fully configured.
-
-This change just reverts the logic to the old behavior to avoid the crash.
-
-Fixes: 8b13eddfdf04 ("netfilter: refactor NAT redirect IPv4 to use it from nf_tables")
-Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
- net/netfilter/nf_nat_redirect.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/net/netfilter/nf_nat_redirect.c b/net/netfilter/nf_nat_redirect.c
-index 97b75f9bfbcd..d43869879fcf 100644
---- a/net/netfilter/nf_nat_redirect.c
-+++ b/net/netfilter/nf_nat_redirect.c
-@@ -55,7 +55,7 @@ nf_nat_redirect_ipv4(struct sk_buff *skb,
-
- rcu_read_lock();
- indev = __in_dev_get_rcu(skb->dev);
-- if (indev != NULL) {
-+ if (indev && indev->ifa_list) {
- ifa = indev->ifa_list;
- newdst = ifa->ifa_local;
- }
---
-2.5.0
-
diff --git a/nouveau-displayoff-fix.patch b/nouveau-displayoff-fix.patch
new file mode 100644
index 000000000..32045d3c8
--- /dev/null
+++ b/nouveau-displayoff-fix.patch
@@ -0,0 +1,61 @@
+From 95664e66fad964c3dd7945d6edfb1d0931844664 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Thu, 18 Feb 2016 08:14:19 +1000
+Subject: drm/nouveau/disp/dp: ensure sink is powered up before attempting link
+ training
+
+This can happen under some annoying circumstances, and is a quick fix
+until more substantial changes can be made.
+
+Fixed eDP mode changes on (at least) the Lenovo P50.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Cc: stable@vger.kernel.org
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
+index 74e2f7c..9688970 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
+@@ -328,6 +328,7 @@ nvkm_dp_train(struct work_struct *w)
+ .outp = outp,
+ }, *dp = &_dp;
+ u32 datarate = 0;
++ u8 pwr;
+ int ret;
+
+ if (!outp->base.info.location && disp->func->sor.magic)
+@@ -355,6 +356,15 @@ nvkm_dp_train(struct work_struct *w)
+ /* disable link interrupt handling during link training */
+ nvkm_notify_put(&outp->irq);
+
++ /* ensure sink is not in a low-power state */
++ if (!nvkm_rdaux(outp->aux, DPCD_SC00, &pwr, 1)) {
++ if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) {
++ pwr &= ~DPCD_SC00_SET_POWER;
++ pwr |= DPCD_SC00_SET_POWER_D0;
++ nvkm_wraux(outp->aux, DPCD_SC00, &pwr, 1);
++ }
++ }
++
+ /* enable down-spreading and execute pre-train script from vbios */
+ dp_link_train_init(dp, outp->dpcd[3] & 0x01);
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
+index 9596290..6e10c5e 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
+@@ -71,5 +71,11 @@
+ #define DPCD_LS0C_LANE1_POST_CURSOR2 0x0c
+ #define DPCD_LS0C_LANE0_POST_CURSOR2 0x03
+
++/* DPCD Sink Control */
++#define DPCD_SC00 0x00600
++#define DPCD_SC00_SET_POWER 0x03
++#define DPCD_SC00_SET_POWER_D0 0x01
++#define DPCD_SC00_SET_POWER_D3 0x03
++
+ void nvkm_dp_train(struct work_struct *);
+ #endif
+--
+cgit v0.10.2
+
diff --git a/nouveau-stable-backports.patch b/nouveau-stable-backports.patch
deleted file mode 100644
index bd6d210e0..000000000
--- a/nouveau-stable-backports.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From fe9c94340928d8ec3ea1ae74f99c3c9b18684129 Mon Sep 17 00:00:00 2001
-From: Martin Peres <martin.peres@free.fr>
-Date: Sun, 29 Nov 2015 16:10:18 +0200
-Subject: [PATCH 1/3] drm/nouveau/bios/fan: hardcode the fan mode to linear
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is an oversight that made use of the trip-point-based fan managenent on
-cards that never expose those. This led the fan to stay at fan_min.
-
-Fortunately, the emergency code would kick when the temperature would reach
-90°C.
-
-Reported-by: Tom Englund <tomenglund26@gmail.com>
-Tested-by: Tom Englund <tomenglund26@gmail.com>
-Signed-off-by: Martin Peres <martin.peres@free.fr>
-Tested-by: Daemon32 <lnf.purple@gmail.com>
-Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92126
-Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-Cc: stable@vger.kernel.org
----
- drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c
-index 43006db6fd58..80fed7e78dcb 100644
---- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c
-@@ -83,6 +83,7 @@ nvbios_fan_parse(struct nvkm_bios *bios, struct nvbios_therm_fan *fan)
- fan->type = NVBIOS_THERM_FAN_UNK;
- }
-
-+ fan->fan_mode = NVBIOS_THERM_FAN_LINEAR;
- fan->min_duty = nvbios_rd08(bios, data + 0x02);
- fan->max_duty = nvbios_rd08(bios, data + 0x03);
-
---
-2.5.0
-
-
-From acdc10375119fc5dd76d7051a5ae4a41f61c45aa Mon Sep 17 00:00:00 2001
-From: Ben Skeggs <bskeggs@redhat.com>
-Date: Mon, 4 Jan 2016 09:01:13 +1000
-Subject: [PATCH 2/3] drm/nouveau/gr/nv40: fix oops in interrupt handler
-
-fdo#93557
-
-Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-Cc: stable@vger.kernel.org
----
- drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
-index ffa902ece872..05a895496fc6 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
-@@ -156,6 +156,7 @@ nv40_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
- return -ENOMEM;
- nvkm_object_ctor(&nv40_gr_chan, oclass, &chan->object);
- chan->gr = gr;
-+ chan->fifo = fifoch;
- *pobject = &chan->object;
-
- spin_lock_irqsave(&chan->gr->base.engine.lock, flags);
---
-2.5.0
-
-
-From c5d07dcb6d6260a51a2309d5f62c3391637afa86 Mon Sep 17 00:00:00 2001
-From: Ben Skeggs <bskeggs@redhat.com>
-Date: Fri, 8 Jan 2016 08:56:51 +1000
-Subject: [PATCH 3/3] drm/nouveau/kms: take mode_config mutex in connector
- hotplug path
-
-fdo#93634
-
-Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-Cc: stable@vger.kernel.org
----
- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
-index 2e7cbe933533..2a5ed7460354 100644
---- a/drivers/gpu/drm/nouveau/nouveau_connector.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
-@@ -969,10 +969,13 @@ nouveau_connector_hotplug(struct nvif_notify *notify)
-
- NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name);
-
-+ mutex_lock(&drm->dev->mode_config.mutex);
- if (plugged)
- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
- else
- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
-+ mutex_unlock(&drm->dev->mode_config.mutex);
-+
- drm_helper_hpd_irq_event(connector->dev);
- }
-
---
-2.5.0
-
diff --git a/ovl-fix-permission-checking-for-setattr.patch b/ovl-fix-permission-checking-for-setattr.patch
deleted file mode 100644
index 167ecda99..000000000
--- a/ovl-fix-permission-checking-for-setattr.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From acff81ec2c79492b180fade3c2894425cd35a545 Mon Sep 17 00:00:00 2001
-From: Miklos Szeredi <miklos@szeredi.hu>
-Date: Fri, 4 Dec 2015 19:18:48 +0100
-Subject: [PATCH] ovl: fix permission checking for setattr
-
-[Al Viro] The bug is in being too enthusiastic about optimizing ->setattr()
-away - instead of "copy verbatim with metadata" + "chmod/chown/utimes"
-(with the former being always safe and the latter failing in case of
-insufficient permissions) it tries to combine these two. Note that copyup
-itself will have to do ->setattr() anyway; _that_ is where the elevated
-capabilities are right. Having these two ->setattr() (one to set verbatim
-copy of metadata, another to do what overlayfs ->setattr() had been asked
-to do in the first place) combined is where it breaks.
-
-Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
-Cc: <stable@vger.kernel.org>
-Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
----
- fs/overlayfs/inode.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
-index ec0c2a050043..961284936917 100644
---- a/fs/overlayfs/inode.c
-+++ b/fs/overlayfs/inode.c
-@@ -49,13 +49,13 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
- if (err)
- goto out;
-
-- upperdentry = ovl_dentry_upper(dentry);
-- if (upperdentry) {
-+ err = ovl_copy_up(dentry);
-+ if (!err) {
-+ upperdentry = ovl_dentry_upper(dentry);
-+
- mutex_lock(&upperdentry->d_inode->i_mutex);
- err = notify_change(upperdentry, attr, NULL);
- mutex_unlock(&upperdentry->d_inode->i_mutex);
-- } else {
-- err = ovl_copy_up_last(dentry, attr, false);
- }
- ovl_drop_write(dentry);
- out:
---
-2.5.0
-
diff --git a/ptrace-being-capable-wrt-a-process-requires-mapped-u.patch b/ptrace-being-capable-wrt-a-process-requires-mapped-u.patch
deleted file mode 100644
index 55c3ab9d1..000000000
--- a/ptrace-being-capable-wrt-a-process-requires-mapped-u.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 64a37c8197f4e1c2637cd80326f4649282176369 Mon Sep 17 00:00:00 2001
-From: Jann Horn <jann@thejh.net>
-Date: Sat, 26 Dec 2015 03:52:31 +0100
-Subject: [PATCH] ptrace: being capable wrt a process requires mapped uids/gids
-
-ptrace_has_cap() checks whether the current process should be
-treated as having a certain capability for ptrace checks
-against another process. Until now, this was equivalent to
-has_ns_capability(current, target_ns, CAP_SYS_PTRACE).
-
-However, if a root-owned process wants to enter a user
-namespace for some reason without knowing who owns it and
-therefore can't change to the namespace owner's uid and gid
-before entering, as soon as it has entered the namespace,
-the namespace owner can attach to it via ptrace and thereby
-gain access to its uid and gid.
-
-While it is possible for the entering process to switch to
-the uid of a claimed namespace owner before entering,
-causing the attempt to enter to fail if the claimed uid is
-wrong, this doesn't solve the problem of determining an
-appropriate gid.
-
-With this change, the entering process can first enter the
-namespace and then safely inspect the namespace's
-properties, e.g. through /proc/self/{uid_map,gid_map},
-assuming that the namespace owner doesn't have access to
-uid 0.
-
-Changed in v2: The caller needs to be capable in the
-namespace into which tcred's uids/gids can be mapped.
-
-Signed-off-by: Jann Horn <jann@thejh.net>
----
- kernel/ptrace.c | 33 ++++++++++++++++++++++++++++-----
- 1 file changed, 28 insertions(+), 5 deletions(-)
-
-diff --git a/kernel/ptrace.c b/kernel/ptrace.c
-index 787320de68e0..407c382b45c8 100644
---- a/kernel/ptrace.c
-+++ b/kernel/ptrace.c
-@@ -20,6 +20,7 @@
- #include <linux/uio.h>
- #include <linux/audit.h>
- #include <linux/pid_namespace.h>
-+#include <linux/user_namespace.h>
- #include <linux/syscalls.h>
- #include <linux/uaccess.h>
- #include <linux/regset.h>
-@@ -207,12 +208,34 @@ static int ptrace_check_attach(struct task_struct *child, bool ignore_state)
- return ret;
- }
-
--static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
-+static bool ptrace_has_cap(const struct cred *tcred, unsigned int mode)
- {
-+ struct user_namespace *tns = tcred->user_ns;
-+
-+ /* When a root-owned process enters a user namespace created by a
-+ * malicious user, the user shouldn't be able to execute code under
-+ * uid 0 by attaching to the root-owned process via ptrace.
-+ * Therefore, similar to the capable_wrt_inode_uidgid() check,
-+ * verify that all the uids and gids of the target process are
-+ * mapped into a namespace below the current one in which the caller
-+ * is capable.
-+ * No fsuid/fsgid check because __ptrace_may_access doesn't do it
-+ * either.
-+ */
-+ while (
-+ !kuid_has_mapping(tns, tcred->euid) ||
-+ !kuid_has_mapping(tns, tcred->suid) ||
-+ !kuid_has_mapping(tns, tcred->uid) ||
-+ !kgid_has_mapping(tns, tcred->egid) ||
-+ !kgid_has_mapping(tns, tcred->sgid) ||
-+ !kgid_has_mapping(tns, tcred->gid)) {
-+ tns = tns->parent;
-+ }
-+
- if (mode & PTRACE_MODE_NOAUDIT)
-- return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE);
-+ return has_ns_capability_noaudit(current, tns, CAP_SYS_PTRACE);
- else
-- return has_ns_capability(current, ns, CAP_SYS_PTRACE);
-+ return has_ns_capability(current, tns, CAP_SYS_PTRACE);
- }
-
- /* Returns 0 on success, -errno on denial. */
-@@ -241,7 +264,7 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
- gid_eq(cred->gid, tcred->sgid) &&
- gid_eq(cred->gid, tcred->gid))
- goto ok;
-- if (ptrace_has_cap(tcred->user_ns, mode))
-+ if (ptrace_has_cap(tcred, mode))
- goto ok;
- rcu_read_unlock();
- return -EPERM;
-@@ -252,7 +275,7 @@ ok:
- dumpable = get_dumpable(task->mm);
- rcu_read_lock();
- if (dumpable != SUID_DUMP_USER &&
-- !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
-+ !ptrace_has_cap(__task_cred(task), mode)) {
- rcu_read_unlock();
- return -EPERM;
- }
---
-2.5.0
-
diff --git a/rtlwifi-fix-memory-leak-for-USB-device.patch b/rtlwifi-fix-memory-leak-for-USB-device.patch
deleted file mode 100644
index 8c06c863a..000000000
--- a/rtlwifi-fix-memory-leak-for-USB-device.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 17bc55864f81dd730d05f09b1641312a7990d636 Mon Sep 17 00:00:00 2001
-From: Peter Wu <peter@lekensteyn.nl>
-Date: Mon, 7 Dec 2015 01:07:31 +0100
-Subject: [PATCH] rtlwifi: fix memory leak for USB device
-
-Free skb for received frames with a wrong checksum. This can happen
-pretty rapidly, exhausting all memory.
-
-This fixes a memleak (detected with kmemleak). Originally found while
-using monitor mode, but it also appears during managed mode (once the
-link is up).
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Peter Wu <peter@lekensteyn.nl>
-ACKed-by: Larry Finger <Larry.Finger@lwfinger.net>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
- drivers/net/wireless/rtlwifi/usb.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
-index 2721cf8..aac1ed3 100644
---- a/drivers/net/wireless/rtlwifi/usb.c
-+++ b/drivers/net/wireless/rtlwifi/usb.c
-@@ -531,6 +531,8 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
- ieee80211_rx(hw, skb);
- else
- dev_kfree_skb_any(skb);
-+ } else {
-+ dev_kfree_skb_any(skb);
- }
- }
-
---
-2.5.0
-
diff --git a/rtlwifi-rtl8821ae-Fix-5G-failure-when-EEPROM-is-inco.patch b/rtlwifi-rtl8821ae-Fix-5G-failure-when-EEPROM-is-inco.patch
deleted file mode 100644
index b3ab35e2c..000000000
--- a/rtlwifi-rtl8821ae-Fix-5G-failure-when-EEPROM-is-inco.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 1bd0c273bcf537adadedd7cc69408b99afd1534c Mon Sep 17 00:00:00 2001
-From: Larry Finger <Larry.Finger@lwfinger.net>
-Date: Wed, 20 Jan 2016 21:26:18 -0600
-Subject: [PATCH] rtlwifi: rtl8821ae: Fix 5G failure when EEPROM is incorrectly
- encoded
-
-Recently, it has been reported that D-Link DWA-582 cards, which use an
-RTL8812AE chip are not able to scan for 5G networks. The problems started
-with kernel 4.2, which is the first version that had commit d10101a60372
-("rtlwifi: rtl8821ae: Fix problem with regulatory information"). With this
-patch, the driver went from setting a default channel plan to using
-the value derived from EEPROM.
-
-Bug reports at https://bugzilla.kernel.org/show_bug.cgi?id=111031 and
-https://bugzilla.redhat.com/show_bug.cgi?id=1279653 are examples of this
-problem.
-
-The problem was solved once I learned that the internal country code was
-resulting in a regulatory set with only 2.4 GHz channels. With the RTL8821AE
-chips available to me, the country code was such that both 2.4 and 5 GHz
-channels are allowed. The fix is to allow both bands even when the EEPROM
-is incorrectly encoded.
-
-Fixes: d10101a60372 ("rtlwifi: rtl8821ae: Fix problem with regulatory information")
-Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
-Cc: littlesmartguy@gmail.com
-Cc: gabe@codehaus.org
-Cc: Stable <stable@vger.kernel.org> [v4.2+]
----
- drivers/net/wireless/rtlwifi/regd.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c
-index a62bf0a65c32..5be34118e0af 100644
---- a/drivers/net/wireless/rtlwifi/regd.c
-+++ b/drivers/net/wireless/rtlwifi/regd.c
-@@ -351,7 +351,6 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
- case COUNTRY_CODE_SPAIN:
- case COUNTRY_CODE_FRANCE:
- case COUNTRY_CODE_ISRAEL:
-- case COUNTRY_CODE_WORLD_WIDE_13:
- return &rtl_regdom_12_13;
- case COUNTRY_CODE_MKK:
- case COUNTRY_CODE_MKK1:
-@@ -360,6 +359,7 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
- return &rtl_regdom_14_60_64;
- case COUNTRY_CODE_GLOBAL_DOMAIN:
- return &rtl_regdom_14;
-+ case COUNTRY_CODE_WORLD_WIDE_13:
- case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL:
- return &rtl_regdom_12_13_5g_all;
- default:
---
-2.5.0
-
diff --git a/scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch b/scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
index a51cb9b4a..7b9976517 100644
--- a/scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
+++ b/scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
@@ -1,3 +1,4 @@
+From 7afe9a8d7dca86a8f35250f21f5f0a62ea2fedf7 Mon Sep 17 00:00:00 2001
From: "kernel-team@fedoraproject.org" <kernel-team@fedoraproject.org>
Date: Fri, 10 Feb 2012 14:56:13 -0500
Subject: [PATCH] scsi: sd_revalidate_disk prevent NULL ptr deref
@@ -9,18 +10,19 @@ Upstream-status: Fedora mustard (might be worth dropping...)
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
-index 3b2fcb4fada0..f0f9e8574303 100644
+index 3d22fc3..07aec76 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
-@@ -2717,13 +2717,18 @@ static int sd_try_extended_inquiry(struct scsi_device *sdp)
+@@ -2825,7 +2825,7 @@ static inline u32 logical_to_sectors(struct scsi_device *sdev, u32 blocks)
static int sd_revalidate_disk(struct gendisk *disk)
{
struct scsi_disk *sdkp = scsi_disk(disk);
- struct scsi_device *sdp = sdkp->device;
+ struct scsi_device *sdp;
+ struct request_queue *q = sdkp->disk->queue;
unsigned char *buffer;
- unsigned int max_xfer;
-
+ unsigned int dev_max, rw_max;
+@@ -2833,6 +2833,11 @@ static int sd_revalidate_disk(struct gendisk *disk)
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
"sd_revalidate_disk\n"));
@@ -32,3 +34,6 @@ index 3b2fcb4fada0..f0f9e8574303 100644
/*
* If the device is offline, don't try and read capacity or any
* of the other niceties.
+--
+2.5.0
+
diff --git a/selinux-fix-bug-in-conditional-rules-handling.patch b/selinux-fix-bug-in-conditional-rules-handling.patch
deleted file mode 100644
index 6a78f5b2e..000000000
--- a/selinux-fix-bug-in-conditional-rules-handling.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From f3bef67992e8698897b584616535803887c4a73e Mon Sep 17 00:00:00 2001
-From: Stephen Smalley <sds@tycho.nsa.gov>
-Date: Mon, 23 Nov 2015 16:07:41 -0500
-Subject: [PATCH] selinux: fix bug in conditional rules handling
-
-commit fa1aa143ac4a ("selinux: extended permissions for ioctls")
-introduced a bug into the handling of conditional rules, skipping the
-processing entirely when the caller does not provide an extended
-permissions (xperms) structure. Access checks from userspace using
-/sys/fs/selinux/access do not include such a structure since that
-interface does not presently expose extended permission information.
-As a result, conditional rules were being ignored entirely on userspace
-access requests, producing denials when access was allowed by
-conditional rules in the policy. Fix the bug by only skipping
-computation of extended permissions in this situation, not the entire
-conditional rules processing.
-
-Reported-by: Laurent Bigonville <bigon@debian.org>
-Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
-[PM: fixed long lines in patch description]
-Cc: stable@vger.kernel.org # 4.3
-Signed-off-by: Paul Moore <pmoore@redhat.com>
----
- security/selinux/ss/conditional.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
-index 18643bf9894d..456e1a9bcfde 100644
---- a/security/selinux/ss/conditional.c
-+++ b/security/selinux/ss/conditional.c
-@@ -638,7 +638,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
- {
- struct avtab_node *node;
-
-- if (!ctab || !key || !avd || !xperms)
-+ if (!ctab || !key || !avd)
- return;
-
- for (node = avtab_search_node(ctab, key); node;
-@@ -657,7 +657,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
- if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) ==
- (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED)))
- avd->auditallow |= node->datum.u.data;
-- if ((node->key.specified & AVTAB_ENABLED) &&
-+ if (xperms && (node->key.specified & AVTAB_ENABLED) &&
- (node->key.specified & AVTAB_XPERMS))
- services_compute_xperms_drivers(xperms, node);
- }
---
-2.5.0
-
diff --git a/sources b/sources
index a7e5f25bf..be63b529d 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,3 @@
-58b35794eee3b6d52ce7be39357801e7 linux-4.3.tar.xz
-7c516c9528b9f9aac0136944b0200b7e perf-man-4.3.tar.gz
-d31631a3d05d66054fbb988f05ddfa6d patch-4.3.6.xz
+9a78fa2eb6c68ca5a40ed5af08142599 linux-4.4.tar.xz
+dcbc8fe378a676d5d0dd208cf524e144 perf-man-4.4.tar.gz
+078427483ee96f3e072e7b5409b5a117 patch-4.4.3.xz
diff --git a/unix-correctly-track-in-flight-fds-in-sending-proces.patch b/unix-correctly-track-in-flight-fds-in-sending-proces.patch
new file mode 100644
index 000000000..eb513ef6b
--- /dev/null
+++ b/unix-correctly-track-in-flight-fds-in-sending-proces.patch
@@ -0,0 +1,159 @@
+From 415e3d3e90ce9e18727e8843ae343eda5a58fad6 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Wed, 3 Feb 2016 02:11:03 +0100
+Subject: [PATCH] unix: correctly track in-flight fds in sending process
+ user_struct
+
+The commit referenced in the Fixes tag incorrectly accounted the number
+of in-flight fds over a unix domain socket to the original opener
+of the file-descriptor. This allows another process to arbitrary
+deplete the original file-openers resource limit for the maximum of
+open files. Instead the sending processes and its struct cred should
+be credited.
+
+To do so, we add a reference counted struct user_struct pointer to the
+scm_fp_list and use it to account for the number of inflight unix fds.
+
+Fixes: 712f4aad406bb1 ("unix: properly account for FDs passed over unix sockets")
+Reported-by: David Herrmann <dh.herrmann@gmail.com>
+Cc: David Herrmann <dh.herrmann@gmail.com>
+Cc: Willy Tarreau <w@1wt.eu>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ include/net/af_unix.h | 4 ++--
+ include/net/scm.h | 1 +
+ net/core/scm.c | 7 +++++++
+ net/unix/af_unix.c | 4 ++--
+ net/unix/garbage.c | 8 ++++----
+ 5 files changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/af_unix.h b/include/net/af_unix.h
+index 2a91a0561a47..9b4c418bebd8 100644
+--- a/include/net/af_unix.h
++++ b/include/net/af_unix.h
+@@ -6,8 +6,8 @@
+ #include <linux/mutex.h>
+ #include <net/sock.h>
+
+-void unix_inflight(struct file *fp);
+-void unix_notinflight(struct file *fp);
++void unix_inflight(struct user_struct *user, struct file *fp);
++void unix_notinflight(struct user_struct *user, struct file *fp);
+ void unix_gc(void);
+ void wait_for_unix_gc(void);
+ struct sock *unix_get_socket(struct file *filp);
+diff --git a/include/net/scm.h b/include/net/scm.h
+index 262532d111f5..59fa93c01d2a 100644
+--- a/include/net/scm.h
++++ b/include/net/scm.h
+@@ -21,6 +21,7 @@ struct scm_creds {
+ struct scm_fp_list {
+ short count;
+ short max;
++ struct user_struct *user;
+ struct file *fp[SCM_MAX_FD];
+ };
+
+diff --git a/net/core/scm.c b/net/core/scm.c
+index 14596fb37172..2696aefdc148 100644
+--- a/net/core/scm.c
++++ b/net/core/scm.c
+@@ -87,6 +87,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
+ *fplp = fpl;
+ fpl->count = 0;
+ fpl->max = SCM_MAX_FD;
++ fpl->user = NULL;
+ }
+ fpp = &fpl->fp[fpl->count];
+
+@@ -107,6 +108,10 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
+ *fpp++ = file;
+ fpl->count++;
+ }
++
++ if (!fpl->user)
++ fpl->user = get_uid(current_user());
++
+ return num;
+ }
+
+@@ -119,6 +124,7 @@ void __scm_destroy(struct scm_cookie *scm)
+ scm->fp = NULL;
+ for (i=fpl->count-1; i>=0; i--)
+ fput(fpl->fp[i]);
++ free_uid(fpl->user);
+ kfree(fpl);
+ }
+ }
+@@ -336,6 +342,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
+ for (i = 0; i < fpl->count; i++)
+ get_file(fpl->fp[i]);
+ new_fpl->max = new_fpl->count;
++ new_fpl->user = get_uid(fpl->user);
+ }
+ return new_fpl;
+ }
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 49d5093eb055..29be035f9c65 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1496,7 +1496,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+ UNIXCB(skb).fp = NULL;
+
+ for (i = scm->fp->count-1; i >= 0; i--)
+- unix_notinflight(scm->fp->fp[i]);
++ unix_notinflight(scm->fp->user, scm->fp->fp[i]);
+ }
+
+ static void unix_destruct_scm(struct sk_buff *skb)
+@@ -1561,7 +1561,7 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+ return -ENOMEM;
+
+ for (i = scm->fp->count - 1; i >= 0; i--)
+- unix_inflight(scm->fp->fp[i]);
++ unix_inflight(scm->fp->user, scm->fp->fp[i]);
+ return max_level;
+ }
+
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 8fcdc2283af5..6a0d48525fcf 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -116,7 +116,7 @@ struct sock *unix_get_socket(struct file *filp)
+ * descriptor if it is for an AF_UNIX socket.
+ */
+
+-void unix_inflight(struct file *fp)
++void unix_inflight(struct user_struct *user, struct file *fp)
+ {
+ struct sock *s = unix_get_socket(fp);
+
+@@ -133,11 +133,11 @@ void unix_inflight(struct file *fp)
+ }
+ unix_tot_inflight++;
+ }
+- fp->f_cred->user->unix_inflight++;
++ user->unix_inflight++;
+ spin_unlock(&unix_gc_lock);
+ }
+
+-void unix_notinflight(struct file *fp)
++void unix_notinflight(struct user_struct *user, struct file *fp)
+ {
+ struct sock *s = unix_get_socket(fp);
+
+@@ -152,7 +152,7 @@ void unix_notinflight(struct file *fp)
+ list_del_init(&u->link);
+ unix_tot_inflight--;
+ }
+- fp->f_cred->user->unix_inflight--;
++ user->unix_inflight--;
+ spin_unlock(&unix_gc_lock);
+ }
+
+--
+2.5.0
+
diff --git a/usb-make-xhci-platform-driver-use-64-bit-or-32-bit-D.patch b/usb-make-xhci-platform-driver-use-64-bit-or-32-bit-D.patch
deleted file mode 100644
index 79f58f775..000000000
--- a/usb-make-xhci-platform-driver-use-64-bit-or-32-bit-D.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From: Mark Langsdorf <mlangsdo@redhat.com>
-Date: Wed, 25 Mar 2015 14:12:51 -0400
-Subject: [PATCH] usb: make xhci platform driver use 64 bit or 32 bit DMA
-
-The xhci platform driver needs to work on systems that either only
-support 64-bit DMA or only support 32-bit DMA. Attempt to set a
-coherent dma mask for 64-bit DMA, and attempt again with 32-bit
-DMA if that fails.
-
-Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
----
- drivers/usb/host/xhci-plat.c | 15 +++++++--------
- 1 file changed, 7 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
-index 890ad9d9d329..122b1fb12b7e 100644
---- a/drivers/usb/host/xhci-plat.c
-+++ b/drivers/usb/host/xhci-plat.c
-@@ -93,14 +93,13 @@ static int xhci_plat_probe(struct platform_device *pdev)
- if (irq < 0)
- return -ENODEV;
-
-- /* Initialize dma_mask and coherent_dma_mask to 32-bits */
-- ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-- if (ret)
-- return ret;
-- if (!pdev->dev.dma_mask)
-- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-- else
-- dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
-+ /* Try setting the coherent_dma_mask to 64 bits, then try 32 bits */
-+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
-+ if (ret) {
-+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-+ if (ret)
-+ return ret;
-+ }
-
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd)
diff --git a/watchdog-Disable-watchdog-on-virtual-machines.patch b/watchdog-Disable-watchdog-on-virtual-machines.patch
index 01cbba943..11bce5bb7 100644
--- a/watchdog-Disable-watchdog-on-virtual-machines.patch
+++ b/watchdog-Disable-watchdog-on-virtual-machines.patch
@@ -1,3 +1,4 @@
+From f1293c68aff98cd913a59b151aac938ec4ce4857 Mon Sep 17 00:00:00 2001
From: Dave Jones <davej@redhat.com>
Date: Tue, 24 Jun 2014 08:43:34 -0400
Subject: [PATCH] watchdog: Disable watchdog on virtual machines.
@@ -20,7 +21,7 @@ Signed-off-by: Dave Jones <davej@redhat.com>
1 file changed, 29 insertions(+)
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
-index a6ffa43f2993..b378b762844a 100644
+index 18f34cf..6aadffe 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -20,6 +20,7 @@
@@ -31,8 +32,8 @@ index a6ffa43f2993..b378b762844a 100644
#include <asm/irq_regs.h>
#include <linux/kvm_para.h>
-@@ -155,6 +156,32 @@ static int __init softlockup_all_cpu_backtrace_setup(char *str)
- __setup("softlockup_all_cpu_backtrace=", softlockup_all_cpu_backtrace_setup);
+@@ -185,6 +186,32 @@ static int __init hardlockup_all_cpu_backtrace_setup(char *str)
+ __setup("hardlockup_all_cpu_backtrace=", hardlockup_all_cpu_backtrace_setup);
#endif
+static int disable_watchdog(const struct dmi_system_id *d)
@@ -64,7 +65,7 @@ index a6ffa43f2993..b378b762844a 100644
/*
* Hard-lockup warnings should be triggered after just a few seconds. Soft-
* lockups can have false positives under extreme conditions. So we generally
-@@ -928,6 +955,8 @@ int proc_watchdog_cpumask(struct ctl_table *table, int write,
+@@ -1030,6 +1057,8 @@ out:
void __init lockup_detector_init(void)
{
@@ -73,3 +74,6 @@ index a6ffa43f2993..b378b762844a 100644
set_sample_period();
#ifdef CONFIG_NO_HZ_FULL
+--
+2.5.0
+