]> review.fuel-infra Code Review - packages/trusty/i40e-dkms.git/commitdiff
Update i40e to 2.4.6 03/38503/1
authorDenis V. Meltsaykin <dmeltsaykin@mirantis.com>
Tue, 15 May 2018 15:55:50 +0000 (17:55 +0200)
committerDenis V. Meltsaykin <dmeltsaykin@mirantis.com>
Tue, 15 May 2018 15:55:50 +0000 (17:55 +0200)
It was found that 2.2.4 had memory leaks, so the fix is to update to 2.4.6
which was tested in production use.

Change-Id: I70f783bb49145618ec93c296d0b4bb5a89340c61
Closes-Bug: #1770608

51 files changed:
debian/changelog
i40e-dkms/i40e-2.2.4/SUMS [deleted file]
i40e-dkms/i40e-2.4.6/COPYING [moved from i40e-dkms/i40e-2.2.4/COPYING with 100% similarity]
i40e-dkms/i40e-2.4.6/README [moved from i40e-dkms/i40e-2.2.4/README with 56% similarity]
i40e-dkms/i40e-2.4.6/SUMS [new file with mode: 0644]
i40e-dkms/i40e-2.4.6/i40e.7 [moved from i40e-dkms/i40e-2.2.4/i40e.7 with 75% similarity]
i40e-dkms/i40e-2.4.6/i40e.spec [moved from i40e-dkms/i40e-2.2.4/i40e.spec with 99% similarity]
i40e-dkms/i40e-2.4.6/pci.updates [moved from i40e-dkms/i40e-2.2.4/pci.updates with 94% similarity]
i40e-dkms/i40e-2.4.6/scripts/dump_tables [moved from i40e-dkms/i40e-2.2.4/scripts/dump_tables with 100% similarity]
i40e-dkms/i40e-2.4.6/scripts/set_irq_affinity [moved from i40e-dkms/i40e-2.2.4/scripts/set_irq_affinity with 100% similarity]
i40e-dkms/i40e-2.4.6/scripts/virt_perf_default [moved from i40e-dkms/i40e-2.2.4/scripts/virt_perf_default with 100% similarity]
i40e-dkms/i40e-2.4.6/src/Makefile [moved from i40e-dkms/i40e-2.2.4/src/Makefile with 93% similarity]
i40e-dkms/i40e-2.4.6/src/Module.supported [moved from i40e-dkms/i40e-2.2.4/src/Module.supported with 100% similarity]
i40e-dkms/i40e-2.4.6/src/common.mk [moved from i40e-dkms/i40e-2.2.4/src/common.mk with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e.h [moved from i40e-dkms/i40e-2.2.4/src/i40e.h with 93% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_adminq.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_adminq.c with 95% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_adminq.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_adminq.h with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_adminq_cmd.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_adminq_cmd.h with 98% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_alloc.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_alloc.h with 97% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_client.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_client.c with 96% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_client.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_client.h with 98% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_common.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_common.c with 97% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_dcb.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_dcb.c with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_dcb.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_dcb.h with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_dcb_nl.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_dcb_nl.c with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_debugfs.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_debugfs.c with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_devids.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_devids.h with 92% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_diag.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_diag.c with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_diag.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_diag.h with 97% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_ethtool.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_ethtool.c with 87% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_helper.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_helper.h with 98% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_hmc.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_hmc.c with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_hmc.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_hmc.h with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_lan_hmc.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_lan_hmc.c with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_lan_hmc.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_lan_hmc.h with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_main.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_main.c with 97% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_nvm.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_nvm.c with 89% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_osdep.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_osdep.h with 98% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_prototype.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_prototype.h with 93% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_ptp.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_ptp.c with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_register.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_register.h with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_status.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_status.h with 97% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_trace.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_trace.h with 99% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_txrx.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_txrx.c with 86% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_txrx.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_txrx.h with 90% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_type.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_type.h with 98% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_virtchnl_pf.c [moved from i40e-dkms/i40e-2.2.4/src/i40e_virtchnl_pf.c with 98% similarity]
i40e-dkms/i40e-2.4.6/src/i40e_virtchnl_pf.h [moved from i40e-dkms/i40e-2.2.4/src/i40e_virtchnl_pf.h with 99% similarity]
i40e-dkms/i40e-2.4.6/src/kcompat.c [moved from i40e-dkms/i40e-2.2.4/src/kcompat.c with 98% similarity]
i40e-dkms/i40e-2.4.6/src/kcompat.h [moved from i40e-dkms/i40e-2.2.4/src/kcompat.h with 97% similarity]
i40e-dkms/i40e-2.4.6/src/virtchnl.h [moved from i40e-dkms/i40e-2.2.4/src/virtchnl.h with 99% similarity]

index 340bc3e7dde4ef4d58309cf6b373ed07c7242a53..a0b5edd6161ee19408de77fb5127ef7eb8965a63 100644 (file)
@@ -1,3 +1,9 @@
+i40e-dkms (2.4.6-1~u14.04+mos1) mos; urgency=low
+
+  * Update to version 2.4.6
+
+ -- Denis Meltsaykin <dmeltsaykin@mirantis.com>  Tue, 15 May 2018 17:54:00 +0200
+
 i40e-dkms (2.2.4-1~u14.04+mos1) mos; urgency=low
 
   * Update to version 2.2.4
diff --git a/i40e-dkms/i40e-2.2.4/SUMS b/i40e-dkms/i40e-2.2.4/SUMS
deleted file mode 100644 (file)
index 9c4f8c1..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-23200     3 i40e-2.2.4/i40e.7
-41054    52 i40e-2.2.4/README
-57015     7 i40e-2.2.4/pci.updates
-46157    11 i40e-2.2.4/i40e.spec
-43521    19 i40e-2.2.4/COPYING
-11661   364 i40e-2.2.4/src/i40e_register.h
-36073     9 i40e-2.2.4/src/i40e_dcb_nl.c
-00545    82 i40e-2.2.4/src/i40e_adminq_cmd.h
-39134    46 i40e-2.2.4/src/i40e_nvm.c
-56456    47 i40e-2.2.4/src/i40e_type.h
-28147    22 i40e-2.2.4/src/i40e_prototype.h
-62648    57 i40e-2.2.4/src/kcompat.c
-58605     4 i40e-2.2.4/src/i40e_status.h
-04760   190 i40e-2.2.4/src/i40e_common.c
-25757     6 i40e-2.2.4/src/i40e_lan_hmc.h
-25014     2 i40e-2.2.4/src/i40e_diag.h
-25701     4 i40e-2.2.4/src/i40e_helper.h
-56270     8 i40e-2.2.4/src/i40e_hmc.h
-43670    23 i40e-2.2.4/src/i40e_client.c
-61287   178 i40e-2.2.4/src/i40e_ethtool.c
-06523     7 i40e-2.2.4/src/i40e_trace.h
-27367    30 i40e-2.2.4/src/i40e_adminq.c
-24070     2 i40e-2.2.4/src/i40e_devids.h
-13309     5 i40e-2.2.4/src/i40e_diag.c
-38197    36 i40e-2.2.4/src/i40e.h
-45149    19 i40e-2.2.4/src/i40e_txrx.h
-15513    23 i40e-2.2.4/src/virtchnl.h
-25383    27 i40e-2.2.4/src/i40e_ptp.c
-60199    35 i40e-2.2.4/src/i40e_lan_hmc.c
-22894    27 i40e-2.2.4/src/i40e_dcb.c
-15728   169 i40e-2.2.4/src/kcompat.h
-40073   366 i40e-2.2.4/src/i40e_main.c
-12661     7 i40e-2.2.4/src/i40e_client.h
-06581     6 i40e-2.2.4/src/Makefile
-38484     4 i40e-2.2.4/src/i40e_osdep.h
-03889     3 i40e-2.2.4/src/i40e_alloc.h
-12976    80 i40e-2.2.4/src/i40e_debugfs.c
-44588     1 i40e-2.2.4/src/Module.supported
-22387     6 i40e-2.2.4/src/i40e_virtchnl_pf.h
-58955     5 i40e-2.2.4/src/i40e_adminq.h
-28000    12 i40e-2.2.4/src/common.mk
-48557    93 i40e-2.2.4/src/i40e_virtchnl_pf.c
-62481   100 i40e-2.2.4/src/i40e_txrx.c
-12466     6 i40e-2.2.4/src/i40e_dcb.h
-03386    11 i40e-2.2.4/src/i40e_hmc.c
-33977     7 i40e-2.2.4/scripts/set_irq_affinity
-20875     2 i40e-2.2.4/scripts/dump_tables
-49876     5 i40e-2.2.4/scripts/virt_perf_default
similarity index 56%
rename from i40e-dkms/i40e-2.2.4/README
rename to i40e-dkms/i40e-2.4.6/README
index 948900a0cc22e4cf076750f6deb4e5844027ce00..fb477ae6d601400aa7d4535a7e02d87a318049af 100644 (file)
@@ -1,10 +1,8 @@
 
-i40e Linux* Base Driver for the Intel(R) XL710 Ethernet Controller Family
+i40e Linux* Base Driver for the Intel(R) Ethernet Controller 700 Series
 ===============================================================================
 
-===============================================================================
-
-June 21, 2017
+December 4, 2017
 
 ===============================================================================
 
@@ -16,7 +14,7 @@ Contents
 - Identifying Your Adapter
 - Building and Installation
 - Command Line Parameters
-- Intel(R) i40e Ethernet Flow Director
+- Intel(R) Ethernet Flow Director
 - Additional Features & Configurations
 - Known Issues
 
@@ -27,125 +25,112 @@ Contents
 Important Notes
 ---------------
 
+TC0 must be enabled when setting up DCB on a switch
+---------------------------------------------------
+The kernel assumes that TC0 is available, and will disable Priority Flow 
+Control (PFC) on the device if TC0 is not available. To fix this, ensure TC0 is 
+enabled when setting up DCB on your switch.
+
+
 Enabling a VF link if the port is disconnected
 ----------------------------------------------
-
-If the physical function (PF) link is down, you can force link up (from the host
-PF) on any virtual functions (VF) bound to the PF. Note that this requires
-kernel support (Redhat kernel 3.10.0-327 or newer, upstream kernel 3.11.0 or
-newer, and associated iproute2 user space support). If the following command
-does not work, it may not be supported by your system. The following command
+If the physical function (PF) link is down, you can force link up (from the 
+host PF) on any virtual functions (VF) bound to the PF. Note that this requires 
+kernel support (Redhat kernel 3.10.0-327 or newer, upstream kernel 3.11.0 or 
+newer, and associated iproute2 user space support). If the following command 
+does not work, it may not be supported by your system. The following command 
 forces link up on VF 0 bound to PF eth0:
   ip link set eth0 vf 0 state enable
 
 
 Do not unload port driver if VF with active VM is bound to it
 -------------------------------------------------------------
-
-Do not unload a port's driver if a Virtual Function (VF) with an active Virtual
-Machine (VM) is bound to it. Doing so will cause the port to appear to hang.
+Do not unload a port's driver if a Virtual Function (VF) with an active Virtual 
+Machine (VM) is bound to it. Doing so will cause the port to appear to hang. 
 Once the VM shuts down, or otherwise releases the VF, the command will complete.
 
 
 Configuring SR-IOV for improved network security
 ------------------------------------------------
-
-In a virtualized environment, on Intel(R) Server Adapters that support SR-IOV,
-the virtual function (VF) may be subject to malicious behavior. Software-
-generated layer two frames, like IEEE 802.3x (link flow control), IEEE 802.1Qbb
-(priority based flow-control), and others of this type, are not expected and
-can throttle traffic between the host and the virtual switch, reducing
-performance. To resolve this issue, configure all SR-IOV enabled ports for
-VLAN tagging. This configuration allows unexpected, and potentially malicious,
-frames to be dropped.
+In a virtualized environment, on Intel(R) Ethernet Server Adapters that support 
+SR-IOV, the virtual function (VF) may be subject to malicious behavior. 
+Software-generated layer two frames, like IEEE 802.3x (link flow control), IEEE 
+802.1Qbb (priority based flow-control), and others of this type, are not 
+expected and can throttle traffic between the host and the virtual switch, 
+reducing performance. To resolve this issue, configure all SR-IOV enabled ports 
+for VLAN tagging. This configuration allows unexpected, and potentially 
+malicious, frames to be dropped.
 
 
 Overview
 --------
-
 This driver supports kernel versions 2.6.32 and newer.
 
-It supports Linux supported x86_64 systems.
-
-Driver information can be obtained using ethtool, lspci, and ifconfig.
-Instructions on updating ethtool can be found in the section Additional
+Driver information can be obtained using ethtool, lspci, and ifconfig. 
+Instructions on updating ethtool can be found in the section Additional 
 Configurations later in this document.
 
-This driver is only supported as a loadable module at this time. Intel is
-not supplying patches against the kernel source to allow for static linking of
-the drivers.
-
-For questions related to hardware requirements, refer to the documentation
-supplied with your Intel adapter. All hardware requirements listed apply to
-use with Linux.
+This driver is only supported as a loadable module at this time. Intel is not 
+supplying patches against the kernel source to allow for static linking of the 
+drivers.
 
-The following features are now available in supported kernels:
-- Native VLANs
-- Channel Bonding (teaming)
-- SNMP
+For questions related to hardware requirements, refer to the documentation 
+supplied with your Intel adapter. All hardware requirements listed apply to use 
+with Linux.
 
-Adapter teaming is implemented using the native Linux Channel bonding
-module. This is included in supported Linux kernels.
-
-Channel Bonding documentation can be found in the Linux kernel source:
+Adapter teaming is implemented using the native Linux Channel bonding module. 
+This is included in supported Linux kernels. Channel Bonding documentation can 
+be found in the Linux kernel source:
 /documentation/networking/bonding.txt
 
-The driver information previously displayed in the /proc file system is not
+The driver information previously displayed in the /proc file system is not 
 supported in this release.
 
-
-NOTE: 1 Gb devices based on the Intel(R) Ethernet Controller X722 do not
-support the following features:
+NOTE: 1 Gb devices based on the Intel(R) Ethernet Network Connection X722 do 
+not support the following features:
   * Data Center Bridging (DCB)
   * QOS
   * VMQ
   * SR-IOV
-  * Task Encapsulation offload (VxLAN, NVGRE)
+  * Task Encapsulation offload (VXLAN, NVGRE)
   * Energy Efficient Ethernet (EEE)
   * Auto-media detect
 
 
-
-
 Identifying Your Adapter
 ------------------------
 The driver in this release is compatible with devices based on the following:
   * Intel(R) Ethernet Controller X710
   * Intel(R) Ethernet Controller XL710
-  * Intel(R) Ethernet Controller X722
-
+  * Intel(R) Ethernet Network Connection X722
   * Intel(R) Ethernet Controller XXV710
 
+For the best performance, make sure the latest NVM/FW is installed on your 
+device and that you are using the newest drivers.
 
-
-For information on how to identify your adapter, go to the Adapter &
-Driver ID Guide at:
-http://support.intel.com/support/go/network/adapter/proidguide.htm
-
-For the best performance, make sure the latest NVM/FW is installed on your device
- and that you are using the newest drivers.
-
-For the latest NVM/FW images and Intel network drivers, refer to the
-following website and select your adapter.
+For information on how to identify your adapter, and for the latest NVM/FW 
+images and Intel network drivers, refer to the Intel Support website:
 http://www.intel.com/support
 
 
 SFP+ and QSFP+ Devices:
+-----------------------
+For information about supported media, refer to this document:
+http://www.intel.com/content/dam/www/public/us/en/documents/release-notes/xl710-
+ethernet-controller-feature-matrix.pdf
+NOTE: Some adapters based on the Intel(R) Ethernet Controller 700 Series only 
+support Intel Ethernet Optics modules. On these adapters, other modules are not 
+supported and will not function.
 
-For information about supported media, follow the link below:
-  http://www.intel.com/content/dam/www/public/us/en/documents/
-  release-notes/xl710-ethernet-controller-feature-matrix.pdf
-NOTES:
-* Some Intel branded network adapters based on the X710/XL710 controller
-  only support Intel branded modules. On these adapters, other modules
-  are not supported and will not function.
-* For connections based on the X710/XL710 controller, support is
-  dependent on your system board. Please see your vendor for details.
-* In all cases Intel recommends using Intel optics; other modules may
-  function but are not validated by Intel. Contact Intel for supported
-  media types.
-* In systems that do not have adequate airflow to cool the adapter and
-  optical modules, you must use high temperature optical modules.
+NOTE: For connections based on Intel(R) Ethernet Controller 700 Series, support 
+is dependent on your system board. Please see your vendor for details.
+
+NOTE:In all cases Intel recommends using Intel Ethernet Optics; other modules 
+may function but are not validated by Intel. Contact Intel for supported media 
+types.
+
+NOTE: In systems that do not have adequate airflow to cool the adapter and 
+optical modules, you must use high temperature optical modules.
 
 
 ================================================================================
@@ -153,16 +138,16 @@ NOTES:
 
 Building and Installation
 -------------------------
+To build a binary RPM* package of this driver, run 'rpmbuild -tb 
+i40e-<x.x.x>.tar.gz', where <x.x.x> is the version number for the driver tar 
+file.
 
-To build a binary RPM* package of this driver, run 'rpmbuild -tb
-i40e-<x.x.x>.tar.gz', where <x.x.x> is the version number for the driver tar file.
-
-NOTES:
+Note: For the build to work properly, the currently running kernel MUST match 
+the version and configuration of the installed kernel sources. If you have just 
+recompiled the kernel reboot the system before building.
 
-- For the build to work properly, the currently running kernel MUST match
-  the version and configuration of the installed kernel sources. If you have
-  just recompiled the kernel reboot the system before building.
-- RPM functionality has only been tested in Red Hat distributions.
+Note: RPM functionality has only been tested in Red Hat distributions.
+_lbank_line_
 
 1. Move the base driver tar file to the directory of your choice. For
    example, use '/home/username/i40e' or '/usr/local/src/i40e'.
@@ -183,6 +168,12 @@ NOTES:
    The install location listed above is the default location. This may differ
    for various Linux distributions.
 
+  NOTE: To gather and display additional statistics, use the
+  I40E_ADD_PROBES pre-processor macro:
+  #make CFLAGS_EXTRA=-DI40E_ADD_PROBES
+  Please note that this additional statistics gathering can impact
+  performance.
+
 5. Load the module using the modprobe command:
    modprobe <i40e> [parameter=port1_value,port2_value]
 
@@ -200,12 +191,10 @@ NOTES:
    that is being tested:
    ping <IP_address>
 
-NOTE:
-   For certain distributions like (but not limited to) RedHat Enterprise
-   Linux 7 and Ubuntu, once the driver is installed the initrd/initramfs
-   file may need to be updated to prevent the OS loading old versions
-   of the i40e driver. The dracut utility may be used on RedHat
-   distributions:
+Note: For certain distributions like (but not limited to) RedHat Enterprise 
+Linux 7 and Ubuntu, once the driver is installed the initrd/initramfs file may 
+need to be updated to prevent the OS loading old versions of the i40e driver. 
+The dracut utility may be used on RedHat distributions:
        # dracut --force
    For Ubuntu:
        # update-initramfs -u
@@ -216,47 +205,45 @@ NOTE:
 
 Command Line Parameters
 -----------------------
-In general, ethtool and other OS specific commands are used to configure user
-changeable parameters after the driver is loaded. The i40e driver only supports
-the max_vfs kernel parameter on older kernels that do not have the standard
-sysfs interface. The only other module parameter supported is the debug
+In general, ethtool and other OS specific commands are used to configure user 
+changeable parameters after the driver is loaded. The i40e driver only supports 
+the max_vfs kernel parameter on older kernels that do not have the standard 
+sysfs interface. The only other module parameter supported is the debug 
 parameter that can control the default logging verbosity of the driver.
 
-If the driver is built as a module, the following optional parameters are used
-by entering them on the command line with the modprobe command using this
+If the driver is built as a module, the following optional parameters are used 
+by entering them on the command line with the modprobe command using this 
 syntax:
 modprobe i40e [<option>=<VAL1>]
 
-There needs to be a <VAL#> for each network port in the system supported by
+There needs to be a <VAL#> for each network port in the system supported by 
 this driver. The values will be applied to each instance, in function order.
 For example:
 modprobe i40e max_vfs=7
 
-The default value for each parameter is generally the recommended setting,
+The default value for each parameter is generally the recommended setting, 
 unless otherwise noted.
 
 
-
 max_vfs
 -------
-This parameter adds support for SR-IOV. It causes the driver to spawn up to
+This parameter adds support for SR-IOV. It causes the driver to spawn up to 
 max_vfs worth of virtual functions.
 Valid Range:
-1-32 (X710 based devices)
-1-64 (XL710 based devices)
-
-
-NOTE: This parameter is only used on kernel 3.7.x and below. On kernel 3.8.x
-and above, use sysfs to enable VFs. Also, for Red Hat distributions,
-this parameter is only used on version 6.6 and older. For version 6.7 and
-newer, use sysfs. For example:
-#echo $num_vf_enabled > /sys/class/net/$dev/device/sriov_numvfs        //enable VFs
+1-32 (Intel Ethernet Controller X710 based devices)
+1-64 (Intel Ethernet Controller XXV710/XL710 based devices)
+
+NOTE: This parameter is only used on kernel 3.7.x and below. On kernel 3.8.x 
+and above, use sysfs to enable VFs. Also, for Red Hat distributions, this 
+parameter is only used on version 6.6 and older. For version 6.7 and newer, use 
+sysfs. For example:
+#echo $num_vf_enabled > /sys/class/net/$dev/device/sriov_numvfs        //enable 
+VFs
 #echo 0 > /sys/class/net/$dev/device/sriov_numvfs      //disable VFs
 
-
-The parameters for the driver are referenced by position. Thus, if you have a
-dual port adapter, or more than one adapter in your system, and want N virtual
-functions per port, you must specify a number for each port with each parameter
+The parameters for the driver are referenced by position. Thus, if you have a 
+dual port adapter, or more than one adapter in your system, and want N virtual 
+functions per port, you must specify a number for each port with each parameter 
 separated by a comma. For example:
 
   modprobe i40e max_vfs=4
@@ -267,21 +254,21 @@ This will spawn 4 VFs on the first port.
 
 This will spawn 2 VFs on the first port and 4 VFs on the second port.
 
-NOTE: Caution must be used in loading the driver with these parameters.
-Depending on your system configuration, number of slots, etc., it is impossible
+NOTE: Caution must be used in loading the driver with these parameters. 
+Depending on your system configuration, number of slots, etc., it is impossible 
 to predict in all cases where the positions would be on the command line.
 
-NOTE: Neither the device nor the driver control how VFs are mapped into config
-space. Bus layout will vary by operating system. On operating systems that
-support it, you can check sysfs to find the mapping. 
-
+NOTE: Neither the device nor the driver control how VFs are mapped into config 
+space. Bus layout will vary by operating system. On operating systems that 
+support it, you can check sysfs to find the mapping.
 
-Some hardware configurations support fewer SR-IOV instances, as the whole
-XL710 controller (all functions) is limited to 128 SR-IOV interfaces in total.
+Some hardware configurations support fewer SR-IOV instances, as the whole Intel 
+Ethernet Controller XL710 (all functions) is limited to 128 SR-IOV interfaces 
+in total.
 
-NOTE: When SR-IOV mode is enabled, hardware VLAN
-filtering and VLAN tag stripping/insertion will remain enabled. Please remove
-the old VLAN filter before the new VLAN filter is added. For example,
+NOTE: When SR-IOV mode is enabled, hardware VLAN filtering and VLAN tag 
+stripping/insertion will remain enabled. Please remove the old VLAN filter 
+before the new VLAN filter is added. For example,
 ip link set eth0 vf 0 vlan 100 // set vlan 100 for VF 0
 ip link set eth0 vf 0 vlan 0   // Delete vlan 100
 ip link set eth0 vf 0 vlan 200 // set a new vlan 200 for VF 0
@@ -289,45 +276,42 @@ ip link set eth0 vf 0 vlan 200    // set a new vlan 200 for VF 0
 
 Configuring SR-IOV for improved network security
 ------------------------------------------------
-
-In a virtualized environment, on Intel(R) Server Adapters that support SR-IOV,
-the virtual function (VF) may be subject to malicious behavior. Software-
-generated layer two frames, like IEEE 802.3x (link flow control), IEEE 802.1Qbb
-(priority based flow-control), and others of this type, are not expected and
-can throttle traffic between the host and the virtual switch, reducing
-performance. To resolve this issue, configure all SR-IOV enabled ports for
-VLAN tagging. This configuration allows unexpected, and potentially malicious,
-frames to be dropped.
+In a virtualized environment, on Intel(R) Ethernet Server Adapters that support 
+SR-IOV, the virtual function (VF) may be subject to malicious behavior. 
+Software-generated layer two frames, like IEEE 802.3x (link flow control), IEEE 
+802.1Qbb (priority based flow-control), and others of this type, are not 
+expected and can throttle traffic between the host and the virtual switch, 
+reducing performance. To resolve this issue, configure all SR-IOV enabled ports 
+for VLAN tagging. This configuration allows unexpected, and potentially 
+malicious, frames to be dropped.
 
 
 Configuring VLAN tagging on SR-IOV enabled adapter ports
 --------------------------------------------------------
-
-To configure VLAN tagging for the ports on an SR-IOV enabled adapter,
-use the following command. The VLAN configuration should be done 
-before the VF driver is loaded or the VM is booted.
+To configure VLAN tagging for the ports on an SR-IOV enabled adapter, use the 
+following command. The VLAN configuration should be done before the VF driver 
+is loaded or the VM is booted.
 
 $ ip link set dev <PF netdev id> vf <id> vlan <vlan id>
 
-For example, the following instructions will configure PF eth0 and 
-the first VF on VLAN 10.
+For example, the following instructions will configure PF eth0 and the first VF 
+on VLAN 10.
 $ ip link set dev eth0 vf 0 vlan 10
-.
+
 
 VLAN Tag Packet Steering
 ------------------------
-
-Allows you to send all packets with a specific VLAN tag to a particular
-SR-IOV virtual function (VF). Further, this feature allows you to designate
-a particular VF as trusted, and allows that trusted VF to request selective
+Allows you to send all packets with a specific VLAN tag to a particular SR-IOV 
+virtual function (VF). Further, this feature allows you to designate a 
+particular VF as trusted, and allows that trusted VF to request selective 
 promiscuous mode on the Physical Function (PF).
 
-To set a VF as trusted or untrusted, enter the following command in the
+To set a VF as trusted or untrusted, enter the following command in the 
 Hypervisor:
   # ip link set dev eth0 vf 1 trust [on|off]
 
-Once the VF is designated as trusted, use the following commands in the VM
-to set the VF to promiscuous mode.
+Once the VF is designated as trusted, use the following commands in the VM to 
+set the VF to promiscuous mode.
   For promiscuous all:
   #ip link set eth2 promisc on
     Where eth2 is a VF interface in the VM
@@ -335,150 +319,146 @@ to set the VF to promiscuous mode.
   #ip link set eth2 allmulticast on
     Where eth2 is a VF interface in the VM
 
-    NOTE: By default, the ethtool priv-flag vf-true-promisc-support is set to 
-    "off",meaning that promiscuous mode for the VF will be limited. To set the
-    promiscuous mode for the VF to true promiscuous and allow the VF to see
-    all ingress traffic, use the following command.
-      #ethtool -set-priv-flags p261p1 vf-true-promisc-support on
-    The vf-true-promisc-support priv-flag does not enable promiscuous mode;
-    rather, it designates which type of promiscuous mode (limited or true)
-    you will get when you enable promiscuous mode using the ip link commands 
-    above. Note that this is a global setting that affects the entire device.
-    However,the vf-true-promisc-support priv-flag is only exposed to the first
-    PF of the device. The PF remains in limited promiscuous mode (unless it
-    is in MFP mode) regardless of the vf-true-promisc-support setting.
+NOTE: By default, the ethtool priv-flag vf-true-promisc-support is set to 
+"off",meaning that promiscuous mode for the VF will be limited. To set the 
+promiscuous mode for the VF to true promiscuous and allow the VF to see all 
+ingress traffic, use the following command.
+  #ethtool -set-priv-flags p261p1 vf-true-promisc-support on
+The vf-true-promisc-support priv-flag does not enable promiscuous mode; rather, 
+it designates which type of promiscuous mode (limited or true) you will get 
+when you enable promiscuous mode using the ip link commands above. Note that 
+this is a global setting that affects the entire device. However,the 
+vf-true-promisc-support priv-flag is only exposed to the first PF of the 
+device. The PF remains in limited promiscuous mode (unless it is in MFP mode) 
+regardless of the vf-true-promisc-support setting.
 
 Now add a VLAN interface on the VF interface.
   #ip link add link eth2 name eth2.100 type vlan id 100
 
-Note that the order in which you set the VF to promiscuous mode and add
-the VLAN interface does not matter (you can do either first). The end result
-in this example is that the VF will get all traffic that is tagged with
-VLAN 100.
+Note that the order in which you set the VF to promiscuous mode and add the 
+VLAN interface does not matter (you can do either first). The end result in 
+this example is that the VF will get all traffic that is tagged with VLAN 100.
 
 
 Intel(R) Ethernet Flow Director
 -------------------------------
-NOTE: Flow director parameters are only supported on kernel versions 2.6.30 or
-newer.
+NOTE: Intel Ethernet Flow Director parameters are only supported on kernel 
+versions 2.6.30 or newer.
 
-The Flow Director performs the following tasks:
+The Intel Ethernet Flow Director performs the following tasks:
 
-  - Directs receive packets according to their flows to different queues.
-  - Enables tight control on routing a flow in the platform.
-  - Matches flows and CPU cores for flow affinity.
-  - Supports multiple parameters for flexible flow classification and load
-    balancing (in SFP mode only).
+- Directs receive packets according to their flows to different queues.
+- Enables tight control on routing a flow in the platform.
+- Matches flows and CPU cores for flow affinity.
+- Supports multiple parameters for flexible flow classification and load
+  balancing (in SFP mode only).
 
-NOTES:
+NOTE: An included script (set_irq_affinity) automates setting the IRQ to CPU 
+affinity.
+
+NOTE: The Linux i40edriver supports the following flow types: IPv4, TCPv4, and 
+UDPv4. For a given flow type, it supports valid combinations of IP addresses 
+(source or destination) and UDP/TCP ports (source and destination). For 
+example, you can supply only a source IP address, a source IP address and a 
+destination port, or any combination of one or more of these four parameters.
 
-  - An included script (set_irq_affinity) automates setting the IRQ to
-    CPU affinity.
-
-  - The Linux i40e driver supports the following flow types: IPv4, TCPv4, and
-    UDPv4. For a given flow type, it supports valid combinations of
-    IP addresses (source or destination) and UDP/TCP ports (source and 
-    destination). For example, you can supply only a source IP address,
-    a source IP address and a destination port, or any combination of one or
-    more of these four parameters.
-  - The Linux i40e driver allows you to filter traffic based on a user-defined
-    flexible two-byte pattern and offset by using the ethtool user-def and
-    mask fields. Only L3 and L4 flow types are supported for user-defined 
-    flexible filters. For a given flow type, you must clear all Flow Director
-    filters before changing the input set (for that flow type).
+NOTE: The Linux i40edriver allows you to filter traffic based on a user-defined 
+flexible two-byte pattern and offset by using the ethtool user-def and mask 
+fields. Only L3 and L4 flow types are supported for user-defined flexible 
+filters. For a given flow type, you must clear all Intel Ethernet Flow Director 
+filters before changing the input set (for that flow type).
 
 ethtool commands:
 
-  - To enable or disable the Flow Director:
+To enable or disable the Intel Ethernet Flow Director:
 
-       # ethtool -K ethX ntuple <on|off>
+  # ethtool -K ethX ntuple <on|off>
 
-       When disabling ntuple filters, all the user programed filters are
-       flushed from the driver cache and hardware. All needed filters must
-       be re-added when ntuple is re-enabled.
+When disabling ntuple filters, all the user programed filters are flushed from 
+the driver cache and hardware. All needed filters must be re-added when ntuple 
+is re-enabled.
 
-  - To add a filter that directs packet to queue 2, use -U or -N switch:
+To add a filter that directs packet to queue 2, use -U or -N switch:
 
-       # ethtool -N ethX flow-type tcp4 src-ip 192.168.10.1 dst-ip \
-       192.168.10.2 src-port 2000 dst-port 2001 action 2 [loc 1]
+  # ethtool -N ethX flow-type tcp4 src-ip 192.168.10.1 dst-ip \
+  192.168.10.2 src-port 2000 dst-port 2001 action 2 [loc 1]
 
-   To set a filter using only the source and destination IP?address:
+To set a filter using only the source and destination IP address:
 
-       # ethtool -N ethX flow-type tcp4 src-ip 192.168.10.1 dst-ip \
-       192.168.10.2 action 2 [loc 1]
+  # ethtool -N ethX flow-type tcp4 src-ip 192.168.10.1 dst-ip \
+  192.168.10.2 action 2 [loc 1]
 
-   To set a filter based on a user defined pattern and offset:
+To set a filter based on a user defined pattern and offset:
 
-       # ethtool -N ethX flow-type tcp4 src-ip 192.168.10.1 dst-ip \
-       192.168.10.2 user-def 0xffffffff00000001 m 0x40 action 2 [loc 1]
+  # ethtool -N ethX flow-type tcp4 src-ip 192.168.10.1 dst-ip \
+  192.168.10.2 user-def 0xffffffff00000001 m 0x40 action 2 [loc 1]
 
-       where the value of the user-def field (0xffffffff00000001) is the
-       pattern and m 0x40 is the offset.
+  where the value of the user-def field (0xffffffff00000001) is the
+  pattern and m 0x40 is the offset.
 
-       Note that in this case the mask (m 0x40) parameter is used with the
-       user-def field, whereas for cloud filter support the mask parameter
-       is not used.
+Note that in this case the mask (m 0x40) parameter is used with the user-def 
+field, whereas for cloud filter support the mask parameter is not used.
 
-  - To see the list of filters currently present:
-       # ethtool <-u|-n> ethX
+To see the list of filters currently present:
+  # ethtool <-u|-n> ethX
 
 Application Targeted Routing (ATR) Perfect Filters
 --------------------------------------------------
-ATR is enabled by default when the kernel is in multiple transmit queue mode.
-An ATR flow director filter rule is added when a TCP-IP flow starts and is
-deleted when the flow ends. When a TCP-IP Flow Director rule is added from
-ethtool (Sideband filter), ATR is turned off by the driver. To re-enable ATR,
-the sideband can be disabled with the ethtool -K option. If sideband is
-re-enabled after ATR is re-enabled, ATR remains enabled until a TCP-IP flow
-is added. When all TCP-IP sideband rules are deleted, ATR is automatically
-re-enabled.
-
-Packets that match the ATR rules are counted in fdir_atr_match stats in
+ATR is enabled by default when the kernel is in multiple transmit queue mode. 
+An ATR Intel Ethernet Flow Director filter rule is added when a TCP-IP flow 
+starts and is deleted when the flow ends. When a TCP-IP Intel Ethernet Flow 
+Director rule is added from ethtool (Sideband filter), ATR is turned off by the 
+driver. To re-enable ATR, the sideband can be disabled with the ethtool -K 
+option. If sideband is re-enabled after ATR is re-enabled, ATR remains enabled 
+until a TCP-IP flow is added. When all TCP-IP sideband rules are deleted, ATR 
+is automatically re-enabled.
+
+Packets that match the ATR rules are counted in fdir_atr_match stats in 
 ethtool, which also can be used to verify whether ATR rules still exist.
 
 Sideband Perfect Filters
 ------------------------
-
-Sideband Perfect Filters are used to direct traffic that matches specified
-characteristics. They are enabled through ethtool's ntuple interface.
-To add a new filter use the following command:
-  ethtool -U <device> flow-type <type> src-ip <ip> dst-ip <ip> src-port <port>
+Sideband Perfect Filters are used to direct traffic that matches specified 
+characteristics. They are enabled through ethtool's ntuple interface. To add a 
+new filter use the following command:
+  ethtool -U <device> flow-type <type> src-ip <ip> dst-ip <ip> src-port <port> 
 dst-port <port> action <queue>
 Where:
   <device> - the ethernet device to program
   <type> - can be ip4, tcp4, udp4, or sctp4
   <ip> - the ip address to match on
   <port> - the port number to match on
-  <queue> - the queue to direct traffic towards (-1 discards the matched traffic)
+  <queue> - the queue to direct traffic towards (-1 discards the matched 
+traffic)
 Use the following command to display all of the active filters:
   ethtool -u <device>
 Use the following command to delete a filter:
   ethtool -U <device> delete <N>
-<N> is the filter id displayed when printing all the active filters, and may
-also have been specified using "loc <N>" when adding the filter.
+Where <N> is the filter id displayed when printing all the active filters, and 
+may also have been specified using "loc <N>" when adding the filter.
 
-The following example matches TCP traffic sent from 192.168.0.1, port 5300,
+The following example matches TCP traffic sent from 192.168.0.1, port 5300, 
 directed to 192.168.0.5, port 80, and sends it to queue 7:
   ethtool -U enp130s0 flow-type tcp4 src-ip 192.168.0.1 dst-ip 192.168.0.5
   src-port 5300 dst-port 7 action 7
 
-For each flow-type, the programmed filters must all have the same matching
+For each flow-type, the programmed filters must all have the same matching 
 input set. For example, issuing the following two commands is acceptable:
   ethtool -U enp130s0 flow-type ip4 src-ip 192.168.0.1 src-port 5300 action 7
   ethtool -U enp130s0 flow-type ip4 src-ip 192.168.0.5 src-port 55 action 10
-Issuing the next two commands, however, is not acceptable, since the first
-specifies scr-ip and the second specifies dst-ip:
+Issuing the next two commands, however, is not acceptable, since the first 
+specifies src-ip and the second specifies dst-ip:
   ethtool -U enp130s0 flow-type ip4 src-ip 192.168.0.1 src-port 5300 action 7
   ethtool -U enp130s0 flow-type ip4 dst-ip 192.168.0.5 src-port 55 action 10
-The second command will fail with an error. You may program multiple filters
-with the same fields, using different values, but, on one device, you may not
+The second command will fail with an error. You may program multiple filters 
+with the same fields, using different values, but, on one device, you may not 
 program two tcp4 filters with different matching fields.
 
-Matching on a sub-portion of a field is not supported by the i40e driver,
-thus partial mask fields are not supported.
+Matching on a sub-portion of a field is not supported by the i40edriver, thus 
+partial mask fields are not supported.
 
-The driver also supports matching user-defined data within the packet payload.
-This flexible data is specified using the "user-def" field of the ethtool
+The driver also supports matching user-defined data within the packet payload. 
+This flexible data is specified using the "user-def" field of the ethtool 
 command in the following way:
 +----------------------------+--------------------------+
 | 31    28    24    20    16 | 15    12    8    4    0  |
@@ -489,91 +469,88 @@ command in the following way:
 For example,
   ... user-def 0x4FFFF ...
 
-tells the filter to look 4 bytes into the payload and match that value against
-0xFFFF. The offset is based on the beginning of the payload, and not the
+tells the filter to look 4 bytes into the payload and match that value against 
+0xFFFF. The offset is based on the beginning of the payload, and not the 
 beginning of the packet. Thus
 
   flow-type tcp4 ... user-def 0x8BEAF ...
 
-would match TCP/IPv4 packets which have the value 0xBEAF 8 bytes into the TCP/IPv4 payload.
+would match TCP/IPv4 packets which have the value 0xBEAF 8 bytes into the 
+TCP/IPv4 payload.
 
-Note that ICMP headers are parsed as 4 bytes of header and 4 bytes of payload.
-Thus to match the first byte of the payload, you must actually add 4 bytes
-to the offset. Also note that ip4 filters match both ICMP frames as well as
-raw (unknown) ip4 frames, where the payload will be the L3 payload of the
-IP4 frame.
+Note that ICMP headers are parsed as 4 bytes of header and 4 bytes of payload. 
+Thus to match the first byte of the payload, you must actually add 4 bytes to 
+the offset. Also note that ip4 filters match both ICMP frames as well as raw 
+(unknown) ip4 frames, where the payload will be the L3 payload of the IP4 frame.
 
-The maximum offset is 64. The hardware will only read up to 64 bytes of data
-from the payload. The offset must be even because the flexible data is 2 bytes
+The maximum offset is 64. The hardware will only read up to 64 bytes of data 
+from the payload. The offset must be even because the flexible data is 2 bytes 
 long and must be aligned to byte 0 of the packet payload.
 
-The user-defined flexible offset is also considered part of the input set and
-cannot be programmed separately for multiple filters of the same type. However,
-the flexible data is not part of the input set and multiple filters may use the
+The user-defined flexible offset is also considered part of the input set and 
+cannot be programmed separately for multiple filters of the same type. However, 
+the flexible data is not part of the input set and multiple filters may use the 
 same offset but match against different data.
 
-To create filters that direct traffic to a specific Virtual Function, use the
-?action" parameter. Specify the action as a 64 bit value, where the lower 32
+To create filters that direct traffic to a specific Virtual Function, use the 
+"action" parameter. Specify the action as a 64 bit value, where the lower 32 
 bits represents the queue number, while the next 8 bits represent which VF.
 Note that 0 is the PF, so the VF identifier is offset by 1. For example:
 
   ... action 0x800000002 ...
 
-specifies to direct traffic to Virtual Function 7 (8 minus 1) into queue 2 of
+specifies to direct traffic to Virtual Function 7 (8 minus 1) into queue 2 of 
 that VF.
 
-Note that these filters will not break internal routing rules, and will not
-route traffic that otherwise would not have been sent to the specified Virtual
+Note that these filters will not break internal routing rules, and will not 
+route traffic that otherwise would not have been sent to the specified Virtual 
 Function.
 
 
 Cloud Filter Support
 --------------------
-On a complex network that supports multiple types of traffic (such as for
-storage as well as cloud), cloud filter support allows you to send one type of
- traffic (for example, the storage traffic) to the Physical Function (PF) and
-another type (say, the cloud traffic) to a Virtual Function (VF). Because cloud
-networks are typically VXLAN/Geneve-based, you can define a cloud filter to
-identify VXLAN/Geneve packets and send them to a queue in the VF to be
-processed by the virtual machine (VM). Similarly, other cloud filters can be
+On a complex network that supports multiple types of traffic (such as for 
+storage as well as cloud), cloud filter support allows you to send one type of 
+traffic (for example, the storage traffic) to the Physical Function (PF) and 
+another type (say, the cloud traffic) to a Virtual Function (VF). Because cloud 
+networks are typically VXLAN/GENEVE-based, you can define a cloud filter to 
+identify VXLAN/GENEVE packets and send them to a queue in the VF to be 
+processed by the virtual machine (VM). Similarly, other cloud filters can be 
 designed for various other traffic tunneling.
 
-NOTES:
-  - Cloud filters are only supported when the underlying device is in Single
-    Function per Port mode.
-  - The "action -1" option, which drops matching packets in regular Flow
-    Director filters, is not available to drop packets when used with 
-    cloud filters.
-  - For IPv4 and ether flow-types, cloud filters cannot be used for TCP or
-    UDP filters.
-  - Cloud filters can be used as a method for implementing queue splitting in
-    the PF.
+NOTE: Cloud filters are only supported when the underlying device is in Single 
+Function per Port mode.
+
+NOTE: The "action -1" option, which drops matching packets in regular Intel 
+Ethernet Flow Director filters, is not available to drop packets when used with 
+cloud filters.
+
+NOTE: For IPv4 and ether flow-types, cloud filters cannot be used for TCP or 
+UDP filters.
+
+NOTE: Cloud filters can be used as a method for implementing queue splitting in 
+the PF.
 
 The following filters are supported:
   Cloud Filters
-    Inner MAC, Inner VLAN (for NVGRE, VXLAN or Geneve packets)
-    Inner MAC, Inner VLAN, Tenant ID (for NVGRE, VXLAN or Geneve packets)
-    Inner MAC, Tenant ID (NVGRE packet or VXLAN/Geneve packets)
+    Inner MAC, Inner VLAN (for NVGRE, VXLAN or GENEVE packets)
+    Inner MAC, Inner VLAN, Tenant ID (for NVGRE, VXLAN or GENEVE packets)
+    Inner MAC, Tenant ID (NVGRE packet or VXLAN/GENEVE packets)
     Outer MAC L2 filter
-    Inner MAC filter
-    Outer MAC, Tenant ID, Inner MAC
-    Application Destination IP
-    Application Source-IP, Inner MAC
     ToQueue: Use MAC, VLAN to point to a queue
   L3 filters
     Application Destination IP
 
-Cloud filters are specified using ethtool's ntuple interface, but the driver
-uses user-def to determine whether to treat the filter as a cloud filter or a
-regular filter. To enable a cloud filter, set the highest bit of the user-def
-field, "user-def 0x8000000000000000" to enable the cloud features described
-below. This specifies to the driver to treat the filter specially and not treat
-it like the regular filters described above. Note that cloud filters also read
-the other bits in the user-def field separately so you cannot use the flexible
+Cloud filters are specified using ethtool's ntuple interface, but the driver 
+uses user-def to determine whether to treat the filter as a cloud filter or a 
+regular filter. To enable a cloud filter, set the highest bit of the user-def 
+field, "user-def 0x8000000000000000" to enable the cloud features described 
+below. This specifies to the driver to treat the filter specially and not treat 
+it like the regular filters described above. Note that cloud filters also read 
+the other bits in the user-def field separately so you cannot use the flexible 
 data feature described above.
 
-For regular Flow Director filters:
-
+For regular Intel Ethernet Flow Director filters:
   - No user-def specified or highest bit (bit 63) is 0
 
   Example:
@@ -582,28 +559,27 @@ For regular Flow Director filters:
     action 6 loc
 
 For L3 filters (non-tunneled packets):
-
   - "user-def 0x8000000000000000" (no Tenant ID/VNI specified in remaining
     bits of the user-def field)
   - Only L3 parameters (src-IP, dst-IP) are considered
 
   Example:
 
-    ethtool -U enp130s0 flow-type ip4 src-ip 192.168.42.13 dst-ip 192.168.42.33 /
+    ethtool -U enp130s0 flow-type ip4 src-ip 192.168.42.13 dst-ip 192.168.42.33 
+/
     src-port 12344 dst-port 12344 user-def 0x8000000000000000 action /
     0x200000000 loc 3
       Redirect traffic coming from 192.168.42.13 port 12344 with destination
       192.168.42.33 port 12344 into VF id 1, and call this "rule 3"
 
 For cloud filters (tunneled packets):
-
   - All other filters, including where Tenant ID/VNI is specified.
   - The lower 32 bits of the user-def field can carry the tenant ID/VNI
     if required.
   - The VF can be specified using the "action" field, just as regular filters
     described in the Flow director Filter section above.
   - Cloud filters can be defined with inner MAC, outer MAC, inner IP address,
-     inner VLAN, and VNI as part of the cloud tuple. Cloud filters filter on
+    inner VLAN, and VNI as part of the cloud tuple. Cloud filters filter on
     destination (not source) MAC and IP. The destination and source MAC
     address fields in the ethtool command are overloaded as dst = outer,
     src = inner MAC address to facilitate tuple definition for a cloud filter.
@@ -612,12 +588,12 @@ For cloud filters (tunneled packets):
 
   Example:
 
-    ethtool -U enp130s0 flow-type ip4 src-ip 192.168.42.13 dst-ip 192.168.42.33 /
-    src-port 12344 dst-port 12344 user-def 0x8000000000000022 loc 38 action /
-    0x200000000
+    ethtool –U enp130s0 flow-type ether dst 8b:9d:ed:6a:ce:43 \
+    src 1d:44:9d:54:da:de user-def 0x8000000000000022 loc 38 \
+    action 0x200000000
       Redirect traffic on VXLAN using tunnel id 34 (hex 0x22) coming from
-      192.168.42.13 port 12344 with destination 192.168.42.33 port 12344 into
-      VF id 1, and call this "rule 38"
+      outer MAC address 8b:9d:ed:6a:ce:43 and inner MAC address
+      1d:44:9d:54:da:de into VF id 1 and call this “rule 38”.
 
 
 ================================================================================
@@ -629,22 +605,30 @@ Additional Features and Configurations
 
 Configuring the Driver on Different Distributions
 -------------------------------------------------
+Configuring a network driver to load properly when the system is started is 
+distribution dependent. Typically, the configuration process involves adding an 
+alias line to /etc/modules.conf or /etc/modprobe.conf as well as editing other 
+system startup scripts and/or configuration files. Many popular Linux 
+distributions ship with tools to make these changes for you. To learn the 
+proper way to configure a network device for your system, refer to your 
+distribution documentation. If during this process you are asked for the driver 
+or module name, the name for the Base Driver is i40e.
 
-Configuring a network driver to load properly when the system is started is
-distribution dependent. Typically, the configuration process involves adding
-an alias line to /etc/modules.conf or /etc/modprobe.conf as well as editing
-other system startup scripts and/or configuration files. Many popular Linux
-distributions ship with tools to make these changes for you. To learn the
-proper way to configure a network device for your system, refer to your
-distribution documentation. If during this process you are asked for the
-driver or module name, the name for the Base Driver is i40e.
+
+Setting the link-down-on-close Private Flag
+-------------------------------------------
+When the link-down-on-close private flag is set to "on", the port's link will 
+go down when the interface is brought down using the ifconfig ethX down command.
+
+Use ethtool to view and set link-down-on-close, as follows:
+  ethtool --show-priv-flags ethX
+  ethtool --set-priv-flags ethX link-down-on-close [on|off]
 
 
 Viewing Link Messages
 ---------------------
-
-Link messages will not be displayed to the console if the distribution is
-restricting system messages. In order to see network driver link messages on
+Link messages will not be displayed to the console if the distribution is 
+restricting system messages. In order to see network driver link messages on 
 your console, set dmesg to eight by entering the following:
 dmesg -n 8
 
@@ -653,10 +637,10 @@ NOTE: This setting is not saved across reboots.
 
 Jumbo Frames
 ------------
-Jumbo Frames support is enabled by changing the Maximum Transmission Unit
-(MTU) to a value larger than the default value of 1500.
+Jumbo Frames support is enabled by changing the Maximum Transmission Unit (MTU) 
+to a value larger than the default value of 1500.
 
-Use the ifconfig command to increase the MTU size. For example, enter the
+Use the ifconfig command to increase the MTU size. For example, enter the 
 following where <x> is the interface number:
 
    ifconfig eth<x> mtu 9000 up
@@ -664,31 +648,28 @@ Alternatively, you can use the ip command as follows:
    ip link set mtu 9000 dev eth<x>
    ip link set up dev eth<x>
 
-This setting is not saved across reboots. The setting change can be made
+This setting is not saved across reboots. The setting change can be made 
 permanent by adding 'MTU=9000' to the file:
 /etc/sysconfig/network-scripts/ifcfg-eth<x> for RHEL or to the file
 /etc/sysconfig/network/<config_file> for SLES.
 
+NOTE: The maximum MTU setting for Jumbo Frames is 9702. This value coincides 
+with the maximum Jumbo Frames size of 9728 bytes.
 
-
-NOTES:
-- The maximum MTU setting for Jumbo Frames is 9702. This value coincides
-  with the maximum Jumbo Frames size of 9728 bytes.
-- This driver will attempt to use multiple page sized buffers to receive
-  each jumbo packet. This should help to avoid buffer starvation issues
-  when allocating receive packets.
-
+NOTE: This driver will attempt to use multiple page sized buffers to receive 
+each jumbo packet. This should help to avoid buffer starvation issues when 
+allocating receive packets.
 
 
 ethtool
 -------
-The driver utilizes the ethtool interface for driver configuration and
-diagnostics, as well as displaying statistical information. The latest
-ethtool version is required for this functionality. Download it at
+The driver utilizes the ethtool interface for driver configuration and 
+diagnostics, as well as displaying statistical information. The latest ethtool 
+version is required for this functionality. Download it at:
 http://ftp.kernel.org/pub/software/network/ethtool/
 
-Supported ethtool Commands and Options
---------------------------------------
+Supported ethtool Commands and Options for Filtering
+----------------------------------------------------
 -n --show-nfc
   Retrieves the receive network flow classification configurations.
 
@@ -698,7 +679,8 @@ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6
 -N --config-nfc
   Configures the receive network flow classification.
 
-rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r...
+rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 
+m|v|t|s|d|f|n|r...
   Configures the hash options for the specified network traffic type.
 
   udp4 UDP over IPv4
@@ -710,46 +692,39 @@ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r..
 
 Speed and Duplex Configuration
 ------------------------------
-
-In addressing speed and duplex configuration issues, you need to
-distinguish between copper-based adapters and fiber-based adapters.
-
-In the default mode, an Intel(R) Network Adapter using copper connections
-will attempt to auto-negotiate with its link partner to determine the best
-setting. If the adapter cannot establish link with the link partner using
-auto-negotiation, you may need to manually configure the adapter and link
-partner to identical settings to establish link and pass packets. This
-should only be needed when attempting to link with an older switch that
-does not support auto-negotiation or one that has been forced to a specific
-speed or duplex mode. Your link partner must match the setting you choose.
-1 Gbps speeds and higher cannot be forced. Use the autonegotiation
-advertising setting to manually set devices for 1 Gbps and higher.
-
-NOTE: You cannot set the speed for Intel(R) Ethernet Network Adapter
-XXV710 based devices.
-
-
-
-
-
-
-Speed, duplex, and autonegotiation advertising are configured through
-the ethtool* utility. ethtool is included with all versions of Red Hat
-after Red Hat 7.2. For the latest version, download and install
-ethtool from the following website:
+In addressing speed and duplex configuration issues, you need to distinguish 
+between copper-based adapters and fiber-based adapters.
+
+In the default mode, an Intel(R) Ethernet Network Adapter using copper 
+connections will attempt to auto-negotiate with its link partner to determine 
+the best setting. If the adapter cannot establish link with the link partner 
+using auto-negotiation, you may need to manually configure the adapter and link 
+partner to identical settings to establish link and pass packets. This should 
+only be needed when attempting to link with an older switch that does not 
+support auto-negotiation or one that has been forced to a specific speed or 
+duplex mode. Your link partner must match the setting you choose. 1 Gbps speeds 
+and higher cannot be forced. Use the autonegotiation advertising setting to 
+manually set devices for 1 Gbps and higher.
+
+NOTE: You cannot set the speed for devices based on the Intel(R) Ethernet 
+Network Adapter XXV710 based devices.
+
+Speed, duplex, and autonegotiation advertising are configured through the 
+ethtool* utility. ethtool is included with all versions of Red Hat after Red 
+Hat 7.2. For the latest version, download and install ethtool from the 
+following website:
 
    http://ftp.kernel.org/pub/software/network/ethtool/
 
+Caution: Only experienced network administrators should force speed and duplex 
+or change autonegotiation advertising manually. The settings at the switch must 
+always match the adapter settings. Adapter performance may suffer or your 
+adapter may not operate if you configure the adapter differently from your 
+switch.
 
-Caution: Only experienced network administrators should force speed and
-duplex or change autonegotiation advertising manually. The settings at
-the switch must always match the adapter settings. Adapter performance
-may suffer or your adapter may not operate if you configure the adapter
-differently from your switch.
-
-An Intel(R) Network Adapter using fiber-based connections, however, will not
-attempt to auto-negotiate with its link partner since those adapters operate
-only in full duplex and only at their native speed.
+An Intel(R) Ethernet Network Adapter using fiber-based connections, however, 
+will not attempt to auto-negotiate with its link partner since those adapters 
+operate only in full duplex and only at their native speed.
 
 
 NAPI
@@ -761,32 +736,34 @@ https://www.linuxfoundation.org/collaborate/workgroups/networking/napi
 
 Flow Control
 ------------
-
-Ethernet Flow Control (IEEE 802.3x) can be configured with ethtool to enable
-receiving and transmitting pause frames for i40e. When transmit is enabled,
-pause frames are generated when the receive packet buffer crosses a predefined
-threshold. When receive is enabled, the transmit unit will halt for the time
+Ethernet Flow Control (IEEE 802.3x) can be configured with ethtool to enable 
+receiving and transmitting pause frames for i40e. When transmit is enabled, 
+pause frames are generated when the receive packet buffer crosses a predefined 
+threshold. When receive is enabled, the transmit unit will halt for the time 
 delay specified when a pause frame is received. 
 
+NOTE: You must have a flow control capable link partner.
+
 Flow Control is disabled by default.
 
 Use ethtool to change the flow control settings.
 
-ethtool:
-ethtool -s eth? autoneg off rx on tx on
-
-
-
-
-NOTE: You must have a flow control capable link partner.
-
+To enable or disable rx or tx Flow Control:
+ethtool -A eth? rx <on|off> tx <on|off>
+Note: This command only enables or disables Flow Control if auto-negotiation is 
+disabled. If auto-negotiation is enabled, this command changes the parameters 
+used for auto-negotiation with the link partner.
 
+To enable or disable auto-negotiation:
+ethtool -s eth? autoneg <on|off>
+Note: Flow Control auto-negotiation is part of link auto-negotiation. Depending 
+on your device, you may not be able to change the auto-negotiation setting.
 
 
 RSS Hash Flow
 -------------
 
-Allows you to set the hash bytes per flow type and any combination of one or
+Allows you to set the hash bytes per flow type and any combination of one or 
 more options for Receive Side Scaling (RSS) hash byte configuration.
 
 #ethtool -N <dev> rx-flow-hash <type> <option>
@@ -806,89 +783,121 @@ And <option> is one or more of:
 MAC and VLAN anti-spoofing feature
 ----------------------------------
 
-When a malicious driver attempts to send a spoofed packet, it is dropped by
-the hardware and not transmitted.
-NOTE: This feature can be disabled for a specific Virtual Function (VF).
+When a malicious driver attempts to send a spoofed packet, it is dropped by the 
+hardware and not transmitted.
+NOTE: This feature can be disabled for a specific Virtual Function (VF):
 ip link set <pf dev> vf <vf id> spoofchk {off|on}
 
 
 IEEE 1588 Precision Time Protocol (PTP) Hardware Clock (PHC)
 ------------------------------------------------------------
 
-Precision Time Protocol (PTP) is used to synchronize clocks in a computer
-network. PTP support varies among Intel devices that support this driver.
-Use "ethtool -T <netdev name>" to get a definitive list of PTP capabilities
+Precision Time Protocol (PTP) is used to synchronize clocks in a computer 
+network. PTP support varies among Intel devices that support this driver. Use 
+"ethtool -T <netdev name>" to get a definitive list of PTP capabilities 
 supported by the device.
 
 
 
-VXLAN Overlay HW Offloading
+IEEE 802.1ad (QinQ) Support
 ---------------------------
 
-Virtual Extensible LAN (VXLAN) allows you to extend an L2 network over an L3
-network, which may be useful in a virtualized or cloud environment. Some Intel(R)
-Ethernet Network devices perform VXLAN processing, offloading it from the
-operating system. This reduces CPU utilization.
+The IEEE 802.1ad standard, informally known as QinQ, allows for multiple VLAN 
+IDs within a single Ethernet frame. VLAN IDs are sometimes referred to as 
+"tags," and multiple VLAN IDs are thus referred to as a "tag stack." Tag stacks 
+allow L2 tunneling and the ability to segregate traffic within a particular 
+VLAN ID, among other uses.
+
+The following are examples of how to configure 802.1ad (QinQ):
+  ip link add link eth0 eth0.24 type vlan proto 802.1ad id 24
+  ip link add link eth0.24 eth0.24.371 type vlan proto 802.1Q id 371
+Where "24" and "371" are example VLAN IDs.
+
+NOTES:
+- 802.1ad (QinQ)is supported in 3.19 and later kernels.
+- Receive checksum offloads, cloud filters, and VLAN acceleration are not 
+supported for 802.1ad (QinQ) packets.
+
+
+VXLAN and GENEVE Overlay HW Offloading
+--------------------------------------
+
+Virtual Extensible LAN (VXLAN) allows you to extend an L2 network over an L3 
+network, which may be useful in a virtualized or cloud environment. Some 
+Intel(R) Ethernet Network devices perform VXLAN processing, offloading it from 
+the operating system. This reduces CPU utilization.
  
-VXLAN offloading is controlled by the tx and rx checksum offload options
-provided by ethtool. That is, if tx checksum offload is enabled, and the
+VXLAN offloading is controlled by the tx and rx checksum offload options 
+provided by ethtool. That is, if tx checksum offload is enabled, and the 
 adapter has the capability, VXLAN offloading is also enabled.
 
-Support for VXLAN HW offloading is dependent on
-kernel support of the HW offloading features.
+Support for VXLAN and GENEVE HW offloading is dependent on kernel support of 
+the HW offloading features.
 
 
 Multiple Functions per Port
 ---------------------------
 
-On X710/XL710 based adapters that support it, you can set up multiple functions
-on each physical port. You configure these functions through the System
-Setup/BIOS.
+Some adapters based on the Intel Ethernet Controller X710/XL710 support 
+multiple functions on a single physical port. Configure these functions through 
+the System Setup/BIOS.
 
-Minimum TX Bandwidth is the guaranteed minimum data transmission bandwidth, as
-a percentage of the full physical port link speed, that the partition will
-receive. The bandwidth the partition is awarded will never fall below the level
-you specify here.
+Minimum TX Bandwidth is the guaranteed minimum data transmission bandwidth, as 
+a percentage of the full physical port link speed, that the partition will 
+receive. The bandwidth the partition is awarded will never fall below the level 
+you specify.
 
 The range for the minimum bandwidth values is:
 1 to ((100 minus # of partitions on the physical port) plus 1)
-For example, if a physical port has 4 partitions, the range would be
+For example, if a physical port has 4 partitions, the range would be:
 1 to ((100 - 4) + 1 = 97)
 
-The Maximum Bandwidth percentage represents the maximum transmit
-bandwidth allocated to the partition as a percentage of the full physical port
-link speed. The accepted range of values is 1-100. The value can be used as a
-limiter, should you chose that any one particular function not be able to
-consume 100% of a port's bandwidth (should it be available). The sum of
-all the values for Maximum Bandwidth is not restricted, because no more than
-100% of a port's bandwidth can ever be used.
+The Maximum Bandwidth percentage represents the maximum transmit bandwidth 
+allocated to the partition as a percentage of the full physical port link 
+speed. The accepted range of values is 1-100. The value is used as a limiter, 
+should you chose that any one particular function not be able to consume 100% 
+of a port's bandwidth (should it be available). The sum of all the values for 
+Maximum Bandwidth is not restricted, because no more than 100% of a port's 
+bandwidth can ever be used.
+
+NOTE: X710/XXV710 devices fail to enable Max VFs (64) when Multiple Functions 
+per Port (MFP) and SR-IOV are enabled. An error from i40e is logged that says 
+"add vsi failed for VF N, aq_err 16". To workaround the issue, enable less than 
+64 virtual functions (VFs).
 
 
 Data Center Bridging (DCB)
 --------------------------
-DCB is a configuration Quality of Service implementation in hardware.
-It uses the VLAN priority tag (802.1p) to filter traffic. That means
-that there are 8 different priorities that traffic can be filtered into.
-It also enables priority flow control (802.1Qbb) which can limit or
-eliminate the number of dropped packets during network stress. Bandwidth
-can be allocated to each of these priorities, which is enforced at the
-hardware level (802.1Qaz).
 
-Adapter firmware implements LLDP and DCBX protocol agents as per 802.1AB
-and 802.1Qaz respectively. The firmware based DCBX agent runs in willing
-mode only and can accept settings from a DCBX capable peer. Software
-configuration of DCBX parameters via dcbtool/lldptool are not supported.
+NOTE:
+The kernel assumes that TC0 is available, and will disable Priority Flow 
+Control (PFC) on the device if TC0 is not available. To fix this, ensure TC0 is 
+enabled when setting up DCB on your switch.
+
 
-The i40e driver implements the DCB netlink interface layer to allow
-user-space to communicate with the driver and query DCB configuration for
-the port.
+DCB is a configuration Quality of Service implementation in hardware. It uses 
+the VLAN priority tag (802.1p) to filter traffic. That means that there are 8 
+different priorities that traffic can be filtered into. It also enables 
+priority flow control (802.1Qbb) which can limit or eliminate the number of 
+dropped packets during network stress. Bandwidth can be allocated to each of 
+these priorities, which is enforced at the hardware level (802.1Qaz).
+
+Adapter firmware implements LLDP and DCBX protocol agents as per 802.1AB and 
+802.1Qaz respectively. The firmware based DCBX agent runs in willing mode only 
+and can accept settings from a DCBX capable peer. Software configuration of 
+DCBX parameters via dcbtool/lldptool are not supported.
+
+NOTE: Firmware LLDP can be disabled by setting the private flag disable-fw-lldp.
+
+The i40e driver implements the DCB netlink interface layer to allow user-space 
+to communicate with the driver and query DCB configuration for the port.
 
 
 Interrupt Rate Limiting
 -----------------------
 
-The Intel(R) Ethernet Controller XL710 family supports an interrupt rate
-limiting mechanism. The user can control, via ethtool, the number of
+The Intel(R) Ethernet Controller XL710 family supports an interrupt rate 
+limiting mechanism. The user can control, via ethtool, the number of 
 microseconds between interrupts.
 
 Syntax:
@@ -896,34 +905,33 @@ Syntax:
 
 Valid Range: 0-235 (0=no limit)
 
-The range of 0-235 microseconds provides an effective range of 4,310 to
-250,000 interrupts per second. The value of rx-usecs-high can be set
-independently of rx-usecs and tx-usecs in the same ethtool command, and
-is also independent of the adaptive interrupt moderation algorithm. The
-underlying hardware supports granularity in 4-microsecond intervals, so
-adjacent values may result in the same interrupt rate.
+The range of 0-235 microseconds provides an effective range of 4,310 to 250,000 
+interrupts per second. The value of rx-usecs-high can be set independently of 
+rx-usecs and tx-usecs in the same ethtool command, and is also independent of 
+the adaptive interrupt moderation algorithm. The underlying hardware supports 
+granularity in 4-microsecond intervals, so adjacent values may result in the 
+same interrupt rate.
 
 One possible use case is the following:
 # ethtool -C ethX adaptive-rx off adaptive-tx off rx-usecs-high 20 rx-usecs 5
 tx-usecs 5
 
-The above command would disable adaptive interrupt moderation, and allow a
-maximum of 5 microseconds before indicating a receive or transmit was complete.
- However, instead of resulting in as many as 200,000 interrupts per second, it
+The above command would disable adaptive interrupt moderation, and allow a 
+maximum of 5 microseconds before indicating a receive or transmit was complete. 
+However, instead of resulting in as many as 200,000 interrupts per second, it 
 limits total interrupts per second to 50,000 via the rx-usecs-high parameter.
 
 
 Performance Optimization:
 -------------------------
 
-Driver defaults are meant to fit a wide variety of workloads, but if further
-optimization is required we recommend experimenting with the following
-settings.
+Driver defaults are meant to fit a wide variety of workloads, but if further 
+optimization is required we recommend experimenting with the following settings.
 
-NOTE: For better performance when processing small (64B) frame sizes,
-try enabling Hyper threading in the BIOS in order to increase the number
-of logical cores in the system and subsequently increase the number of
-queues available to the adapter.
+NOTE: For better performance when processing small (64B) frame sizes, try 
+enabling Hyper threading in the BIOS in order to increase the number of logical 
+cores in the system and subsequently increase the number of queues available to 
+the adapter.
 
 Virtualized Environments:
 
@@ -942,8 +950,8 @@ Virtualized Environments:
 
 Non-virtualized Environments
 
-Pin the adapter's IRQs to specific cores by disabling the irqbalance service
-and using the included set_irq_affinity script. Please see the script's help
+Pin the adapter's IRQs to specific cores by disabling the irqbalance service 
+and using the included set_irq_affinity script. Please see the script's help 
 text for further options.
 
   - The following settings will distribute the IRQs across all the cores
@@ -958,7 +966,7 @@ text for further options.
 
 For very CPU intensive workloads, we recommend pinning the IRQs to all cores.
 
-For IP Forwarding: Disable Adaptive ITR and lower rx and tx interrupts per
+For IP Forwarding: Disable Adaptive ITR and lower rx and tx interrupts per 
 queue using ethtool.
 
   - Setting rx-usecs and tx-usecs to 125 will limit interrupts to about 8000
@@ -967,7 +975,7 @@ queue using ethtool.
     # ethtool -C <interface> adaptive-rx off adaptive-tx off rx-usecs 125 
     tx-usecs 125
 
-For lower CPU utilization: Disable Adaptive ITR and lower rx and tx interrupts
+For lower CPU utilization: Disable Adaptive ITR and lower rx and tx interrupts 
 per queue using ethtool.
 
   - Setting rx-usecs and tx-usecs to 250 will limit interrupts to about 4000
@@ -976,8 +984,8 @@ per queue using ethtool.
     # ethtool -C <interface> adaptive-rx off adaptive-tx off rx-usecs 250 
     tx-usecs 250
 
-For lower latency: Disable Adaptive ITR and ITR by setting rx and tx to 0
-using ethtool.
+For lower latency: Disable Adaptive ITR and ITR by setting rx and tx to 0 using 
+ethtool.
 
     # ethtool -C <interface> adaptive-rx off adaptive-tx off rx-usecs 0 
     tx-usecs 0
@@ -990,204 +998,198 @@ Known Issues/Troubleshooting
 ----------------------------
 
 
+Failure to enable MAX VFs when MFP and SR-IOV enabled
+-----------------------------------------------------
+
+X710/XXV710 devices fail to enable Max VFs (64) when Multiple Functions per 
+Port (MFP) and SR-IOV are enabled. An error from i40e is logged that says "add 
+vsi failed for VF N, aq_err 16". To workaround the issue, enable less than 64 
+virtual functions (VFs).
+
+
 ip link show command shows incorrect VF MAC if VF MAC was set from VF side
 --------------------------------------------------------------------------
+Executing the command "ip link show" only shows MAC addresses if they are set 
+by the PF. Otherwise, it shows all zeros.
 
-Executing the command "ip link show" only shows MAC addresses if they
-are set by the PF. Otherwise, it shows all zeros.
-
-This is expected behavior. The PF driver is passing zeroes to the VF
-driver that the VF driver can generate its own random MAC address and report
-it to the guest OS. Without this feature, some guest operating systems
-will incorrectly assign the VF a new interface name each time they reboot.
+This is expected behavior. The PF driver is passing zeroes to the VF driver 
+that the VF driver can generate its own random MAC address and report it to the 
+guest OS. Without this feature, some guest operating systems will incorrectly 
+assign the VF a new interface name each time they reboot.
 
 
 SSL error (No such file) when installing driver on Ubuntu 14.04
 ---------------------------------------------------------------
-When installing the driver on Ubuntu 14.04, you may get an SSL error stating
-"no such file or directory." This issue does not affect driver installation
-or performance and can be ignored.
+When installing the driver on Ubuntu 14.04, you may get an SSL error stating 
+"no such file or directory." This issue does not affect driver installation or 
+performance and can be ignored.
 
 
 IPv6/UDP checksum offload does not work on some older kernels
 -------------------------------------------------------------
-Some distributions with older kernels do not properly enable IPv6/UDP
-checksum offload. To use IPv6 checksum offload, it may be necessary to
-upgrade to a newer kernel.
+Some distributions with older kernels do not properly enable IPv6/UDP checksum 
+offload. To use IPv6 checksum offload, it may be necessary to upgrade to a 
+newer kernel.
 
 
 Poor performance when using VXLAN encapsulation
 -----------------------------------------------
-When using VXLAN encapsulation on Red Hat Enterprise Linux 7.2 and 7.3,
-you may experience poor performance due to limitations in the kernel on
-these OS releases. To resolve this issue, upgrade your kernel.
+When using VXLAN encapsulation on Red Hat Enterprise Linux 7.2 and 7.3, you may 
+experience poor performance due to limitations in the kernel on these OS 
+releases. To resolve this issue, upgrade your kernel.
 
 
 Driver Buffer Overflow Fix
 --------------------------
-
-The fix to resolve CVE-2016-8105, referenced in Intel SA-00069
-https://security-center.intel.com/advisory.aspx?intelid=INTEL-SA-00069
-&languageid=en-fr, is included in this and future versions of the driver.
+The fix to resolve CVE-2016-8105, referenced in Intel SA-00069 
+<https://security-center.intel.com/advisory.aspx?intelid=INTEL-SA-00069&language
+id=en-fr>, is included in this and future versions of the driver.
 
 
 depmod warning messages about unknown symbol during installation
 ----------------------------------------------------------------
-
-During driver installation, you may see depmod warning messages referring
-to unknown symbols i40e_register_client and i40e_unregister_client. These
-messages are informational only; no user action is required. The installation
-should complete successfully.
+During driver installation, you may see depmod warning messages referring to 
+unknown symbols i40e_register_client and i40e_unregister_client. These messages 
+are informational only; no user action is required. The installation should 
+complete successfully.
 
 
 Error: <ifname> selects TX queue XX but real number of TX queues is YY
 ----------------------------------------------------------------------
-
-When configuring the number of queues under heavy traffic load, you may
-see an error message stating "<ifname> selects TX queue XX, but real number
-of TX queues is YY". This message is informational only and does not affect
+When configuring the number of queues under heavy traffic load, you may see an 
+error message stating "<ifname> selects TX queue XX, but real number of TX 
+queues is YY". This message is informational only and does not affect 
 functionality.
 
 
 Windows Server 2016 Does Not Work as a Guest OS on Older RHEL and SLES KVMs
 ---------------------------------------------------------------------------
-
-Microsoft* Windows Server* 2016 does not work as a guest operating system
-on the KVM hypervisor version included with Red Hat* Enterprise Linux* (RHEL)
-version 6.8 and Suse* Linux Enterprise Server (SLES) version 11.4. Windows
+Microsoft* Windows Server* 2016 does not work as a guest operating system on 
+the KVM hypervisor version included with Red Hat* Enterprise Linux* (RHEL) 
+version 6.8 and Suse* Linux Enterprise Server (SLES) version 11.4. Windows 
 Server 2016 does work as a guest OS on RHEL 7.2 and SLES 12.1.
 
 
 Fixing Performance Issues When Using IOMMU in Virtualized Environments
 ----------------------------------------------------------------------
-The IOMMU feature of the processor prevents I/O devices from accessing memory
-outside the boundaries set by the OS. It also allows devices to be directly
-assigned to a Virtual Machine. However, IOMMU may affect performance, both
-in latency (each DMA access by the device must be translated by the IOMMU)
-and in CPU utilization (each buffer assigned to every device must be mapped
-in the IOMMU).
-
-If you experience significant performance issues with IOMMU, try using it in
-?passthrough? mode by adding the following to the kernel boot command line:
+The IOMMU feature of the processor prevents I/O devices from accessing memory 
+outside the boundaries set by the OS. It also allows devices to be directly 
+assigned to a Virtual Machine. However, IOMMU may affect performance, both in 
+latency (each DMA access by the device must be translated by the IOMMU) and in 
+CPU utilization (each buffer assigned to every device must be mapped in the 
+IOMMU).
+
+If you experience significant performance issues with IOMMU, try using it in 
+"passthrough" mode by adding the following to the kernel boot command line:
   intel_iommu=on iommu=pt
 
-NOTE: This mode enables remapping for assigning devices to VMs, providing
-near-native I/O performance, but does not provide the additional memory
+NOTE: This mode enables remapping for assigning devices to VMs, providing 
+near-native I/O performance, but does not provide the additional memory 
 protection.
 
 
 Transmit hangs leading to no traffic
 ------------------------------------
-
-Disabling flow control while the device is under stress may cause tx hangs and
-eventually lead to the device no longer passing traffic. You must reboot the
+Disabling flow control while the device is under stress may cause tx hangs and 
+eventually lead to the device no longer passing traffic. You must reboot the 
 system to resolve this issue.
 
 
 Incomplete messages in the system log
 -------------------------------------
-
-The NVMUpdate utility may write several incomplete messages in the system log.
+The NVMUpdate utility may write several incomplete messages in the system log. 
 These messages take the form:
   in the driver Pci Ex config function byte index 114
   in the driver Pci Ex config function byte index 115
 These messages can be ignored.
 
 
-Bad checksum counter incorrectly increments when using VxLAN
+Bad checksum counter incorrectly increments when using VXLAN
 ------------------------------------------------------------
-
-When passing non-UDP traffic over a VxLAN interface, the port.rx_csum_bad
+When passing non-UDP traffic over a VXLAN interface, the port.rx_csum_bad 
 counter increments for the packets.
 
 
 Statistic counters reset when promiscuous mode is changed
 ---------------------------------------------------------
-
-Changing promiscuous mode triggers a reset of the physical function driver.
+Changing promiscuous mode triggers a reset of the physical function driver. 
 This will reset the statistic counters.
 
 
 Virtual machine does not get link
 ---------------------------------
-
-If the virtual machine has more than one virtual port assigned to it, and those
-virtual ports are bound to different physical ports, you may not get link on all
-of the virtual ports. The following command may work around the issue:
+If the virtual machine has more than one virtual port assigned to it, and those 
+virtual ports are bound to different physical ports, you may not get link on 
+all of the virtual ports. The following command may work around the issue:
 ethtool -r <PF>
-Where <PF> is the PF interface in the host, for example: p5p1. You may need to
+Where <PF> is the PF interface in the host, for example: p5p1. You may need to 
 run the command more than once to get link on all virtual ports.
 
 
 MAC address of Virtual Function changes unexpectedly
 ----------------------------------------------------
-
-If a Virtual Function's MAC address is not assigned in the host, then the
-VF (virtual function) driver will use a random MAC address. This random MAC
-address may change each time the VF driver is reloaded. You can assign a
-static MAC address in the host machine. This static MAC address will survive
+If a Virtual Function's MAC address is not assigned in the host, then the VF 
+(virtual function) driver will use a random MAC address. This random MAC 
+address may change each time the VF driver is reloaded. You can assign a static 
+MAC address in the host machine. This static MAC address will survive
 a VF driver reload.
 
 
 Changing the number of Rx or Tx queues with ethtool -L may cause a kernel panic
 -------------------------------------------------------------------------------
-
-Changing the number of Rx or Tx queues with ethtool -L while traffic is flowing
-and the interface is up may cause a kernel panic. Bring the interface down first
-to avoid the issue. For example:
+Changing the number of Rx or Tx queues with ethtool -L while traffic is flowing 
+and the interface is up may cause a kernel panic. Bring the interface down 
+first to avoid the issue. For example:
   ip link set ethx down
   ethtool -L ethx combined 4
 
 
-Adding a Flow Director Sideband rule fails incorrectly
-------------------------------------------------------
-
-If you try to add a Flow Director rule when no more sideband rule space is
-available, i40e logs an error that the rule could not be added, but ethtool
-returns success. You can remove rules to free up space. In addition, remove
-the rule that failed. This will evict it from the driver's cache.
-
+Adding an Intel Ethernet Flow Director Sideband rule fails incorrectly
+----------------------------------------------------------------------
+If you try to add an Intel Ethernet Flow Director rule when no more sideband 
+rule space is available, i40e logs an error that the rule could not be added, 
+but ethtool returns success. You can remove rules to free up space. In 
+addition, remove the rule that failed. This will evict it from the driver's 
+cache.
 
-Flow Director Sideband Logic adds duplicate filter
---------------------------------------------------
 
-The Flow Director Sideband Logic adds a duplicate filter in the software filter
-list if the location is not specified or the specified location differs from
-the previous location but has the same filter criteria. In this case, the
-second of the two filters that appear is the valid one in hardware and it
-decides the filter action.
+Intel Ethernet Flow Director Sideband Logic adds duplicate filter
+-----------------------------------------------------------------
+The Intel Ethernet Flow Director Sideband Logic adds a duplicate filter in the 
+software filter list if the location is not specified or the specified location 
+differs from the previous location but has the same filter criteria. In this 
+case, the second of the two filters that appear is the valid one in hardware 
+and it decides the filter action.
 
 
 Multiple Interfaces on Same Ethernet Broadcast Network
 ------------------------------------------------------
+Due to the default ARP behavior on Linux, it is not possible to have one system 
+on two IP networks in the same Ethernet broadcast domain (non-partitioned 
+switch) behave as expected. All Ethernet interfaces will respond to IP traffic 
+for any IP address assigned to the system. This results in unbalanced receive 
+traffic.
 
-Due to the default ARP behavior on Linux, it is not possible to have one
-system on two IP networks in the same Ethernet broadcast domain
-(non-partitioned switch) behave as expected. All Ethernet interfaces will
-respond to IP traffic for any IP address assigned to the system. This results
-in unbalanced receive traffic.
-
-If you have multiple interfaces in a server, either turn on ARP filtering by
+If you have multiple interfaces in a server, either turn on ARP filtering by 
 entering:
 echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
 
 This only works if your kernel's version is higher than 2.4.5.
 
 
-NOTE: This setting is not saved across reboots. The configuration change can
-be made permanent by adding the following line to the file /etc/sysctl.conf:
+NOTE: This setting is not saved across reboots. The configuration change can be 
+made permanent by adding the following line to the file /etc/sysctl.conf:
 net.ipv4.conf.all.arp_filter = 1
 
-Another alternative is to install the interfaces in separate broadcast domains
+Another alternative is to install the interfaces in separate broadcast domains 
 (either in different switches or in a switch partitioned to VLANs).
 
 
 UDP Stress Test Dropped Packet Issue
 ------------------------------------
-
-Under small packet UDP stress with the i40e driver, the system may
-drop UDP packets due to socket buffers being full. Setting the driver Flow
-Control variables to the minimum may resolve the issue. You may also try
+Under small packet UDP stress with the i40e driver, the system may drop UDP 
+packets due to socket buffers being full. Setting the driver Intel Ethernet 
+Flow Control variables to the minimum may resolve the issue. You may also try
 increasing the kernel's default buffer sizes by changing the values in
 
   /proc/sys/net/core/rmem_default and rmem_max
@@ -1195,75 +1197,67 @@ increasing the kernel's default buffer sizes by changing the values in
 
 Unplugging Network Cable While ethtool -p is Running
 ----------------------------------------------------
-
-In kernel versions 2.6.32 and newer, unplugging the network cable while
-ethtool -p is running will cause the system to become unresponsive to
-keyboard commands, except for control-alt-delete. Restarting the system
-appears to be the only remedy.
+In kernel versions 2.6.32 and newer, unplugging the network cable while ethtool 
+-p is running will cause the system to become unresponsive to keyboard 
+commands, except for control-alt-delete. Restarting the system should resolve 
+the issue.
 
 
 Rx Page Allocation Errors
 -------------------------
-
-'Page allocation failure. order:0' errors may occur under stress.
-with kernels 2.6.25 and newer.
-This is caused by the way the Linux kernel reports this
-stressed condition.
+'Page allocation failure. order:0' errors may occur under stress. with kernels 
+2.6.25 and newer. 
+This is caused by the way the Linux kernel reports this stressed condition.
 
 
 
 Lower than expected performance
 -------------------------------
+Some PCIe x8 slots are actually configured as x4 slots. These slots have 
+insufficient bandwidth for full line rate with dual port and quad port devices. 
+In addition, if you put a PCIe v3.0-capable adapter into a PCIe v2.x slot, you 
+cannot get full bandwidth. The driver detects this situation and writes the 
+following message in the system log:
 
-Some PCIe x8 slots are actually configured as x4 slots. These slots have
-insufficient bandwidth for full line rate with dual port and quad port
-devices. In addition, if you put a PCIe Generation 3-capable adapter
-into a PCIe Generation 2 slot, you cannot get full bandwidth. The driver
-detects this situation and writes the following message in the system log:
-
-"PCI-Express bandwidth available for this card is not sufficient for optimal
+"PCI-Express bandwidth available for this card is not sufficient for optimal 
 performance. For optimal performance a x8 PCI-Express slot is required."
 
-If this error occurs, moving your adapter to a true PCIe Generation 3 x8 slot
- will resolve the issue.
+If this error occurs, moving your adapter to a true PCIe v3.0 x8 slot will 
+resolve the issue.
 
 
 ethtool may incorrectly display SFP+ fiber module as direct attached cable
 --------------------------------------------------------------------------
-
-Due to kernel limitations, port type can only be correctly displayed on kernel
+Due to kernel limitations, port type can only be correctly displayed on kernel 
 2.6.33 or greater.
 
 
 Running ethtool -t ethX command causes break between PF and test client
 -----------------------------------------------------------------------
-
-When there are active VFs, "ethtool -t" performs a full diagnostic. In the
-process, it resets itself and all attached VFs. The VF drivers encouter a
+When there are active VFs, "ethtool -t" performs a full diagnostic. In the 
+process, it resets itself and all attached VFs. The VF drivers encounter a 
 disruption, but are able to recover.
 
 
-Enabling SR-IOV in a 64-bit Microsoft* Windows Server* 2012/R2 guest OS
-under Linux KVM
-------------------------------------------------------------------------
-
-KVM Hypervisor/VMM supports direct assignment of a PCIe device to a VM. This
-includes traditional PCIe devices, as well as SR-IOV-capable devices using
-Intel XL710-based controllers.
+Enabling SR-IOV in a 64-bit Microsoft* Windows Server* 2012/R2 guest OS under 
+Linux KVM
+--------------------------------------------------------------------------------
+KVM Hypervisor/VMM supports direct assignment of a PCIe device to a VM. This 
+includes traditional PCIe devices, as well as SR-IOV-capable devices based on 
+the Intel Ethernet Controller XL710.
 
 
 Unable to obtain DHCP lease on boot with RedHat
 -----------------------------------------------
-
-In configurations where the auto-negotiation process takes more than 5
-seconds, the boot script may fail with the following message:
+In configurations where the auto-negotiation process takes more than 5 seconds, 
+the boot script may fail with the following message:
 "ethX: failed. No link present. Check cable?"
 
-This error may occur even though the presence of link can be confirmed using
+This error may occur even though the presence of link can be confirmed using 
 ethtool ethx. In this case, try setting "LINKDELAY=30" in
 /etc/sysconfig/network-scripts/ifdfg-ethx.
 
-The same issue can occur during a network boot (via PXE) on RedHat
+The same issue can occur during a network boot (via PXE) on RedHat 
 distributions that use the dracut script:
 "Warning: No carrier detected on interface <interface_name>"
 
@@ -1271,15 +1265,14 @@ In this case add "rd.net.timeout.carrier=30" at the kernel command line.
 
 NOTE: Link time can vary. Adjust LINKDELAY value accordingly.
 
-Alternatively, NetworkManager can be used to configure the interfaces, which
-avoids the set timeout. For configuration instructions of NetworkManager
-refer to the documentation provided by your distribution.
+Alternatively, NetworkManager can be used to configure the interfaces, which 
+avoids the set timeout. For configuration instructions of NetworkManager refer 
+to the documentation provided by your distribution.
 
 
 Loading i40e driver in 3.2.x and newer kernels displays kernel tainted message
 ------------------------------------------------------------------------------
-
-Due to recent kernel changes, loading an out of tree driver causes the kernel
+Due to recent kernel changes, loading an out of tree driver causes the kernel 
 to be tainted.
 
 
@@ -1293,11 +1286,9 @@ www.intel.com/support/
 
 or the Intel Wired Networking project hosted by Sourceforge at:
 http://sourceforge.net/projects/e1000
-
-If an issue is identified with the released source code on a supported
-kernel with a supported adapter, email the specific information related to the
-issue to e1000-devel@lists.sf.net.
-
+If an issue is identified with the released source code on a supported kernel 
+with a supported adapter, email the specific information related to the issue 
+to e1000-devel@lists.sf.net.
 
 
 ================================================================================
@@ -1305,20 +1296,19 @@ issue to e1000-devel@lists.sf.net.
 
 License
 -------
-
-This program is free software; you can redistribute it and/or modify it under
-the terms and conditions of the GNU General Public License, version 2, as
+This program is free software; you can redistribute it and/or modify it under 
+the terms and conditions of the GNU General Public License, version 2, as 
 published by the Free Software Foundation.
 
-This program is distributed in the hope it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-PARTICULAR PURPOSE. See the GNU General Public License for more details.
+This program is distributed in the hope 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, write to the Free Software Foundation, Inc., 51 Franklin
+You should have received a copy of the GNU General Public License along with 
+this program; if not, write to the Free Software Foundation, Inc., 51 Franklin 
 St - Fifth Floor, Boston, MA 02110-1301 USA.
 
-The full GNU General Public License is included in this distribution in the
+The full GNU General Public License is included in this distribution in the 
 file called "COPYING".
 
 Copyright(c) 2014-2017 Intel Corporation.
@@ -1327,9 +1317,8 @@ Copyright(c) 2014-2017 Intel Corporation.
 
 Trademarks
 ----------
-
-Intel and Itanium are trademarks or registered trademarks of Intel
-Corporation or its subsidiaries in the United States and/or other countries.
+Intel and Itanium are trademarks or registered trademarks of Intel Corporation 
+or its subsidiaries in the United States and/or other countries.
 
 * Other names and brands may be claimed as the property of others.
 
diff --git a/i40e-dkms/i40e-2.4.6/SUMS b/i40e-dkms/i40e-2.4.6/SUMS
new file mode 100644 (file)
index 0000000..6aae663
--- /dev/null
@@ -0,0 +1,48 @@
+08564   109 i40e-2.4.6/src/i40e_txrx.c
+41515    20 i40e-2.4.6/src/i40e_txrx.h
+09324     4 i40e-2.4.6/src/i40e_osdep.h
+56307     4 i40e-2.4.6/src/i40e_helper.h
+39730     7 i40e-2.4.6/src/i40e_trace.h
+19269   369 i40e-2.4.6/src/i40e_main.c
+45570   178 i40e-2.4.6/src/i40e_ethtool.c
+21177    36 i40e-2.4.6/src/i40e.h
+26657    80 i40e-2.4.6/src/i40e_debugfs.c
+08628    94 i40e-2.4.6/src/i40e_virtchnl_pf.c
+07022     6 i40e-2.4.6/src/i40e_virtchnl_pf.h
+11204    23 i40e-2.4.6/src/i40e_client.c
+24595     7 i40e-2.4.6/src/i40e_client.h
+07868     9 i40e-2.4.6/src/i40e_dcb_nl.c
+28819    27 i40e-2.4.6/src/i40e_ptp.c
+62562   191 i40e-2.4.6/src/i40e_common.c
+63604    30 i40e-2.4.6/src/i40e_adminq.c
+50421     5 i40e-2.4.6/src/i40e_adminq.h
+22692    83 i40e-2.4.6/src/i40e_adminq_cmd.h
+29864   364 i40e-2.4.6/src/i40e_register.h
+15312    48 i40e-2.4.6/src/i40e_type.h
+09757     4 i40e-2.4.6/src/i40e_status.h
+31866    11 i40e-2.4.6/src/i40e_hmc.c
+29823     5 i40e-2.4.6/src/i40e_diag.c
+08614     2 i40e-2.4.6/src/i40e_diag.h
+04545    35 i40e-2.4.6/src/i40e_lan_hmc.c
+04399     6 i40e-2.4.6/src/i40e_lan_hmc.h
+07701     3 i40e-2.4.6/src/i40e_alloc.h
+31071     8 i40e-2.4.6/src/i40e_hmc.h
+43697    23 i40e-2.4.6/src/i40e_prototype.h
+57274    46 i40e-2.4.6/src/i40e_nvm.c
+00985     2 i40e-2.4.6/src/i40e_devids.h
+48100    27 i40e-2.4.6/src/i40e_dcb.c
+11217     6 i40e-2.4.6/src/i40e_dcb.h
+54678   173 i40e-2.4.6/src/kcompat.h
+56098    58 i40e-2.4.6/src/kcompat.c
+33574    23 i40e-2.4.6/src/virtchnl.h
+56182     6 i40e-2.4.6/src/Makefile
+35144    12 i40e-2.4.6/src/common.mk
+44588     1 i40e-2.4.6/src/Module.supported
+33977     7 i40e-2.4.6/scripts/set_irq_affinity
+49876     5 i40e-2.4.6/scripts/virt_perf_default
+20875     2 i40e-2.4.6/scripts/dump_tables
+45078     7 i40e-2.4.6/pci.updates
+43521    19 i40e-2.4.6/COPYING
+30395    55 i40e-2.4.6/README
+60959     3 i40e-2.4.6/i40e.7
+63230    11 i40e-2.4.6/i40e.spec
similarity index 75%
rename from i40e-dkms/i40e-2.2.4/i40e.7
rename to i40e-dkms/i40e-2.4.6/i40e.7
index 2205b7e815f9649cf83fce77ab57ac7a92b1b69c..20803e9e737a6c74a5ba6ffabec128bb51a66c50 100644 (file)
@@ -17,24 +17,20 @@ modprobe i40e [<option>=<VAL1>,<VAL2>,...]
 This driver is intended for \fB2.6.32\fR and newer kernels. 
 This driver includes support for any 64 bit Linux supported system, 
 including Itanium(R)2, x86_64, PPC64,ARM, etc.
-
 .LP
 This driver is only supported as a loadable module at this time. Intel is
 not supplying patches against the kernel source to allow for static linking of
 the drivers.
 
 
-
 For questions related to hardware requirements, refer to the documentation
 supplied with your Intel adapter. All hardware requirements listed apply to
 use with Linux.
 .SH Jumbo Frames
 .LP
-Jumbo Frames support is enabled by changing the Maximum Transmission Unit
-(MTU) to a value larger than the default value of 1500.
+Jumbo Frames support is enabled by changing the Maximum Transmission Unit (MTU) to a value larger than the default value of 1500.
 
-Use the ifconfig command to increase the MTU size. For example, enter the
-following where <x> is the interface number:
+Use the ifconfig command to increase the MTU size. For example, enter the following where <x> is the interface number:
 
    ifconfig eth<x> mtu 9000 up
 Alternatively, you can use the ip command as follows:
@@ -42,25 +38,17 @@ Alternatively, you can use the ip command as follows:
    ip link set up dev eth<x>
 
 .LP
-NOTES:
-- The maximum MTU setting for Jumbo Frames is 9702. This value coincides
-  with the maximum Jumbo Frames size of 9728 bytes.
-- This driver will attempt to use multiple page sized buffers to receive
-  each jumbo packet. This should help to avoid buffer starvation issues
-  when allocating receive packets.
+NOTE: The maximum MTU setting for Jumbo Frames is 9702. This value coincides with the maximum Jumbo Frames size of 9728 bytes.
 
+NOTE: This driver will attempt to use multiple page sized buffers to receive each jumbo packet. This should help to avoid buffer starvation issues when allocating receive packets.
 See the section "Jumbo Frames" in the Readme.
 .SH SUPPORT
 .LP
-For additional information regarding building and installation,
-see the
+For additional information regarding building and installation, see the
 README
 included with the driver.
 For general information, go to the Intel support website at:
 .B www.intel.com/support/
 .LP
-If an issue is identified with the released source code on a supported
-kernel with a supported adapter, email the specific information related to the
-issue to e1000-devel@lists.sf.net.
-
+If an issue is identified with the released source code on a supported kernel with a supported adapter, email the specific information related to the issue to e1000-devel@lists.sf.net.
 .LP
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/i40e.spec
rename to i40e-dkms/i40e-2.4.6/i40e.spec
index f5fb9f0acaa80117242372a535dd32efadb2a4ab..081ee37724dfe46b3aab25fbc4a4abe132beedfe 100644 (file)
@@ -1,6 +1,6 @@
 Name: i40e
 Summary: Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
-Version: 2.2.4
+Version: 2.4.6
 Release: 1
 Source: %{name}-%{version}.tar.gz
 Vendor: Intel Corporation
similarity index 94%
rename from i40e-dkms/i40e-2.2.4/pci.updates
rename to i40e-dkms/i40e-2.4.6/pci.updates
index 3931711f932ced21a5cfb982281779e3b7fa8126..29197c0d862860e87726b55c1923c69793125ad3 100644 (file)
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
-# Copyright(c) 2013 - 2017 Intel Corporation.
+# Copyright(c) 2013 - 2018 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
@@ -57,6 +57,7 @@
                8086 000b  Ethernet Server Adapter X710-DA2 for OCP
                8086 000d  Ethernet Controller X710 for 10GbE SFP+
                8086 000e  Ethernet Server Adapter OCP X710-2
+               8086 000f  Ethernet Server Adapter OCP X710-2
                8086 4005  Ethernet Controller X710 for 10GbE SFP+
                8086 4006  Ethernet Controller X710 for 10GbE SFP+
                8086 4007  Ethernet Controller X710 for 10GbE SFP+
                8086 0000  Ethernet Controller XXV710 for 25GbE backplane
                8086 000a  Ethernet 25G 2P XXV710 Mezz
        158b  Ethernet Controller XXV710 for 25GbE SFP28
+               1590 0000  Ethernet Network Adapter XXV710-2
+               1590 0253  Ethernet 10/25/Gb 2-port 661SFP28 Adapter
                8086 0000  Ethernet Network Adapter XXV710
                8086 0001  Ethernet Network Adapter XXV710-2
                8086 0002  Ethernet Network Adapter XXV710-2
                8086 0003  Ethernet Network Adapter XXV710-1
                8086 0004  Ethernet Network Adapter XXV710-1
+               8086 0005  Ethernet Network Adapter OCP XXV710-2
+               8086 0006  Ethernet Network Adapter OCP XXV710-2
                8086 0007  Ethernet Network Adapter OCP XXV710-1
                8086 0008  Ethernet Network Adapter OCP XXV710-1
                8086 0009  Ethernet 25G 2P XXV710 Adapter
                8086 4001  Ethernet Network Adapter XXV710-2
-       37cc  Ethernet Connection X722
        37ce  Ethernet Connection X722 for 10GbE backplane
                1590 0215  Ethernet 10Gb 2-port 568i Adapter
                17aa 4023  Ethernet Connection X722 for 10GbE backplane
                17aa 4020  Ethernet Connection X722 for 1GbE
                17aa 4021  Ethernet Connection X722 for 1GbE
                17aa 4022  Ethernet Connection X722 for 1GbE
+               17aa 4024  Ethernet Connection X722 for 1GbE
        37d2  Ethernet Connection X722 for 10GBASE-T
                1590 0218  Ethernet 10Gb 2-port 568FLR-MMT Adapter
                17aa 4020  Ethernet Connection X722 for 10GBASE-T
                17aa 4021  Ethernet Connection X722 for 10GBASE-T
+               17aa 4024  Ethernet Connection X722 for 10GBASE-T
        37d3  Ethernet Connection X722 for 10GbE SFP+
                1590 0219  Ethernet 10Gb 2-port 568FLR-MMSFP+ Adapter
                17aa 4020  Ethernet Connection X722 for 10GbE SFP+
similarity index 93%
rename from i40e-dkms/i40e-2.2.4/src/Makefile
rename to i40e-dkms/i40e-2.4.6/src/Makefile
index f653b7140ca8a9266c898d3ff251daec29ca0d85..d33d3a82c264d51067d6dab2a88477c685eb2750 100644 (file)
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
-# Copyright(c) 2013 - 2017 Intel Corporation.
+# Copyright(c) 2013 - 2018 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
@@ -54,14 +54,16 @@ else        # ifneq($(KERNELRELEASE),)
 
 DRIVER := i40e
 
-ifeq (,$(wildcard common.mk))
-  $(error Cannot find common.mk build rules)
-else
-  include common.mk
-endif
+# If the user just wants to print the help output, don't include common.mk or
+# perform any other checks. This ensures that running "make help" will always
+# work even if kernel-devel is not installed, or if the common.mk fails under
+# any other error condition.
+ifneq ($(MAKECMDGOALS),help)
+include common.mk
 
 # i40e does not support building on kernels older than 2.6.32
 $(call minimum_kver_check,2,6,32)
+endif
 
 ###############
 # Build rules #
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/common.mk
rename to i40e-dkms/i40e-2.4.6/src/common.mk
index 87c13db7dd012c49872623a2384bf37ceba13b2e..70f252f00ddb96d57db3bfa7a192d706eeaf4364 100644 (file)
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
-# Copyright(c) 2013 - 2017 Intel Corporation.
+# Copyright(c) 2013 - 2018 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
similarity index 93%
rename from i40e-dkms/i40e-2.2.4/src/i40e.h
rename to i40e-dkms/i40e-2.4.6/src/i40e.h
index be0459d388d761eec372edf176fb1a502c7c2386..d7ac580bcaf193c71d8f13ebd026ca0a2596eaea 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -149,6 +149,7 @@ enum i40e_state_t {
        __I40E_MDD_EVENT_PENDING,
        __I40E_VFLR_EVENT_PENDING,
        __I40E_RESET_RECOVERY_PENDING,
+       __I40E_TIMEOUT_RECOVERY_PENDING,
        __I40E_MISC_IRQ_REQUESTED,
        __I40E_RESET_INTR_RECEIVED,
        __I40E_REINIT_REQUESTED,
@@ -463,59 +464,60 @@ struct i40e_pf {
        struct timer_list service_timer;
        struct work_struct service_task;
 
-       u64 hw_features;
-#define I40E_HW_RSS_AQ_CAPABLE                 BIT_ULL(0)
-#define I40E_HW_128_QP_RSS_CAPABLE             BIT_ULL(1)
-#define I40E_HW_ATR_EVICT_CAPABLE              BIT_ULL(2)
-#define I40E_HW_WB_ON_ITR_CAPABLE              BIT_ULL(3)
-#define I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE    BIT_ULL(4)
-#define I40E_HW_NO_PCI_LINK_CHECK              BIT_ULL(5)
-#define I40E_HW_100M_SGMII_CAPABLE             BIT_ULL(6)
-#define I40E_HW_NO_DCB_SUPPORT                 BIT_ULL(7)
-#define I40E_HW_USE_SET_LLDP_MIB               BIT_ULL(8)
-#define I40E_HW_GENEVE_OFFLOAD_CAPABLE         BIT_ULL(9)
-#define I40E_HW_PTP_L4_CAPABLE                 BIT_ULL(10)
-#define I40E_HW_WOL_MC_MAGIC_PKT_WAKE          BIT_ULL(11)
-#define I40E_HW_MPLS_HDR_OFFLOAD_CAPABLE       BIT_ULL(12)
-#define I40E_HW_HAVE_CRT_RETIMER               BIT_ULL(13)
-#define I40E_HW_OUTER_UDP_CSUM_CAPABLE         BIT_ULL(14)
-#define I40E_HW_PHY_CONTROLS_LEDS              BIT_ULL(15)
-#define I40E_HW_STOP_FW_LLDP                   BIT_ULL(16)
-#define I40E_HW_PORT_ID_VALID                  BIT_ULL(17)
-#define I40E_HW_RESTART_AUTONEG                        BIT_ULL(18)
+       u32 hw_features;
+#define I40E_HW_RSS_AQ_CAPABLE                 BIT(0)
+#define I40E_HW_128_QP_RSS_CAPABLE             BIT(1)
+#define I40E_HW_ATR_EVICT_CAPABLE              BIT(2)
+#define I40E_HW_WB_ON_ITR_CAPABLE              BIT(3)
+#define I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE    BIT(4)
+#define I40E_HW_NO_PCI_LINK_CHECK              BIT(5)
+#define I40E_HW_100M_SGMII_CAPABLE             BIT(6)
+#define I40E_HW_NO_DCB_SUPPORT                 BIT(7)
+#define I40E_HW_USE_SET_LLDP_MIB               BIT(8)
+#define I40E_HW_GENEVE_OFFLOAD_CAPABLE         BIT(9)
+#define I40E_HW_PTP_L4_CAPABLE                 BIT(10)
+#define I40E_HW_WOL_MC_MAGIC_PKT_WAKE          BIT(11)
+#define I40E_HW_MPLS_HDR_OFFLOAD_CAPABLE       BIT(12)
+#define I40E_HW_HAVE_CRT_RETIMER               BIT(13)
+#define I40E_HW_OUTER_UDP_CSUM_CAPABLE         BIT(14)
+#define I40E_HW_PHY_CONTROLS_LEDS              BIT(15)
+#define I40E_HW_STOP_FW_LLDP                   BIT(16)
+#define I40E_HW_PORT_ID_VALID                  BIT(17)
+#define I40E_HW_RESTART_AUTONEG                        BIT(18)
 
        u64 flags;
-#define I40E_FLAG_RX_CSUM_ENABLED              BIT_ULL(0)
-#define I40E_FLAG_MSI_ENABLED                  BIT_ULL(1)
-#define I40E_FLAG_MSIX_ENABLED                 BIT_ULL(2)
-#define I40E_FLAG_RSS_ENABLED                  BIT_ULL(3)
-#define I40E_FLAG_VMDQ_ENABLED                 BIT_ULL(4)
-#define I40E_FLAG_FILTER_SYNC                  BIT_ULL(5)
-#define I40E_FLAG_SRIOV_ENABLED                        BIT_ULL(6)
-#define I40E_FLAG_DCB_CAPABLE                  BIT_ULL(7)
-#define I40E_FLAG_DCB_ENABLED                  BIT_ULL(8)
-#define I40E_FLAG_FD_SB_ENABLED                        BIT_ULL(9)
-#define I40E_FLAG_FD_ATR_ENABLED               BIT_ULL(10)
-#define I40E_FLAG_FD_SB_AUTO_DISABLED          BIT_ULL(11)
-#define I40E_FLAG_FD_ATR_AUTO_DISABLED         BIT_ULL(12)
-#define I40E_FLAG_MFP_ENABLED                  BIT_ULL(13)
-#define I40E_FLAG_UDP_FILTER_SYNC              BIT_ULL(14)
-#define I40E_FLAG_HW_ATR_EVICT_ENABLED         BIT_ULL(15)
-#define I40E_FLAG_VEB_MODE_ENABLED             BIT_ULL(16)
-#define I40E_FLAG_VEB_STATS_ENABLED            BIT_ULL(17)
-#define I40E_FLAG_LINK_POLLING_ENABLED         BIT_ULL(18)
-#define I40E_FLAG_TRUE_PROMISC_SUPPORT         BIT_ULL(19)
-#define I40E_FLAG_TEMP_LINK_POLLING            BIT_ULL(20)
-#define I40E_FLAG_LEGACY_RX                    BIT_ULL(21)
+#define I40E_FLAG_RX_CSUM_ENABLED              BIT(0)
+#define I40E_FLAG_MSI_ENABLED                  BIT(1)
+#define I40E_FLAG_MSIX_ENABLED                 BIT(2)
+#define I40E_FLAG_RSS_ENABLED                  BIT(3)
+#define I40E_FLAG_VMDQ_ENABLED                 BIT(4)
+#define I40E_FLAG_FILTER_SYNC                  BIT(5)
+#define I40E_FLAG_SRIOV_ENABLED                        BIT(6)
+#define I40E_FLAG_DCB_CAPABLE                  BIT(7)
+#define I40E_FLAG_DCB_ENABLED                  BIT(8)
+#define I40E_FLAG_FD_SB_ENABLED                        BIT(9)
+#define I40E_FLAG_FD_ATR_ENABLED               BIT(10)
+#define I40E_FLAG_FD_SB_AUTO_DISABLED          BIT(11)
+#define I40E_FLAG_FD_ATR_AUTO_DISABLED         BIT(12)
+#define I40E_FLAG_MFP_ENABLED                  BIT(13)
+#define I40E_FLAG_UDP_FILTER_SYNC              BIT(14)
+#define I40E_FLAG_HW_ATR_EVICT_ENABLED         BIT(15)
+#define I40E_FLAG_VEB_MODE_ENABLED             BIT(16)
+#define I40E_FLAG_VEB_STATS_ENABLED            BIT(17)
+#define I40E_FLAG_LINK_POLLING_ENABLED         BIT(18)
+#define I40E_FLAG_TRUE_PROMISC_SUPPORT         BIT(19)
+#define I40E_FLAG_TEMP_LINK_POLLING            BIT(20)
+#define I40E_FLAG_LEGACY_RX                    BIT(21)
 #ifdef HAVE_PTP_1588_CLOCK
-#define I40E_FLAG_PTP                          BIT_ULL(22)
+#define I40E_FLAG_PTP                          BIT(22)
 #endif /* HAVE_PTP_1588_CLOCK */
-#define I40E_FLAG_IWARP_ENABLED                        BIT_ULL(23)
-#define I40E_FLAG_SERVICE_CLIENT_REQUESTED     BIT_ULL(24)
-#define I40E_FLAG_CLIENT_L2_CHANGE             BIT_ULL(25)
-#define I40E_FLAG_CLIENT_RESET                 BIT_ULL(26)
-#define I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED   BIT_ULL(27)
-#define I40E_FLAG_SOURCE_PRUNING_DISABLED       BIT_ULL(28)
+#define I40E_FLAG_IWARP_ENABLED                        BIT(23)
+#define I40E_FLAG_SERVICE_CLIENT_REQUESTED     BIT(24)
+#define I40E_FLAG_CLIENT_L2_CHANGE             BIT(25)
+#define I40E_FLAG_CLIENT_RESET                 BIT(26)
+#define I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED   BIT(27)
+#define I40E_FLAG_SOURCE_PRUNING_DISABLED       BIT(28)
+#define I40E_FLAG_DISABLE_FW_LLDP              BIT(29)
 
        /* flag to enable/disable vf base mode support */
        bool vf_base_mode_only;
@@ -604,8 +606,6 @@ struct i40e_pf {
        u64 rx_udp_cso;
        u64 rx_sctp_cso;
        u64 rx_ip4_cso;
-       u64 hw_csum_rx_vxlan;
-       u64 hw_csum_rx_geneve;
        u64 hw_csum_rx_outer;
        u64 rx_tcp_cso_err;
        u64 rx_udp_cso_err;
@@ -814,6 +814,7 @@ struct i40e_q_vector {
        struct i40e_ring_container rx;
        struct i40e_ring_container tx;
 
+       u8 itr_countdown;       /* when 0 should adjust adaptive ITR */
        u8 num_ringpairs;       /* total number of ring pairs in vector */
 
 #ifdef HAVE_IRQ_AFFINITY_NOTIFY
@@ -824,8 +825,6 @@ struct i40e_q_vector {
        struct rcu_head rcu;    /* to avoid race with update stats on free */
        char name[I40E_INT_NAME_STR_LEN];
        bool arm_wb_state;
-#define ITR_COUNTDOWN_START 100
-       u8 itr_countdown;       /* when 0 should adjust ITR */
 } ____cacheline_internodealigned_in_smp;
 
 /* lan device */
@@ -1028,6 +1027,7 @@ void i40e_veb_release(struct i40e_veb *veb);
 int i40e_veb_config_tc(struct i40e_veb *veb, u8 enabled_tc);
 int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid);
 void i40e_vsi_remove_pvid(struct i40e_vsi *vsi);
+int i40e_get_cloud_filter_type(u8 flags, u16 *type);
 int i40e_add_del_cloud_filter(struct i40e_pf *pf,
                              struct i40e_cloud_filter *filter,
                              bool add);
@@ -1117,5 +1117,4 @@ i40e_status i40e_get_partition_bw_setting(struct i40e_pf *pf);
 i40e_status i40e_set_partition_bw_setting(struct i40e_pf *pf);
 i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf);
 void i40e_print_link_message(struct i40e_vsi *vsi, bool isup);
-const char *i40e_tunnel_name(struct i40e_udp_port_config *port);
 #endif /* _I40E_H_ */
similarity index 95%
rename from i40e-dkms/i40e-2.2.4/src/i40e_adminq.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_adminq.c
index b28a2704057cfb3c08999eb69e2ee0578c589c50..9cf1ecc2f2c56218b2636181b7b6f3b48f8ed33e 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -610,17 +610,17 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
                goto init_adminq_free_arq;
 
        /* get the NVM version info */
-       i40e_read_nvm_word(hw, I40E_SR_NVM_DEV_STARTER_VERSION,
-                          &hw->nvm.version);
-       i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_LO, &eetrack_lo);
-       i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
-       hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
-       i40e_read_nvm_word(hw, I40E_SR_BOOT_CONFIG_PTR, &cfg_ptr);
-       i40e_read_nvm_word(hw, (cfg_ptr + I40E_NVM_OEM_VER_OFF),
-                          &oem_hi);
-       i40e_read_nvm_word(hw, (cfg_ptr + (I40E_NVM_OEM_VER_OFF + 1)),
-                          &oem_lo);
-       hw->nvm.oem_ver = ((u32)oem_hi << 16) | oem_lo;
+               i40e_read_nvm_word(hw, I40E_SR_NVM_DEV_STARTER_VERSION,
+                                  &hw->nvm.version);
+               i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_LO, &eetrack_lo);
+               i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
+               hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
+               i40e_read_nvm_word(hw, I40E_SR_BOOT_CONFIG_PTR, &cfg_ptr);
+               i40e_read_nvm_word(hw, (cfg_ptr + I40E_NVM_OEM_VER_OFF),
+                                  &oem_hi);
+               i40e_read_nvm_word(hw, (cfg_ptr + (I40E_NVM_OEM_VER_OFF + 1)),
+                                  &oem_lo);
+               hw->nvm.oem_ver = ((u32)oem_hi << 16) | oem_lo;
 
        /* The ability to RX (not drop) 802.1ad frames was added in API 1.7 */
        if ((hw->aq.api_maj_ver > 1) ||
@@ -628,12 +628,18 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
             (hw->aq.api_min_ver >= 7)))
                hw->flags |= I40E_HW_FLAG_802_1AD_CAPABLE;
 
-       if (hw->mac.type ==  I40E_MAC_XL710 &&
+       if (hw->mac.type == I40E_MAC_XL710 &&
            hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
            hw->aq.api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710) {
                hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE;
        }
 
+       /* Newer versions of firmware require lock when reading the NVM */
+       if ((hw->aq.api_maj_ver > 1) ||
+           ((hw->aq.api_maj_ver == 1) &&
+            (hw->aq.api_min_ver >= 5)))
+               hw->flags |= I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK;
+
        if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) {
                ret_code = I40E_ERR_FIRMWARE_API_VERSION;
                goto init_adminq_free_arq;
@@ -931,10 +937,15 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
        /* update the error if time out occurred */
        if ((!cmd_completed) &&
            (!details->async && !details->postpone)) {
-               i40e_debug(hw,
-                          I40E_DEBUG_AQ_MESSAGE,
-                          "AQTX: Writeback timeout.\n");
-               status = I40E_ERR_ADMIN_QUEUE_TIMEOUT;
+               if (rd32(hw, hw->aq.asq.len) & I40E_GL_ATQLEN_ATQCRIT_MASK) {
+                       i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
+                                  "AQTX: AQ Critical error.\n");
+                       status = I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR;
+               } else {
+                       i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
+                                  "AQTX: Writeback timeout.\n");
+                       status = I40E_ERR_ADMIN_QUEUE_TIMEOUT;
+               }
        }
 
 asq_send_command_error:
@@ -996,7 +1007,7 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
        }
 
        /* set next_to_use to head */
-       ntu = (rd32(hw, hw->aq.arq.head) & I40E_PF_ARQH_ARQH_MASK);
+       ntu = rd32(hw, hw->aq.arq.head) & I40E_PF_ARQH_ARQH_MASK;
        if (ntu == ntc) {
                /* nothing to do - shouldn't need to update ring's values */
                ret_code = I40E_ERR_ADMIN_QUEUE_NO_WORK;
@@ -1054,7 +1065,7 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
        hw->aq.arq.next_to_clean = ntc;
        hw->aq.arq.next_to_use = ntu;
 
-       i40e_nvmupd_check_wait_event(hw, LE16_TO_CPU(e->desc.opcode));
+       i40e_nvmupd_check_wait_event(hw, LE16_TO_CPU(e->desc.opcode), &e->desc);
 clean_arq_element_out:
        /* Set pending if needed, unlock and return */
        if (pending != NULL)
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_adminq.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_adminq.h
index e6739d33c7e99a2101655536e85c31b151a436cf..5f76acd64cfde859b189a78458ce6f1d4dfdf80a 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 98%
rename from i40e-dkms/i40e-2.2.4/src/i40e_adminq_cmd.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_adminq_cmd.h
index 5522cc498a34c6778fafa2b818433e832a455803..b7d3f8609b6cae4c1e049d9acfb775cbc6fe71c3 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -204,6 +204,7 @@ enum i40e_admin_queue_opc {
        /* DCB commands */
        i40e_aqc_opc_dcb_ignore_pfc     = 0x0301,
        i40e_aqc_opc_dcb_updated        = 0x0302,
+       i40e_aqc_opc_set_dcb_parameters = 0x0303,
 
        /* TX scheduler */
        i40e_aqc_opc_configure_vsi_bw_limit             = 0x0400,
@@ -254,6 +255,7 @@ enum i40e_admin_queue_opc {
        i40e_aqc_opc_nvm_update                 = 0x0703,
        i40e_aqc_opc_nvm_config_read            = 0x0704,
        i40e_aqc_opc_nvm_config_write           = 0x0705,
+       i40e_aqc_opc_nvm_progress               = 0x0706,
        i40e_aqc_opc_oem_post_update            = 0x0720,
        i40e_aqc_opc_thermal_sensor             = 0x0721,
 
@@ -2120,11 +2122,28 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_an_advt_reg);
 
 /* Set Loopback mode (0x0618) */
 struct i40e_aqc_set_lb_mode {
-       __le16  lb_mode;
+       u8      lb_level;
+#define I40E_AQ_LB_NONE        0
+#define I40E_AQ_LB_MAC 1
+#define I40E_AQ_LB_SERDES      2
+#define I40E_AQ_LB_PHY_INT     3
+#define I40E_AQ_LB_PHY_EXT     4
+#define I40E_AQ_LB_CPVL_PCS    5
+#define I40E_AQ_LB_CPVL_EXT    6
 #define I40E_AQ_LB_PHY_LOCAL   0x01
 #define I40E_AQ_LB_PHY_REMOTE  0x02
 #define I40E_AQ_LB_MAC_LOCAL   0x04
-       u8      reserved[14];
+       u8      lb_type;
+#define I40E_AQ_LB_LOCAL       0
+#define I40E_AQ_LB_FAR 0x01
+       u8      speed;
+#define I40E_AQ_LB_SPEED_NONE  0
+#define I40E_AQ_LB_SPEED_1G    1
+#define I40E_AQ_LB_SPEED_10G   2
+#define I40E_AQ_LB_SPEED_40G   3
+#define I40E_AQ_LB_SPEED_20G   4
+       u8      force_speed;
+       u8      reserved[12];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_set_lb_mode);
@@ -2175,8 +2194,8 @@ struct i40e_aqc_phy_register_access {
 #define I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE 2
        u8      dev_addres;
        u8      reserved1[2];
-       u32     reg_address;
-       u32     reg_value;
+       __le32  reg_address;
+       __le32  reg_value;
        u8      reserved2[4];
 };
 
@@ -2188,8 +2207,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_phy_register_access);
  */
 struct i40e_aqc_nvm_update {
        u8      command_flags;
-#define I40E_AQ_NVM_LAST_CMD   0x01
-#define I40E_AQ_NVM_FLASH_ONLY 0x80
+#define I40E_AQ_NVM_LAST_CMD                   0x01
+#define I40E_AQ_NVM_FLASH_ONLY                 0x80
+#define I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT   1
+#define I40E_AQ_NVM_PRESERVATION_FLAGS_MASK    0x03
+#define I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED        0x03
+#define I40E_AQ_NVM_PRESERVATION_FLAGS_ALL     0x01
        u8      module_pointer;
        __le16  length;
        __le32  offset;
@@ -2449,6 +2472,17 @@ struct i40e_aqc_lldp_start {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start);
 
+/* Set DCB (direct 0x0303) */
+struct i40e_aqc_set_dcb_parameters {
+       u8 command;
+#define I40E_AQ_DCB_SET_AGENT  0x1
+#define I40E_DCB_VALID         0x1
+       u8 valid_flags;
+       u8 reserved[14];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_set_dcb_parameters);
+
 /* Get CEE DCBX Oper Config (0x0A07)
  * uses the generic descriptor struct
  * returns below as indirect response
similarity index 97%
rename from i40e-dkms/i40e-2.2.4/src/i40e_alloc.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_alloc.h
index c42a90fdba852600296ebb9935e69dc33f005aee..572fa261adf9821fa2779322a6dd7c069ab01a9b 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 96%
rename from i40e-dkms/i40e-2.2.4/src/i40e_client.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_client.c
index ebad3fbca4a3b55e587340b1bf64f3e78eeba75e..b1e6e1cf577094f29d13291337e090aaceb740d9 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -287,9 +287,6 @@ out:
 /**
  * i40e_client_add_instance - add a client instance struct to the instance list
  * @pf: pointer to the board struct
- * @client: pointer to a client struct in the client list.
- * @existing: if there was already an existing instance
- *
  **/
 static void i40e_client_add_instance(struct i40e_pf *pf)
 {
@@ -375,11 +372,11 @@ void i40e_client_subtask(struct i40e_pf *pf)
        if (!client || !cdev)
                return;
 
-       /* Here we handle client opens. If the client is down, but
-        * the netdev is up, then open the client.
+       /* Here we handle client opens. If the client is down, and
+        * the netdev is registered, then open the client.
         */
        if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
-               if (!test_bit(__I40E_VSI_DOWN, vsi->state) &&
+               if (vsi->netdev_registered &&
                    client->ops && client->ops->open) {
                        set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
                        ret = client->ops->open(&cdev->lan_info, client);
@@ -390,17 +387,19 @@ void i40e_client_subtask(struct i40e_pf *pf)
                                i40e_client_del_instance(pf);
                        }
                }
-       } else {
-       /* Likewise for client close. If the client is up, but the netdev
-        * is down, then close the client.
-        */
-               if (test_bit(__I40E_VSI_DOWN, vsi->state) &&
-                   client->ops && client->ops->close) {
-                       clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
-                       client->ops->close(&cdev->lan_info, client, false);
-                       i40e_client_release_qvlist(&cdev->lan_info);
-               }
        }
+
+       /* enable/disable PE TCP_ENA flag based on netdev down/up
+        */
+       if (test_bit(__I40E_VSI_DOWN, vsi->state))
+               i40e_client_update_vsi_ctxt(&cdev->lan_info, client,
+                                           0, 0, 0,
+                                           I40E_CLIENT_VSI_FLAG_TCP_ENABLE);
+       else
+               i40e_client_update_vsi_ctxt(&cdev->lan_info, client,
+                                           0, 0,
+                                           I40E_CLIENT_VSI_FLAG_TCP_ENABLE,
+                                           I40E_CLIENT_VSI_FLAG_TCP_ENABLE);
 }
 
 /**
@@ -715,13 +714,13 @@ static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev,
                return -ENOENT;
        }
 
-       if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE) &&
-           (flag & I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE)) {
+       if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) &&
+           (flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) {
                ctxt.info.valid_sections =
                        cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
                ctxt.info.queueing_opt_flags |= I40E_AQ_VSI_QUE_OPT_TCP_ENA;
-       } else if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE) &&
-                 !(flag & I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE)) {
+       } else if ((valid_flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE) &&
+                 !(flag & I40E_CLIENT_VSI_FLAG_TCP_ENABLE)) {
                ctxt.info.valid_sections =
                        cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
                ctxt.info.queueing_opt_flags &= ~I40E_AQ_VSI_QUE_OPT_TCP_ENA;
similarity index 98%
rename from i40e-dkms/i40e-2.2.4/src/i40e_client.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_client.h
index 4f02e5b98537d1394d405b22bb1005d72255cf5c..081cdb24295cedcd11ead789bb3cd2ad623d6a86 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -129,7 +129,7 @@ struct i40e_info {
 
 #define I40E_CLIENT_RESET_LEVEL_PF   1
 #define I40E_CLIENT_RESET_LEVEL_CORE 2
-#define I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE  BIT(1)
+#define I40E_CLIENT_VSI_FLAG_TCP_ENABLE  BIT(1)
 
 struct i40e_ops {
        /* setup_q_vector_list enables queues with a particular vector */
similarity index 97%
rename from i40e-dkms/i40e-2.2.4/src/i40e_common.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_common.c
index 89521a4f62e056dd598824131f468d73436c8d3e..da132e9a950fa7a297ad55e58be066a5a1ad0552 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -275,6 +275,8 @@ const char *i40e_stat_str(struct i40e_hw *hw, i40e_status stat_err)
                return "I40E_NOT_SUPPORTED";
        case I40E_ERR_FIRMWARE_API_VERSION:
                return "I40E_ERR_FIRMWARE_API_VERSION";
+       case I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR:
+               return "I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR";
        }
 
        snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
@@ -944,7 +946,8 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
                hw->pf_id = (u8)(func_rid & 0x7);
 
        if (hw->mac.type == I40E_MAC_X722)
-               hw->flags |= I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE;
+               hw->flags |= I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE |
+                            I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK;
 
        status = i40e_init_nvm(hw);
        return status;
@@ -1462,6 +1465,7 @@ u32 i40e_led_get(struct i40e_hw *hw)
                case I40E_COMBINED_ACTIVITY:
                case I40E_FILTER_ACTIVITY:
                case I40E_MAC_ACTIVITY:
+               case I40E_LINK_ACTIVITY:
                        continue;
                default:
                        break;
@@ -1510,6 +1514,7 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
                case I40E_COMBINED_ACTIVITY:
                case I40E_FILTER_ACTIVITY:
                case I40E_MAC_ACTIVITY:
+               case I40E_LINK_ACTIVITY:
                        continue;
                default:
                        break;
@@ -1520,9 +1525,6 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
                gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) &
                             I40E_GLGEN_GPIO_CTL_LED_MODE_MASK);
 
-               if (mode == I40E_LINK_ACTIVITY)
-                       blink = false;
-
                if (blink)
                        gpio_val |= BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
                else
@@ -1861,7 +1863,11 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
 
        if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
            hw->aq.api_min_ver >= 7) {
-               hw->phy.phy_types = LE32_TO_CPU(*(__le32 *)resp->link_type);
+               __le32 tmp;
+
+               i40e_memcpy(&tmp, resp->link_type, sizeof(tmp),
+                           I40E_NONDMA_TO_NONDMA);
+               hw->phy.phy_types = LE32_TO_CPU(tmp);
                hw->phy.phy_types |= ((u64)resp->link_type_ext << 32);
        }
 
@@ -3667,13 +3673,14 @@ exit:
  * @length: length of the section to be written (in bytes from the offset)
  * @data: command buffer (size [bytes] = length)
  * @last_command: tells if this is the last command in a series
+ * @preservation_flags: Preservation mode flags
  * @cmd_details: pointer to command details structure or NULL
  *
  * Update the NVM using the admin queue commands
  **/
 i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
                                u32 offset, u16 length, void *data,
-                               bool last_command,
+                               bool last_command, u8 preservation_flags,
                                struct i40e_asq_cmd_details *cmd_details)
 {
        struct i40e_aq_desc desc;
@@ -3692,6 +3699,16 @@ i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
        /* If this is the last command in a series, set the proper flag. */
        if (last_command)
                cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
+       if (hw->mac.type == I40E_MAC_X722) {
+               if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_SELECTED)
+                       cmd->command_flags |=
+                               (I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED <<
+                                I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
+               else if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_ALL)
+                       cmd->command_flags |=
+                               (I40E_AQ_NVM_PRESERVATION_FLAGS_ALL <<
+                                I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
+       }
        cmd->module_pointer = module_pointer;
        cmd->offset = CPU_TO_LE32(offset);
        cmd->length = CPU_TO_LE16(length);
@@ -3706,6 +3723,25 @@ i40e_aq_update_nvm_exit:
        return status;
 }
 
+/**
+ * i40e_aq_nvm_progress
+ * @hw: pointer to the hw struct
+ * @progress: pointer to progress returned from AQ
+ *
+ * Gets progress of flash rearrangement process
+ **/
+i40e_status i40e_aq_nvm_progress(struct i40e_hw *hw, u8 *progress,
+                               struct i40e_asq_cmd_details *cmd_details)
+{
+       i40e_status status;
+       struct i40e_aq_desc desc;
+
+       i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_progress);
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+       *progress = desc.params.raw[0];
+       return status;
+}
+
 /**
  * i40e_aq_get_lldp_mib
  * @hw: pointer to the hw struct
@@ -3870,7 +3906,34 @@ i40e_status i40e_aq_start_lldp(struct i40e_hw *hw,
        i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
 
        cmd->command = I40E_AQ_LLDP_AGENT_START;
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_aq_set_dcb_parameters
+ * @hw: pointer to the hw struct
+ * @cmd_details: pointer to command details structure or NULL
+ * @dcb_enable: True if DCB configuration needs to be applied
+ *
+ **/
+enum i40e_status_code
+i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable,
+                          struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_set_dcb_parameters *cmd =
+               (struct i40e_aqc_set_dcb_parameters *)&desc.params.raw;
+       i40e_status status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_set_dcb_parameters);
 
+       if (dcb_enable) {
+               cmd->valid_flags = I40E_DCB_VALID;
+               cmd->command = I40E_AQ_DCB_SET_AGENT;
+       }
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
        return status;
@@ -5444,6 +5507,64 @@ phy_blinking_end:
        return status;
 }
 
+/**
+ * i40e_led_get_reg - read LED register
+ * @hw: pointer to the HW structure
+ * @led_addr: LED register address
+ * @reg_val: read register value
+ **/
+static i40e_status i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
+                                             u32 *reg_val)
+{
+       i40e_status status;
+       u8 phy_addr = 0;
+
+       *reg_val = 0;
+       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
+               status = i40e_aq_get_phy_register(hw,
+                                               I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
+                                               I40E_PHY_COM_REG_PAGE,
+                                               I40E_PHY_LED_PROV_REG_1,
+                                               reg_val, NULL);
+       } else {
+               phy_addr = i40e_get_phy_address(hw, hw->port);
+               status = i40e_read_phy_register_clause45(hw,
+                                                        I40E_PHY_COM_REG_PAGE,
+                                                        led_addr, phy_addr,
+                                                        (u16 *)reg_val);
+       }
+       return status;
+}
+
+/**
+ * i40e_led_set_reg - write LED register
+ * @hw: pointer to the HW structure
+ * @led_addr: LED register address
+ * @reg_val: register value to write
+ **/
+static i40e_status i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
+                                             u32 reg_val)
+{
+       i40e_status status;
+       u8 phy_addr = 0;
+
+       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
+               status = i40e_aq_set_phy_register(hw,
+                                               I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
+                                               I40E_PHY_COM_REG_PAGE,
+                                               I40E_PHY_LED_PROV_REG_1,
+                                               reg_val, NULL);
+       } else {
+               phy_addr = i40e_get_phy_address(hw, hw->port);
+               status = i40e_write_phy_register_clause45(hw,
+                                                         I40E_PHY_COM_REG_PAGE,
+                                                         led_addr, phy_addr,
+                                                         (u16)reg_val);
+       }
+
+       return status;
+}
+
 /**
  * i40e_led_get_phy - return current on/off mode
  * @hw: pointer to the hw struct
@@ -5456,43 +5577,35 @@ i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
 {
        i40e_status status = I40E_SUCCESS;
        u16 gpio_led_port;
+       u32 reg_val_aq;
+       u16 temp_addr;
        u8 phy_addr = 0;
        u16 reg_val;
-       u16 temp_addr;
-       u8 port_num;
-       u32 i;
-       u32 reg_val_aq;
 
        if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
-               status =
-                     i40e_aq_get_phy_register(hw,
-                                              I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
-                                              I40E_PHY_COM_REG_PAGE,
-                                              I40E_PHY_LED_PROV_REG_1,
-                                              &reg_val_aq, NULL);
-               if (status)
-                       return status;
-               *val = (u16)reg_val_aq;
-       } else {
-               temp_addr = I40E_PHY_LED_PROV_REG_1;
-               i = rd32(hw, I40E_PFGEN_PORTNUM);
-               port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
-               phy_addr = i40e_get_phy_address(hw, port_num);
-
-               for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
-                    temp_addr++) {
-                       status =
-                        i40e_read_phy_register_clause45(hw,
+               status = i40e_aq_get_phy_register(hw,
+                                               I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
+                                               I40E_PHY_COM_REG_PAGE,
+                                               I40E_PHY_LED_PROV_REG_1,
+                                               &reg_val_aq, NULL);
+               if (status == I40E_SUCCESS)
+                       *val = (u16)reg_val_aq;
+               return status;
+       }
+       temp_addr = I40E_PHY_LED_PROV_REG_1;
+       phy_addr = i40e_get_phy_address(hw, hw->port);
+       for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
+            temp_addr++) {
+               status = i40e_read_phy_register_clause45(hw,
                                                         I40E_PHY_COM_REG_PAGE,
                                                         temp_addr, phy_addr,
                                                         &reg_val);
-                       if (status)
-                               return status;
-                       *val = reg_val;
-                       if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
-                               *led_addr = temp_addr;
-                               break;
-                       }
+               if (status)
+                       return status;
+               *val = reg_val;
+               if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
+                       *led_addr = temp_addr;
+                       break;
                }
        }
        return status;
@@ -5512,113 +5625,35 @@ i40e_status i40e_led_set_phy(struct i40e_hw *hw, bool on,
        i40e_status status = I40E_SUCCESS;
        u32 led_ctl = 0;
        u32 led_reg = 0;
-       u8 phy_addr = 0;
-       u8 port_num;
-       u32 i;
 
-       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
-               status =
-                     i40e_aq_get_phy_register(hw,
-                                              I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
-                                              I40E_PHY_COM_REG_PAGE,
-                                              I40E_PHY_LED_PROV_REG_1,
-                                              &led_reg, NULL);
-       } else {
-               i = rd32(hw, I40E_PFGEN_PORTNUM);
-               port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
-               phy_addr = i40e_get_phy_address(hw, port_num);
-               status = i40e_read_phy_register_clause45(hw,
-                                                        I40E_PHY_COM_REG_PAGE,
-                                                        led_addr, phy_addr,
-                                                        (u16 *)&led_reg);
-       }
+       status = i40e_led_get_reg(hw, led_addr, &led_reg);
        if (status)
                return status;
        led_ctl = led_reg;
        if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
                led_reg = 0;
-               if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
-                   hw->aq.api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710) {
-                       status = i40e_aq_set_phy_register(hw,
-                                       I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
-                                       I40E_PHY_COM_REG_PAGE,
-                                       I40E_PHY_LED_PROV_REG_1,
-                                       led_reg, NULL);
-               } else {
-                       status = i40e_write_phy_register_clause45(hw,
-                                                       I40E_PHY_COM_REG_PAGE,
-                                                       led_addr, phy_addr,
-                                                       (u16)led_reg);
-               }
+               status = i40e_led_set_reg(hw, led_addr, led_reg);
                if (status)
                        return status;
        }
-       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
-               status =
-                     i40e_aq_get_phy_register(hw,
-                                              I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
-                                              I40E_PHY_COM_REG_PAGE,
-                                              I40E_PHY_LED_PROV_REG_1,
-                                              &led_reg, NULL);
-       } else {
-               status = i40e_read_phy_register_clause45(hw,
-                                                        I40E_PHY_COM_REG_PAGE,
-                                                        led_addr, phy_addr,
-                                                        (u16 *)&led_reg);
-       }
+       status = i40e_led_get_reg(hw, led_addr, &led_reg);
        if (status)
                goto restore_config;
        if (on)
                led_reg = I40E_PHY_LED_MANUAL_ON;
        else
                led_reg = 0;
-
-       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
-               status =
-                     i40e_aq_set_phy_register(hw,
-                                              I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
-                                              I40E_PHY_COM_REG_PAGE,
-                                              I40E_PHY_LED_PROV_REG_1,
-                                              led_reg, NULL);
-       } else {
-               status =
-                   i40e_write_phy_register_clause45(hw, I40E_PHY_COM_REG_PAGE,
-                                                    led_addr, phy_addr,
-                                                    (u16)led_reg);
-       }
+       status = i40e_led_set_reg(hw, led_addr, led_reg);
        if (status)
                goto restore_config;
        if (mode & I40E_PHY_LED_MODE_ORIG) {
                led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
-               if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
-                       status = i40e_aq_set_phy_register(hw,
-                                       I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
-                                       I40E_PHY_COM_REG_PAGE,
-                                       I40E_PHY_LED_PROV_REG_1,
-                                       led_ctl, NULL);
-               } else {
-                       status = i40e_write_phy_register_clause45(hw,
-                                                        I40E_PHY_COM_REG_PAGE,
-                                                        led_addr, phy_addr,
-                                                        (u16)led_ctl);
-               }
+               status = i40e_led_set_reg(hw, led_addr, led_ctl);
        }
        return status;
+
 restore_config:
-       if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
-               status =
-                     i40e_aq_set_phy_register(hw,
-                                              I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
-                                              I40E_PHY_COM_REG_PAGE,
-                                              I40E_PHY_LED_PROV_REG_1,
-                                              led_ctl, NULL);
-       } else {
-               status =
-                       i40e_write_phy_register_clause45(hw,
-                                                        I40E_PHY_COM_REG_PAGE,
-                                                        led_addr, phy_addr,
-                                                        (u16)led_ctl);
-       }
+       status = i40e_led_set_reg(hw, led_addr, led_ctl);
        return status;
 }
 
@@ -5774,8 +5809,8 @@ i40e_status i40e_aq_set_phy_register(struct i40e_hw *hw,
 
        cmd->phy_interface = phy_select;
        cmd->dev_addres = dev_addr;
-       cmd->reg_address = reg_addr;
-       cmd->reg_value = reg_val;
+       cmd->reg_address = CPU_TO_LE32(reg_addr);
+       cmd->reg_value = CPU_TO_LE32(reg_val);
 
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
@@ -5808,11 +5843,11 @@ i40e_status i40e_aq_get_phy_register(struct i40e_hw *hw,
 
        cmd->phy_interface = phy_select;
        cmd->dev_addres = dev_addr;
-       cmd->reg_address = reg_addr;
+       cmd->reg_address = CPU_TO_LE32(reg_addr);
 
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
        if (!status)
-               *reg_val = cmd->reg_value;
+               *reg_val = LE32_TO_CPU(cmd->reg_value);
 
        return status;
 }
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_dcb.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_dcb.c
index 5e874954f8c65945c399c3b8ffadd0c75d61ad57..4bdffdceb6df74c7e3b879073a8f0ae75d9fe00c 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_dcb.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_dcb.h
index a02b7fea1ef87e76aba7a95f8e4c476bfe75949f..f4123ea44fce8a3400ee8aebeb81fccab4e9c5d1 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_dcb_nl.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_dcb_nl.c
index ddbb33796af5f0c8a8935ce053167f3390c6ba76..8982e765ca3c50ee928f11d6331896b8203a7115 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_debugfs.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_debugfs.c
index 64c32e8363dafd2bdbbde05b26710bfd9ee0af66..60ce72864ddf5c6736767f042d385b6adbbeb0cb 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -312,7 +312,7 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
                 vsi->rx_buf_failed, vsi->rx_page_failed);
        rcu_read_lock();
        for (i = 0; i < vsi->num_queue_pairs; i++) {
-               struct i40e_ring *rx_ring = ACCESS_ONCE(vsi->rx_rings[i]);
+               struct i40e_ring *rx_ring = READ_ONCE(vsi->rx_rings[i]);
 
                if (!rx_ring)
                        continue;
@@ -364,12 +364,12 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
                         rx_ring->q_vector);
                dev_info(&pf->pdev->dev,
                         "    rx_rings[%i]: rx_itr_setting = %d (%s)\n",
-                        i, rx_ring->rx_itr_setting,
-                        ITR_IS_DYNAMIC(rx_ring->rx_itr_setting) ?
+                        i, rx_ring->itr_setting,
+                        ITR_IS_DYNAMIC(rx_ring->itr_setting) ?
                                "dynamic" : "fixed");
        }
        for (i = 0; i < vsi->num_queue_pairs; i++) {
-               struct i40e_ring *tx_ring = ACCESS_ONCE(vsi->tx_rings[i]);
+               struct i40e_ring *tx_ring = READ_ONCE(vsi->tx_rings[i]);
 
                if (!tx_ring)
                        continue;
@@ -416,8 +416,8 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
                         i, tx_ring->dcb_tc);
                dev_info(&pf->pdev->dev,
                         "    tx_rings[%i]: tx_itr_setting = %d (%s)\n",
-                        i, tx_ring->tx_itr_setting,
-                        ITR_IS_DYNAMIC(tx_ring->tx_itr_setting) ?
+                        i, tx_ring->itr_setting,
+                        ITR_IS_DYNAMIC(tx_ring->itr_setting) ?
                                "dynamic" : "fixed");
        }
        rcu_read_unlock();
@@ -2078,7 +2078,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
                aq_status = i40e_aq_update_nvm(&pf->hw,
                                               I40E_SR_NVM_CONTROL_WORD,
                                               0x10, sizeof(nvm_word),
-                                              &nvm_word, true, NULL);
+                                              &nvm_word, true, 0, NULL);
                /* Save off last admin queue command status before releasing
                 * the NVM
                 */
similarity index 92%
rename from i40e-dkms/i40e-2.2.4/src/i40e_devids.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_devids.h
index 6e5ec29a44e42e7df404c289b11b7e1814b7697a..044f0533e79edfdeb121d4c3ee381d8678280c4b 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -48,3 +48,6 @@
                                         (d) == I40E_DEV_ID_QSFP_B  || \
                                         (d) == I40E_DEV_ID_QSFP_C)
 
+#define i40e_is_25G_device(d)          ((d) == I40E_DEV_ID_25G_B  || \
+                                        (d) == I40E_DEV_ID_25G_SFP28)
+
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_diag.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_diag.c
index 5d6e0cc48fa4c231947ff3518ff69da6de462e31..f4fb5313e663ae55dd806441e8d4e722c63a7e10 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 97%
rename from i40e-dkms/i40e-2.2.4/src/i40e_diag.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_diag.h
index c0a1772f13eb1087040f1b2a7296f4d0fd45b16f..167169a354e0f1a22bc40347e7850fae8b4d1108 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 87%
rename from i40e-dkms/i40e-2.2.4/src/i40e_ethtool.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_ethtool.c
index dde2251cd8047996df019788ff87a63705ae152e..d97286f62ad28f93a9eface670d632614a9f5c64 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -134,6 +134,10 @@ static const struct i40e_stats i40e_gstrings_stats[] = {
        I40E_PF_STAT("link_xoff_rx", stats.link_xoff_rx),
        I40E_PF_STAT("link_xon_tx", stats.link_xon_tx),
        I40E_PF_STAT("link_xoff_tx", stats.link_xoff_tx),
+       I40E_PF_STAT("priority_xon_rx", stats.priority_xon_rx),
+       I40E_PF_STAT("priority_xoff_rx", stats.priority_xoff_rx),
+       I40E_PF_STAT("priority_xon_tx", stats.priority_xon_tx),
+       I40E_PF_STAT("priority_xoff_tx", stats.priority_xoff_tx),
        I40E_PF_STAT("rx_size_64", stats.rx_size_64),
        I40E_PF_STAT("rx_size_127", stats.rx_size_127),
        I40E_PF_STAT("rx_size_255", stats.rx_size_255),
@@ -175,8 +179,6 @@ static const struct i40e_stats i40e_gstrings_stats[] = {
        I40E_PF_STAT("rx_udp_cso", rx_udp_cso),
        I40E_PF_STAT("rx_sctp_cso", rx_sctp_cso),
        I40E_PF_STAT("rx_ip4_cso", rx_ip4_cso),
-       I40E_PF_STAT("rx_csum_offload_vxlan", hw_csum_rx_vxlan),
-       I40E_PF_STAT("rx_csum_offload_geneve", hw_csum_rx_geneve),
        I40E_PF_STAT("rx_csum_offload_outer", hw_csum_rx_outer),
        I40E_PF_STAT("rx_tcp_cso_error", rx_tcp_cso_err),
        I40E_PF_STAT("rx_udp_cso_error", rx_udp_cso_err),
@@ -267,6 +269,7 @@ static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
 #endif
        I40E_PRIV_FLAG("disable-source-pruning",
                       I40E_FLAG_SOURCE_PRUNING_DISABLED, 0),
+       I40E_PRIV_FLAG("disable-fw-lldp", I40E_FLAG_DISABLE_FW_LLDP, 0),
 };
 
 #define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags)
@@ -280,6 +283,116 @@ static const struct i40e_priv_flags i40e_gl_gstrings_priv_flags[] = {
 #define I40E_GL_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gl_gstrings_priv_flags)
 
 #endif /* HAVE_ETHTOOL_GET_SSET_COUNT */
+#ifndef ETHTOOL_GLINKSETTINGS
+#define I40E_LEGACY_LINK_MASK_SIZE 1
+/**
+ * struct ethtool_link_ksettings
+ * @link_modes: supported and advertising, single item arrays
+ *
+ * This struct and the following macros provide a way to support the old
+ * ethtool get/set_settings API on older kernels, but in the style of the new
+ * GLINKSETTINGS API.  In this way, the same code can be used to support both
+ * APIs as seemlessly as possible.
+ *
+ * It should be noted the old API only has support up to the first 32 bits.
+ */
+struct ethtool_link_ksettings {
+       struct {
+               u32 speed;
+               u8 port;
+               u8 duplex;
+               u8 autoneg;
+       } base;
+       struct {
+               unsigned long supported[I40E_LEGACY_LINK_MASK_SIZE];
+               unsigned long advertising[I40E_LEGACY_LINK_MASK_SIZE];
+       } link_modes;
+};
+
+#define ETHTOOL_LINK_NAME_advertising(mode) ADVERTISED_ ## mode
+#define ETHTOOL_LINK_NAME_supported(mode) SUPPORTED_ ## mode
+#define ETHTOOL_LINK_NAME(name) ETHTOOL_LINK_NAME_ ## name
+#define ETHTOOL_LINK_CONVERT(name, mode)                               \
+       ETHTOOL_LINK_NAME(name)(mode)
+
+/**
+ * ethtool_link_ksettings_zero_link_mode
+ * @ptr: ptr to ksettings struct
+ * @name: supported or advertising
+ */
+#define ethtool_link_ksettings_zero_link_mode(ptr, name)               \
+       (*((ptr)->link_modes.name) = 0x0)
+
+/**
+ * ethtool_link_ksettings_add_link_mode
+ * @ptr: ptr to ksettings struct
+ * @name: supported or advertising
+ * @mode: link mode to add
+ */
+#define ethtool_link_ksettings_add_link_mode(ptr, name, mode)          \
+       (*((ptr)->link_modes.name) |= ETHTOOL_LINK_CONVERT(name, mode))
+
+/**
+ * ethtool_link_ksettings_test_link_mode
+ * @ptr: ptr to ksettings struct
+ * @name: supported or advertising
+ * @mode: link mode to add
+ */
+#define ethtool_link_ksettings_test_link_mode(ptr, name, mode)         \
+       (!!(*((ptr)->link_modes.name) & ETHTOOL_LINK_CONVERT(name, mode)))
+
+/**
+ * ethtool_link_ksettings_del_link_mode
+ * @ptr: ptr to ksettings struct
+ * @name: supported or advertising
+ * @mode: link mode to delete
+ */
+#ifdef ethtool_link_ksettings_del_link_mode
+#undef ethtool_link_ksettings_del_link_mode
+#endif
+#define ethtool_link_ksettings_del_link_mode(ptr, name, mode)          \
+       ((*(ptr)->link_modes.name) &=                                   \
+        ~((unsigned long)ETHTOOL_LINK_CONVERT(name, mode)))
+
+/**
+ * i40e_ethtool_ksettings_to_cmd
+ * @ks: ethtool_link_ksettings struct
+ * @cmd: ethtool_cmd struct
+ *
+ * Convert a ethtool_link_ksettings to a ethtool_cmd
+ */
+static void i40e_ethtool_ksettings_to_cmd(struct ethtool_link_ksettings *ks,
+                                         struct ethtool_cmd *cmd)
+{
+       cmd->supported = (u32)ks->link_modes.supported[0];
+       cmd->advertising = (u32)ks->link_modes.advertising[0];
+       ethtool_cmd_speed_set(cmd, ks->base.speed);
+       cmd->duplex = ks->base.duplex;
+       cmd->autoneg = ks->base.autoneg;
+       cmd->port = ks->base.port;
+}
+
+/**
+ * ethtool_intersect_link_mode_masks
+ * @dst: resulting intersection and first mask
+ * @src: mask to AND with
+ *
+ * Given two link mode masks, AND them together and save the result in dst.
+ */
+static void ethtool_intersect_link_masks(struct ethtool_link_ksettings *dst,
+                                        struct ethtool_link_ksettings *src)
+{
+       int idx = 0;
+
+       for (; idx < I40E_LEGACY_LINK_MASK_SIZE; idx++) {
+               dst->link_modes.supported[idx] &=
+                       src->link_modes.supported[idx];
+               dst->link_modes.advertising[idx] &=
+                       src->link_modes.advertising[idx];
+       }
+}
+
+#endif /* !ETHTOOL_GLINKSETTINGS */
 /**
  * i40e_partition_setting_complaint - generic complaint for MFP restriction
  * @pf: the PF struct
@@ -292,29 +405,30 @@ static void i40e_partition_setting_complaint(struct i40e_pf *pf)
 
 /**
  * i40e_phy_type_to_ethtool - convert the phy_types to ethtool link modes
- * @phy_types: phy types to convert
- * @supported: pointer to the ethtool supported variable to fill in
- * @advertising: pointer to the ethtool advertising variable to fill in
+ * @pf: PF struct with phy_types
+ * @ks: ethtool link ksettings struct to fill out
  *
  **/
-static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, u32 *supported,
-                                    u32 *advertising)
+static void i40e_phy_type_to_ethtool(struct i40e_pf *pf,
+                                    struct ethtool_link_ksettings *ks)
 {
        struct i40e_link_status *hw_link_info = &pf->hw.phy.link_info;
        u64 phy_types = pf->hw.phy.phy_types;
 
-       *supported = 0x0;
-       *advertising = 0x0;
+       ethtool_link_ksettings_zero_link_mode(ks, supported);
+       ethtool_link_ksettings_zero_link_mode(ks, advertising);
 
        if (phy_types & I40E_CAP_PHY_TYPE_SGMII) {
-               *supported |= SUPPORTED_Autoneg |
-                            SUPPORTED_1000baseT_Full;
-               *advertising |= ADVERTISED_Autoneg;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    1000baseT_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
-                       *advertising |= ADVERTISED_1000baseT_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            1000baseT_Full);
                if (pf->hw_features & I40E_HW_100M_SGMII_CAPABLE) {
-                       *supported |= SUPPORTED_100baseT_Full;
-                       *advertising |= ADVERTISED_100baseT_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                            100baseT_Full);
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            100baseT_Full);
                }
        }
        if (phy_types & I40E_CAP_PHY_TYPE_XAUI ||
@@ -322,669 +436,118 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, u32 *supported,
            phy_types & I40E_CAP_PHY_TYPE_SFI ||
            phy_types & I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU ||
            phy_types & I40E_CAP_PHY_TYPE_10GBASE_AOC) {
-               *supported |= SUPPORTED_10000baseT_Full;
-               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB) {
-                       *advertising |= ADVERTISED_10000baseT_Full;
-               }
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    10000baseT_Full);
+               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            10000baseT_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_T) {
-               *supported |= SUPPORTED_Autoneg |
-                            SUPPORTED_10000baseT_Full;
-               *advertising |= ADVERTISED_Autoneg;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    10000baseT_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
-                       *advertising |= ADVERTISED_10000baseT_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            10000baseT_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_XLAUI ||
            phy_types & I40E_CAP_PHY_TYPE_XLPPI ||
            phy_types & I40E_CAP_PHY_TYPE_40GBASE_AOC)
-               *supported |= SUPPORTED_40000baseCR4_Full;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    40000baseCR4_Full);
        if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4_CU ||
            phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4) {
-               *supported |= SUPPORTED_Autoneg |
-                            SUPPORTED_40000baseCR4_Full;
-               *advertising |= ADVERTISED_Autoneg;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    40000baseCR4_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_40GB)
-                       *advertising |= ADVERTISED_40000baseCR4_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            40000baseCR4_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_100BASE_TX) {
-               *supported |= SUPPORTED_Autoneg |
-                            SUPPORTED_100baseT_Full;
-               *advertising |= ADVERTISED_Autoneg;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    100baseT_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_100MB)
-                       *advertising |= ADVERTISED_100baseT_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            100baseT_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_1000BASE_T) {
-               *supported |= SUPPORTED_Autoneg |
-                            SUPPORTED_1000baseT_Full;
-               *advertising |= ADVERTISED_Autoneg;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    1000baseT_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
-                       *advertising |= ADVERTISED_1000baseT_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            1000baseT_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_SR4)
-               *supported |= SUPPORTED_40000baseSR4_Full;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    40000baseSR4_Full);
        if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_LR4)
-               *supported |= SUPPORTED_40000baseLR4_Full;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    40000baseLR4_Full);
        if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_KR4) {
-               *supported |= SUPPORTED_40000baseKR4_Full |
-                            SUPPORTED_Autoneg;
-               *advertising |= ADVERTISED_40000baseKR4_Full |
-                              ADVERTISED_Autoneg;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    40000baseLR4_Full);
+               ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                    40000baseLR4_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_20GBASE_KR2) {
-               *supported |= SUPPORTED_20000baseKR2_Full |
-                            SUPPORTED_Autoneg;
-               *advertising |= ADVERTISED_Autoneg;
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    20000baseKR2_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_20GB)
-                       *advertising |= ADVERTISED_20000baseKR2_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            20000baseKR2_Full);
        }
-       if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_KR) {
-               if (!(pf->hw_features & I40E_HW_HAVE_CRT_RETIMER))
-                       *supported |= SUPPORTED_10000baseKR_Full |
-                                     SUPPORTED_Autoneg;
-               *advertising |= ADVERTISED_Autoneg;
+       if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_KX4) {
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    10000baseKX4_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
-                       if (!(pf->hw_features & I40E_HW_HAVE_CRT_RETIMER))
-                               *advertising |= ADVERTISED_10000baseKR_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            10000baseKX4_Full);
        }
-       if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_KX4) {
-               *supported |= SUPPORTED_10000baseKX4_Full |
-                            SUPPORTED_Autoneg;
-               *advertising |= ADVERTISED_Autoneg;
+       if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_KR &&
+           !(pf->hw_features & I40E_HW_HAVE_CRT_RETIMER)) {
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    10000baseKR_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
-                       *advertising |= ADVERTISED_10000baseKX4_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            10000baseKR_Full);
        }
-       if (phy_types & I40E_CAP_PHY_TYPE_1000BASE_KX) {
-               if (!(pf->hw_features & I40E_HW_HAVE_CRT_RETIMER))
-                       *supported |= SUPPORTED_1000baseKX_Full |
-                                     SUPPORTED_Autoneg;
-               *advertising |= ADVERTISED_Autoneg;
+       if (phy_types & I40E_CAP_PHY_TYPE_1000BASE_KX &&
+           !(pf->hw_features & I40E_HW_HAVE_CRT_RETIMER)) {
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    1000baseKX_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
-                       if (!(pf->hw_features & I40E_HW_HAVE_CRT_RETIMER))
-                               *advertising |= ADVERTISED_1000baseKX_Full;
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            1000baseKX_Full);
        }
-       /* Older kernels, that do not use ETHTOOL_GLINKSETTINGS should at least
-        * report Autoneg capability
-        */
-       if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR ||
-           phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR ||
-           phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
-           phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR ||
-           phy_types & I40E_CAP_PHY_TYPE_10GBASE_SR ||
-           phy_types & I40E_CAP_PHY_TYPE_10GBASE_LR ||
-           phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 ||
-           phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU ||
-           phy_types & I40E_CAP_PHY_TYPE_1000BASE_SX ||
-           phy_types & I40E_CAP_PHY_TYPE_1000BASE_LX ||
-           phy_types & I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL) {
-               *supported |= SUPPORTED_Autoneg;
-               *advertising |= ADVERTISED_Autoneg;
+#ifdef HAVE_ETHTOOL_25G_BITS
+       /* need to add 25G PHY types */
+       if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR) {
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    25000baseKR_Full);
+               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            25000baseKR_Full);
        }
-}
-
-/**
- * i40e_get_settings_link_up - Get the Link settings for when link is up
- * @hw: hw structure
- * @ecmd: ethtool command to fill in
- * @netdev: network interface device structure
- *
- * Reports link settings that can be determined when link is up
- **/
-static void i40e_get_settings_link_up(struct i40e_hw *hw,
-                                     struct ethtool_cmd *ecmd,
-                                     struct net_device *netdev,
-                                     struct i40e_pf *pf)
-{
-       struct i40e_link_status *hw_link_info = &hw->phy.link_info;
-       u32 link_speed = hw_link_info->link_speed;
-       u32 e_advertising = 0x0;
-       u32 e_supported = 0x0;
-
-       /* Initialize supported and advertised settings based on phy settings */
-       switch (hw_link_info->phy_type) {
-       case I40E_PHY_TYPE_40GBASE_CR4:
-       case I40E_PHY_TYPE_40GBASE_CR4_CU:
-               ecmd->supported = SUPPORTED_Autoneg |
-                                 SUPPORTED_40000baseCR4_Full;
-               ecmd->advertising = ADVERTISED_Autoneg |
-                                   ADVERTISED_40000baseCR4_Full;
-               break;
-       case I40E_PHY_TYPE_XLAUI:
-       case I40E_PHY_TYPE_XLPPI:
-       case I40E_PHY_TYPE_40GBASE_AOC:
-               ecmd->supported = SUPPORTED_40000baseCR4_Full;
-               break;
-       case I40E_PHY_TYPE_40GBASE_SR4:
-               ecmd->supported = SUPPORTED_40000baseSR4_Full;
-               break;
-       case I40E_PHY_TYPE_40GBASE_LR4:
-               ecmd->supported = SUPPORTED_40000baseLR4_Full;
-               break;
-       case I40E_PHY_TYPE_10GBASE_SR:
-       case I40E_PHY_TYPE_10GBASE_LR:
-       case I40E_PHY_TYPE_1000BASE_SX:
-       case I40E_PHY_TYPE_1000BASE_LX:
-               ecmd->supported = SUPPORTED_10000baseT_Full;
-               if (hw_link_info->module_type[2] & I40E_MODULE_TYPE_1000BASE_SX ||
-                   hw_link_info->module_type[2] & I40E_MODULE_TYPE_1000BASE_LX) {
-                       ecmd->supported |= SUPPORTED_1000baseT_Full;
-                       if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
-                               ecmd->advertising |= ADVERTISED_1000baseT_Full;
-               }
-               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
-                       ecmd->advertising |= ADVERTISED_10000baseT_Full;
-               break;
-       case I40E_PHY_TYPE_10GBASE_T:
-       case I40E_PHY_TYPE_1000BASE_T:
-       case I40E_PHY_TYPE_100BASE_TX:
-               ecmd->supported = SUPPORTED_Autoneg |
-                                 SUPPORTED_10000baseT_Full |
-                                 SUPPORTED_1000baseT_Full |
-                                 SUPPORTED_100baseT_Full;
-               ecmd->advertising = ADVERTISED_Autoneg;
-               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
-                       ecmd->advertising |= ADVERTISED_10000baseT_Full;
-               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
-                       ecmd->advertising |= ADVERTISED_1000baseT_Full;
-               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_100MB)
-                       ecmd->advertising |= ADVERTISED_100baseT_Full;
-               break;
-       case I40E_PHY_TYPE_1000BASE_T_OPTICAL:
-               ecmd->supported = SUPPORTED_Autoneg |
-                                 SUPPORTED_1000baseT_Full;
-               ecmd->advertising = ADVERTISED_Autoneg |
-                                   ADVERTISED_1000baseT_Full;
-               break;
-       case I40E_PHY_TYPE_10GBASE_CR1_CU:
-       case I40E_PHY_TYPE_10GBASE_CR1:
-               ecmd->supported = SUPPORTED_Autoneg |
-                                 SUPPORTED_10000baseT_Full;
-               ecmd->advertising = ADVERTISED_Autoneg |
-                                   ADVERTISED_10000baseT_Full;
-               break;
-       case I40E_PHY_TYPE_XAUI:
-       case I40E_PHY_TYPE_XFI:
-       case I40E_PHY_TYPE_SFI:
-       case I40E_PHY_TYPE_10GBASE_SFPP_CU:
-       case I40E_PHY_TYPE_10GBASE_AOC:
-               ecmd->supported = SUPPORTED_10000baseT_Full;
-               break;
-       case I40E_PHY_TYPE_SGMII:
-               ecmd->supported = SUPPORTED_Autoneg |
-                                 SUPPORTED_1000baseT_Full;
-               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
-                       ecmd->advertising |= ADVERTISED_1000baseT_Full;
-               if (pf->hw_features & I40E_HW_100M_SGMII_CAPABLE) {
-                       ecmd->supported |= SUPPORTED_100baseT_Full;
-                       if (hw_link_info->requested_speeds &
-                           I40E_LINK_SPEED_100MB)
-                               ecmd->advertising |= ADVERTISED_100baseT_Full;
-               }
-               break;
-       case I40E_PHY_TYPE_40GBASE_KR4:
-       case I40E_PHY_TYPE_20GBASE_KR2:
-       case I40E_PHY_TYPE_10GBASE_KR:
-       case I40E_PHY_TYPE_10GBASE_KX4:
-       case I40E_PHY_TYPE_1000BASE_KX:
-               ecmd->supported |= SUPPORTED_40000baseKR4_Full |
-                                  SUPPORTED_20000baseKR2_Full |
-                                  SUPPORTED_10000baseKR_Full |
-                                  SUPPORTED_10000baseKX4_Full |
-                                  SUPPORTED_1000baseKX_Full |
-                                  SUPPORTED_Autoneg;
-               ecmd->advertising |= ADVERTISED_40000baseKR4_Full |
-                                    ADVERTISED_20000baseKR2_Full |
-                                    ADVERTISED_10000baseKR_Full |
-                                    ADVERTISED_10000baseKX4_Full |
-                                    ADVERTISED_1000baseKX_Full |
-                                    ADVERTISED_Autoneg;
-               break;
-       case I40E_PHY_TYPE_25GBASE_KR:
-       case I40E_PHY_TYPE_25GBASE_CR:
-       case I40E_PHY_TYPE_25GBASE_SR:
-       case I40E_PHY_TYPE_25GBASE_LR:
-               ecmd->supported = SUPPORTED_Autoneg;
-               ecmd->advertising = ADVERTISED_Autoneg;
-               /* TODO: add speeds when ethtool is ready to support*/
-               break;
-       default:
-               /* if we got here and link is up something bad is afoot */
-               netdev_info(netdev, "WARNING: Link is up but PHY type 0x%x is not recognized.\n",
-                           hw_link_info->phy_type);
+       if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR) {
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    25000baseCR_Full);
+               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            25000baseCR_Full);
        }
-
-       /* Now that we've worked out everything that could be supported by the
-        * current phy type, get what is supported by the NVM and and them to
-        * get what is truly supported
-        */
-       i40e_phy_type_to_ethtool(pf, &e_supported,
-                                &e_advertising);
-
-       ecmd->supported = ecmd->supported & e_supported;
-       ecmd->advertising = ecmd->advertising & e_advertising;
-
-       /* Set speed and duplex */
-       switch (link_speed) {
-       case I40E_LINK_SPEED_40GB:
-               ethtool_cmd_speed_set(ecmd, SPEED_40000);
-               break;
-       case I40E_LINK_SPEED_25GB:
-#ifdef SPEED_25000
-               ethtool_cmd_speed_set(ecmd, SPEED_25000);
-#else
-               netdev_info(netdev,
-                           "Speed is 25G, display not supported by this version of ethtool.\n");
-#endif
-               break;
-       case I40E_LINK_SPEED_20GB:
-               ethtool_cmd_speed_set(ecmd, SPEED_20000);
-               break;
-       case I40E_LINK_SPEED_10GB:
-               ethtool_cmd_speed_set(ecmd, SPEED_10000);
-               break;
-       case I40E_LINK_SPEED_1GB:
-               ethtool_cmd_speed_set(ecmd, SPEED_1000);
-               break;
-       case I40E_LINK_SPEED_100MB:
-               ethtool_cmd_speed_set(ecmd, SPEED_100);
-               break;
-       default:
-               break;
-       }
-       ecmd->duplex = DUPLEX_FULL;
-}
-
-/**
- * i40e_get_settings_link_down - Get the Link settings for when link is down
- * @hw: hw structure
- * @ecmd: ethtool command to fill in
- *
- * Reports link settings that can be determined when link is down
- **/
-static void i40e_get_settings_link_down(struct i40e_hw *hw,
-                                       struct ethtool_cmd *ecmd,
-                                       struct i40e_pf *pf)
-{
-       /* link is down and the driver needs to fall back on
-        * supported phy types to figure out what info to display
-        */
-       i40e_phy_type_to_ethtool(pf, &ecmd->supported,
-                                &ecmd->advertising);
-
-       /* With no link speed and duplex are unknown */
-       ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
-       ecmd->duplex = DUPLEX_UNKNOWN;
-}
-
-/**
- * i40e_get_settings - Get Link Speed and Duplex settings
- * @netdev: network interface device structure
- * @ecmd: ethtool command
- *
- * Reports speed/duplex settings based on media_type
- **/
-static int i40e_get_settings(struct net_device *netdev,
-                            struct ethtool_cmd *ecmd)
-{
-       struct i40e_netdev_priv *np = netdev_priv(netdev);
-       struct i40e_pf *pf = np->vsi->back;
-       struct i40e_hw *hw = &pf->hw;
-       struct i40e_link_status *hw_link_info = &hw->phy.link_info;
-       bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
-
-       if (link_up)
-               i40e_get_settings_link_up(hw, ecmd, netdev, pf);
-       else
-               i40e_get_settings_link_down(hw, ecmd, pf);
-
-       /* Now set the settings that don't rely on link being up/down */
-       /* Set autoneg settings */
-       ecmd->autoneg = (hw_link_info->an_info & I40E_AQ_AN_COMPLETED ?
-                         AUTONEG_ENABLE : AUTONEG_DISABLE);
-
-       /* Set media type settings */
-       switch (hw->phy.media_type) {
-       case I40E_MEDIA_TYPE_BACKPLANE:
-               ecmd->supported |= SUPPORTED_Autoneg |
-                                  SUPPORTED_Backplane;
-               ecmd->advertising |= ADVERTISED_Autoneg |
-                                    ADVERTISED_Backplane;
-               ecmd->port = PORT_NONE;
-               break;
-       case I40E_MEDIA_TYPE_BASET:
-               ecmd->supported |= SUPPORTED_TP;
-               ecmd->advertising |= ADVERTISED_TP;
-               ecmd->port = PORT_TP;
-               break;
-       case I40E_MEDIA_TYPE_DA:
-       case I40E_MEDIA_TYPE_CX4:
-               ecmd->supported |= SUPPORTED_FIBRE;
-               ecmd->advertising |= ADVERTISED_FIBRE;
-               ecmd->port = PORT_DA;
-               break;
-       case I40E_MEDIA_TYPE_FIBER:
-               ecmd->supported |= SUPPORTED_FIBRE;
-               ecmd->port = PORT_FIBRE;
-               break;
-       case I40E_MEDIA_TYPE_UNKNOWN:
-       default:
-               ecmd->port = PORT_OTHER;
-               break;
-       }
-
-       /* Set transceiver */
-       ecmd->transceiver = XCVR_EXTERNAL;
-
-       /* Set flow control settings */
-       ecmd->supported |= SUPPORTED_Pause;
-
-       switch (hw->fc.requested_mode) {
-       case I40E_FC_FULL:
-               ecmd->advertising |= ADVERTISED_Pause;
-               break;
-       case I40E_FC_TX_PAUSE:
-               ecmd->advertising |= ADVERTISED_Asym_Pause;
-               break;
-       case I40E_FC_RX_PAUSE:
-               ecmd->advertising |= (ADVERTISED_Pause |
-                                     ADVERTISED_Asym_Pause);
-               break;
-       default:
-               ecmd->advertising &= ~(ADVERTISED_Pause |
-                                      ADVERTISED_Asym_Pause);
-               break;
-       }
-
-       return 0;
-}
-
-/**
- * i40e_set_settings - Set Speed and Duplex
- * @netdev: network interface device structure
- * @ecmd: ethtool command
- *
- * Set speed/duplex per media_types advertised/forced
- **/
-static int i40e_set_settings(struct net_device *netdev,
-                            struct ethtool_cmd *ecmd)
-{
-       struct i40e_netdev_priv *np = netdev_priv(netdev);
-       struct i40e_aq_get_phy_abilities_resp abilities;
-       struct i40e_aq_set_phy_config config;
-       struct i40e_pf *pf = np->vsi->back;
-       struct i40e_vsi *vsi = np->vsi;
-       struct i40e_hw *hw = &pf->hw;
-       struct ethtool_cmd safe_ecmd;
-       i40e_status status = 0;
-       bool change = false;
-       int timeout = 50;
-       int err = 0;
-       u8 autoneg;
-       u32 advertise;
-       u32 old_ethtool_advertising = 0;
-
-       /* Changing port settings is not supported if this isn't the
-        * port's controlling PF
-        */
-       if (hw->partition_id != 1) {
-               i40e_partition_setting_complaint(pf);
-               return -EOPNOTSUPP;
-       }
-
-       if (vsi != pf->vsi[pf->lan_vsi])
-               return -EOPNOTSUPP;
-
-       if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
-           hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
-           hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE &&
-           hw->phy.media_type != I40E_MEDIA_TYPE_DA &&
-           hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
-               return -EOPNOTSUPP;
-
-       if (hw->device_id == I40E_DEV_ID_KX_B ||
-           hw->device_id == I40E_DEV_ID_KX_C ||
-           hw->device_id == I40E_DEV_ID_20G_KR2 ||
-           hw->device_id == I40E_DEV_ID_20G_KR2_A) {
-               netdev_info(netdev, "Changing settings is not supported on backplane.\n");
-               return -EOPNOTSUPP;
-       }
-
-       /* get our own copy of the bits to check against */
-       memset(&safe_ecmd, 0, sizeof(struct ethtool_cmd));
-       i40e_get_settings(netdev, &safe_ecmd);
-
-       /* save autoneg and speed out of ecmd */
-       autoneg = ecmd->autoneg;
-       advertise = ecmd->advertising;
-
-       /* set autoneg and speed back to what they currently are */
-       ecmd->autoneg = safe_ecmd.autoneg;
-       ecmd->advertising = safe_ecmd.advertising;
-
-       /* Due to a bug in ethtool versions < 3.6 this check is necessary */
-       old_ethtool_advertising = ecmd->supported &
-                                 (ADVERTISED_10baseT_Half |
-                                  ADVERTISED_10baseT_Full |
-                                  ADVERTISED_100baseT_Half |
-                                  ADVERTISED_100baseT_Full |
-                                  ADVERTISED_1000baseT_Half |
-                                  ADVERTISED_1000baseT_Full |
-                                  ADVERTISED_2500baseX_Full |
-                                  ADVERTISED_10000baseT_Full);
-       old_ethtool_advertising |= (old_ethtool_advertising |
-                                  ADVERTISED_20000baseMLD2_Full |
-                                  ADVERTISED_20000baseKR2_Full);
-
-       if (advertise == old_ethtool_advertising)
-               netdev_info(netdev, "If you are not setting advertising to %x then you may have an old version of ethtool. Please update.\n",
-                           advertise);
-       ecmd->cmd = safe_ecmd.cmd;
-       /* If ecmd and safe_ecmd are not the same now, then they are
-        * trying to set something that we do not support
-        */
-       if (memcmp(ecmd, &safe_ecmd, sizeof(struct ethtool_cmd)))
-               return -EOPNOTSUPP;
-
-       while (test_and_set_bit(__I40E_CONFIG_BUSY, pf->state)) {
-               timeout--;
-               if (!timeout)
-                       return -EBUSY;
-               usleep_range(1000, 2000);
-       }
-
-       /* Get the current phy config */
-       status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
-                                             NULL);
-       if (status) {
-               err = -EAGAIN;
-               goto done;
-       }
-
-       /* Copy abilities to config in case autoneg is not
-        * set below
-        */
-       memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
-       config.abilities = abilities.abilities;
-
-       /* Check autoneg */
-       if (autoneg == AUTONEG_ENABLE) {
-               /* If autoneg was not already enabled */
-               if (!(hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED)) {
-                       /* If autoneg is not supported, return error */
-                       if (!(safe_ecmd.supported & SUPPORTED_Autoneg)) {
-                               netdev_info(netdev, "Autoneg not supported on this phy\n");
-                               err = -EINVAL;
-                               goto done;
-                       }
-                       /* Autoneg is allowed to change */
-                       config.abilities = abilities.abilities |
-                                          I40E_AQ_PHY_ENABLE_AN;
-                       change = true;
-               }
-       } else {
-               /* If autoneg is currently enabled */
-               if (hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED) {
-                       /* If autoneg is supported 10GBASE_T is the only phy
-                        * that can disable it, so otherwise return error
-                        */
-                       if (safe_ecmd.supported & SUPPORTED_Autoneg &&
-                           hw->phy.link_info.phy_type !=
-                           I40E_PHY_TYPE_10GBASE_T) {
-                               netdev_info(netdev, "Autoneg cannot be disabled on this phy\n");
-                               err = -EINVAL;
-                               goto done;
-                       }
-                       /* Autoneg is allowed to change */
-                       config.abilities = abilities.abilities &
-                                          ~I40E_AQ_PHY_ENABLE_AN;
-                       change = true;
-               }
-       }
-
-       if (advertise & ~safe_ecmd.supported) {
-               err = -EINVAL;
-               goto done;
-       }
-
-       if (advertise & ADVERTISED_100baseT_Full)
-               config.link_speed |= I40E_LINK_SPEED_100MB;
-       if (advertise & ADVERTISED_1000baseT_Full ||
-           advertise & ADVERTISED_1000baseKX_Full)
-               config.link_speed |= I40E_LINK_SPEED_1GB;
-       if (advertise & ADVERTISED_10000baseT_Full ||
-           advertise & ADVERTISED_10000baseKX4_Full ||
-           advertise & ADVERTISED_10000baseKR_Full)
-               config.link_speed |= I40E_LINK_SPEED_10GB;
-       if (advertise & ADVERTISED_20000baseKR2_Full)
-               config.link_speed |= I40E_LINK_SPEED_20GB;
-       if (advertise & ADVERTISED_40000baseKR4_Full ||
-           advertise & ADVERTISED_40000baseCR4_Full ||
-           advertise & ADVERTISED_40000baseSR4_Full ||
-           advertise & ADVERTISED_40000baseLR4_Full)
-               config.link_speed |= I40E_LINK_SPEED_40GB;
-
-       /* If speed didn't get set, set it to what it currently is.
-        * This is needed because if advertise is 0 (as it is when autoneg
-        * is disabled) then speed won't get set.
-        */
-       if (!config.link_speed)
-               config.link_speed = abilities.link_speed;
-
-       if (change || (abilities.link_speed != config.link_speed)) {
-               /* copy over the rest of the abilities */
-               config.phy_type = abilities.phy_type;
-               config.phy_type_ext = abilities.phy_type_ext;
-               config.eee_capability = abilities.eee_capability;
-               config.eeer = abilities.eeer_val;
-               config.low_power_ctrl = abilities.d3_lpan;
-               config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
-                                   I40E_AQ_PHY_FEC_CONFIG_MASK;
-
-               /* save the requested speeds */
-               hw->phy.link_info.requested_speeds = config.link_speed;
-               /* set link and auto negotiation so changes take effect */
-               config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-               /* If link is up put link down */
-               if (hw->phy.link_info.link_info & I40E_AQ_LINK_UP) {
-                       /* Tell the OS link is going down, the link will go
-                        * back up when fw says it is ready asynchronously
-                        */
-                       i40e_print_link_message(vsi, false);
-                       netif_carrier_off(netdev);
-                       netif_tx_stop_all_queues(netdev);
-               }
-
-               /* make the aq call */
-               status = i40e_aq_set_phy_config(hw, &config, NULL);
-               if (status) {
-                       netdev_info(netdev, "Set phy config failed, err %s aq_err %s\n",
-                                   i40e_stat_str(hw, status),
-                                   i40e_aq_str(hw, hw->aq.asq_last_status));
-                       err = -EAGAIN;
-                       goto done;
-               }
-
-               status = i40e_update_link_info(hw);
-               if (status)
-                       netdev_dbg(netdev, "Updating link info failed with err %s aq_err %s\n",
-                                  i40e_stat_str(hw, status),
-                                  i40e_aq_str(hw, hw->aq.asq_last_status));
-
-       } else {
-               netdev_info(netdev, "Nothing changed, exiting without setting anything.\n");
-       }
-
-done:
-       clear_bit(__I40E_CONFIG_BUSY, pf->state);
-
-       return err;
-}
-
-#ifdef ETHTOOL_GLINKSETTINGS
-#define ETHTOOL_LINK_MODE_MASK_U32  \
-       DIV_ROUND_UP(__ETHTOOL_LINK_MODE_MASK_NBITS, 32)
-
-/**
- * ethtool_link_ksettings_clear_link_mode - unset a bit in link_ksettings
- * link mode mask
- *   @ptr : pointer to ethtool_link_ksettings
- *   @name : one of supported, advertising or lp_advertising
- *   @mode : one of ETHTOOL_LINK_MODE_*_BIT
- * (not atomic and no bounds checking)
- **/
-#define ethtool_link_ksettings_clear_link_mode(ptr, name, mode)           \
-       __clear_bit(ETHTOOL_LINK_MODE_ ## mode ## _BIT, (ptr)->link_modes.name)
-
-/**
- * i40e_get_link_settings_link_down - Get the Link settings when link is down
- * @hw: hw structure
- * @ksettings: ethtool command to fill in
- * @pf: pointer to physical function struct
- *
- * Reports link settings that can be determined when link is down
- **/
-static void i40e_get_link_settings_link_down(struct i40e_hw *hw,
-                                      struct ethtool_link_ksettings *ksettings,
-                                      struct i40e_pf *pf)
-{
-       struct i40e_link_status *hw_link_info = &pf->hw.phy.link_info;
-       u64 phy_types = pf->hw.phy.phy_types;
-
-       i40e_phy_type_to_ethtool(pf, (u32 *)&ksettings->link_modes.supported[0],
-                                (u32 *)&ksettings->link_modes.advertising[0]);
-#ifdef HAVE_ETHTOOL_25G_BITS
-       /* need to add 25G PHY types */
-       if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
-                                                    25000baseKR_Full);
-               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
-                                                            25000baseKR_Full);
-       }
-       if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
-                                                    25000baseCR_Full);
-               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
-                                                            25000baseCR_Full);
-       }
-       if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
-           phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
-                                                    25000baseSR_Full);
-               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
-                                                            25000baseSR_Full);
+       if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
+           phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR) {
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    25000baseSR_Full);
+               if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                            25000baseSR_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_AOC ||
            phy_types & I40E_CAP_PHY_TYPE_25GBASE_ACC) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
+               ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     25000baseCR_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                             25000baseCR_Full);
        }
 #endif /* HAVE_ETHTOOL_25G_BITS */
@@ -992,37 +555,33 @@ static void i40e_get_link_settings_link_down(struct i40e_hw *hw,
        /* need to add new 10G PHY types */
        if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 ||
            phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
+               ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     10000baseCR_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                             10000baseCR_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_SR) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
+               ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     10000baseSR_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                             10000baseSR_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_LR) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
+               ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     10000baseLR_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                             10000baseLR_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_1000BASE_SX ||
            phy_types & I40E_CAP_PHY_TYPE_1000BASE_LX ||
            phy_types & I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
+               ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     1000baseX_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                             1000baseX_Full);
        }
 #else
@@ -1031,44 +590,67 @@ static void i40e_get_link_settings_link_down(struct i40e_hw *hw,
            phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU ||
            phy_types & I40E_CAP_PHY_TYPE_10GBASE_SR ||
            phy_types & I40E_CAP_PHY_TYPE_10GBASE_LR) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
+               ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     10000baseT_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                             10000baseT_Full);
        }
        if (phy_types & I40E_CAP_PHY_TYPE_1000BASE_SX ||
            phy_types & I40E_CAP_PHY_TYPE_1000BASE_LX ||
            phy_types & I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL) {
-               ethtool_link_ksettings_add_link_mode(ksettings, supported,
+               ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     1000baseT_Full);
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
-                       ethtool_link_ksettings_add_link_mode(ksettings,
-                                                            advertising,
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                             1000baseT_Full);
        }
 #endif /* HAVE_ETHTOOL_NEW_10G_BITS */
-       ksettings->base.speed = SPEED_UNKNOWN;
-       ksettings->base.duplex = DUPLEX_UNKNOWN;
+       /* Autoneg PHY types */
+       if (phy_types & I40E_CAP_PHY_TYPE_SGMII ||
+           phy_types & I40E_CAP_PHY_TYPE_40GBASE_KR4 ||
+           phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4_CU ||
+           phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4 ||
+           phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
+           phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR ||
+           phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR ||
+           phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR ||
+           phy_types & I40E_CAP_PHY_TYPE_20GBASE_KR2 ||
+           phy_types & I40E_CAP_PHY_TYPE_10GBASE_T ||
+           phy_types & I40E_CAP_PHY_TYPE_10GBASE_SR ||
+           phy_types & I40E_CAP_PHY_TYPE_10GBASE_LR ||
+           phy_types & I40E_CAP_PHY_TYPE_10GBASE_KX4 ||
+           phy_types & I40E_CAP_PHY_TYPE_10GBASE_KR ||
+           phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU ||
+           phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 ||
+           phy_types & I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL ||
+           phy_types & I40E_CAP_PHY_TYPE_1000BASE_T ||
+           phy_types & I40E_CAP_PHY_TYPE_1000BASE_SX ||
+           phy_types & I40E_CAP_PHY_TYPE_1000BASE_LX ||
+           phy_types & I40E_CAP_PHY_TYPE_1000BASE_KX ||
+           phy_types & I40E_CAP_PHY_TYPE_100BASE_TX) {
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    Autoneg);
+               ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                    Autoneg);
+       }
 }
 
 /**
- * i40e_get_link_settings_link_up - Get Link info and duplex settings
+ * i40e_get_settings_link_up - Get Link settings for when link is up
  * @hw: hw structure
- * @ksettings: ethtool structure to fill in
+ * @ks: ethtool ksettings to fill in
  * @netdev: network interface device structure
  * @pf: pointer to physical function struct
  **/
-static void i40e_get_link_settings_link_up(struct i40e_hw *hw,
-                                          struct ethtool_link_ksettings *ks,
-                                          struct net_device *netdev,
-                                          struct i40e_pf *pf)
+static void i40e_get_settings_link_up(struct i40e_hw *hw,
+                                     struct ethtool_link_ksettings *ks,
+                                     struct net_device *netdev,
+                                     struct i40e_pf *pf)
 {
        struct i40e_link_status *hw_link_info = &hw->phy.link_info;
-       u32 link_speed = hw_link_info->link_speed;
        struct ethtool_link_ksettings cap_ksettings;
-       int idx;
+       u32 link_speed = hw_link_info->link_speed;
 
        /* Initialize supported and advertised settings based on phy settings */
        switch (hw_link_info->phy_type) {
@@ -1133,9 +715,8 @@ static void i40e_get_link_settings_link_up(struct i40e_hw *hw,
                                                             1000baseT_Full);
                        if (hw_link_info->requested_speeds &
                            I40E_LINK_SPEED_1GB)
-                               ethtool_link_ksettings_add_link_mode(ks,
-                                                               advertising,
-                                                               1000baseT_Full);
+                               ethtool_link_ksettings_add_link_mode(
+                                    ks, advertising, 1000baseT_Full);
                }
                if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
                        ethtool_link_ksettings_add_link_mode(ks, advertising,
@@ -1202,9 +783,8 @@ static void i40e_get_link_settings_link_up(struct i40e_hw *hw,
                                                             100baseT_Full);
                        if (hw_link_info->requested_speeds &
                            I40E_LINK_SPEED_100MB)
-                               ethtool_link_ksettings_add_link_mode(ks,
-                                                                advertising,
-                                                                100baseT_Full);
+                               ethtool_link_ksettings_add_link_mode(
+                                     ks, advertising, 100baseT_Full);
                }
                break;
        case I40E_PHY_TYPE_40GBASE_KR4:
@@ -1215,6 +795,10 @@ static void i40e_get_link_settings_link_up(struct i40e_hw *hw,
        case I40E_PHY_TYPE_1000BASE_KX:
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     40000baseKR4_Full);
+#ifdef HAVE_ETHTOOL_25G_BITS
+               ethtool_link_ksettings_add_link_mode(ks, supported,
+                                                    25000baseKR_Full);
+#endif
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     20000baseKR2_Full);
                ethtool_link_ksettings_add_link_mode(ks, supported,
@@ -1226,6 +810,10 @@ static void i40e_get_link_settings_link_up(struct i40e_hw *hw,
                ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
                ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                     40000baseKR4_Full);
+#ifdef HAVE_ETHTOOL_25G_BITS
+               ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                    25000baseKR_Full);
+#endif
                ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                     20000baseKR2_Full);
                ethtool_link_ksettings_add_link_mode(ks, advertising,
@@ -1235,12 +823,6 @@ static void i40e_get_link_settings_link_up(struct i40e_hw *hw,
                ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                     1000baseKX_Full);
                ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
-#ifdef HAVE_ETHTOOL_25G_BITS
-               ethtool_link_ksettings_add_link_mode(ks, supported,
-                                                    25000baseKR_Full);
-               ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                    25000baseKR_Full);
-#endif /* HAVE_ETHTOOL_25G_BITS */
                break;
        case I40E_PHY_TYPE_25GBASE_CR:
                ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
@@ -1278,22 +860,12 @@ static void i40e_get_link_settings_link_up(struct i40e_hw *hw,
        }
 
        /* Now that we've worked out everything that could be supported by the
-        * current phy type, get what is supported by the NVM and and them to
-        * get what is truly supported
+        * current PHY type, get what is supported by the NVM and intersect
+        * them to get what is truly supported
         */
        memset(&cap_ksettings, 0, sizeof(struct ethtool_link_ksettings));
-       cap_ksettings.base.cmd = ks->base.cmd;
-       cap_ksettings.base.link_mode_masks_nwords =
-                                          ks->base.link_mode_masks_nwords;
-       i40e_get_link_settings_link_down(hw, &cap_ksettings, pf);
-
-       for (idx = 0; idx < ETHTOOL_LINK_MODE_MASK_U32; idx++) {
-               ks->base.link_mode_masks[idx] &=
-                                       cap_ksettings.base.link_mode_masks[idx];
-               ks->base.link_mode_masks[idx + ETHTOOL_LINK_MODE_MASK_U32] &=
-                                       cap_ksettings.base.link_mode_masks[idx +
-                                       ETHTOOL_LINK_MODE_MASK_U32];
-       }
+       i40e_phy_type_to_ethtool(pf, &cap_ksettings);
+       ethtool_intersect_link_masks(ks, &cap_ksettings);
 
        /* Set speed and duplex */
        switch (link_speed) {
@@ -1322,34 +894,54 @@ static void i40e_get_link_settings_link_up(struct i40e_hw *hw,
 }
 
 /**
- * i40e_get_link_settings - Get Link Speed and Duplex settings
+ * i40e_get_settings_link_down - Get the Link settings when link is down
+ * @hw: hw structure
+ * @ks: ethtool ksettings to fill in
+ * @pf: pointer to physical function struct
+ *
+ * Reports link settings that can be determined when link is down
+ **/
+static void i40e_get_settings_link_down(struct i40e_hw *hw,
+                                       struct ethtool_link_ksettings *ks,
+                                       struct i40e_pf *pf)
+{
+       /* link is down and the driver needs to fall back on
+        * supported phy types to figure out what info to display
+        */
+       i40e_phy_type_to_ethtool(pf, ks);
+       /* With no link speed and duplex are unknown */
+       ks->base.speed = SPEED_UNKNOWN;
+       ks->base.duplex = DUPLEX_UNKNOWN;
+}
+
+/**
+ * i40e_get_link_ksettings - Get Link Speed and Duplex settings
  * @netdev: network interface device structure
- * @ksettings: ethtool command
+ * @ks: ethtool ksettings
  *
  * Reports speed/duplex settings based on media_type
  **/
-static int i40e_get_link_settings(struct net_device *netdev,
-                                 struct ethtool_link_ksettings *ks)
+static int i40e_get_link_ksettings(struct net_device *netdev,
+                                  struct ethtool_link_ksettings *ks)
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_pf *pf = np->vsi->back;
        struct i40e_hw *hw = &pf->hw;
        struct i40e_link_status *hw_link_info = &hw->phy.link_info;
        bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
-       struct ethtool_link_settings *settings = &ks->base;
 
        ethtool_link_ksettings_zero_link_mode(ks, supported);
        ethtool_link_ksettings_zero_link_mode(ks, advertising);
 
        if (link_up)
-               i40e_get_link_settings_link_up(hw, ks, netdev, pf);
+               i40e_get_settings_link_up(hw, ks, netdev, pf);
        else
-               i40e_get_link_settings_link_down(hw, ks, pf);
+               i40e_get_settings_link_down(hw, ks, pf);
 
        /* Now set the settings that don't rely on link being up/down */
        /* Set autoneg settings */
-       settings->autoneg = (hw_link_info->an_info & I40E_AQ_AN_COMPLETED ?
-                         AUTONEG_ENABLE : AUTONEG_DISABLE);
+       ks->base.autoneg = (hw_link_info->an_info & I40E_AQ_AN_COMPLETED ?
+                           AUTONEG_ENABLE : AUTONEG_DISABLE);
 
        /* Set media type settings */
        switch (hw->phy.media_type) {
@@ -1359,63 +951,330 @@ static int i40e_get_link_settings(struct net_device *netdev,
                ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
                ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                     Backplane);
-               settings->port = PORT_NONE;
+               ks->base.port = PORT_NONE;
                break;
        case I40E_MEDIA_TYPE_BASET:
                ethtool_link_ksettings_add_link_mode(ks, supported, TP);
                ethtool_link_ksettings_add_link_mode(ks, advertising, TP);
-               settings->port = PORT_TP;
+               ks->base.port = PORT_TP;
                break;
        case I40E_MEDIA_TYPE_DA:
        case I40E_MEDIA_TYPE_CX4:
                ethtool_link_ksettings_add_link_mode(ks, supported, FIBRE);
                ethtool_link_ksettings_add_link_mode(ks, advertising, FIBRE);
-               settings->port = PORT_DA;
+               ks->base.port = PORT_DA;
                break;
        case I40E_MEDIA_TYPE_FIBER:
                ethtool_link_ksettings_add_link_mode(ks, supported, FIBRE);
-               settings->port = PORT_FIBRE;
+               ks->base.port = PORT_FIBRE;
                break;
        case I40E_MEDIA_TYPE_UNKNOWN:
        default:
-               settings->port = PORT_OTHER;
+               ks->base.port = PORT_OTHER;
+               break;
+       }
+
+       /* Set flow control settings */
+       ethtool_link_ksettings_add_link_mode(ks, supported, Pause);
+
+       switch (hw->fc.requested_mode) {
+       case I40E_FC_FULL:
+               ethtool_link_ksettings_add_link_mode(ks, advertising, Pause);
+               break;
+       case I40E_FC_TX_PAUSE:
+               ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                    Asym_Pause);
+               break;
+       case I40E_FC_RX_PAUSE:
+               ethtool_link_ksettings_add_link_mode(ks, advertising, Pause);
+               ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                    Asym_Pause);
+               break;
+       default:
+               ethtool_link_ksettings_del_link_mode(ks, advertising, Pause);
+               ethtool_link_ksettings_del_link_mode(ks, advertising,
+                                                    Asym_Pause);
                break;
        }
+       return 0;
+}
+
+#ifdef ETHTOOL_GLINKSETTINGS
+/**
+ * i40e_set_link_ksettings - Set Speed and Duplex
+ * @netdev: network interface device structure
+ * @ks: ethtool ksettings
+ *
+ * Set speed/duplex per media_types advertised/forced
+ **/
+static int i40e_set_link_ksettings(struct net_device *netdev,
+                                  const struct ethtool_link_ksettings *ks)
+{
+       struct i40e_netdev_priv *np = netdev_priv(netdev);
+       struct i40e_aq_get_phy_abilities_resp abilities;
+       struct ethtool_link_ksettings safe_ks;
+       struct ethtool_link_ksettings copy_ks;
+       struct i40e_aq_set_phy_config config;
+       struct i40e_pf *pf = np->vsi->back;
+       struct i40e_vsi *vsi = np->vsi;
+       struct i40e_hw *hw = &pf->hw;
+       bool autoneg_changed = false;
+       i40e_status status = 0;
+       int timeout = 50;
+       int err = 0;
+       u8 autoneg;
+
+       /* Changing port settings is not supported if this isn't the
+        * port's controlling PF
+        */
+       if (hw->partition_id != 1) {
+               i40e_partition_setting_complaint(pf);
+               return -EOPNOTSUPP;
+       }
+       if (vsi != pf->vsi[pf->lan_vsi])
+               return -EOPNOTSUPP;
+       if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
+           hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
+           hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE &&
+           hw->phy.media_type != I40E_MEDIA_TYPE_DA &&
+           hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
+               return -EOPNOTSUPP;
+       if (hw->device_id == I40E_DEV_ID_KX_B ||
+           hw->device_id == I40E_DEV_ID_KX_C ||
+           hw->device_id == I40E_DEV_ID_20G_KR2 ||
+           hw->device_id == I40E_DEV_ID_20G_KR2_A) {
+               netdev_info(netdev, "Changing settings is not supported on backplane.\n");
+               return -EOPNOTSUPP;
+       }
+
+       /* copy the ksettings to copy_ks to avoid modifying the origin */
+       memcpy(&copy_ks, ks, sizeof(struct ethtool_link_ksettings));
+
+       /* save autoneg out of ksettings */
+       autoneg = copy_ks.base.autoneg;
+
+       memset(&safe_ks, 0, sizeof(safe_ks));
+       /* Get link modes supported by hardware and check against modes
+        * requested by user.  Return an error if unsupported mode was set.
+        */
+       i40e_phy_type_to_ethtool(pf, &safe_ks);
+       if (!bitmap_subset(copy_ks.link_modes.advertising,
+                          safe_ks.link_modes.supported,
+                          __ETHTOOL_LINK_MODE_MASK_NBITS))
+               return -EINVAL;
+
+       /* get our own copy of the bits to check against */
+       memset(&safe_ks, 0, sizeof(struct ethtool_link_ksettings));
+       safe_ks.base.cmd = copy_ks.base.cmd;
+       safe_ks.base.link_mode_masks_nwords =
+               copy_ks.base.link_mode_masks_nwords;
+       i40e_get_link_ksettings(netdev, &safe_ks);
+
+       /* set autoneg back to what it currently is */
+       copy_ks.base.autoneg = safe_ks.base.autoneg;
+
+       /* If copy_ks.base and safe_ks.base are not the same now, then they are
+        * trying to set something that we do not support.
+        */
+       if (memcmp(&copy_ks.base, &safe_ks.base,
+                  sizeof(struct ethtool_link_settings)))
+               return -EOPNOTSUPP;
+
+       while (test_and_set_bit(__I40E_CONFIG_BUSY, pf->state)) {
+               timeout--;
+               if (!timeout)
+                       return -EBUSY;
+               usleep_range(1000, 2000);
+       }
+
+       /* Get the current phy config */
+       status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
+                                             NULL);
+       if (status) {
+               err = -EAGAIN;
+               goto done;
+       }
+
+       /* Copy abilities to config in case autoneg is not
+        * set below
+        */
+       memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
+       config.abilities = abilities.abilities;
+
+       /* Check autoneg */
+       if (autoneg == AUTONEG_ENABLE) {
+               /* If autoneg was not already enabled */
+               if (!(hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED)) {
+                       /* If autoneg is not supported, return error */
+                       if (!ethtool_link_ksettings_test_link_mode(
+                                     &safe_ks, supported, Autoneg)) {
+                               netdev_info(netdev, "Autoneg not supported on this phy\n");
+                               err = -EINVAL;
+                               goto done;
+                       }
+                       /* Autoneg is allowed to change */
+                       config.abilities = abilities.abilities |
+                                          I40E_AQ_PHY_ENABLE_AN;
+                       autoneg_changed = true;
+               }
+       } else {
+               /* If autoneg is currently enabled */
+               if (hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED) {
+                       /* If autoneg is supported 10GBASE_T is the only PHY
+                        * that can disable it, so otherwise return error
+                        */
+                       if (ethtool_link_ksettings_test_link_mode(
+                                    &safe_ks, supported, Autoneg) &&
+                           hw->phy.link_info.phy_type !=
+                           I40E_PHY_TYPE_10GBASE_T) {
+                               netdev_info(netdev, "Autoneg cannot be disabled on this phy\n");
+                               err = -EINVAL;
+                               goto done;
+                       }
+                       /* Autoneg is allowed to change */
+                       config.abilities = abilities.abilities &
+                                          ~I40E_AQ_PHY_ENABLE_AN;
+                       autoneg_changed = true;
+               }
+       }
+
+       if (ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 100baseT_Full))
+               config.link_speed |= I40E_LINK_SPEED_100MB;
+       if (ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 1000baseT_Full) ||
+#ifdef HAVE_ETHTOOL_NEW_10G_BITS
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 1000baseX_Full) ||
+#endif
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 1000baseKX_Full))
+               config.link_speed |= I40E_LINK_SPEED_1GB;
+       if (ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 10000baseT_Full) ||
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 10000baseKX4_Full) ||
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 10000baseKR_Full) ||
+#ifdef HAVE_ETHTOOL_NEW_10G_BITS
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 10000baseCR_Full) ||
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 10000baseSR_Full))
+#else
+           0)
+#endif /* HAVE_ETHTOOL_NEW_10G_BITS */
+               config.link_speed |= I40E_LINK_SPEED_10GB;
+       if (ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 20000baseKR2_Full))
+               config.link_speed |= I40E_LINK_SPEED_20GB;
+#ifdef HAVE_ETHTOOL_25G_BITS
+       if (ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 25000baseCR_Full) ||
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 25000baseKR_Full) ||
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 25000baseSR_Full))
+               config.link_speed |= I40E_LINK_SPEED_25GB;
+#endif /* HAVE_ETHTOOL_25G_BITS */
+       if (ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 40000baseKR4_Full) ||
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 40000baseCR4_Full) ||
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 40000baseSR4_Full) ||
+           ethtool_link_ksettings_test_link_mode(ks, advertising,
+                                                 40000baseLR4_Full))
+               config.link_speed |= I40E_LINK_SPEED_40GB;
+
+       /* If speed didn't get set, set it to what it currently is.
+        * This is needed because if advertise is 0 (as it is when autoneg
+        * is disabled) then speed won't get set.
+        */
+       if (!config.link_speed)
+               config.link_speed = abilities.link_speed;
+       if (autoneg_changed || (abilities.link_speed != config.link_speed)) {
+               /* copy over the rest of the abilities */
+               config.phy_type = abilities.phy_type;
+               config.phy_type_ext = abilities.phy_type_ext;
+               config.eee_capability = abilities.eee_capability;
+               config.eeer = abilities.eeer_val;
+               config.low_power_ctrl = abilities.d3_lpan;
+               config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
+                                   I40E_AQ_PHY_FEC_CONFIG_MASK;
+
+               /* save the requested speeds */
+               hw->phy.link_info.requested_speeds = config.link_speed;
+               /* set link and auto negotiation so changes take effect */
+               config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
+               /* If link is up put link down */
+               if (hw->phy.link_info.link_info & I40E_AQ_LINK_UP) {
+                       /* Tell the OS link is going down, the link will go
+                        * back up when fw says it is ready asynchronously
+                        */
+                       i40e_print_link_message(vsi, false);
+                       netif_carrier_off(netdev);
+                       netif_tx_stop_all_queues(netdev);
+               }
+
+               /* make the aq call */
+               status = i40e_aq_set_phy_config(hw, &config, NULL);
+               if (status) {
+                       netdev_info(netdev,
+                                   "Set phy config failed, err %s aq_err %s\n",
+                                   i40e_stat_str(hw, status),
+                                   i40e_aq_str(hw, hw->aq.asq_last_status));
+                       err = -EAGAIN;
+                       goto done;
+               }
+
+               status = i40e_update_link_info(hw);
+               if (status)
+                       netdev_dbg(netdev,
+                                  "Updating link info failed with err %s aq_err %s\n",
+                                  i40e_stat_str(hw, status),
+                                  i40e_aq_str(hw, hw->aq.asq_last_status));
+
+       } else {
+               netdev_info(netdev, "Nothing changed, exiting without setting anything.\n");
+       }
 
-       /* Set flow control settings */
-       ethtool_link_ksettings_add_link_mode(ks, supported, Pause);
+done:
+       clear_bit(__I40E_CONFIG_BUSY, pf->state);
 
-       switch (hw->fc.requested_mode) {
-       case I40E_FC_FULL:
-               ethtool_link_ksettings_add_link_mode(ks, advertising, Pause);
-               break;
-       case I40E_FC_TX_PAUSE:
-               ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                    Asym_Pause);
-               break;
-       case I40E_FC_RX_PAUSE:
-               ethtool_link_ksettings_add_link_mode(ks, advertising, Pause);
-               ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                    Asym_Pause);
-               break;
-       default:
-               ethtool_link_ksettings_clear_link_mode(ks, advertising, Pause);
-               ethtool_link_ksettings_clear_link_mode(ks, advertising,
-                                                      Asym_Pause);
-               break;
-       }
+       return err;
+}
+
+#else /* ETHTOOL_GLINKSETTINGS */
+/**
+ * i40e_get_settings - Get Link Speed and Duplex settings
+ * @netdev: network interface device structure
+ * @ecmd: ethtool command
+ *
+ * Reports speed/duplex settings based on media_type.  Since we've backported
+ * the new API constructs to use in the old API, this ends up just being a
+ * wrapper to i40e_get_link_ksettings.
+ **/
+static int i40e_get_settings(struct net_device *netdev,
+                            struct ethtool_cmd *ecmd)
+{
+       struct ethtool_link_ksettings ks;
+
+       i40e_get_link_ksettings(netdev, &ks);
+       i40e_ethtool_ksettings_to_cmd(&ks, ecmd);
+       ecmd->transceiver = XCVR_EXTERNAL;
        return 0;
 }
 
 /**
- * i40e_set_link_settings - Set Speed and Duplex
+ * i40e_set_settings - Set Speed and Duplex
  * @netdev: network interface device structure
- * @ksettings_passed: ethtool command
+ * @ecmd: ethtool command
  *
  * Set speed/duplex per media_types advertised/forced
  **/
-static int i40e_set_link_settings(struct net_device *netdev,
-                         const struct ethtool_link_ksettings *ksettings_passed)
+static int i40e_set_settings(struct net_device *netdev,
+                            struct ethtool_cmd *ecmd)
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_aq_get_phy_abilities_resp abilities;
@@ -1423,21 +1282,14 @@ static int i40e_set_link_settings(struct net_device *netdev,
        struct i40e_pf *pf = np->vsi->back;
        struct i40e_vsi *vsi = np->vsi;
        struct i40e_hw *hw = &pf->hw;
-       struct ethtool_link_ksettings safe_ksettings;
+       struct ethtool_cmd safe_ecmd;
        i40e_status status = 0;
-       bool autoneg_changed = false;
+       bool change = false;
        int timeout = 50;
        int err = 0;
        u8 autoneg;
-       struct ethtool_link_ksettings ksettings_real, *ksettings;
-       u32 advertise[ETHTOOL_LINK_MODE_MASK_U32];
-       u32 safe_supported[ETHTOOL_LINK_MODE_MASK_U32];
-       int i;
-
-       ksettings = &ksettings_real;
-       memcpy(ksettings,
-              ksettings_passed,
-              sizeof(struct ethtool_link_ksettings));
+       u32 advertise;
+       u32 old_ethtool_advertising = 0;
 
        /* Changing port settings is not supported if this isn't the
         * port's controlling PF
@@ -1446,59 +1298,59 @@ static int i40e_set_link_settings(struct net_device *netdev,
                i40e_partition_setting_complaint(pf);
                return -EOPNOTSUPP;
        }
+
        if (vsi != pf->vsi[pf->lan_vsi])
                return -EOPNOTSUPP;
+
        if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
            hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
            hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE &&
            hw->phy.media_type != I40E_MEDIA_TYPE_DA &&
            hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
                return -EOPNOTSUPP;
+
        if (hw->device_id == I40E_DEV_ID_KX_B ||
            hw->device_id == I40E_DEV_ID_KX_C ||
            hw->device_id == I40E_DEV_ID_20G_KR2 ||
            hw->device_id == I40E_DEV_ID_20G_KR2_A) {
-               netdev_info(netdev,
-                           "Changing settings is not supported on backplane.\n");
+               netdev_info(netdev, "Changing settings is not supported on backplane.\n");
                return -EOPNOTSUPP;
        }
 
-       /* save autoneg and speed out of ksettings */
-       autoneg = ksettings->base.autoneg;
-       memcpy(advertise, &ksettings->link_modes.advertising,
-              sizeof(advertise));
-
-       memset(&safe_ksettings, 0, sizeof(safe_ksettings));
-       /* Get link modes supported by hardware... */
-       i40e_get_link_settings_link_down(hw, &safe_ksettings, pf);
-       memcpy(safe_supported, &safe_ksettings.link_modes.supported,
-              sizeof(safe_supported));
-       /* ...and check against modes requested by user.
-        * Return an error if unsupported mode was set.
-        */
-       for (i = 0; i < ETHTOOL_LINK_MODE_MASK_U32; i++) {
-               if ((advertise[i] & safe_supported[i]) != advertise[i])
-                       return -EINVAL;
-       }
-
        /* get our own copy of the bits to check against */
-       memset(&safe_ksettings, 0, sizeof(struct ethtool_link_ksettings));
-       safe_ksettings.base.cmd                    = ksettings->base.cmd;
-       safe_ksettings.base.link_mode_masks_nwords =
-               ksettings->base.link_mode_masks_nwords;
-       i40e_get_link_settings(netdev, &safe_ksettings);
+       memset(&safe_ecmd, 0, sizeof(struct ethtool_cmd));
+       i40e_get_settings(netdev, &safe_ecmd);
+
+       /* save autoneg and speed out of ecmd */
+       autoneg = ecmd->autoneg;
+       advertise = ecmd->advertising;
 
        /* set autoneg and speed back to what they currently are */
-       ksettings->base.autoneg = safe_ksettings.base.autoneg;
-       memcpy((void *)ksettings->link_modes.advertising,
-              safe_ksettings.link_modes.advertising,
-              sizeof(advertise));
+       ecmd->autoneg = safe_ecmd.autoneg;
+       ecmd->advertising = safe_ecmd.advertising;
+
+       /* Due to a bug in ethtool versions < 3.6 this check is necessary */
+       old_ethtool_advertising = ecmd->supported &
+                                 (ADVERTISED_10baseT_Half |
+                                  ADVERTISED_10baseT_Full |
+                                  ADVERTISED_100baseT_Half |
+                                  ADVERTISED_100baseT_Full |
+                                  ADVERTISED_1000baseT_Half |
+                                  ADVERTISED_1000baseT_Full |
+                                  ADVERTISED_2500baseX_Full |
+                                  ADVERTISED_10000baseT_Full);
+       old_ethtool_advertising |= (old_ethtool_advertising |
+                                  ADVERTISED_20000baseMLD2_Full |
+                                  ADVERTISED_20000baseKR2_Full);
 
-       /* If ksettings.base and safe_ksettings.base are not the same now,
-        * then they are trying to set something that we do not support.
+       if (advertise == old_ethtool_advertising)
+               netdev_info(netdev, "If you are not setting advertising to %x then you may have an old version of ethtool. Please update.\n",
+                           advertise);
+       ecmd->cmd = safe_ecmd.cmd;
+       /* If ecmd and safe_ecmd are not the same now, then they are
+        * trying to set something that we do not support
         */
-       if (memcmp(&ksettings->base, &safe_ksettings.base,
-                  sizeof(struct ethtool_link_settings)))
+       if (memcmp(ecmd, &safe_ecmd, sizeof(struct ethtool_cmd)))
                return -EOPNOTSUPP;
 
        while (test_and_set_bit(__I40E_CONFIG_BUSY, pf->state)) {
@@ -1527,17 +1379,15 @@ static int i40e_set_link_settings(struct net_device *netdev,
                /* If autoneg was not already enabled */
                if (!(hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED)) {
                        /* If autoneg is not supported, return error */
-                       if (!(safe_ksettings.link_modes.supported[0] &
-                             SUPPORTED_Autoneg)) {
-                               netdev_info(netdev,
-                                           "Autoneg not supported on this phy\n");
+                       if (!(safe_ecmd.supported & SUPPORTED_Autoneg)) {
+                               netdev_info(netdev, "Autoneg not supported on this phy\n");
                                err = -EINVAL;
                                goto done;
                        }
                        /* Autoneg is allowed to change */
                        config.abilities = abilities.abilities |
                                           I40E_AQ_PHY_ENABLE_AN;
-                       autoneg_changed = true;
+                       change = true;
                }
        } else {
                /* If autoneg is currently enabled */
@@ -1545,59 +1395,40 @@ static int i40e_set_link_settings(struct net_device *netdev,
                        /* If autoneg is supported 10GBASE_T is the only phy
                         * that can disable it, so otherwise return error
                         */
-                       if (safe_ksettings.link_modes.supported[0] &
-                           SUPPORTED_Autoneg &&
+                       if (safe_ecmd.supported & SUPPORTED_Autoneg &&
                            hw->phy.link_info.phy_type !=
                            I40E_PHY_TYPE_10GBASE_T) {
-                               netdev_info(netdev,
-                                           "Autoneg cannot be disabled on this phy\n");
+                               netdev_info(netdev, "Autoneg cannot be disabled on this phy\n");
                                err = -EINVAL;
                                goto done;
                        }
                        /* Autoneg is allowed to change */
                        config.abilities = abilities.abilities &
                                           ~I40E_AQ_PHY_ENABLE_AN;
-                       autoneg_changed = true;
+                       change = true;
                }
        }
 
-       if (advertise[0] & ADVERTISED_100baseT_Full)
+       if (advertise & ~safe_ecmd.supported) {
+               err = -EINVAL;
+               goto done;
+       }
+
+       if (advertise & ADVERTISED_100baseT_Full)
                config.link_speed |= I40E_LINK_SPEED_100MB;
-       if (advertise[0] & ADVERTISED_1000baseT_Full ||
-           advertise[0] & ADVERTISED_1000baseKX_Full)
-               config.link_speed |= I40E_LINK_SPEED_1GB;
-       if (advertise[0] & ADVERTISED_10000baseT_Full ||
-           advertise[0] & ADVERTISED_10000baseKX4_Full ||
-           advertise[0] & ADVERTISED_10000baseKR_Full)
-               config.link_speed |= I40E_LINK_SPEED_10GB;
-#ifdef HAVE_ETHTOOL_NEW_10G_BITS
-       if (ethtool_link_ksettings_test_link_mode(ksettings_passed, advertising,
-                                                 1000baseX_Full))
+       if (advertise & ADVERTISED_1000baseT_Full ||
+           advertise & ADVERTISED_1000baseKX_Full)
                config.link_speed |= I40E_LINK_SPEED_1GB;
-
-       if (ethtool_link_ksettings_test_link_mode(ksettings_passed, advertising,
-                                                 10000baseCR_Full) ||
-           ethtool_link_ksettings_test_link_mode(ksettings_passed, advertising,
-                                                 10000baseKR_Full) ||
-           ethtool_link_ksettings_test_link_mode(ksettings_passed, advertising,
-                                                 10000baseSR_Full))
+       if (advertise & ADVERTISED_10000baseT_Full ||
+           advertise & ADVERTISED_10000baseKX4_Full ||
+           advertise & ADVERTISED_10000baseKR_Full)
                config.link_speed |= I40E_LINK_SPEED_10GB;
-#endif /* HAVE_ETHTOOL_NEW_10G_BITS */
-       if (advertise[0] & ADVERTISED_20000baseKR2_Full)
+       if (advertise & ADVERTISED_20000baseKR2_Full)
                config.link_speed |= I40E_LINK_SPEED_20GB;
-#ifdef HAVE_ETHTOOL_25G_BITS
-       if (ethtool_link_ksettings_test_link_mode(ksettings_passed, advertising,
-                                                 25000baseCR_Full) ||
-           ethtool_link_ksettings_test_link_mode(ksettings_passed, advertising,
-                                                 25000baseKR_Full) ||
-           ethtool_link_ksettings_test_link_mode(ksettings_passed, advertising,
-                                                 25000baseSR_Full))
-               config.link_speed |= I40E_LINK_SPEED_25GB;
-#endif /* HAVE_ETHTOOL_25G_BITS */
-       if (advertise[0] & ADVERTISED_40000baseKR4_Full ||
-           advertise[0] & ADVERTISED_40000baseCR4_Full ||
-           advertise[0] & ADVERTISED_40000baseSR4_Full ||
-           advertise[0] & ADVERTISED_40000baseLR4_Full)
+       if (advertise & ADVERTISED_40000baseKR4_Full ||
+           advertise & ADVERTISED_40000baseCR4_Full ||
+           advertise & ADVERTISED_40000baseSR4_Full ||
+           advertise & ADVERTISED_40000baseLR4_Full)
                config.link_speed |= I40E_LINK_SPEED_40GB;
 
        /* If speed didn't get set, set it to what it currently is.
@@ -1606,7 +1437,8 @@ static int i40e_set_link_settings(struct net_device *netdev,
         */
        if (!config.link_speed)
                config.link_speed = abilities.link_speed;
-       if (autoneg_changed || (abilities.link_speed != config.link_speed)) {
+
+       if (change || abilities.link_speed != config.link_speed) {
                /* copy over the rest of the abilities */
                config.phy_type = abilities.phy_type;
                config.phy_type_ext = abilities.phy_type_ext;
@@ -1633,22 +1465,21 @@ static int i40e_set_link_settings(struct net_device *netdev,
                /* make the aq call */
                status = i40e_aq_set_phy_config(hw, &config, NULL);
                if (status) {
-                       netdev_info(netdev,
-                                   "Set phy config failed, err %s aq_err %s\n",
+                       netdev_info(netdev, "Set phy config failed, err %s aq_err %s\n",
                                    i40e_stat_str(hw, status),
                                    i40e_aq_str(hw, hw->aq.asq_last_status));
                        err = -EAGAIN;
                        goto done;
                }
+
                status = i40e_update_link_info(hw);
                if (status)
-                       netdev_dbg(netdev,
-                                  "Updating link info failed with err %s aq_err %s\n",
+                       netdev_dbg(netdev, "Updating link info failed with err %s aq_err %s\n",
                                   i40e_stat_str(hw, status),
                                   i40e_aq_str(hw, hw->aq.asq_last_status));
+
        } else {
-               netdev_info(netdev,
-                           "Nothing changed, exiting without setting anything.\n");
+               netdev_info(netdev, "Nothing changed, exiting without setting anything.\n");
        }
 
 done:
@@ -2298,7 +2129,7 @@ static int i40e_set_ringparam(struct net_device *netdev,
                        if (err)
                                goto rx_unwind;
 
-                       /* now allocate the rx buffers to make sure the OS
+                       /* now allocate the Rx buffers to make sure the OS
                         * has enough memory, any failure here means abort
                         */
                        ring = &rx_rings[i];
@@ -2447,7 +2278,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
        }
        rcu_read_lock();
        for (j = 0; j < vsi->num_queue_pairs; j++) {
-               tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
+               tx_ring = READ_ONCE(vsi->tx_rings[j]);
 
                if (!tx_ring)
                        continue;
@@ -3033,14 +2864,14 @@ static int __i40e_get_coalesce(struct net_device *netdev,
        rx_ring = vsi->rx_rings[queue];
        tx_ring = vsi->tx_rings[queue];
 
-       if (ITR_IS_DYNAMIC(rx_ring->rx_itr_setting))
+       if (ITR_IS_DYNAMIC(rx_ring->itr_setting))
                ec->use_adaptive_rx_coalesce = 1;
 
-       if (ITR_IS_DYNAMIC(tx_ring->tx_itr_setting))
+       if (ITR_IS_DYNAMIC(tx_ring->itr_setting))
                ec->use_adaptive_tx_coalesce = 1;
 
-       ec->rx_coalesce_usecs = rx_ring->rx_itr_setting & ~I40E_ITR_DYNAMIC;
-       ec->tx_coalesce_usecs = tx_ring->tx_itr_setting & ~I40E_ITR_DYNAMIC;
+       ec->rx_coalesce_usecs = rx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
+       ec->tx_coalesce_usecs = tx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
 
        /* we use the _usecs_high to store/set the interrupt rate limit
         * that the hardware supports, that almost but not quite
@@ -3097,37 +2928,40 @@ static void i40e_set_itr_per_queue(struct i40e_vsi *vsi,
                                   struct ethtool_coalesce *ec,
                                   int queue)
 {
+       struct i40e_ring *rx_ring = vsi->rx_rings[queue];
+       struct i40e_ring *tx_ring = vsi->tx_rings[queue];
        struct i40e_pf *pf = vsi->back;
        struct i40e_hw *hw = &pf->hw;
        struct i40e_q_vector *q_vector;
-       u16 vector, intrl;
+       u16 intrl;
 
        intrl = i40e_intrl_usec_to_reg(vsi->int_rate_limit);
 
-       vsi->rx_rings[queue]->rx_itr_setting = ec->rx_coalesce_usecs;
-       vsi->tx_rings[queue]->tx_itr_setting = ec->tx_coalesce_usecs;
+       rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs);
+       tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs);
 
        if (ec->use_adaptive_rx_coalesce)
-               vsi->rx_rings[queue]->rx_itr_setting |= I40E_ITR_DYNAMIC;
+               rx_ring->itr_setting |= I40E_ITR_DYNAMIC;
        else
-               vsi->rx_rings[queue]->rx_itr_setting &= ~I40E_ITR_DYNAMIC;
+               rx_ring->itr_setting &= ~I40E_ITR_DYNAMIC;
 
        if (ec->use_adaptive_tx_coalesce)
-               vsi->tx_rings[queue]->tx_itr_setting |= I40E_ITR_DYNAMIC;
+               tx_ring->itr_setting |= I40E_ITR_DYNAMIC;
        else
-               vsi->tx_rings[queue]->tx_itr_setting &= ~I40E_ITR_DYNAMIC;
+               tx_ring->itr_setting &= ~I40E_ITR_DYNAMIC;
+
+       q_vector = rx_ring->q_vector;
+       q_vector->rx.target_itr = ITR_TO_REG(rx_ring->itr_setting);
 
-       q_vector = vsi->rx_rings[queue]->q_vector;
-       q_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[queue]->rx_itr_setting);
-       vector = vsi->base_vector + q_vector->v_idx;
-       wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1), q_vector->rx.itr);
+       q_vector = tx_ring->q_vector;
+       q_vector->tx.target_itr = ITR_TO_REG(tx_ring->itr_setting);
 
-       q_vector = vsi->tx_rings[queue]->q_vector;
-       q_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[queue]->tx_itr_setting);
-       vector = vsi->base_vector + q_vector->v_idx;
-       wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1), q_vector->tx.itr);
+       /* The interrupt handler itself will take care of programming
+        * the Tx and Rx ITR values based on the values we have entered
+        * into the q_vector, no need to write the values now.
+        */
 
-       wr32(hw, I40E_PFINT_RATEN(vector - 1), intrl);
+       wr32(hw, I40E_PFINT_RATEN(q_vector->reg_idx), intrl);
        i40e_flush(hw);
 }
 
@@ -3153,11 +2987,11 @@ static int __i40e_set_coalesce(struct net_device *netdev,
                vsi->work_limit = ec->tx_max_coalesced_frames_irq;
 
        if (queue < 0) {
-               cur_rx_itr = vsi->rx_rings[0]->rx_itr_setting;
-               cur_tx_itr = vsi->tx_rings[0]->tx_itr_setting;
+               cur_rx_itr = vsi->rx_rings[0]->itr_setting;
+               cur_tx_itr = vsi->tx_rings[0]->itr_setting;
        } else if (queue < vsi->num_queue_pairs) {
-               cur_rx_itr = vsi->rx_rings[queue]->rx_itr_setting;
-               cur_tx_itr = vsi->tx_rings[queue]->tx_itr_setting;
+               cur_rx_itr = vsi->rx_rings[queue]->itr_setting;
+               cur_tx_itr = vsi->tx_rings[queue]->itr_setting;
        } else {
                netif_info(pf, drv, netdev, "Invalid queue value, queue range is 0 - %d\n",
                           vsi->num_queue_pairs - 1);
@@ -3185,7 +3019,7 @@ static int __i40e_set_coalesce(struct net_device *netdev,
                return -EINVAL;
        }
 
-       if (ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1)) {
+       if (ec->rx_coalesce_usecs > I40E_MAX_ITR) {
                netif_info(pf, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n");
                return -EINVAL;
        }
@@ -3196,16 +3030,16 @@ static int __i40e_set_coalesce(struct net_device *netdev,
                return -EINVAL;
        }
 
-       if (ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1)) {
+       if (ec->tx_coalesce_usecs > I40E_MAX_ITR) {
                netif_info(pf, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n");
                return -EINVAL;
        }
 
        if (ec->use_adaptive_rx_coalesce && !cur_rx_itr)
-               ec->rx_coalesce_usecs = I40E_MIN_ITR << 1;
+               ec->rx_coalesce_usecs = I40E_MIN_ITR;
 
        if (ec->use_adaptive_tx_coalesce && !cur_tx_itr)
-               ec->tx_coalesce_usecs = I40E_MIN_ITR << 1;
+               ec->tx_coalesce_usecs = I40E_MIN_ITR;
 
        intrl_reg = i40e_intrl_usec_to_reg(ec->rx_coalesce_usecs_high);
        vsi->int_rate_limit = INTRL_REG_TO_USEC(intrl_reg);
@@ -3348,13 +3182,14 @@ static int i40e_get_rss_hash_opts(struct i40e_pf *pf, struct ethtool_rxnfc *cmd)
        return 0;
 }
 
-/* i40e_check_mask - Check whether a mask field is set
+/**
+ * i40e_check_mask - Check whether a mask field is set
  * @mask: the full mask value
  * @field; mask of the field to check
  *
  * If the given mask is fully set, return positive value. If the mask for the
  * field is fully unset, return zero. Otherwise return a negative error code.
- */
+ **/
 static int i40e_check_mask(u64 mask, u64 field)
 {
        u64 value = mask & field;
@@ -3367,7 +3202,8 @@ static int i40e_check_mask(u64 mask, u64 field)
                return -1;
 }
 
-/* i40e_parse_rx_flow_user_data - Deconstruct user-defined data
+/**
+ * i40e_parse_rx_flow_user_data - Deconstruct user-defined data
  * @fsp: pointer to rx flow specification
  * @data: pointer to userdef data structure for storage
  *
@@ -3383,9 +3219,8 @@ static int i40e_check_mask(u64 mask, u64 field)
  * Returns 0 if the data is valid, and non-zero if the userdef data is invalid
  * and the filter should be rejected. The data structure will always be
  * modified even if FLOW_EXT is not set.
-
  *
- */
+ **/
 static int i40e_parse_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp,
                                        struct i40e_rx_flow_userdef *data)
 {
@@ -3447,12 +3282,13 @@ static int i40e_parse_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp,
        return 0;
 }
 
-/* i40e_fill_rx_flow_user_data - Fill in user-defined data field
+/**
+ * i40e_fill_rx_flow_user_data - Fill in user-defined data field
  * @fsp: pointer to rx_flow specification
  *
  * Reads the userdef data structure and properly fills in the user defined
  * fields of the rx_flow_spec.
- */
+ **/
 static void i40e_fill_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp,
                                        struct i40e_rx_flow_userdef *data)
 {
@@ -3607,16 +3443,16 @@ static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf,
 
 no_input_set:
        if (input_set & I40E_L3_SRC_MASK)
-               fsp->m_u.tcp_ip4_spec.ip4src = htonl(0xFFFF);
+               fsp->m_u.tcp_ip4_spec.ip4src = htonl(0xFFFFFFFF);
 
        if (input_set & I40E_L3_DST_MASK)
-               fsp->m_u.tcp_ip4_spec.ip4dst = htonl(0xFFFF);
+               fsp->m_u.tcp_ip4_spec.ip4dst = htonl(0xFFFFFFFF);
 
        if (input_set & I40E_L4_SRC_MASK)
-               fsp->m_u.tcp_ip4_spec.psrc = htons(0xFFFFFFFF);
+               fsp->m_u.tcp_ip4_spec.psrc = htons(0xFFFF);
 
        if (input_set & I40E_L4_DST_MASK)
-               fsp->m_u.tcp_ip4_spec.pdst = htons(0xFFFFFFFF);
+               fsp->m_u.tcp_ip4_spec.pdst = htons(0xFFFF);
 
        if (rule->dest_ctl == I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET)
                fsp->ring_cookie = RX_CLS_FLOW_DISC;
@@ -3994,6 +3830,10 @@ static int i40e_cloud_filter_mask2flags(struct i40e_pf *pf,
                break;
 
        case IP_USER_FLOW:
+               if (pf->hw.mac.type == I40E_MAC_X722) {
+                       dev_info(&pf->pdev->dev, "Failed to set filter. Destination IP filters are not supported for this device.\n");
+                       return I40E_ERR_CONFIG;
+               }
                if (fsp->m_u.usr_ip4_spec.ip4dst == cpu_to_be32(0xffffffff)) {
                        i |= I40E_CLOUD_FIELD_IIP;
                } else if (!fsp->m_u.usr_ip4_spec.ip4dst) {
@@ -4037,6 +3877,13 @@ static int i40e_cloud_filter_mask2flags(struct i40e_pf *pf,
                        i |= I40E_CLOUD_FIELD_TEN_ID;
        }
 
+       /* Make sure the flags produce a valid type */
+       if (i40e_get_cloud_filter_type(i, NULL)) {
+               dev_info(&pf->pdev->dev, "Invalid mask config, flags = %d\n",
+                        i);
+               return I40E_ERR_CONFIG;
+       }
+
        *flags = i;
        return I40E_SUCCESS;
 }
@@ -4106,11 +3953,8 @@ static int i40e_add_cloud_filter_ethtool(struct i40e_vsi *vsi,
        q_index = ring;
 
        ret = i40e_cloud_filter_mask2flags(pf, fsp, userdef, &flags);
-       if (ret || !flags) {
-               dev_info(&pf->pdev->dev, "Invalid mask config, flags = %d\n",
-                        flags);
+       if (ret)
                return -EINVAL;
-       }
 
        /* if filter exists with same id, delete the old one */
        parent = NULL;
@@ -4131,13 +3975,7 @@ static int i40e_add_cloud_filter_ethtool(struct i40e_vsi *vsi,
                /* found it in the cloud list, so remove it */
                ret = i40e_add_del_cloud_filter(pf, filter, false);
                if (ret && (pf->hw.aq.asq_last_status != I40E_AQ_RC_ENOENT)) {
-                       dev_info(&pf->pdev->dev,
-                                "fail to delete old cloud filter, err %s, aq_err %s\n",
-                                i40e_stat_str(&pf->hw, ret),
-                                i40e_aq_str(&pf->hw,
-                                            pf->hw.aq.asq_last_status));
-                       return i40e_aq_rc_to_posix(ret,
-                                                  pf->hw.aq.asq_last_status);
+                       return ret;
                }
                hlist_del(&filter->cloud_node);
                kfree(filter);
@@ -4193,12 +4031,7 @@ static int i40e_add_cloud_filter_ethtool(struct i40e_vsi *vsi,
        ret = i40e_add_del_cloud_filter(pf, filter, true);
        if (ret) {
                kfree(filter);
-               dev_info(&pf->pdev->dev,
-                        "fail to add cloud filter, err %s aq_err %s\n",
-                        i40e_stat_str(&pf->hw, ret),
-                        i40e_aq_str(&pf->hw,
-                                    pf->hw.aq.asq_last_status));
-               return i40e_aq_rc_to_posix(ret, pf->hw.aq.asq_last_status);
+               return ret;
        }
 
        /* add filter to the ordered list */
@@ -4313,13 +4146,14 @@ static int i40e_update_ethtool_fdir_entry(struct i40e_vsi *vsi,
        return 0;
 }
 
-/** i40e_prune_flex_pit_list - Cleanup unused entries in FLX_PIT table
+/**
+ * i40e_prune_flex_pit_list - Cleanup unused entries in FLX_PIT table
  * @pf: pointer to PF structure
  *
  * This function searches the list of filters and determines which FLX_PIT
  * entries are still required. It will prune any entries which are no longer
  * in use after the deletion.
- */
+ **/
 static void i40e_prune_flex_pit_list(struct i40e_pf *pf)
 {
        struct i40e_flex_pit *entry, *tmp;
@@ -4408,14 +4242,15 @@ static int i40e_del_fdir_entry(struct i40e_vsi *vsi,
        return ret;
 }
 
-/* i40e_unused_pit_index - Find an unused PIT index for given list
+/**
+ * i40e_unused_pit_index - Find an unused PIT index for given list
  * @pf: the PF data structure
  *
  * Find the first unused flexible PIT index entry. We search both the L3 and
  * L4 flexible PIT lists so that the returned index is unique and unused by
  * either currently programmed L3 or L4 filters. We use a bit field as storage
  * to track which indexes are already used.
- */
+ **/
 static u8 i40e_unused_pit_index(struct i40e_pf *pf)
 {
        unsigned long available_index = 0xFF;
@@ -4435,14 +4270,15 @@ static u8 i40e_unused_pit_index(struct i40e_pf *pf)
        return find_first_bit(&available_index, 8);
 }
 
-/* i40e_find_flex_offset - Find an existing flex src_offset
+/**
+ * i40e_find_flex_offset - Find an existing flex src_offset
  * @flex_pit_list: L3 or L4 flex PIT list
  * @src_offset: new src_offset to find
  *
  * Searches the flex_pit_list for an existing offset. If no offset is
  * currently programmed, then this will return an ERR_PTR if there is no space
  * to add a new offset, otherwise it returns NULL.
- */
+ **/
 static
 struct i40e_flex_pit *i40e_find_flex_offset(struct list_head *flex_pit_list,
                                            u16 src_offset)
@@ -4470,7 +4306,8 @@ struct i40e_flex_pit *i40e_find_flex_offset(struct list_head *flex_pit_list,
        return NULL;
 }
 
-/* i40e_add_flex_offset - Add src_offset to flex PIT table list
+/**
+ * i40e_add_flex_offset - Add src_offset to flex PIT table list
  * @flex_pit_list: L3 or L4 flex PIT list
  * @src_offset: new src_offset to add
  * @pit_index: the PIT index to program
@@ -4481,7 +4318,7 @@ struct i40e_flex_pit *i40e_find_flex_offset(struct list_head *flex_pit_list,
  * store another offset.
  *
  * Returns 0 on success, and negative value on error.
- */
+ **/
 static int i40e_add_flex_offset(struct list_head *flex_pit_list,
                                u16 src_offset,
                                u8 pit_index)
@@ -4624,7 +4461,7 @@ static void __i40e_reprogram_flex_pit(struct i40e_pf *pf,
  *
  * This function reprograms both the L3 and L4 FLX_PIT tables. See the
  * internal helper function for implementation details.
- */
+ **/
 static void i40e_reprogram_flex_pit(struct i40e_pf *pf)
 {
        __i40e_reprogram_flex_pit(pf, &pf->l3_flex_pit_list,
@@ -4668,12 +4505,13 @@ static const char *i40e_flow_str(struct ethtool_rx_flow_spec *fsp)
        }
 }
 
-/* i40e_pit_index_to_mask - Return the FLEX mask for a given PIT index
+/**
+ * i40e_pit_index_to_mask - Return the FLEX mask for a given PIT index
  * @pit_index: PIT index to convert
  *
  * Returns the mask for a given PIT index. Will return 0 if the pit_index is
  * of range.
- */
+ **/
 static u64 i40e_pit_index_to_mask(int pit_index)
 {
        switch (pit_index) {
@@ -5061,6 +4899,16 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
 
        i40e_write_fd_input_set(pf, index, new_mask);
 
+       /* IP_USER_FLOW filters match both IPv4/Other and IPv4/Fragmented
+        * frames. If we're programming the input set for IPv4/Other, we also
+        * need to program the IPv4/Fragmented input set. Since we don't have
+        * separate support, we'll always assume and enforce that the two flow
+        * types must have matching input sets.
+        */
+       if (index == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER)
+               i40e_write_fd_input_set(pf, I40E_FILTER_PCTYPE_FRAG_IPV4,
+                                       new_mask);
+
        /* Add the new offset and update table, if necessary */
        if (new_flex_offset) {
                err = i40e_add_flex_offset(&pf->l4_flex_pit_list, src_offset,
@@ -5082,6 +4930,87 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
        return 0;
 }
 
+/**
+ * i40e_match_fdir_filter - Return true of two filters match
+ * @a: pointer to filter struct
+ * @b: pointer to filter struct
+ *
+ * Returns true if the two filters match exactly the same criteria. I.e. they
+ * match the same flow type and have the same parameters. We don't need to
+ * check any input-set since all filters of the same flow type must use the
+ * same input set.
+ **/
+static bool i40e_match_fdir_filter(struct i40e_fdir_filter *a,
+                                  struct i40e_fdir_filter *b)
+{
+       /* The filters do not much if any of these criteria differ. */
+       if (a->dst_ip != b->dst_ip ||
+           a->src_ip != b->src_ip ||
+           a->dst_port != b->dst_port ||
+           a->src_port != b->src_port ||
+           a->flow_type != b->flow_type ||
+           a->ip4_proto != b->ip4_proto)
+               return false;
+
+       return true;
+}
+
+/**
+ * i40e_disallow_matching_filters - Check that new filters differ
+ * @vsi: pointer to the targeted VSI
+ * @input: new filter to check
+ *
+ * Due to hardware limitations, it is not possible for two filters that match
+ * similar criteria to be programmed at the same time. This is true for a few
+ * reasons:
+ *
+ * (a) all filters matching a particular flow type must use the same input
+ * set, that is they must match the same criteria.
+ * (b) different flow types will never match the same packet, as the flow type
+ * is decided by hardware before checking which rules apply.
+ * (c) hardware has no way to distinguish which order filters apply in.
+ *
+ * Due to this, we can't really support using the location data to order
+ * filters in the hardware parsing. It is technically possible for the user to
+ * request two filters matching the same criteria but which select different
+ * queues. In this case, rather than keep both filters in the list, we reject
+ * the 2nd filter when the user requests adding it.
+ *
+ * This avoids needing to track location for programming the filter to
+ * hardware, and ensures that we avoid some strange scenarios involving
+ * deleting filters which match the same criteria.
+ **/
+static int i40e_disallow_matching_filters(struct i40e_vsi *vsi,
+                                         struct i40e_fdir_filter *input)
+{
+       struct i40e_pf *pf = vsi->back;
+       struct i40e_fdir_filter *rule;
+       struct hlist_node *node2;
+
+       /* Loop through every filter, and check that it doesn't match */
+       hlist_for_each_entry_safe(rule, node2,
+                                 &pf->fdir_filter_list, fdir_node) {
+               /* Don't check the filters match if they share the same fd_id,
+                * since the new filter is actually just updating the target
+                * of the old filter.
+                */
+               if (rule->fd_id == input->fd_id)
+                       continue;
+
+               /* If any filters match, then print a warning message to the
+                * kernel message buffer and bail out.
+                */
+               if (i40e_match_fdir_filter(rule, input)) {
+                       dev_warn(&pf->pdev->dev,
+                                "Existing user defined filter %d already matches this flow.\n",
+                                rule->fd_id);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 /**
  * i40e_add_fdir_ethtool - Add/Remove Flow Director filters
  * @vsi: pointer to the targeted VSI
@@ -5194,20 +5123,29 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
                input->flex_offset = userdef.flex_offset;
        }
 
-       ret = i40e_add_del_fdir(vsi, input, true);
+       /* Avoid programming two filters with identical match criteria. */
+       ret = i40e_disallow_matching_filters(vsi, input);
        if (ret)
-               goto free_input;
+               goto free_filter_memory;
 
        /* Add the input filter to the fdir_filter_list, possibly replacing
         * a previous filter. Do not free the input structure after adding it
         * to the list as this would cause a use after free bug.
         */
-       (void)i40e_del_cloud_filter_ethtool(pf, cmd);
        i40e_update_ethtool_fdir_entry(vsi, input, fsp->location);
 
+       (void)i40e_del_cloud_filter_ethtool(pf, cmd);
+       ret = i40e_add_del_fdir(vsi, input, true);
+
+       if (ret)
+               goto remove_sw_rule;
+
        return 0;
 
-free_input:
+remove_sw_rule:
+       hlist_del(&input->fdir_node);
+       pf->fdir_pf_active_filters--;
+free_filter_memory:
        kfree(input);
        return ret;
 }
@@ -5388,8 +5326,10 @@ static u32 i40e_get_rxfh_indir_size(struct net_device *netdev)
  * @netdev: network interface device structure
  * @indir: indirection table
  * @key: hash key
+ * @hfunc: hash function
  *
- * Reads the indirection table directly from the hardware. Always returns 0.
+ * Reads the indirection table directly from the hardware. Returns 0 on
+ * success.
  **/
 #ifdef HAVE_RXFH_HASHFUNC
 static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
@@ -5413,15 +5353,12 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
                return 0;
 
        seed = key;
-
        lut = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL);
        if (!lut)
                return -ENOMEM;
-
        ret = i40e_get_rss(vsi, seed, lut, I40E_HLUT_ARRAY_SIZE);
        if (ret)
                goto out;
-
        for (i = 0; i < I40E_HLUT_ARRAY_SIZE; i++)
                indir[i] = (u32)(lut[i]);
 
@@ -5481,7 +5418,6 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
                memcpy(vsi->rss_hkey_user, key, I40E_HKEY_ARRAY_SIZE);
                seed = vsi->rss_hkey_user;
        }
-
        if (!vsi->rss_lut_user) {
                vsi->rss_lut_user = kzalloc(I40E_HLUT_ARRAY_SIZE, GFP_KERNEL);
                if (!vsi->rss_lut_user)
@@ -5595,6 +5531,8 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
        }
 
 flags_complete:
+       changed_flags = orig_flags ^ new_flags;
+
        /* Before we finalize any flag changes, we need to perform some
         * checks to ensure that the changes are supported and safe.
         */
@@ -5604,11 +5542,38 @@ flags_complete:
            !(pf->hw_features & I40E_HW_ATR_EVICT_CAPABLE))
                return -EOPNOTSUPP;
 
+       /* If the driver detected FW LLDP was disabled on init, this flag could
+        * be set, however we do not support _changing_ the flag if NPAR is
+        * enabled or FW API version < 1.7.  There are situations where older
+        * FW versions/NPAR enabled PFs could disable LLDP, however we _must_
+        * not allow the user to enable/disable LLDP with this flag on
+        * unsupported FW verions.
+        */
+       if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
+               if (pf->hw.func_caps.npar_enable) {
+                       dev_warn(&pf->pdev->dev,
+                                "Unable to change FW LLDP if NPAR active\n");
+                       return -EOPNOTSUPP;
+               }
+
+               if (pf->hw.aq.api_maj_ver < 1 ||
+                   (pf->hw.aq.api_maj_ver == 1 &&
+                    pf->hw.aq.api_min_ver < 7)) {
+                       dev_warn(&pf->pdev->dev,
+                                "FW ver does not support changing FW LLDP\n");
+                       return -EOPNOTSUPP;
+               }
+       }
+
        /* Compare and exchange the new flags into place. If we failed, that
-        * is if cmpxchg64 returns anything but the old value, this means that
+        * is if cmpxchg returns anything but the old value, this means that
         * something else has modified the flags variable since we copied it
         * originally. We'll just punt with an error and log something in the
         * message buffer.
+        *
+        * This is the point of no return for this function.  We need to have
+        * checked any discrepencies or misconfigurations and returned
+        * EOPNOTSUPP before updating pf->flags here.
         */
        if (cmpxchg64(&pf->flags, orig_flags, new_flags) != orig_flags) {
                dev_warn(&pf->pdev->dev,
@@ -5616,8 +5581,6 @@ flags_complete:
                return -EAGAIN;
        }
 
-       changed_flags = orig_flags ^ new_flags;
-
        /* Process any additional changes needed as a result of flag changes.
         * The changed_flags value reflects the list of bits that were
         * changed in the code above.
@@ -5649,12 +5612,43 @@ flags_complete:
                }
        }
 
+       if ((changed_flags & pf->flags &
+            I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
+           (pf->flags & I40E_FLAG_MFP_ENABLED))
+               dev_warn(&pf->pdev->dev,
+                        "Turning on link-down-on-close flag may affect other partitions\n");
+
+       if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
+               if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) {
+                       struct i40e_dcbx_config *dcbcfg;
+                       int i;
+
+                       i40e_aq_stop_lldp(&pf->hw, true, NULL);
+                       i40e_aq_set_dcb_parameters(&pf->hw, true, NULL);
+                       /* reset local_dcbx_config to default */
+                       dcbcfg = &pf->hw.local_dcbx_config;
+                       dcbcfg->etscfg.willing = 1;
+                       dcbcfg->etscfg.maxtcs = 0;
+                       dcbcfg->etscfg.tcbwtable[0] = 100;
+                       for (i = 1; i < I40E_MAX_TRAFFIC_CLASS; i++)
+                               dcbcfg->etscfg.tcbwtable[i] = 0;
+                       for (i = 0; i < I40E_MAX_USER_PRIORITY; i++)
+                               dcbcfg->etscfg.prioritytable[i] = 0;
+                       dcbcfg->etscfg.tsatable[0] = I40E_IEEE_TSA_ETS;
+                       dcbcfg->pfc.willing = 1;
+                       dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
+               } else {
+                       i40e_aq_start_lldp(&pf->hw, NULL);
+               }
+       }
+
        /* Issue reset to cause things to take effect, as additional bits
         * are added we will need to create a mask of bits requiring reset
         */
        if (changed_flags & (I40E_FLAG_VEB_STATS_ENABLED |
                             I40E_FLAG_LEGACY_RX |
-                            I40E_FLAG_SOURCE_PRUNING_DISABLED))
+                            I40E_FLAG_SOURCE_PRUNING_DISABLED |
+                            I40E_FLAG_DISABLE_FW_LLDP))
                i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED), true);
 
        return 0;
@@ -5723,13 +5717,14 @@ static int i40e_get_module_info(struct net_device *netdev,
                        netdev_warn(vsi->netdev, "Module address swap to access page 0xA2 is not supported.\n");
                        modinfo->type = ETH_MODULE_SFF_8079;
                        modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
-               } else if (sff8472_comp == 0x00) {
+               } else if (sff8472_comp &&
+                          (sff8472_swap & I40E_MODULE_SFF_DIAG_CAPAB)) {
+                       modinfo->type = ETH_MODULE_SFF_8472;
+                       modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+               } else {
                        /* Module is not SFF-8472 compliant */
                        modinfo->type = ETH_MODULE_SFF_8079;
                        modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
-               } else {
-                       modinfo->type = ETH_MODULE_SFF_8472;
-                       modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
                }
                break;
        case I40E_MODULE_TYPE_QSFP_PLUS:
@@ -5817,8 +5812,10 @@ static int i40e_get_module_eeprom(struct net_device *netdev,
 #endif /* ETHTOOL_GMODULEINFO */
 
 static const struct ethtool_ops i40e_ethtool_ops = {
+#ifndef ETHTOOL_GLINKSETTINGS
        .get_settings           = i40e_get_settings,
        .set_settings           = i40e_set_settings,
+#endif
        .get_drvinfo            = i40e_get_drvinfo,
        .get_regs_len           = i40e_get_regs_len,
        .get_regs               = i40e_get_regs,
@@ -5905,8 +5902,8 @@ static const struct ethtool_ops i40e_ethtool_ops = {
 #endif /* ETHTOOL_PERQUEUE */
 #endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */
 #ifdef ETHTOOL_GLINKSETTINGS
-       .get_link_ksettings = i40e_get_link_settings,
-       .set_link_ksettings = i40e_set_link_settings,
+       .get_link_ksettings = i40e_get_link_ksettings,
+       .set_link_ksettings = i40e_set_link_ksettings,
 #endif /* ETHTOOL_GLINKSETTINGS */
 };
 
similarity index 98%
rename from i40e-dkms/i40e-2.2.4/src/i40e_helper.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_helper.h
index 699b21ee41808edd0354f292b7d37a52461f5ab7..7521ef8bc606c8df3b7da2e59780808f94b817ad 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_hmc.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_hmc.c
index bf72f1ee07e70465256145e61ff2ee300c1ebbab..62af2a5b97fa645434de20422b8365dd010c1e15 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_hmc.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_hmc.h
index 5d1d796e58ed258e5e0ad8eac8d5c6bac9a843ab..1f8fc854341e82a35f8d129305c5ed1a569da268 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_lan_hmc.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_lan_hmc.c
index 899bf81ed4c5159eadb5ec84c77a26b38899ab4f..14457189ac79baff1ab2ebc32a9b3210fc2678ae 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_lan_hmc.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_lan_hmc.h
index 71aa4a2f08b4f17889bceb8cf381891551a3c76d..a087cac7f7b21ed8c1bd0a6dfc18e3e72f453740 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 97%
rename from i40e-dkms/i40e-2.2.4/src/i40e_main.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_main.c
index 5bc0f4cb557d725328db55b04aa5b9edefc12125..ae669c3fa761eb0f6be215fb3687e30de3028cfe 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -59,14 +59,14 @@ static const char i40e_driver_string[] =
 #define DRV_VERSION_DESC ""
 
 #define DRV_VERSION_MAJOR 2
-#define DRV_VERSION_MINOR 2
-#define DRV_VERSION_BUILD 4
+#define DRV_VERSION_MINOR 4
+#define DRV_VERSION_BUILD 6
 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
        __stringify(DRV_VERSION_MINOR) "." \
        __stringify(DRV_VERSION_BUILD) \
        DRV_VERSION_DESC __stringify(DRV_VERSION_LOCAL)
 const char i40e_driver_version_str[] = DRV_VERSION;
-static const char i40e_copyright[] = "Copyright(c) 2013 - 2017 Intel Corporation.";
+static const char i40e_copyright[] = "Copyright(c) 2013 - 2018 Intel Corporation.";
 
 /* a bit of forward declarations */
 static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi);
@@ -335,6 +335,10 @@ static void i40e_tx_timeout(struct net_device *netdev)
                      (pf->tx_timeout_last_recovery + netdev->watchdog_timeo)))
                return;   /* don't do any new action before the next timeout */
 
+       /* don't kick off another recovery if one is already pending */
+       if (test_and_set_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state))
+               return;
+
        if (tx_ring) {
                head = i40e_get_head(tx_ring);
                /* Read interrupt register */
@@ -366,7 +370,9 @@ static void i40e_tx_timeout(struct net_device *netdev)
                set_bit(__I40E_GLOBAL_RESET_REQUESTED, pf->state);
                break;
        default:
-               netdev_err(netdev, "tx_timeout recovery unsuccessful\n");
+               netdev_err(netdev, "tx_timeout recovery unsuccessful, device is in non-recoverable state.\n");
+               set_bit(__I40E_DOWN_REQUESTED, pf->state);
+               set_bit(__I40E_VSI_DOWN_REQUESTED, vsi->state);
                break;
        }
 
@@ -439,7 +445,7 @@ static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
                u64 bytes, packets;
                unsigned int start;
 
-               tx_ring = ACCESS_ONCE(vsi->tx_rings[i]);
+               tx_ring = READ_ONCE(vsi->tx_rings[i]);
                if (!tx_ring)
                        continue;
 
@@ -560,8 +566,6 @@ void i40e_pf_reset_stats(struct i40e_pf *pf)
        pf->rx_udp_cso_err = 0;
        pf->rx_sctp_cso_err = 0;
        pf->rx_ip4_cso_err = 0;
-       pf->hw_csum_rx_vxlan = 0;
-       pf->hw_csum_rx_geneve = 0;
        pf->hw_csum_rx_outer = 0;
 #endif
 }
@@ -835,7 +839,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
        rcu_read_lock();
        for (q = 0; q < vsi->num_queue_pairs; q++) {
                /* locate Tx ring */
-               p = ACCESS_ONCE(vsi->tx_rings[q]);
+               p = READ_ONCE(vsi->tx_rings[q]);
 
 #ifdef HAVE_NDO_GET_STATS64
                do {
@@ -852,6 +856,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
                tx_busy += p->tx_stats.tx_busy;
                tx_linearize += p->tx_stats.tx_linearize;
                tx_force_wb += p->tx_stats.tx_force_wb;
+
                /* Rx queue is part of the same block as Tx queue */
                p = &p[1];
 #ifdef HAVE_NDO_GET_STATS64
@@ -880,6 +885,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
        ns->rx_bytes = rx_b;
        ns->tx_packets = tx_p;
        ns->tx_bytes = tx_b;
+
        /* update netdev stats from eth stats */
        i40e_update_eth_stats(vsi);
        ons->tx_errors = oes->tx_errors;
@@ -1673,6 +1679,10 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
        num_tc_qps = qcount / numtc;
        num_tc_qps = min_t(int, num_tc_qps, i40e_pf_get_max_q_per_tc(pf));
 
+       /* Do not allow use more TC queue pairs than MSI-X vectors exist */
+       if (pf->flags & I40E_FLAG_MSIX_ENABLED)
+               num_tc_qps = min_t(int, num_tc_qps, pf->num_lan_msix);
+
        /* Setup queue offset/count for all TCs for given VSI */
        for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
                /* See if the given TC is enabled for the given VSI */
@@ -2036,6 +2046,73 @@ i40e_aqc_broadcast_filter(struct i40e_vsi *vsi, const char *vsi_name,
        return aq_ret;
 }
 
+/**
+ * i40e_set_promiscuous - set promiscuous mode
+ * @pf: board private structure
+ * @promisc: promisc on or off
+ *
+ * There are different ways of setting promiscuous mode on a PF depending on
+ * what state/environment we're in.  This identifies and sets it appropriately.
+ * Returns I40E_SUCCESS on success.
+ **/
+static int i40e_set_promiscuous(struct i40e_pf *pf, bool promisc)
+{
+       struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+       struct i40e_hw *hw = &pf->hw;
+       i40e_status aq_ret;
+
+       if (vsi->type == I40E_VSI_MAIN &&
+           pf->lan_veb != I40E_NO_VEB &&
+           !(pf->flags & I40E_FLAG_MFP_ENABLED)) {
+               /* set defport ON for Main VSI instead of true promisc
+                * this way we will get all unicast/multicast and VLAN
+                * promisc behavior but will not get VF or VMDq traffic
+                * replicated on the Main VSI.
+                */
+               if (promisc)
+                       aq_ret = i40e_aq_set_default_vsi(hw,
+                                                        vsi->seid,
+                                                        NULL);
+               else
+                       aq_ret = i40e_aq_clear_default_vsi(hw,
+                                                          vsi->seid,
+                                                          NULL);
+               if (aq_ret) {
+                       dev_info(&pf->pdev->dev,
+                                "Set default VSI failed, err %s, aq_err %s\n",
+                                i40e_stat_str(hw, aq_ret),
+                                i40e_aq_str(hw, hw->aq.asq_last_status));
+               }
+       } else {
+               aq_ret = i40e_aq_set_vsi_unicast_promiscuous(
+                                                 hw,
+                                                 vsi->seid,
+                                                 promisc, NULL,
+                                                 true);
+               if (aq_ret) {
+                       dev_info(&pf->pdev->dev,
+                                "set unicast promisc failed, err %s, aq_err %s\n",
+                                i40e_stat_str(hw, aq_ret),
+                                i40e_aq_str(hw, hw->aq.asq_last_status));
+               }
+               aq_ret = i40e_aq_set_vsi_multicast_promiscuous(
+                                                 hw,
+                                                 vsi->seid,
+                                                 promisc, NULL);
+               if (aq_ret) {
+                       dev_info(&pf->pdev->dev,
+                                "set multicast promisc failed, err %s, aq_err %s\n",
+                                i40e_stat_str(hw, aq_ret),
+                                i40e_aq_str(hw, hw->aq.asq_last_status));
+               }
+       }
+
+       if (!aq_ret)
+               pf->cur_promisc = promisc;
+
+       return aq_ret;
+}
+
 /**
  * i40e_sync_vsi_filters - Update the VSI filter list to the HW
  * @vsi: ptr to the VSI
@@ -2336,70 +2413,18 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                cur_promisc = (!!(vsi->current_netdev_flags & IFF_PROMISC) ||
                               test_bit(__I40E_VSI_OVERFLOW_PROMISC,
                                        vsi->state));
-               if ((vsi->type == I40E_VSI_MAIN) &&
-                   (pf->lan_veb != I40E_NO_VEB) &&
-                   !(pf->flags & I40E_FLAG_MFP_ENABLED)) {
-                       /* set defport ON for Main VSI instead of true promisc
-                        * this way we will get all unicast/multicast and VLAN
-                        * promisc behavior but will not get VF or VMDq traffic
-                        * replicated on the Main VSI.
-                        */
-                       if (pf->cur_promisc != cur_promisc) {
-                               pf->cur_promisc = cur_promisc;
-                               if (cur_promisc)
-                                       aq_ret =
-                                             i40e_aq_set_default_vsi(hw,
-                                                                     vsi->seid,
-                                                                     NULL);
-                               else
-                                       aq_ret =
-                                           i40e_aq_clear_default_vsi(hw,
-                                                                     vsi->seid,
-                                                                     NULL);
-                               if (aq_ret) {
-                                       retval = i40e_aq_rc_to_posix(aq_ret,
-                                                       hw->aq.asq_last_status);
-                                       dev_info(&pf->pdev->dev,
-                                                "Set default VSI failed on %s, err %s, aq_err %s\n",
-                                                vsi_name,
-                                                i40e_stat_str(hw, aq_ret),
-                                                i40e_aq_str(hw,
-                                                    hw->aq.asq_last_status));
-                               }
-                       }
-               } else {
-                       aq_ret = i40e_aq_set_vsi_unicast_promiscuous(
-                                                         hw,
-                                                         vsi->seid,
-                                                         cur_promisc, NULL,
-                                                         true);
-                       if (aq_ret) {
-                               retval =
-                               i40e_aq_rc_to_posix(aq_ret,
-                                                   hw->aq.asq_last_status);
-                               dev_info(&pf->pdev->dev,
-                                        "set unicast promisc failed on %s, err %s, aq_err %s\n",
-                                        vsi_name,
-                                        i40e_stat_str(hw, aq_ret),
-                                        i40e_aq_str(hw,
-                                                    hw->aq.asq_last_status));
-                       }
-                       aq_ret = i40e_aq_set_vsi_multicast_promiscuous(
-                                                         hw,
-                                                         vsi->seid,
-                                                         cur_promisc, NULL);
-                       if (aq_ret) {
-                               retval =
-                               i40e_aq_rc_to_posix(aq_ret,
-                                                   hw->aq.asq_last_status);
-                               dev_info(&pf->pdev->dev,
-                                        "set multicast promisc failed on %s, err %s, aq_err %s\n",
-                                        vsi_name,
-                                        i40e_stat_str(hw, aq_ret),
-                                        i40e_aq_str(hw,
-                                                    hw->aq.asq_last_status));
-                       }
+               aq_ret = i40e_set_promiscuous(pf, cur_promisc);
+               if (aq_ret) {
+                       retval = i40e_aq_rc_to_posix(aq_ret,
+                                                    hw->aq.asq_last_status);
+                       dev_info(&pf->pdev->dev,
+                                "Setting promiscuous %s failed on %s, err %s aq_err %s\n",
+                                cur_promisc ? "on" : "off",
+                                vsi_name,
+                                i40e_stat_str(hw, aq_ret),
+                                i40e_aq_str(hw, hw->aq.asq_last_status));
                }
+
        }
 out:
        /* if something went wrong then set the changed flag so we try again */
@@ -2926,24 +2951,19 @@ void i40e_vsi_remove_pvid(struct i40e_vsi *vsi)
 
        vsi->info.pvid = 0;
 }
-
 /**
- * i40e_add_del_cloud_filter - Add/del cloud filter
- * @pf: pointer to the physical function struct
- * @filter: cloud filter rule
- * @add: if true, add, if false, delete
+ * i40e_get_cloud_filter_type - Get cloud filter type
+ * @flags: set of enabled fields
+ * @type: location to return type
  *
- * Add or delete a cloud filter for a specific flow spec.
- * Returns 0 if the filter were successfully added.
+ * Given the set of flags indicating which fields are active, look up the type
+ * number for programming the cloud filter in firmware. If the flags are
+ * invalid, return I40E_ERR_CONFIG. @type may be NULL, in which case the
+ * function may be used to verify that the flags would produce a valid type.
  **/
-int i40e_add_del_cloud_filter(struct i40e_pf *pf,
-                             struct i40e_cloud_filter *filter,
-                             bool add)
+int i40e_get_cloud_filter_type(u8 flags, u16 *type)
 {
-       struct i40e_aqc_add_remove_cloud_filters_element_data cld_filter;
-       u32 ipaddr;
-       int ret;
-       static const u16 flag_table[128] = {
+       static const u16 table[128] = {
                [I40E_CLOUD_FILTER_FLAGS_OMAC]  =
                        I40E_AQC_ADD_CLOUD_FILTER_OMAC,
                [I40E_CLOUD_FILTER_FLAGS_IMAC]  =
@@ -2960,10 +2980,38 @@ int i40e_add_del_cloud_filter(struct i40e_pf *pf,
                        I40E_AQC_ADD_CLOUD_FILTER_IIP,
        };
 
-       if ((filter->flags >= ARRAY_SIZE(flag_table)) ||
-           (flag_table[filter->flags] == 0))
+       if (flags >= ARRAY_SIZE(table) || table[flags] == 0)
                return I40E_ERR_CONFIG;
 
+       /* Return type if we're given space to do so */
+       if (type)
+               *type = table[flags];
+
+       return 0;
+}
+
+/**
+ * i40e_add_del_cloud_filter - Add/del cloud filter
+ * @pf: pointer to the physical function struct
+ * @filter: cloud filter rule
+ * @add: if true, add, if false, delete
+ *
+ * Add or delete a cloud filter for a specific flow spec.
+ * Returns 0 if the filter were successfully added.
+ **/
+int i40e_add_del_cloud_filter(struct i40e_pf *pf,
+                             struct i40e_cloud_filter *filter,
+                             bool add)
+{
+       struct i40e_aqc_add_remove_cloud_filters_element_data cld_filter;
+       u32 ipaddr;
+       u16 type;
+       int ret;
+
+       ret = i40e_get_cloud_filter_type(filter->flags, &type);
+       if (ret)
+               return -EINVAL;
+
        memset(&cld_filter, 0, sizeof(cld_filter));
        ether_addr_copy(cld_filter.outer_mac, filter->outer_mac);
        ether_addr_copy(cld_filter.inner_mac, filter->inner_mac);
@@ -2986,8 +3034,7 @@ int i40e_add_del_cloud_filter(struct i40e_pf *pf,
                cld_filter.queue_number = cpu_to_le16(filter->queue_id);
        }
 
-       cld_filter.flags |= cpu_to_le16(flag_table[filter->flags] |
-                                       I40E_AQC_ADD_CLOUD_FLAGS_IPV4);
+       cld_filter.flags |= cpu_to_le16(type | I40E_AQC_ADD_CLOUD_FLAGS_IPV4);
 
        if (add) {
                ret = i40e_aq_add_cloud_filters(&pf->hw, filter->seid,
@@ -3007,7 +3054,7 @@ int i40e_add_del_cloud_filter(struct i40e_pf *pf,
                        "fail to %s cloud filter, err %s aq_err %s\n",
                        add ? "add" : "delete", i40e_stat_str(&pf->hw, ret),
                        i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
-       return ret;
+       return i40e_aq_rc_to_posix(ret, pf->hw.aq.asq_last_status);
 }
 
 /**
@@ -3132,8 +3179,15 @@ static void i40e_config_xps_tx_ring(struct i40e_ring *ring)
                return;
 
        cpu = cpumask_local_spread(ring->q_vector->v_idx, -1);
-       netif_set_xps_queue(ring->netdev, get_cpu_mask(cpu),
+#ifndef HAVE_NETIF_SET_XPS_QUEUE_CONST_MASK
+       /* In kernels before 3.12 the second parameter has no const qualifier.
+        * It is generating warning in older kernels.
+        */
+       netif_set_xps_queue(ring->netdev, (struct cpumask *)get_cpu_mask(cpu),
                            ring->queue_index);
+#else /* !HAVE_NETIF_SET_XPS_QUEUE_CONST_MASK */
+       netif_set_xps_queue(ring->netdev, get_cpu_mask(cpu), ring->queue_index);
+#endif /* !HAVE_NETIF_SET_XPS_QUEUE_CONST_MASK */
 }
 
 /**
@@ -3504,15 +3558,20 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)
        for (i = 0; i < vsi->num_q_vectors; i++, vector++) {
                struct i40e_q_vector *q_vector = vsi->q_vectors[i];
 
-               q_vector->itr_countdown = ITR_COUNTDOWN_START;
-               q_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[i]->rx_itr_setting);
-               q_vector->rx.latency_range = I40E_LOW_LATENCY;
+               q_vector->rx.next_update = jiffies + 1;
+               q_vector->rx.target_itr =
+                       ITR_TO_REG(vsi->rx_rings[i]->itr_setting);
                wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1),
-                    q_vector->rx.itr);
-               q_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[i]->tx_itr_setting);
-               q_vector->tx.latency_range = I40E_LOW_LATENCY;
+                    q_vector->rx.target_itr);
+               q_vector->rx.current_itr = q_vector->rx.target_itr;
+
+               q_vector->tx.next_update = jiffies + 1;
+               q_vector->tx.target_itr =
+                       ITR_TO_REG(vsi->tx_rings[i]->itr_setting);
                wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1),
-                    q_vector->tx.itr);
+                    q_vector->tx.target_itr);
+               q_vector->tx.current_itr = q_vector->tx.target_itr;
+
                wr32(hw, I40E_PFINT_RATEN(vector - 1),
                     i40e_intrl_usec_to_reg(vsi->int_rate_limit));
 
@@ -3601,13 +3660,14 @@ static void i40e_configure_msi_and_legacy(struct i40e_vsi *vsi)
        u32 val;
 
        /* set the ITR configuration */
-       q_vector->itr_countdown = ITR_COUNTDOWN_START;
-       q_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[0]->rx_itr_setting);
-       q_vector->rx.latency_range = I40E_LOW_LATENCY;
-       wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.itr);
-       q_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[0]->tx_itr_setting);
-       q_vector->tx.latency_range = I40E_LOW_LATENCY;
-       wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.itr);
+       q_vector->rx.next_update = jiffies + 1;
+       q_vector->rx.target_itr = ITR_TO_REG(vsi->rx_rings[0]->itr_setting);
+       wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.target_itr);
+       q_vector->rx.current_itr = q_vector->rx.target_itr;
+       q_vector->tx.next_update = jiffies + 1;
+       q_vector->tx.target_itr = ITR_TO_REG(vsi->tx_rings[0]->itr_setting);
+       wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.target_itr);
+       q_vector->tx.current_itr = q_vector->tx.target_itr;
 
        i40e_enable_misc_int_causes(pf);
 
@@ -4159,6 +4219,7 @@ static void i40e_vsi_map_rings_to_vectors(struct i40e_vsi *vsi)
                num_ringpairs = DIV_ROUND_UP(qp_remaining, q_vectors - v_start);
 
                q_vector->num_ringpairs = num_ringpairs;
+               q_vector->reg_idx = q_vector->v_idx + vsi->base_vector - 1;
 
                q_vector->rx.count = 0;
                q_vector->tx.count = 0;
@@ -5207,6 +5268,8 @@ static void i40e_vsi_update_queue_map(struct i40e_vsi *vsi,
 int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
 {
        u8 bw_share[I40E_MAX_TRAFFIC_CLASS] = {0};
+       struct i40e_pf *pf = vsi->back;
+       struct i40e_hw *hw = &pf->hw;
        struct i40e_vsi_context ctxt;
        int ret = 0;
        int i;
@@ -5223,10 +5286,40 @@ int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
 
        ret = i40e_vsi_configure_bw_alloc(vsi, enabled_tc, bw_share);
        if (ret) {
-               dev_info(&vsi->back->pdev->dev,
+               struct i40e_aqc_query_vsi_bw_config_resp bw_config = {0};
+
+               dev_info(&pf->pdev->dev,
                         "Failed configuring TC map %d for VSI %d\n",
                         enabled_tc, vsi->seid);
-               goto out;
+               ret = i40e_aq_query_vsi_bw_config(hw, vsi->seid,
+                                                 &bw_config, NULL);
+               if (ret) {
+                       dev_info(&pf->pdev->dev,
+                                "Failed querying vsi bw info, err %s aq_err %s\n",
+                                i40e_stat_str(hw, ret),
+                                i40e_aq_str(hw, hw->aq.asq_last_status));
+                       goto out;
+               }
+               if ((bw_config.tc_valid_bits & enabled_tc) != enabled_tc) {
+                       u8 valid_tc = bw_config.tc_valid_bits & enabled_tc;
+
+                       if (!valid_tc)
+                               valid_tc = bw_config.tc_valid_bits;
+                       /* Always enable TC0, no matter what */
+                       valid_tc |= 1;
+                       dev_info(&pf->pdev->dev,
+                                "Requested tc 0x%x, but FW reports 0x%x as valid. Attempting to use 0x%x.\n",
+                                enabled_tc, bw_config.tc_valid_bits, valid_tc);
+                       enabled_tc = valid_tc;
+               }
+
+               ret = i40e_vsi_configure_bw_alloc(vsi, enabled_tc, bw_share);
+               if (ret) {
+                       dev_err(&pf->pdev->dev,
+                               "Unable to  configure TC map %d for VSI %d\n",
+                               enabled_tc, vsi->seid);
+                       goto out;
+               }
        }
 
        /* Update Queue Pairs Mapping for currently enabled UPs */
@@ -5244,13 +5337,12 @@ int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
        }
 
        /* Update the VSI after updating the VSI queue-mapping information */
-       ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+       ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
        if (ret) {
-               dev_info(&vsi->back->pdev->dev,
+               dev_info(&pf->pdev->dev,
                         "Update vsi tc config failed, err %s aq_err %s\n",
-                        i40e_stat_str(&vsi->back->hw, ret),
-                        i40e_aq_str(&vsi->back->hw,
-                                    vsi->back->hw.aq.asq_last_status));
+                        i40e_stat_str(hw, ret),
+                        i40e_aq_str(hw, hw->aq.asq_last_status));
                goto out;
        }
        /* update the local VSI info with updated queue map */
@@ -5260,11 +5352,10 @@ int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
        /* Update current VSI BW information */
        ret = i40e_vsi_get_bw_info(vsi);
        if (ret) {
-               dev_info(&vsi->back->pdev->dev,
+               dev_info(&pf->pdev->dev,
                         "Failed updating vsi bw info, err %s aq_err %s\n",
-                        i40e_stat_str(&vsi->back->hw, ret),
-                        i40e_aq_str(&vsi->back->hw,
-                                    vsi->back->hw.aq.asq_last_status));
+                        i40e_stat_str(hw, ret),
+                        i40e_aq_str(hw, hw->aq.asq_last_status));
                goto out;
        }
 
@@ -5421,8 +5512,11 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
        struct i40e_hw *hw = &pf->hw;
        int err = 0;
 
-       /* Do not enable DCB for SW1 and SW2 images even if the FW is capable */
-       if (pf->hw_features & I40E_HW_NO_DCB_SUPPORT)
+       /* Do not enable DCB for SW1 and SW2 images even if the FW is capable
+        * Also do not enable DCBx if FW LLDP agent is disabled
+        */
+       if ((pf->hw_features & I40E_HW_NO_DCB_SUPPORT) ||
+           (pf->flags & I40E_FLAG_DISABLE_FW_LLDP))
                goto out;
 
        /* Get the initial DCB configuration */
@@ -5449,6 +5543,9 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
                        dev_dbg(&pf->pdev->dev,
                                "DCBX offload is supported for this PF.\n");
                }
+       } else if (pf->hw.aq.asq_last_status == I40E_AQ_RC_EPERM) {
+               dev_info(&pf->pdev->dev, "FW LLDP disabled for this PF.\n");
+               pf->flags |= I40E_FLAG_DISABLE_FW_LLDP;
        } else {
                dev_info(&pf->pdev->dev,
                         "Query for DCB configuration failed, err %s aq_err %s\n",
@@ -5806,7 +5903,10 @@ exit:
 }
 
 #ifdef NETIF_F_HW_TC
-#ifdef HAVE_NDO_SETUP_TC_CHAIN_INDEX
+#ifdef HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
+static int __i40e_setup_tc(struct net_device *netdev, enum tc_setup_type type,
+                          void *type_data)
+#elif defined(HAVE_NDO_SETUP_TC_CHAIN_INDEX)
 static int __i40e_setup_tc(struct net_device *netdev, u32 handle,
                           u32 chain_index, __be16 proto,
                           struct tc_to_netdev *tc)
@@ -5815,13 +5915,22 @@ static int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
                           struct tc_to_netdev *tc)
 #endif
 {
-       if (tc->type != TC_SETUP_MQPRIO)
+#ifdef HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
+       struct tc_mqprio_qopt *mqprio = type_data;
+#else
+#ifdef TC_MQPRIO_HW_OFFLOAD_MAX
+       struct tc_mqprio_qopt *mqprio = tc->mqprio;
+#endif /* TC_MQPRIO_HW_OFFLOAD_MAX*/
+       unsigned int type = tc->type;
+#endif /* HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV */
+
+       if (type != TC_SETUP_QDISC_MQPRIO)
                return -EINVAL;
 
 #ifdef TC_MQPRIO_HW_OFFLOAD_MAX
-       tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+       mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
 
-       return i40e_setup_tc(netdev, tc->mqprio->num_tc);
+       return i40e_setup_tc(netdev, mqprio->num_tc);
 #else
        return i40e_setup_tc(netdev, tc->tc);
 #endif
@@ -6016,6 +6125,9 @@ static void i40e_fdir_filter_exit(struct i40e_pf *pf)
        /* Reprogram the default input set for Other/IPv4 */
        i40e_write_fd_input_set(pf, I40E_FILTER_PCTYPE_NONF_IPV4_OTHER,
                                I40E_L3_SRC_MASK | I40E_L3_DST_MASK);
+
+       i40e_write_fd_input_set(pf, I40E_FILTER_PCTYPE_FRAG_IPV4,
+                               I40E_L3_SRC_MASK | I40E_L3_DST_MASK);
 }
 
 /**
@@ -7397,9 +7509,21 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
        }
        i40e_get_oem_version(&pf->hw);
 
+       if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) &&
+           ((hw->aq.fw_maj_ver == 4 && hw->aq.fw_min_ver <= 33) ||
+            hw->aq.fw_maj_ver < 4) && hw->mac.type == I40E_MAC_XL710) {
+               /* The following delay is necessary for 4.33 firmware and older
+                * to recover after EMP reset. 200 ms should suffice but we
+                * put here 300 ms to be sure that FW is ready to operate
+                * after reset.
+                */
+               mdelay(300);
+       }
+
        /* re-verify the eeprom if we just had an EMP reset */
-       if (test_and_clear_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state))
+       if (test_and_clear_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state)) {
                i40e_verify_eeprom(pf);
+       }
 
        i40e_clear_pxe_mode(hw);
        ret = i40e_get_capabilities(pf);
@@ -7418,6 +7542,9 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
                goto end_core_reset;
        }
 
+       /* Enable FW to write a default DCB config on link-up */
+       i40e_aq_set_dcb_parameters(hw, true, NULL);
+
 #ifdef CONFIG_DCB
        ret = i40e_init_pf_dcb(pf);
        if (ret) {
@@ -7550,6 +7677,15 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
        if (!lock_acquired)
                rtnl_unlock();
 
+       /* Restore promiscuous settings */
+       ret = i40e_set_promiscuous(pf, pf->cur_promisc);
+       if (ret)
+               dev_warn(&pf->pdev->dev,
+                        "Failed to restore promiscuous setting: %s, err %s aq_err %s\n",
+                        pf->cur_promisc ? "on" : "off",
+                        i40e_stat_str(&pf->hw, ret),
+                        i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+
        i40e_reset_all_vfs(pf, true);
 
        /* TODO: restart clients */
@@ -7566,6 +7702,7 @@ end_core_reset:
        clear_bit(__I40E_RESET_FAILED, pf->state);
 clear_recovery:
        clear_bit(__I40E_RESET_RECOVERY_PENDING, pf->state);
+       clear_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state);
 }
 
 /**
@@ -7713,7 +7850,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
 
 #if defined(HAVE_VXLAN_RX_OFFLOAD) || defined(HAVE_UDP_ENC_RX_OFFLOAD)
 #if defined(HAVE_UDP_ENC_TUNNEL) || defined(HAVE_UDP_ENC_RX_OFFLOAD)
-const char *i40e_tunnel_name(struct i40e_udp_port_config *port)
+static const char *i40e_tunnel_name(struct i40e_udp_port_config *port)
 {
        switch (port->type) {
        case UDP_TUNNEL_TYPE_VXLAN:
@@ -7787,104 +7924,6 @@ static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf)
 #endif /* HAVE_UDP_ENC_TUNNEL || HAVE_UDP_ENC_RX_OFFLOAD */
 #endif /* HAVE_VXLAN_RX_OFFLOAD || HAVE_UDP_ENC_RX_OFFLOAD */
 
-/**
- * i40e_detect_recover_hung_queue - Function to detect and recover hung_queue
- * @q_idx: TX queue number
- * @vsi: Pointer to VSI struct
- *
- * This function checks specified queue for given VSI. Detects hung condition.
- * We proactively detect hung TX queues by checking if interrupts are disabled
- * but there are pending descriptors.  If it appears hung, attempt to recover
- * by triggering a SW interrupt.
- **/
-static void i40e_detect_recover_hung_queue(int q_idx, struct i40e_vsi *vsi)
-{
-       struct i40e_ring *tx_ring = NULL;
-       struct i40e_pf  *pf;
-       u32 val, tx_pending;
-       int i;
-
-       pf = vsi->back;
-
-       /* now that we have an index, find the tx_ring struct */
-       for (i = 0; i < vsi->num_queue_pairs; i++) {
-               if (vsi->tx_rings[i] && vsi->tx_rings[i]->desc) {
-                       if (q_idx == vsi->tx_rings[i]->queue_index) {
-                               tx_ring = vsi->tx_rings[i];
-                               break;
-                       }
-               }
-       }
-
-       if (!tx_ring)
-               return;
-
-       /* Read interrupt register */
-       if (pf->flags & I40E_FLAG_MSIX_ENABLED)
-               val = rd32(&pf->hw,
-                    I40E_PFINT_DYN_CTLN(tx_ring->q_vector->v_idx +
-                                        tx_ring->vsi->base_vector - 1));
-       else
-               val = rd32(&pf->hw, I40E_PFINT_DYN_CTL0);
-
-       tx_pending = i40e_get_tx_pending(tx_ring);
-
-       /* Interrupts are disabled and TX pending is non-zero,
-        * trigger the SW interrupt (don't wait). Worst case
-        * there will be one extra interrupt which may result
-        * into not cleaning any queues because queues are cleaned.
-        */
-       if (tx_pending && (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK)))
-               i40e_force_wb(vsi, tx_ring->q_vector);
-}
-
-/**
- * i40e_detect_recover_hung - Function to detect and recover hung_queues
- * @pf:  pointer to PF struct
- *
- * LAN VSI has netdev and netdev has TX queues. This function is to check
- * each of those TX queues if they are hung, trigger recovery by issuing
- * SW interrupt.
- **/
-static void i40e_detect_recover_hung(struct i40e_pf *pf)
-{
-       struct net_device *netdev;
-       struct i40e_vsi *vsi;
-       unsigned int i;
-
-       /* Only for LAN VSI */
-       vsi = pf->vsi[pf->lan_vsi];
-
-       if (!vsi)
-               return;
-
-       /* Make sure, VSI state is not DOWN/RECOVERY_PENDING */
-       if (test_bit(__I40E_DOWN, vsi->back->state) ||
-           test_bit(__I40E_RESET_RECOVERY_PENDING, vsi->back->state))
-               return;
-
-       /* Make sure type is MAIN VSI */
-       if (vsi->type != I40E_VSI_MAIN)
-               return;
-
-       netdev = vsi->netdev;
-       if (!netdev)
-               return;
-
-       /* Bail out if netif_carrier is not OK */
-       if (!netif_carrier_ok(netdev))
-               return;
-
-       /* Go thru' TX queues for netdev */
-       for (i = 0; i < netdev->num_tx_queues; i++) {
-               struct netdev_queue *q;
-
-               q = netdev_get_tx_queue(netdev, i);
-               if (q)
-                       i40e_detect_recover_hung_queue(i, vsi);
-       }
-}
-
 /**
  * i40e_service_task - Run the driver's async subtasks
  * @work: pointer to work_struct containing our data
@@ -7905,7 +7944,7 @@ static void i40e_service_task(struct work_struct *work)
        if (test_and_set_bit(__I40E_SERVICE_SCHED, pf->state))
                return;
 
-       i40e_detect_recover_hung(pf);
+       i40e_detect_recover_hung(pf->vsi[pf->lan_vsi]);
        i40e_sync_filters_subtask(pf);
        i40e_reset_subtask(pf);
        i40e_handle_mdd_event(pf);
@@ -7914,13 +7953,14 @@ static void i40e_service_task(struct work_struct *work)
        i40e_fdir_reinit_subtask(pf);
        if (pf->flags & I40E_FLAG_CLIENT_RESET) {
                /* Client subtask will reopen next time through. */
-               i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], true);
+               i40e_notify_client_of_netdev_close(
+                                       pf->vsi[pf->lan_vsi], true);
                pf->flags &= ~I40E_FLAG_CLIENT_RESET;
        } else {
                i40e_client_subtask(pf);
                if (pf->flags & I40E_FLAG_CLIENT_L2_CHANGE) {
                        i40e_notify_client_of_l2_param_changes(
-                                                       pf->vsi[pf->lan_vsi]);
+                                               pf->vsi[pf->lan_vsi]);
                        pf->flags &= ~I40E_FLAG_CLIENT_L2_CHANGE;
                }
        }
@@ -7950,11 +7990,11 @@ static void i40e_service_task(struct work_struct *work)
 
 /**
  * i40e_service_timer - timer callback
- * @data: pointer to PF struct
+ * @t: pointer to timer_list struct
  **/
-static void i40e_service_timer(unsigned long data)
+static void i40e_service_timer(struct timer_list *t)
 {
-       struct i40e_pf *pf = (struct i40e_pf *)data;
+       struct i40e_pf *pf = from_timer(pf, t, service_timer);
 
        mod_timer(&pf->service_timer,
                  round_jiffies(jiffies + pf->service_timer_period));
@@ -8250,7 +8290,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
 
                if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE)
                        tx_ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
-               tx_ring->tx_itr_setting = pf->tx_itr_default;
+               tx_ring->itr_setting = pf->tx_itr_default;
                vsi->tx_rings[i] = tx_ring;
 
                rx_ring = &tx_ring[1];
@@ -8263,7 +8303,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
                rx_ring->count = vsi->num_desc;
                rx_ring->size = 0;
                rx_ring->dcb_tc = 0;
-               rx_ring->rx_itr_setting = pf->rx_itr_default;
+               rx_ring->itr_setting = pf->rx_itr_default;
                vsi->rx_rings[i] = rx_ring;
        }
 
@@ -8534,9 +8574,6 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx)
                netif_napi_add(vsi->netdev, &q_vector->napi,
                               i40e_napi_poll, NAPI_POLL_WEIGHT);
 
-       q_vector->rx.latency_range = I40E_LOW_LATENCY;
-       q_vector->tx.latency_range = I40E_LOW_LATENCY;
-
        /* tie q_vector and vsi together */
        vsi->q_vectors[v_idx] = q_vector;
 
@@ -9038,8 +9075,13 @@ static int i40e_pf_config_rss(struct i40e_pf *pf)
        /* Determine the RSS size of the VSI */
        if (!vsi->rss_size) {
                u16 qcount;
-
-               qcount = vsi->num_queue_pairs / vsi->tc_config.numtc;
+               /* If the firmware does something weird during VSI init, we
+                * could end up with zero TCs. Check for that to avoid
+                * divide-by-zero. It probably won't pass traffic, but it also
+                * won't panic.
+                */
+               qcount = vsi->num_queue_pairs /
+                        (vsi->tc_config.numtc ? vsi->tc_config.numtc : 1);
                vsi->rss_size = min_t(int, pf->alloc_rss_size, qcount);
        }
        if (!vsi->rss_size)
@@ -9244,7 +9286,7 @@ i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf)
        ret = i40e_aq_update_nvm(&pf->hw,
                                 I40E_SR_NVM_CONTROL_WORD,
                                 0x10, sizeof(nvm_word),
-                                &nvm_word, true, NULL);
+                                &nvm_word, true, 0, NULL);
        /* Save off last admin queue command status before releasing
         * the NVM
         */
@@ -9400,13 +9442,13 @@ static int i40e_sw_init(struct i40e_pf *pf)
            (pf->hw.aq.fw_maj_ver >= 6))
                pf->hw_features |= I40E_HW_PTP_L4_CAPABLE;
 
-       if (pf->hw.func_caps.vmdq) {
+       if (pf->hw.func_caps.vmdq && num_online_cpus() != 1) {
                pf->num_vmdq_vsis = I40E_DEFAULT_NUM_VMDQ_VSI;
                pf->flags |= I40E_FLAG_VMDQ_ENABLED;
                pf->num_vmdq_qps = i40e_default_queues_per_vmdq(pf);
        }
 
-       if (pf->hw.func_caps.iwarp) {
+       if (pf->hw.func_caps.iwarp && num_online_cpus() != 1) {
                pf->flags |= I40E_FLAG_IWARP_ENABLED;
                /* IWARP needs one extra vector for CQP just like MISC.*/
                pf->num_iwarp_msix = (int)num_online_cpus() + 1;
@@ -10140,7 +10182,11 @@ static const struct net_device_ops i40e_netdev_ops = {
        .ndo_set_rx_mode        = i40e_set_rx_mode,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = i40e_set_mac,
+#ifdef HAVE_RHEL7_EXTENDED_MIN_MAX_MTU
+       .extended.ndo_change_mtu = i40e_change_mtu,
+#else
        .ndo_change_mtu         = i40e_change_mtu,
+#endif /* HAVE_RHEL7_EXTENDED_MIN_MAX_MTU */
 #if defined(HAVE_PTP_1588_CLOCK) || defined(HAVE_I40E_INTELCIM_IOCTL)
        .ndo_do_ioctl           = i40e_ioctl,
 #endif
@@ -10154,11 +10200,15 @@ static const struct net_device_ops i40e_netdev_ops = {
        .ndo_poll_controller    = i40e_netpoll,
 #endif
 #ifdef HAVE_SETUP_TC
+#ifdef HAVE_RHEL7_NETDEV_OPS_EXT_NDO_SETUP_TC
+       .extended.ndo_setup_tc_rh = __i40e_setup_tc,
+#else
 #ifdef NETIF_F_HW_TC
        .ndo_setup_tc           = __i40e_setup_tc,
 #else
        .ndo_setup_tc           = i40e_setup_tc,
-#endif
+#endif /* NETIF_F_HW_TC */
+#endif /* HAVE_RHEL7_NETDEV_OPS_EXT_NDO_SETUP_TC */
 #endif /* HAVE_SETUP_TC */
 #ifdef HAVE_RHEL7_NET_DEVICE_OPS_EXT
 /* RHEL7 requires this to be defined to enable extended ops.  RHEL7 uses the
@@ -10517,9 +10567,14 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 #endif
 #ifdef HAVE_NETDEVICE_MIN_MAX_MTU
        /* MTU range: 68 - 9706 */
+#ifdef HAVE_RHEL7_EXTENDED_MIN_MAX_MTU
+       netdev->extended->min_mtu = ETH_MIN_MTU;
+       netdev->extended->max_mtu = I40E_MAX_RXBUFFER - I40E_PACKET_HDR_PAD;
+#else
        netdev->min_mtu = ETH_MIN_MTU;
        netdev->max_mtu = I40E_MAX_RXBUFFER - I40E_PACKET_HDR_PAD;
-#endif
+#endif /* HAVE_RHEL7_EXTENDED_MIN_MAX_MTU */
+#endif /* HAVE_NETDEVICE_MIN_MAX_NTU */
 
        return 0;
 }
@@ -12219,6 +12274,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                dev_warn(&pdev->dev, "This device is a pre-production adapter/LOM. Please be aware there may be issues with your hardware. If you are experiencing problems please contact your Intel or hardware representative who provided you with this hardware.\n");
 
        i40e_clear_pxe_mode(hw);
+
        err = i40e_get_capabilities(pf);
        if (err)
                goto err_adminq_setup;
@@ -12269,6 +12325,10 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 #ifdef HAVE_PCI_ERS
        pci_save_state(pdev);
 #endif
+
+       /* Enable FW to write default DCB config on link-up */
+       i40e_aq_set_dcb_parameters(hw, true, NULL);
+
 #ifdef CONFIG_DCB
        err = i40e_init_pf_dcb(pf);
        if (err) {
@@ -12278,9 +12338,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 #endif /* CONFIG_DCB */
 
-
        /* set up periodic task facility */
-       setup_timer(&pf->service_timer, i40e_service_timer, (unsigned long)pf);
+       timer_setup(&pf->service_timer, i40e_service_timer, 0);
        pf->service_timer_period = HZ;
 
        INIT_WORK(&pf->service_task, i40e_service_task);
@@ -12625,19 +12684,19 @@ static void i40e_remove(struct pci_dev *pdev)
        /* no more scheduling of any task */
        set_bit(__I40E_SUSPENDED, pf->state);
        set_bit(__I40E_DOWN, pf->state);
-       if (pf->service_timer.data)
+       if (pf->service_timer.function)
                del_timer_sync(&pf->service_timer);
        if (pf->service_task.func)
                cancel_work_sync(&pf->service_task);
 
+       if (test_bit(__I40E_DEBUG_MODE, pf->state))
+               goto unmap;
+
        /* Client close must be called explicitly here because the timer
         * has been stopped.
         */
        i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], false);
 
-       if (test_bit(__I40E_DEBUG_MODE, pf->state))
-               goto unmap;
-
        if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
                i40e_free_vfs(pf);
                pf->flags &= ~I40E_FLAG_SRIOV_ENABLED;
similarity index 89%
rename from i40e-dkms/i40e-2.2.4/src/i40e_nvm.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_nvm.c
index fa8343c8347883f496fc624fcaf7773091de85c4..1512a42c4eefc9bb4f94b0e8ec888e86f9c6c565 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
 
 #include "i40e_prototype.h"
 
-i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
-                                              u16 *data);
-i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
-                                           u16 *data);
-i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
-                                                u16 *words, u16 *data);
-i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
-                                             u16 *words, u16 *data);
-i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
-                                      u32 offset, u16 words, void *data,
-                                      bool last_command);
-
 /**
  * i40e_init_nvm_ops - Initialize NVM function pointers
  * @hw: pointer to the HW structure
@@ -188,51 +176,6 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
        return ret_code;
 }
 
-/**
- * i40e_read_nvm_word - Reads nvm word and acquire lock if necessary
- * @hw: pointer to the HW structure
- * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
- * @data: word read from the Shadow RAM
- *
- * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
- **/
-i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
-                                        u16 *data)
-{
-       i40e_status ret_code = I40E_SUCCESS;
-
-       ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
-       if (!ret_code) {
-               if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) {
-                       ret_code = i40e_read_nvm_word_aq(hw, offset, data);
-               } else {
-                       ret_code = i40e_read_nvm_word_srctl(hw, offset, data);
-               }
-               i40e_release_nvm(hw);
-       }
-       return ret_code;
-}
-
-/**
- * __i40e_read_nvm_word - Reads nvm word, assumes caller does the locking
- * @hw: pointer to the HW structure
- * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
- * @data: word read from the Shadow RAM
- *
- * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
- **/
-static i40e_status __i40e_read_nvm_word(struct i40e_hw *hw,
-                                                 u16 offset, u16 *data)
-{
-       i40e_status ret_code = I40E_SUCCESS;
-
-       if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
-               ret_code = i40e_read_nvm_word_aq(hw, offset, data);
-       else
-               ret_code = i40e_read_nvm_word_srctl(hw, offset, data);
-       return ret_code;
-}
-
 /**
  * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register
  * @hw: pointer to the HW structure
@@ -241,8 +184,8 @@ static i40e_status __i40e_read_nvm_word(struct i40e_hw *hw,
  *
  * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
  **/
-i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
-                                              u16 *data)
+static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw,
+                                                     u16 offset, u16 *data)
 {
        i40e_status ret_code = I40E_ERR_TIMEOUT;
        u32 sr_reg;
@@ -281,16 +224,67 @@ read_nvm_exit:
        return ret_code;
 }
 
+/**
+ * i40e_read_nvm_aq - Read Shadow RAM.
+ * @hw: pointer to the HW structure.
+ * @module_pointer: module pointer location in words from the NVM beginning
+ * @offset: offset in words from module start
+ * @words: number of words to write
+ * @data: buffer with words to write to the Shadow RAM
+ * @last_command: tells the AdminQ that this is the last command
+ *
+ * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
+ **/
+static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw,
+                                             u8 module_pointer, u32 offset,
+                                             u16 words, void *data,
+                                             bool last_command)
+{
+       i40e_status ret_code = I40E_ERR_NVM;
+       struct i40e_asq_cmd_details cmd_details;
+
+       memset(&cmd_details, 0, sizeof(cmd_details));
+       cmd_details.wb_desc = &hw->nvm_wb_desc;
+
+       /* Here we are checking the SR limit only for the flat memory model.
+        * We cannot do it for the module-based model, as we did not acquire
+        * the NVM resource yet (we cannot get the module pointer value).
+        * Firmware will check the module-based model.
+        */
+       if ((offset + words) > hw->nvm.sr_size)
+               i40e_debug(hw, I40E_DEBUG_NVM,
+                          "NVM write error: offset %d beyond Shadow RAM limit %d\n",
+                          (offset + words), hw->nvm.sr_size);
+       else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
+               /* We can write only up to 4KB (one sector), in one AQ write */
+               i40e_debug(hw, I40E_DEBUG_NVM,
+                          "NVM write fail error: tried to write %d words, limit is %d.\n",
+                          words, I40E_SR_SECTOR_SIZE_IN_WORDS);
+       else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
+                != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
+               /* A single write cannot spread over two sectors */
+               i40e_debug(hw, I40E_DEBUG_NVM,
+                          "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
+                          offset, words);
+       else
+               ret_code = i40e_aq_read_nvm(hw, module_pointer,
+                                           2 * offset,  /*bytes*/
+                                           2 * words,   /*bytes*/
+                                           data, last_command, &cmd_details);
+
+       return ret_code;
+}
+
 /**
  * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ
  * @hw: pointer to the HW structure
  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
  * @data: word read from the Shadow RAM
  *
- * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
+ * Reads one 16 bit word from the Shadow RAM using the AdminQ
  **/
-i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
-                                           u16 *data)
+static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
+                                                  u16 *data)
 {
        i40e_status ret_code = I40E_ERR_TIMEOUT;
 
@@ -301,55 +295,48 @@ i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
 }
 
 /**
- * __i40e_read_nvm_buffer - Reads nvm buffer, caller must acquire lock
+ * __i40e_read_nvm_word - Reads NVM word, assumes caller does the locking
  * @hw: pointer to the HW structure
- * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
- * @words: (in) number of words to read; (out) number of words actually read
- * @data: words read from the Shadow RAM
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
+ * @data: word read from the Shadow RAM
  *
- * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
- * method. The buffer read is preceded by the NVM ownership take
- * and followed by the release.
+ * Reads one 16 bit word from the Shadow RAM.
+ *
+ * Do not use this function except in cases where the nvm lock is already
+ * taken via i40e_acquire_nvm().
  **/
-static i40e_status __i40e_read_nvm_buffer(struct i40e_hw *hw,
-                                                   u16 offset, u16 *words,
-                                                   u16 *data)
+static i40e_status __i40e_read_nvm_word(struct i40e_hw *hw,
+                                                 u16 offset, u16 *data)
 {
-       i40e_status ret_code = I40E_SUCCESS;
 
        if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
-               ret_code = i40e_read_nvm_buffer_aq(hw, offset, words, data);
-       else
-               ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data);
-       return ret_code;
+               return i40e_read_nvm_word_aq(hw, offset, data);
+
+       return i40e_read_nvm_word_srctl(hw, offset, data);
 }
 
 /**
- * i40e_read_nvm_buffer - Reads Shadow RAM buffer and acuire lock if necessary
+ * i40e_read_nvm_word - Reads NVM word, acquires lock if necessary
  * @hw: pointer to the HW structure
- * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
- * @words: (in) number of words to read; (out) number of words actually read
- * @data: words read from the Shadow RAM
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
+ * @data: word read from the Shadow RAM
  *
- * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
- * method. The buffer read is preceded by the NVM ownership take
- * and followed by the release.
+ * Reads one 16 bit word from the Shadow RAM.
  **/
-i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
-                                          u16 *words, u16 *data)
+i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
+                                        u16 *data)
 {
        i40e_status ret_code = I40E_SUCCESS;
 
-       if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) {
+       if (hw->flags & I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK)
                ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
-               if (!ret_code) {
-                       ret_code = i40e_read_nvm_buffer_aq(hw, offset, words,
-                                                        data);
-                       i40e_release_nvm(hw);
-               }
-       } else {
-               ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data);
-       }
+
+       if (ret_code)
+               return ret_code;
+       ret_code = __i40e_read_nvm_word(hw, offset, data);
+
+       if (hw->flags & I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK)
+               i40e_release_nvm(hw);
        return ret_code;
 }
 
@@ -364,8 +351,8 @@ i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
  * method. The buffer read is preceded by the NVM ownership take
  * and followed by the release.
  **/
-i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
-                                                u16 *words, u16 *data)
+static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
+                                                       u16 *words, u16 *data)
 {
        i40e_status ret_code = I40E_SUCCESS;
        u16 index, word;
@@ -395,8 +382,8 @@ i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
  * method. The buffer read is preceded by the NVM ownership take
  * and followed by the release.
  **/
-i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
-                                             u16 *words, u16 *data)
+static i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
+                                                    u16 *words, u16 *data)
 {
        i40e_status ret_code;
        u16 read_size = *words;
@@ -442,53 +429,23 @@ read_nvm_buffer_aq_exit:
 }
 
 /**
- * i40e_read_nvm_aq - Read Shadow RAM.
- * @hw: pointer to the HW structure.
- * @module_pointer: module pointer location in words from the NVM beginning
- * @offset: offset in words from module start
- * @words: number of words to write
- * @data: buffer with words to write to the Shadow RAM
- * @last_command: tells the AdminQ that this is the last command
+ * __i40e_read_nvm_buffer - Reads NVM buffer, caller must acquire lock
+ * @hw: pointer to the HW structure
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
+ * @words: (in) number of words to read; (out) number of words actually read
+ * @data: words read from the Shadow RAM
  *
- * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
+ * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
+ * method.
  **/
-i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
-                                      u32 offset, u16 words, void *data,
-                                      bool last_command)
+static i40e_status __i40e_read_nvm_buffer(struct i40e_hw *hw,
+                                                   u16 offset, u16 *words,
+                                                   u16 *data)
 {
-       i40e_status ret_code = I40E_ERR_NVM;
-       struct i40e_asq_cmd_details cmd_details;
-
-       memset(&cmd_details, 0, sizeof(cmd_details));
-       cmd_details.wb_desc = &hw->nvm_wb_desc;
-
-       /* Here we are checking the SR limit only for the flat memory model.
-        * We cannot do it for the module-based model, as we did not acquire
-        * the NVM resource yet (we cannot get the module pointer value).
-        * Firmware will check the module-based model.
-        */
-       if ((offset + words) > hw->nvm.sr_size)
-               i40e_debug(hw, I40E_DEBUG_NVM,
-                          "NVM write error: offset %d beyond Shadow RAM limit %d\n",
-                          (offset + words), hw->nvm.sr_size);
-       else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
-               /* We can write only up to 4KB (one sector), in one AQ write */
-               i40e_debug(hw, I40E_DEBUG_NVM,
-                          "NVM write fail error: tried to write %d words, limit is %d.\n",
-                          words, I40E_SR_SECTOR_SIZE_IN_WORDS);
-       else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
-                != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
-               /* A single write cannot spread over two sectors */
-               i40e_debug(hw, I40E_DEBUG_NVM,
-                          "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
-                          offset, words);
-       else
-               ret_code = i40e_aq_read_nvm(hw, module_pointer,
-                                           2 * offset,  /*bytes*/
-                                           2 * words,   /*bytes*/
-                                           data, last_command, &cmd_details);
+       if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
+               return i40e_read_nvm_buffer_aq(hw, offset, words, data);
 
-       return ret_code;
+       return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
 }
 
 /**
@@ -502,9 +459,9 @@ i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
  *
  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
  **/
-i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
-                                       u32 offset, u16 words, void *data,
-                                       bool last_command)
+static i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
+                                              u32 offset, u16 words, void *data,
+                                              bool last_command)
 {
        i40e_status ret_code = I40E_ERR_NVM;
        struct i40e_asq_cmd_details cmd_details;
@@ -530,7 +487,8 @@ i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
                ret_code = i40e_aq_update_nvm(hw, module_pointer,
                                              2 * offset,  /*bytes*/
                                              2 * words,   /*bytes*/
-                                             data, last_command, &cmd_details);
+                                             data, last_command, 0,
+                                             &cmd_details);
 
        return ret_code;
 }
@@ -563,16 +521,14 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
        data = (u16 *)vmem.va;
 
        /* read pointer to VPD area */
-       ret_code = __i40e_read_nvm_word(hw, I40E_SR_VPD_PTR,
-                                       &vpd_module);
+       ret_code = __i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
        if (ret_code != I40E_SUCCESS) {
                ret_code = I40E_ERR_NVM_CHECKSUM;
                goto i40e_calc_nvm_checksum_exit;
        }
 
        /* read pointer to PCIe Alt Auto-load module */
-       ret_code = __i40e_read_nvm_word(hw,
-                                       I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
+       ret_code = __i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
                                        &pcie_alt_module);
        if (ret_code != I40E_SUCCESS) {
                ret_code = I40E_ERR_NVM_CHECKSUM;
@@ -658,25 +614,19 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
        u16 checksum_sr = 0;
        u16 checksum_local = 0;
 
-       /* acquire_nvm provides exclusive NVM lock to synchronize access across
-        * PFs. X710 uses i40e_read_nvm_word_srctl which polls for done bit
-        * twice (first time to be able to write address to I40E_GLNVM_SRCTL
-        * register, second to read data from I40E_GLNVM_SRDATA. One PF can see
-        * done bit and try to write address, while another one will interpret
-        * it as a good time to read data. It will cause invalid data to be
-        * read.
+       /* We must acquire the NVM lock in order to correctly synchronize the
+        * NVM accesses across multiple PFs. Without doing so it is possible
+        * for one of the PFs to read invalid data potentially indicating that
+        * the checksum is invalid.
         */
        ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
-       if (!ret_code) {
-               ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
+       if (ret_code)
+               return ret_code;
+       ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
+       __i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
        i40e_release_nvm(hw);
-               if (ret_code != I40E_SUCCESS)
-                       goto i40e_validate_nvm_checksum_exit;
-       } else {
-               goto i40e_validate_nvm_checksum_exit;
-       }
-
-       i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
+       if (ret_code)
+               return ret_code;
 
        /* Verify read checksum from EEPROM is the same as
         * calculated checksum
@@ -688,7 +638,6 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
        if (checksum)
                *checksum = checksum_local;
 
-i40e_validate_nvm_checksum_exit:
        return ret_code;
 }
 
@@ -719,6 +668,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
 static i40e_status i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
                                                    struct i40e_nvm_access *cmd,
                                                    u8 *bytes, int *perrno);
+static i40e_status i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
+                                                   struct i40e_nvm_access *cmd,
+                                                   u8 *bytes, int *perrno);
 static INLINE u8 i40e_nvmupd_get_module(u32 val)
 {
        return (u8)(val & I40E_NVM_MOD_PNT_MASK);
@@ -728,6 +680,12 @@ static INLINE u8 i40e_nvmupd_get_transaction(u32 val)
        return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
 }
 
+static INLINE u8 i40e_nvmupd_get_preservation_flags(u32 val)
+{
+       return (u8)((val & I40E_NVM_PRESERVATION_FLAGS_MASK) >>
+                   I40E_NVM_PRESERVATION_FLAGS_SHIFT);
+}
+
 static const char *i40e_nvm_update_state_str[] = {
        "I40E_NVMUPD_INVALID",
        "I40E_NVMUPD_READ_CON",
@@ -745,6 +703,7 @@ static const char *i40e_nvm_update_state_str[] = {
        "I40E_NVMUPD_STATUS",
        "I40E_NVMUPD_EXEC_AQ",
        "I40E_NVMUPD_GET_AQ_RESULT",
+       "I40E_NVMUPD_GET_AQ_EVENT",
 };
 
 /**
@@ -840,9 +799,9 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
                 * the wait info and return before doing anything else
                 */
                if (cmd->offset == 0xffff) {
-                       i40e_nvmupd_check_wait_event(hw, hw->nvm_wait_opcode);
+                       i40e_nvmupd_clear_wait_state(hw);
                        status = I40E_SUCCESS;
-                       goto exit;
+                       break;
                }
 
                status = I40E_ERR_NOT_READY;
@@ -857,7 +816,7 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
                *perrno = -ESRCH;
                break;
        }
-exit:
+
        i40e_release_spinlock(&hw->aq.arq_spinlock);
        return status;
 }
@@ -986,6 +945,10 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
                status = i40e_nvmupd_get_aq_result(hw, cmd, bytes, perrno);
                break;
 
+       case I40E_NVMUPD_GET_AQ_EVENT:
+               status = i40e_nvmupd_get_aq_event(hw, cmd, bytes, perrno);
+               break;
+
        default:
                i40e_debug(hw, I40E_DEBUG_NVM,
                           "NVMUPD: bad cmd %s in init state\n",
@@ -1160,39 +1123,54 @@ retry:
 }
 
 /**
- * i40e_nvmupd_check_wait_event - handle NVM update operation events
+ * i40e_nvmupd_clear_wait_state - clear wait state on hw
  * @hw: pointer to the hardware structure
- * @opcode: the event that just happened
  **/
-void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode)
+void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw)
 {
-       if (opcode == hw->nvm_wait_opcode) {
+       i40e_debug(hw, I40E_DEBUG_NVM,
+                  "NVMUPD: clearing wait on opcode 0x%04x\n",
+                  hw->nvm_wait_opcode);
 
-               i40e_debug(hw, I40E_DEBUG_NVM,
-                          "NVMUPD: clearing wait on opcode 0x%04x\n", opcode);
-               if (hw->nvm_release_on_done) {
-                       i40e_release_nvm(hw);
-                       hw->nvm_release_on_done = false;
-               }
-               hw->nvm_wait_opcode = 0;
+       if (hw->nvm_release_on_done) {
+               i40e_release_nvm(hw);
+               hw->nvm_release_on_done = false;
+       }
+       hw->nvm_wait_opcode = 0;
 
-               if (hw->aq.arq_last_status) {
-                       hw->nvmupd_state = I40E_NVMUPD_STATE_ERROR;
-                       return;
-               }
+       if (hw->aq.arq_last_status) {
+               hw->nvmupd_state = I40E_NVMUPD_STATE_ERROR;
+               return;
+       }
 
-               switch (hw->nvmupd_state) {
-               case I40E_NVMUPD_STATE_INIT_WAIT:
-                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
-                       break;
+       switch (hw->nvmupd_state) {
+       case I40E_NVMUPD_STATE_INIT_WAIT:
+               hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+               break;
 
-               case I40E_NVMUPD_STATE_WRITE_WAIT:
-                       hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
-                       break;
+       case I40E_NVMUPD_STATE_WRITE_WAIT:
+               hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
+               break;
 
-               default:
-                       break;
-               }
+       default:
+               break;
+       }
+}
+
+/**
+ * i40e_nvmupd_check_wait_event - handle NVM update operation events
+ * @hw: pointer to the hardware structure
+ * @opcode: the event that just happened
+ **/
+void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode,
+                                 struct i40e_aq_desc *desc)
+{
+       u32 aq_desc_len = sizeof(struct i40e_aq_desc);
+
+       if (opcode == hw->nvm_wait_opcode) {
+               i40e_memcpy(&hw->nvm_aq_event_desc, desc,
+                           aq_desc_len, I40E_NONDMA_TO_NONDMA);
+               i40e_nvmupd_clear_wait_state(hw);
        }
 }
 
@@ -1248,6 +1226,9 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
                        else if (module == 0)
                                upd_cmd = I40E_NVMUPD_GET_AQ_RESULT;
                        break;
+               case I40E_NVM_AQE:
+                       upd_cmd = I40E_NVMUPD_GET_AQ_EVENT;
+                       break;
                }
                break;
 
@@ -1310,6 +1291,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
        u32 aq_data_len;
 
        i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
+       if (cmd->offset == 0xffff)
+               return I40E_SUCCESS;
+
        memset(&cmd_details, 0, sizeof(cmd_details));
        cmd_details.wb_desc = &hw->nvm_wb_desc;
 
@@ -1346,6 +1330,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
                }
        }
 
+       if (cmd->offset)
+               memset(&hw->nvm_aq_event_desc, 0, aq_desc_len);
+
        /* and away we go! */
        status = i40e_asq_send_command(hw, aq_desc, buff,
                                       buff_size, &cmd_details);
@@ -1355,6 +1342,7 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
                           i40e_stat_str(hw, status),
                           i40e_aq_str(hw, hw->aq.asq_last_status));
                *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
+               return status;
        }
 
        /* should we wait for a followup event? */
@@ -1435,6 +1423,41 @@ static i40e_status i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
        return I40E_SUCCESS;
 }
 
+/**
+ * i40e_nvmupd_get_aq_event - Get the Admin Queue event from previous exec_aq
+ * @hw: pointer to hardware structure
+ * @cmd: pointer to nvm update command buffer
+ * @bytes: pointer to the data buffer
+ * @perrno: pointer to return error code
+ *
+ * cmd structure contains identifiers and data buffer
+ **/
+static i40e_status i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
+                                                   struct i40e_nvm_access *cmd,
+                                                   u8 *bytes, int *perrno)
+{
+       u32 aq_total_len;
+       u32 aq_desc_len;
+
+       i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
+
+       aq_desc_len = sizeof(struct i40e_aq_desc);
+       aq_total_len = aq_desc_len + LE16_TO_CPU(hw->nvm_aq_event_desc.datalen);
+
+       /* check copylength range */
+       if (cmd->data_size > aq_total_len) {
+               i40e_debug(hw, I40E_DEBUG_NVM,
+                          "%s: copy length %d too big, trimming to %d\n",
+                          __func__, cmd->data_size, aq_total_len);
+               cmd->data_size = aq_total_len;
+       }
+
+       i40e_memcpy(bytes, &hw->nvm_aq_event_desc, cmd->data_size,
+                   I40E_NONDMA_TO_NONDMA);
+
+       return I40E_SUCCESS;
+}
+
 /**
  * i40e_nvmupd_nvm_read - Read NVM
  * @hw: pointer to hardware structure
@@ -1530,18 +1553,20 @@ static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
        i40e_status status = I40E_SUCCESS;
        struct i40e_asq_cmd_details cmd_details;
        u8 module, transaction;
+       u8 preservation_flags;
        bool last;
 
        transaction = i40e_nvmupd_get_transaction(cmd->config);
        module = i40e_nvmupd_get_module(cmd->config);
        last = (transaction & I40E_NVM_LCB);
+       preservation_flags = i40e_nvmupd_get_preservation_flags(cmd->config);
 
        memset(&cmd_details, 0, sizeof(cmd_details));
        cmd_details.wb_desc = &hw->nvm_wb_desc;
 
        status = i40e_aq_update_nvm(hw, module, cmd->offset,
                                    (u16)cmd->data_size, bytes, last,
-                                   &cmd_details);
+                                   preservation_flags, &cmd_details);
        if (status) {
                i40e_debug(hw, I40E_DEBUG_NVM,
                           "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
similarity index 98%
rename from i40e-dkms/i40e-2.2.4/src/i40e_osdep.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_osdep.h
index c3fca50e71537ecbef7ddd2efd9d69fc81326d4b..279c4c1fb687b7170d1fc79f366f021ba4c4fe94 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 93%
rename from i40e-dkms/i40e-2.2.4/src/i40e_prototype.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_prototype.h
index 783e5842ba13ee626a4707bb7cf197a0fd1863c4..51106c7d3730e4d35555d82bb7072a0f97674383 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -221,7 +221,9 @@ i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw,
                                struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
                                u32 offset, u16 length, void *data,
-                               bool last_command,
+                               bool last_command, u8 preservation_flags,
+                               struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_nvm_progress(struct i40e_hw *hw, u8 *progress,
                                struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
                                u8 mib_type, void *buff, u16 buff_size,
@@ -235,6 +237,10 @@ i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
                                struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
                                struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_set_dcb_parameters(struct i40e_hw *hw,
+                                                bool dcb_enable,
+                                                struct i40e_asq_cmd_details
+                                                *cmd_details);
 i40e_status i40e_aq_start_lldp(struct i40e_hw *hw,
                                struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
@@ -349,18 +355,15 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
 void i40e_release_nvm(struct i40e_hw *hw);
 i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
                                         u16 *data);
-i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
-                                          u16 *words, u16 *data);
-i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module,
-                                       u32 offset, u16 words, void *data,
-                                       bool last_command);
 i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw);
 i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
                                                 u16 *checksum);
 i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
                                          struct i40e_nvm_access *cmd,
                                          u8 *bytes, int *);
-void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode);
+void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode,
+                                 struct i40e_aq_desc *desc);
+void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw);
 void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status);
 
 extern struct i40e_rx_ptype_decoded i40e_ptype_lookup[];
@@ -370,6 +373,36 @@ static INLINE struct i40e_rx_ptype_decoded decode_rx_desc_ptype(u8 ptype)
        return i40e_ptype_lookup[ptype];
 }
 
+/**
+ * i40e_virtchnl_link_speed - Convert AdminQ link_speed to virtchnl definition
+ * @link_speed: the speed to convert
+ *
+ * Returns the link_speed in terms of the virtchnl interface, for use in
+ * converting link_speed as reported by the AdminQ into the format used for
+ * talking to virtchnl devices. If we can't represent the link speed properly,
+ * report LINK_SPEED_UNKNOWN.
+ **/
+static INLINE enum virtchnl_link_speed
+i40e_virtchnl_link_speed(enum i40e_aq_link_speed link_speed)
+{
+       switch (link_speed) {
+       case I40E_LINK_SPEED_100MB:
+               return VIRTCHNL_LINK_SPEED_100MB;
+       case I40E_LINK_SPEED_1GB:
+               return VIRTCHNL_LINK_SPEED_1GB;
+       case I40E_LINK_SPEED_10GB:
+               return VIRTCHNL_LINK_SPEED_10GB;
+       case I40E_LINK_SPEED_40GB:
+               return VIRTCHNL_LINK_SPEED_40GB;
+       case I40E_LINK_SPEED_20GB:
+               return VIRTCHNL_LINK_SPEED_20GB;
+       case I40E_LINK_SPEED_25GB:
+               return VIRTCHNL_LINK_SPEED_25GB;
+       case I40E_LINK_SPEED_UNKNOWN:
+       default:
+               return VIRTCHNL_LINK_SPEED_UNKNOWN;
+       }
+}
 /* prototype for functions used for SW spinlocks */
 void i40e_init_spinlock(struct i40e_spinlock *sp);
 void i40e_acquire_spinlock(struct i40e_spinlock *sp);
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_ptp.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_ptp.c
index 2ed5cb10007176f26f3e29bc1324fe4a70ed6d0f..2ccfcb4fff54ae59bc95757be43271b60c8503e3 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -132,7 +132,7 @@ static int i40e_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
        }
 
        smp_mb(); /* Force any pending update before accessing. */
-       adj = ACCESS_ONCE(pf->ptp_base_adj);
+       adj = READ_ONCE(pf->ptp_base_adj);
 
        freq = adj;
        freq *= ppb;
@@ -536,7 +536,7 @@ void i40e_ptp_set_increment(struct i40e_pf *pf)
        wr32(hw, I40E_PRTTSYN_INC_H, (u32)(incval >> 32));
 
        /* Update the base adjustement value. */
-       ACCESS_ONCE(pf->ptp_base_adj) = incval;
+       WRITE_ONCE(pf->ptp_base_adj, incval);
        smp_mb(); /* Force the above update. */
 }
 
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_register.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_register.h
index 0997c3e45576e0563300a87d27c9847f961fc83c..633cf30106935037c7e95090924df61912ff2436 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 97%
rename from i40e-dkms/i40e-2.2.4/src/i40e_status.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_status.h
index 3c36226ceaeba1774a0b4f33ec3cd426e8d00305..16cdcec37d0a37dd2f1d7c91933d79369e446a49 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -92,6 +92,7 @@ enum i40e_status_code {
        I40E_ERR_NOT_READY                      = -63,
        I40E_NOT_SUPPORTED                      = -64,
        I40E_ERR_FIRMWARE_API_VERSION           = -65,
+       I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR     = -66,
 };
 
 #endif /* _I40E_STATUS_H_ */
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_trace.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_trace.h
index 929a6e6b343e534a6f5130849824345c11fe77f4..210eae21ee694d5f521fbdcba523a4b0626c167d 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 86%
rename from i40e-dkms/i40e-2.2.4/src/i40e_txrx.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_txrx.c
index bfa529b20b07ccaed2dcb234385839326688f56a..eea26ba04124cda948c7681e06759f8d693b7b95 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -691,16 +691,22 @@ void i40e_free_tx_resources(struct i40e_ring *tx_ring)
 /**
  * i40e_get_tx_pending - how many tx descriptors not processed
  * @tx_ring: the ring of descriptors
+ * @in_sw: use SW variables
  *
  * Since there is no access to the ring head register
  * in XL710, we need to use our local copies
  **/
-u32 i40e_get_tx_pending(struct i40e_ring *ring)
+u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw)
 {
        u32 head, tail;
 
-       head = i40e_get_head(ring);
-       tail = readl(ring->tail);
+       if (!in_sw) {
+               head = i40e_get_head(ring);
+               tail = readl(ring->tail);
+       } else {
+               head = ring->next_to_clean;
+               tail = ring->next_to_use;
+       }
 
        if (head != tail)
                return (head < tail) ?
@@ -709,6 +715,59 @@ u32 i40e_get_tx_pending(struct i40e_ring *ring)
        return 0;
 }
 
+/**
+ * i40e_detect_recover_hung - Function to detect and recover hung_queues
+ * @vsi:  pointer to vsi struct with tx queues
+ *
+ * VSI has netdev and netdev has TX queues. This function is to check each of
+ * those TX queues if they are hung, trigger recovery by issuing SW interrupt.
+ **/
+void i40e_detect_recover_hung(struct i40e_vsi *vsi)
+{
+       struct i40e_ring *tx_ring = NULL;
+       struct net_device *netdev;
+       unsigned int i;
+       int packets;
+
+       if (!vsi)
+               return;
+
+       if (test_bit(__I40E_VSI_DOWN, vsi->state))
+               return;
+
+       netdev = vsi->netdev;
+       if (!netdev)
+               return;
+
+       if (!netif_carrier_ok(netdev))
+               return;
+
+       for (i = 0; i < vsi->num_queue_pairs; i++) {
+               tx_ring = vsi->tx_rings[i];
+               if (tx_ring && tx_ring->desc) {
+                       /* If packet counter has not changed the queue is
+                        * likely stalled, so force an interrupt for this
+                        * queue.
+                        *
+                        * prev_pkt_ctr would be negative if there was no
+                        * pending work.
+                        */
+                       packets = tx_ring->stats.packets & INT_MAX;
+                       if (tx_ring->tx_stats.prev_pkt_ctr == packets) {
+                               i40e_force_wb(vsi, tx_ring->q_vector);
+                               continue;
+                       }
+
+                       /* Memory barrier between read of packet count and call
+                        * to i40e_get_tx_pending()
+                        */
+                       smp_rmb();
+                       tx_ring->tx_stats.prev_pkt_ctr =
+                           i40e_get_tx_pending(tx_ring, true) ? packets : -1;
+               }
+       }
+}
+
 #define WB_STRIDE 4
 
 /**
@@ -825,7 +884,7 @@ static bool i40e_clean_tx_irq(struct i40e_vsi *vsi,
                 * them to be written back in case we stay in NAPI.
                 * In this mode on X722 we do not enable Interrupt.
                 */
-               unsigned int j = i40e_get_tx_pending(tx_ring);
+               unsigned int j = i40e_get_tx_pending(tx_ring, false);
 
                if (budget &&
                    ((j / WB_STRIDE) == 0) && (j > 0) &&
@@ -880,7 +939,7 @@ static void i40e_enable_wb_on_itr(struct i40e_vsi *vsi,
                      I40E_PFINT_DYN_CTLN_ITR_INDX_MASK; /* set noitr */
 
                wr32(&vsi->back->hw,
-                   I40E_PFINT_DYN_CTLN(q_vector->v_idx + vsi->base_vector - 1),
+                   I40E_PFINT_DYN_CTLN(q_vector->reg_idx),
                    val);
        } else {
                val = I40E_PFINT_DYN_CTL0_WB_ON_ITR_MASK |
@@ -907,8 +966,7 @@ void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
                          /* allow 00 to be written to the index */
 
                wr32(&vsi->back->hw,
-                    I40E_PFINT_DYN_CTLN(q_vector->v_idx +
-                                        vsi->base_vector - 1), val);
+                    I40E_PFINT_DYN_CTLN(q_vector->reg_idx), val);
        } else {
                u32 val = I40E_PFINT_DYN_CTL0_INTENA_MASK |
                          I40E_PFINT_DYN_CTL0_ITR_INDX_MASK | /* set noitr */
@@ -920,101 +978,297 @@ void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
        }
 }
 
+static inline bool i40e_container_is_rx(struct i40e_q_vector *q_vector,
+                                       struct i40e_ring_container *rc)
+{
+       return &q_vector->rx == rc;
+}
+
+static inline unsigned int i40e_itr_divisor(struct i40e_q_vector *q_vector)
+{
+       unsigned int divisor;
+
+       switch (q_vector->vsi->back->hw.phy.link_info.link_speed) {
+       case I40E_LINK_SPEED_40GB:
+               divisor = I40E_ITR_ADAPTIVE_MIN_INC * 1024;
+               break;
+       case I40E_LINK_SPEED_25GB:
+       case I40E_LINK_SPEED_20GB:
+               divisor = I40E_ITR_ADAPTIVE_MIN_INC * 512;
+               break;
+       default:
+       case I40E_LINK_SPEED_10GB:
+               divisor = I40E_ITR_ADAPTIVE_MIN_INC * 256;
+               break;
+       case I40E_LINK_SPEED_1GB:
+       case I40E_LINK_SPEED_100MB:
+               divisor = I40E_ITR_ADAPTIVE_MIN_INC * 32;
+               break;
+       }
+
+       return divisor;
+}
+
 /**
- * i40e_set_new_dynamic_itr - Find new ITR level
+ * i40e_update_itr - update the dynamic ITR value based on statistics
+ * @q_vector: structure containing interrupt and ring information
  * @rc: structure containing ring performance data
  *
- * Returns true if ITR changed, false if not
- *
- * Stores a new ITR value based on packets and byte counts during
- * the last interrupt.  The advantage of per interrupt computation
- * is faster updates and more accurate ITR for the current traffic
- * pattern.  Constants in this function were computed based on
- * theoretical maximum wire speed and thresholds were set based on
- * testing data as well as attempting to minimize response time
+ * Stores a new ITR value based on packets and byte
+ * counts during the last interrupt.  The advantage of per interrupt
+ * computation is faster updates and more accurate ITR for the current
+ * traffic pattern.  Constants in this function were computed
+ * based on theoretical maximum wire speed and thresholds were set based
+ * on testing data as well as attempting to minimize response time
  * while increasing bulk throughput.
  **/
-static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
+static void i40e_update_itr(struct i40e_q_vector *q_vector,
+                           struct i40e_ring_container *rc)
 {
-       enum i40e_latency_range new_latency_range = rc->latency_range;
-       u32 new_itr = rc->itr;
-       int bytes_per_usec;
-       unsigned int usecs, estimated_usecs;
+       unsigned int avg_wire_size, packets, bytes, itr;
+       unsigned long next_update = jiffies;
 
-       if (rc->total_packets == 0 || !rc->itr)
-               return false;
+       /* If we don't have any rings just leave ourselves set for maximum
+        * possible latency so we take ourselves out of the equation.
+        */
+       if (!rc->ring || !ITR_IS_DYNAMIC(rc->ring->itr_setting))
+               return;
 
-       usecs = (rc->itr << 1) * ITR_COUNTDOWN_START;
-       bytes_per_usec = rc->total_bytes / usecs;
+       /* For Rx we want to push the delay up and default to low latency.
+        * for Tx we want to pull the delay down and default to high latency.
+        */
+       itr = i40e_container_is_rx(q_vector, rc) ?
+             I40E_ITR_ADAPTIVE_MIN_USECS | I40E_ITR_ADAPTIVE_LATENCY :
+             I40E_ITR_ADAPTIVE_MAX_USECS | I40E_ITR_ADAPTIVE_LATENCY;
+
+       /* If we didn't update within up to 1 - 2 jiffies we can assume
+        * that either packets are coming in so slow there hasn't been
+        * any work, or that there is so much work that NAPI is dealing
+        * with interrupt moderation and we don't need to do anything.
+        */
+       if (time_after(next_update, rc->next_update))
+               goto clear_counts;
+
+       /* If itr_countdown is set it means we programmed an ITR within
+        * the last 4 interrupt cycles. This has a side effect of us
+        * potentially firing an early interrupt. In order to work around
+        * this we need to throw out any data received for a few
+        * interrupts following the update.
+        */
+       if (q_vector->itr_countdown) {
+               itr = rc->target_itr;
+               goto clear_counts;
+       }
+
+       packets = rc->total_packets;
+       bytes = rc->total_bytes;
 
-       /* The calculations in this algorithm depend on interrupts actually
-        * firing at the ITR rate. This may not happen if the packet rate is
-        * really low, or if we've been napi polling. Check to make sure
-        * that's not the case before we continue.
+       if (i40e_container_is_rx(q_vector, rc)) {
+               /* If Rx there are 1 to 4 packets and bytes are less than
+                * 9000 assume insufficient data to use bulk rate limiting
+                * approach unless Tx is already in bulk rate limiting. We
+                * are likely latency driven.
+                */
+               if (packets && packets < 4 && bytes < 9000 &&
+                   (q_vector->tx.target_itr & I40E_ITR_ADAPTIVE_LATENCY)) {
+                       itr = I40E_ITR_ADAPTIVE_LATENCY;
+                       goto adjust_by_size;
+               }
+       } else if (packets < 4) {
+               /* If we have Tx and Rx ITR maxed and Tx ITR is running in
+                * bulk mode and we are receiving 4 or fewer packets just
+                * reset the ITR_ADAPTIVE_LATENCY bit for latency mode so
+                * that the Rx can relax.
+                */
+               if (rc->target_itr == I40E_ITR_ADAPTIVE_MAX_USECS &&
+                   (q_vector->rx.target_itr & I40E_ITR_MASK) ==
+                    I40E_ITR_ADAPTIVE_MAX_USECS)
+                       goto clear_counts;
+       } else if (packets > 32) {
+               /* If we have processed over 32 packets in a single interrupt
+                * for Tx assume we need to switch over to "bulk" mode.
+                */
+               rc->target_itr &= ~I40E_ITR_ADAPTIVE_LATENCY;
+       }
+
+       /* We have no packets to actually measure against. This means
+        * either one of the other queues on this vector is active or
+        * we are a Tx queue doing TSO with too high of an interrupt rate.
+        *
+        * Between 4 and 56 we can assume that our current interrupt delay
+        * is only slightly too low. As such we should increase it by a small
+        * fixed amount.
         */
-       estimated_usecs = jiffies_to_usecs(jiffies - rc->last_itr_update);
-       if (estimated_usecs > usecs) {
-               new_latency_range = I40E_LOW_LATENCY;
-               goto reset_latency;
+       if (packets < 56) {
+               itr = rc->target_itr + I40E_ITR_ADAPTIVE_MIN_INC;
+               if ((itr & I40E_ITR_MASK) > I40E_ITR_ADAPTIVE_MAX_USECS) {
+                       itr &= I40E_ITR_ADAPTIVE_LATENCY;
+                       itr += I40E_ITR_ADAPTIVE_MAX_USECS;
+               }
+               goto clear_counts;
+       }
+
+       if (packets <= 256) {
+               itr = min(q_vector->tx.current_itr, q_vector->rx.current_itr);
+               itr &= I40E_ITR_MASK;
+
+               /* Between 56 and 112 is our "goldilocks" zone where we are
+                * working out "just right". Just report that our current
+                * ITR is good for us.
+                */
+               if (packets <= 112)
+                       goto clear_counts;
+
+               /* If packet count is 128 or greater we are likely looking
+                * at a slight overrun of the delay we want. Try halving
+                * our delay to see if that will cut the number of packets
+                * in half per interrupt.
+                */
+               itr /= 2;
+               itr &= I40E_ITR_MASK;
+               if (itr < I40E_ITR_ADAPTIVE_MIN_USECS)
+                       itr = I40E_ITR_ADAPTIVE_MIN_USECS;
+
+               goto clear_counts;
        }
 
-       /* simple throttlerate management
-        *   0-10MB/s   lowest (50000 ints/s)
-        *  10-20MB/s   low    (20000 ints/s)
-        *  20-1249MB/s bulk   (18000 ints/s)
+       /* The paths below assume we are dealing with a bulk ITR since
+        * number of packets is greater than 256. We are just going to have
+        * to compute a value and try to bring the count under control,
+        * though for smaller packet sizes there isn't much we can do as
+        * NAPI polling will likely be kicking in sooner rather than later.
+        */
+       itr = I40E_ITR_ADAPTIVE_BULK;
+
+adjust_by_size:
+       /* If packet counts are 256 or greater we can assume we have a gross
+        * overestimation of what the rate should be. Instead of trying to fine
+        * tune it just use the formula below to try and dial in an exact value
+        * give the current packet size of the frame.
+        */
+       avg_wire_size = bytes / packets;
+
+       /* The following is a crude approximation of:
+        *  wmem_default / (size + overhead) = desired_pkts_per_int
+        *  rate / bits_per_byte / (size + ethernet overhead) = pkt_rate
+        *  (desired_pkt_rate / pkt_rate) * usecs_per_sec = ITR value
+        *
+        * Assuming wmem_default is 212992 and overhead is 640 bytes per
+        * packet, (256 skb, 64 headroom, 320 shared info), we can reduce the
+        * formula down to
+        *
+        *  (170 * (size + 24)) / (size + 640) = ITR
         *
-        * The math works out because the divisor is in 10^(-6) which
-        * turns the bytes/us input value into MB/s values, but
-        * make sure to use usecs, as the register values written
-        * are in 2 usec increments in the ITR registers, and make sure
-        * to use the smoothed values that the countdown timer gives us.
+        * We first do some math on the packet size and then finally bitshift
+        * by 8 after rounding up. We also have to account for PCIe link speed
+        * difference as ITR scales based on this.
         */
-       switch (new_latency_range) {
-       case I40E_LOWEST_LATENCY:
-               if (bytes_per_usec > 10)
-                       new_latency_range = I40E_LOW_LATENCY;
-               break;
-       case I40E_LOW_LATENCY:
-               if (bytes_per_usec > 20)
-                       new_latency_range = I40E_BULK_LATENCY;
-               else if (bytes_per_usec <= 10)
-                       new_latency_range = I40E_LOWEST_LATENCY;
-               break;
-       case I40E_BULK_LATENCY:
-       default:
-               if (bytes_per_usec <= 20)
-                       new_latency_range = I40E_LOW_LATENCY;
-               break;
+       if (avg_wire_size <= 60) {
+               /* Start at 250k ints/sec */
+               avg_wire_size = 4096;
+       } else if (avg_wire_size <= 380) {
+               /* 250K ints/sec to 60K ints/sec */
+               avg_wire_size *= 40;
+               avg_wire_size += 1696;
+       } else if (avg_wire_size <= 1084) {
+               /* 60K ints/sec to 36K ints/sec */
+               avg_wire_size *= 15;
+               avg_wire_size += 11452;
+       } else if (avg_wire_size <= 1980) {
+               /* 36K ints/sec to 30K ints/sec */
+               avg_wire_size *= 5;
+               avg_wire_size += 22420;
+       } else {
+               /* plateau at a limit of 30K ints/sec */
+               avg_wire_size = 32256;
        }
 
-reset_latency:
-       rc->latency_range = new_latency_range;
+       /* If we are in low latency mode halve our delay which doubles the
+        * rate to somewhere between 100K to 16K ints/sec
+        */
+       if (itr & I40E_ITR_ADAPTIVE_LATENCY)
+               avg_wire_size /= 2;
 
-       switch (new_latency_range) {
-       case I40E_LOWEST_LATENCY:
-               new_itr = I40E_ITR_50K;
-               break;
-       case I40E_LOW_LATENCY:
-               new_itr = I40E_ITR_20K;
-               break;
-       case I40E_BULK_LATENCY:
-               new_itr = I40E_ITR_18K;
-               break;
-       default:
-               break;
+       /* Resultant value is 256 times larger than it needs to be. This
+        * gives us room to adjust the value as needed to either increase
+        * or decrease the value based on link speeds of 10G, 2.5G, 1G, etc.
+        *
+        * Use addition as we have already recorded the new latency flag
+        * for the ITR value.
+        */
+       itr += DIV_ROUND_UP(avg_wire_size, i40e_itr_divisor(q_vector)) *
+              I40E_ITR_ADAPTIVE_MIN_INC;
+
+       if ((itr & I40E_ITR_MASK) > I40E_ITR_ADAPTIVE_MAX_USECS) {
+               itr &= I40E_ITR_ADAPTIVE_LATENCY;
+               itr += I40E_ITR_ADAPTIVE_MAX_USECS;
        }
 
+clear_counts:
+       /* write back value */
+       rc->target_itr = itr;
+
+       /* next update should occur within next jiffy */
+       rc->next_update = next_update + 1;
+
        rc->total_bytes = 0;
        rc->total_packets = 0;
-       rc->last_itr_update = jiffies;
+}
 
-       if (new_itr != rc->itr) {
-               rc->itr = new_itr;
-               return true;
-       }
-       return false;
+#ifndef CONFIG_I40E_DISABLE_PACKET_SPLIT
+/**
+ * i40e_reuse_rx_page - page flip buffer and store it back on the ring
+ * @rx_ring: rx descriptor ring to store buffers on
+ * @old_buff: donor buffer to have page reused
+ *
+ * Synchronizes page for reuse by the adapter
+ **/
+static void i40e_reuse_rx_page(struct i40e_ring *rx_ring,
+                              struct i40e_rx_buffer *old_buff)
+{
+       struct i40e_rx_buffer *new_buff;
+       u16 nta = rx_ring->next_to_alloc;
+
+       new_buff = &rx_ring->rx_bi[nta];
+
+       /* update, and store next to alloc */
+       nta++;
+       rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
+
+       /* transfer page from old buffer to new buffer */
+       new_buff->dma           = old_buff->dma;
+       new_buff->page          = old_buff->page;
+       new_buff->page_offset   = old_buff->page_offset;
+       new_buff->pagecnt_bias  = old_buff->pagecnt_bias;
 }
 
+#endif /* CONFIG_I40E_DISABLE_PACKET_SPLIT */
+#ifdef CONFIG_I40E_DISABLE_PACKET_SPLIT
+/**
+ * i40e_reuse_rx_skb - Recycle unused skb and store it back on the ring
+ * @rx_ring: rx descriptor ring to store buffers on
+ * @old_buff: donor buffer to have skb reused
+ *
+ * Synchronizes skb for reuse by the adapter
+ **/
+static void i40e_reuse_rx_skb(struct i40e_ring *rx_ring,
+                             struct i40e_rx_buffer *old_buff)
+{
+       struct i40e_rx_buffer *new_buff;
+       u16 nta = rx_ring->next_to_alloc;
+
+       new_buff = &rx_ring->rx_bi[nta];
+
+       /* update, and store next to alloc */
+       nta++;
+       rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
+
+       /* transfer page from old buffer to new buffer */
+       new_buff->dma           = old_buff->dma;
+       new_buff->skb           = old_buff->skb;
+}
+
+#endif /* CONFIG_I40E_DISABLE_PACKET_SPLIT */
 /**
  * i40e_rx_is_programming_status - check for programming status descriptor
  * @qw: qword representing status_error_len in CPU ordering
@@ -1049,15 +1303,32 @@ static void i40e_clean_programming_status(struct i40e_ring *rx_ring,
                                          union i40e_rx_desc *rx_desc,
                                          u64 qw)
 {
-       u32 ntc = rx_ring->next_to_clean + 1;
+       struct i40e_rx_buffer *rx_buffer;
+       u32 ntc = rx_ring->next_to_clean;
        u8 id;
 
        /* fetch, update, and store next to clean */
+       rx_buffer = &rx_ring->rx_bi[ntc++];
        ntc = (ntc < rx_ring->count) ? ntc : 0;
        rx_ring->next_to_clean = ntc;
 
        prefetch(I40E_RX_DESC(rx_ring, ntc));
 
+#ifdef CONFIG_I40E_DISABLE_PACKET_SPLIT
+       /* place unused page back on the ring */
+       i40e_reuse_rx_skb(rx_ring, rx_buffer);
+
+       /* clear contents of buffer_info */
+       rx_buffer->skb = NULL;
+#else
+       /* place unused page back on the ring */
+       i40e_reuse_rx_page(rx_ring, rx_buffer);
+       rx_ring->rx_stats.page_reuse_count++;
+
+       /* clear contents of buffer_info */
+       rx_buffer->page = NULL;
+#endif
+
        id = (qw & I40E_RX_PROG_STATUS_DESC_QW1_PROGID_MASK) >>
                  I40E_RX_PROG_STATUS_DESC_QW1_PROGID_SHIFT;
 
@@ -1103,6 +1374,7 @@ int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring)
 
        tx_ring->next_to_use = 0;
        tx_ring->next_to_clean = 0;
+       tx_ring->tx_stats.prev_pkt_ctr = -1;
        return 0;
 
 err:
@@ -1302,7 +1574,7 @@ static bool i40e_alloc_mapped_skb(struct i40e_ring *rx_ring,
        return true;
 }
 
-#else
+#else /* CONFIG_I40E_DISABLE_PACKET_SPLIT */
 /**
  * i40e_rx_offset - Return expected offset into page to access data
  * @rx_ring: Ring we are requesting offset of
@@ -1418,15 +1690,6 @@ bool i40e_alloc_rx_buffers(struct i40e_ring *rx_ring, u16 cleaned_count)
        union i40e_rx_desc *rx_desc;
        struct i40e_rx_buffer *bi;
 
-       /* Hardware only fetches new descriptors in cache lines of 8,
-        * essentially ignoring the lower 3 bits of the tail register. We want
-        * to ensure our tail writes are aligned to avoid unnecessary work. We
-        * can't simply round down the cleaned count, since we might fail to
-        * allocate some buffers. What we really want is to ensure that
-        * next_to_used + cleaned_count produces an aligned value.
-        */
-       cleaned_count -= (ntu + cleaned_count) & 0x7;
-
        /* do nothing if no valid netdev defined */
        if (!rx_ring->netdev || !cleaned_count)
                return false;
@@ -1614,14 +1877,6 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi,
 #else
                skb->encapsulation = 1;
 #endif
-#ifdef I40E_ADD_PROBES
-       if (strcmp(i40e_tunnel_name(&vsi->back->udp_ports[vsi->idx]),
-                  "vxlan") == 0)
-               vsi->back->hw_csum_rx_vxlan++;
-       else if (strcmp(i40e_tunnel_name(&vsi->back->udp_ports[vsi->idx]),
-                       "geneve") == 0)
-               vsi->back->hw_csum_rx_geneve++;
-#endif /* I40E_ADD_PROBES */
 #endif /* I40E_TUNNEL_SUPPORT */
 
        /* Only report checksum unnecessary for TCP, UDP, or SCTP */
@@ -1794,32 +2049,6 @@ static void i40e_put_rx_buffer(struct i40e_ring *rx_ring,
 }
 
 #else /* CONFIG_I40E_DISABLE_PACKET_SPLIT */
-/**
- * i40e_reuse_rx_page - page flip buffer and store it back on the ring
- * @rx_ring: rx descriptor ring to store buffers on
- * @old_buff: donor buffer to have page reused
- *
- * Synchronizes page for reuse by the adapter
- **/
-static void i40e_reuse_rx_page(struct i40e_ring *rx_ring,
-                              struct i40e_rx_buffer *old_buff)
-{
-       struct i40e_rx_buffer *new_buff;
-       u16 nta = rx_ring->next_to_alloc;
-
-       new_buff = &rx_ring->rx_bi[nta];
-
-       /* update, and store next to alloc */
-       nta++;
-       rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
-
-       /* transfer page from old buffer to new buffer */
-       new_buff->dma           = old_buff->dma;
-       new_buff->page          = old_buff->page;
-       new_buff->page_offset   = old_buff->page_offset;
-       new_buff->pagecnt_bias  = old_buff->pagecnt_bias;
-}
-
 /**
  * i40e_page_is_reusable - check if any reuse is possible
  * @page: page struct to check
@@ -2082,7 +2311,7 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,
  * @rx_buffer: rx buffer to pull data from
  *
  * This function will clean up the contents of the rx_buffer.  It will
- * either recycle the bufer or unmap it and free the associated resources.
+ * either recycle the buffer or unmap it and free the associated resources.
  */
 static void i40e_put_rx_buffer(struct i40e_ring *rx_ring,
                               struct i40e_rx_buffer *rx_buffer)
@@ -2189,6 +2418,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
 
                if (unlikely(i40e_rx_is_programming_status(qword))) {
                        i40e_clean_programming_status(rx_ring, rx_desc, qword);
+                       cleaned_count++;
                        continue;
                }
                size = (qword & I40E_RXD_QW1_LENGTH_PBUF_MASK) >>
@@ -2279,29 +2509,45 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
        return failure ? budget : (int)total_rx_packets;
 }
 
-static u32 i40e_buildreg_itr(const int type, const u16 itr)
+static inline u32 i40e_buildreg_itr(const int type, u16 itr)
 {
        u32 val;
 
+       /* We don't bother with setting the CLEARPBA bit as the data sheet
+        * points out doing so is "meaningless since it was already
+        * auto-cleared". The auto-clearing happens when the interrupt is
+        * asserted.
+        *
+        * Hardware errata 28 for also indicates that writing to a
+        * xxINT_DYN_CTLx CSR with INTENA_MSK (bit 31) set to 0 will clear
+        * an event in the PBA anyway so we need to rely on the automask
+        * to hold pending events for us until the interrupt is re-enabled
+        *
+        * The itr value is reported in microseconds, and the register
+        * value is recorded in 2 microsecond units. For this reason we
+        * only need to shift by the interval shift - 1 instead of the
+        * full value.
+        */
+       itr &= I40E_ITR_MASK;
+
        val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
-             I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
              (type << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
-             (itr << I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT);
+             (itr << (I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT - 1));
 
        return val;
 }
 
 /* a small macro to shorten up some long lines */
 #define INTREG I40E_PFINT_DYN_CTLN
-static inline int get_rx_itr(struct i40e_vsi *vsi, int idx)
-{
-       return vsi->rx_rings[idx]->rx_itr_setting;
-}
 
-static inline int get_tx_itr(struct i40e_vsi *vsi, int idx)
-{
-       return vsi->tx_rings[idx]->tx_itr_setting;
-}
+/* The act of updating the ITR will cause it to immediately trigger. In order
+ * to prevent this from throwing off adaptive update statistics we defer the
+ * update so that it can only happen so often. So after either Tx or Rx are
+ * updated we make the adaptive scheme wait until either the ITR completely
+ * expires via the next_update expiration or we have been through at least
+ * 3 interrupts.
+ */
+#define ITR_COUNTDOWN_START 3
 
 /**
  * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt
@@ -2313,11 +2559,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
                                          struct i40e_q_vector *q_vector)
 {
        struct i40e_hw *hw = &vsi->back->hw;
-       bool rx = false, tx = false;
-       u32 rxval, txval;
-       int vector;
-       int idx = q_vector->v_idx;
-       int rx_itr_setting, tx_itr_setting;
+       u32 intval;
 
        /* If we don't have MSIX, then we only need to re-enable icr0 */
        if (!(vsi->back->flags & I40E_FLAG_MSIX_ENABLED)) {
@@ -2325,67 +2567,49 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
                return;
        }
 
-       vector = (q_vector->v_idx + vsi->base_vector);
-
-       /* avoid dynamic calculation if in countdown mode OR if
-        * all dynamic is disabled
-        */
-       rxval = txval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
+       /* These will do nothing if dynamic updates are not enabled */
+       i40e_update_itr(q_vector, &q_vector->tx);
+       i40e_update_itr(q_vector, &q_vector->rx);
 
-       rx_itr_setting = get_rx_itr(vsi, idx);
-       tx_itr_setting = get_tx_itr(vsi, idx);
-
-       if (q_vector->itr_countdown > 0 ||
-           (!ITR_IS_DYNAMIC(rx_itr_setting) &&
-            !ITR_IS_DYNAMIC(tx_itr_setting))) {
-               goto enable_int;
-       }
-
-       if (ITR_IS_DYNAMIC(rx_itr_setting)) {
-               rx = i40e_set_new_dynamic_itr(&q_vector->rx);
-               rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
-       }
-
-       if (ITR_IS_DYNAMIC(tx_itr_setting)) {
-               tx = i40e_set_new_dynamic_itr(&q_vector->tx);
-               txval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr);
-       }
-
-       if (rx || tx) {
-               /* get the higher of the two ITR adjustments and
-                * use the same value for both ITR registers
-                * when in adaptive mode (Rx and/or Tx)
-                */
-               u16 itr = max(q_vector->tx.itr, q_vector->rx.itr);
-
-               q_vector->tx.itr = q_vector->rx.itr = itr;
-               txval = i40e_buildreg_itr(I40E_TX_ITR, itr);
-               tx = true;
-               rxval = i40e_buildreg_itr(I40E_RX_ITR, itr);
-               rx = true;
-       }
-
-       /* only need to enable the interrupt once, but need
-        * to possibly update both ITR values
+       /* This block of logic allows us to get away with only updating
+        * one ITR value with each interrupt. The idea is to perform a
+        * pseudo-lazy update with the following criteria.
+        *
+        * 1. Rx is given higher priority than Tx if both are in same state
+        * 2. If we must reduce an ITR that is given highest priority.
+        * 3. We then give priority to increasing ITR based on amount.
         */
-       if (rx) {
-               /* set the INTENA_MSK_MASK so that this first write
-                * won't actually enable the interrupt, instead just
-                * updating the ITR (it's bit 31 PF and VF)
+       if (q_vector->rx.target_itr < q_vector->rx.current_itr) {
+               /* Rx ITR needs to be reduced, this is highest priority */
+               intval = i40e_buildreg_itr(I40E_RX_ITR,
+                                          q_vector->rx.target_itr);
+               q_vector->rx.current_itr = q_vector->rx.target_itr;
+               q_vector->itr_countdown = ITR_COUNTDOWN_START;
+       } else if ((q_vector->tx.target_itr < q_vector->tx.current_itr) ||
+                  ((q_vector->rx.target_itr - q_vector->rx.current_itr) <
+                   (q_vector->tx.target_itr - q_vector->tx.current_itr))) {
+               /* Tx ITR needs to be reduced, this is second priority
+                * Tx ITR needs to be increased more than Rx, fourth priority
                 */
-               rxval |= BIT(31);
-               /* don't check _DOWN because interrupt isn't being enabled */
-               wr32(hw, INTREG(vector - 1), rxval);
+               intval = i40e_buildreg_itr(I40E_TX_ITR,
+                                          q_vector->tx.target_itr);
+               q_vector->tx.current_itr = q_vector->tx.target_itr;
+               q_vector->itr_countdown = ITR_COUNTDOWN_START;
+       } else if (q_vector->rx.current_itr != q_vector->rx.target_itr) {
+               /* Rx ITR needs to be increased, third priority */
+               intval = i40e_buildreg_itr(I40E_RX_ITR,
+                                          q_vector->rx.target_itr);
+               q_vector->rx.current_itr = q_vector->rx.target_itr;
+               q_vector->itr_countdown = ITR_COUNTDOWN_START;
+       } else {
+               /* No ITR update, lowest priority */
+               intval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
+               if (q_vector->itr_countdown)
+                       q_vector->itr_countdown--;
        }
 
-enable_int:
        if (!test_bit(__I40E_VSI_DOWN, vsi->state))
-               wr32(hw, INTREG(vector - 1), txval);
-
-       if (q_vector->itr_countdown)
-               q_vector->itr_countdown--;
-       else
-               q_vector->itr_countdown = ITR_COUNTDOWN_START;
+               wr32(hw, INTREG(q_vector->reg_idx), intval);
 }
 
 /**
@@ -3217,10 +3441,30 @@ bool __i40e_chk_linearize(struct sk_buff *skb)
        /* Walk through fragments adding latest fragment, testing it, and
         * then removing stale fragments from the sum.
         */
-       stale = &skb_shinfo(skb)->frags[0];
-       for (;;) {
+       for (stale = &skb_shinfo(skb)->frags[0];; stale++) {
+               int stale_size = skb_frag_size(stale);
+
                sum += skb_frag_size(frag++);
 
+               /* The stale fragment may present us with a smaller
+                * descriptor than the actual fragment size. To account
+                * for that we need to remove all the data on the front and
+                * figure out what the remainder would be in the last
+                * descriptor associated with the fragment.
+                */
+               if (stale_size > I40E_MAX_DATA_PER_TXD) {
+                       int align_pad = -(stale->page_offset) &
+                                       (I40E_MAX_READ_REQ_SIZE - 1);
+
+                       sum -= align_pad;
+                       stale_size -= align_pad;
+
+                       do {
+                               sum -= I40E_MAX_DATA_PER_TXD_ALIGNED;
+                               stale_size -= I40E_MAX_DATA_PER_TXD_ALIGNED;
+                       } while (stale_size > I40E_MAX_DATA_PER_TXD);
+               }
+
                /* if sum is negative we failed to make sufficient progress */
                if (sum < 0)
                        return true;
@@ -3228,7 +3472,7 @@ bool __i40e_chk_linearize(struct sk_buff *skb)
                if (!nr_frags--)
                        break;
 
-               sum -= skb_frag_size(stale++);
+               sum -= stale_size;
        }
 
        return false;
similarity index 90%
rename from i40e-dkms/i40e-2.2.4/src/i40e_txrx.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_txrx.h
index ffcc5857b0f3a483ae8faa6991f54a8d69fda8a9..2100da8426b267b98b052d9a98a92795613ff674 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
 #define _I40E_TXRX_H_
 
 /* Interrupt Throttling and Rate Limiting Goodies */
-
-#define I40E_MAX_ITR               0x0FF0  /* reg uses 2 usec resolution */
-#define I40E_MIN_ITR               0x0001  /* reg uses 2 usec resolution */
-#define I40E_ITR_100K              0x0005
-#define I40E_ITR_50K               0x000A
-#define I40E_ITR_20K               0x0019
-#define I40E_ITR_18K               0x001B
-#define I40E_ITR_8K                0x003E
-#define I40E_ITR_4K                0x007A
-#define I40E_MAX_INTRL             0x3B    /* reg uses 4 usec resolution */
-#define I40E_ITR_RX_DEF            (ITR_REG_TO_USEC(I40E_ITR_20K) | \
-                                   I40E_ITR_DYNAMIC)
-#define I40E_ITR_TX_DEF            (ITR_REG_TO_USEC(I40E_ITR_20K) | \
-                                   I40E_ITR_DYNAMIC)
-#define I40E_ITR_DYNAMIC           0x8000  /* use top bit as a flag */
-#define I40E_MIN_INT_RATE          250     /* ~= 1000000 / (I40E_MAX_ITR * 2) */
-#define I40E_MAX_INT_RATE          500000  /* == 1000000 / (I40E_MIN_ITR * 2) */
 #define I40E_DEFAULT_IRQ_WORK      256
-#define ITR_TO_REG(setting) ((setting & ~I40E_ITR_DYNAMIC) >> 1)
-#define ITR_IS_DYNAMIC(setting) (!!(setting & I40E_ITR_DYNAMIC))
-#define ITR_REG_TO_USEC(itr_reg) (itr_reg << 1)
+
+/* The datasheet for the X710 and XL710 indicate that the maximum value for
+ * the ITR is 8160usec which is then called out as 0xFF0 with a 2usec
+ * resolution. 8160 is 0x1FE0 when written out in hex. So instead of storing
+ * the register value which is divided by 2 lets use the actual values and
+ * avoid an excessive amount of translation.
+ */
+#define I40E_ITR_DYNAMIC       0x8000  /* use top bit as a flag */
+#define I40E_ITR_MASK          0x1FFE  /* mask for ITR register value */
+#define I40E_MIN_ITR                2  /* reg uses 2 usec resolution */
+#define I40E_ITR_100K              10  /* all values below must be even */
+#define I40E_ITR_50K               20
+#define I40E_ITR_20K               50
+#define I40E_ITR_18K               60
+#define I40E_ITR_8K               122
+#define I40E_MAX_ITR             8160  /* maximum value as per datasheet */
+#define ITR_TO_REG(setting) ((setting) & ~I40E_ITR_DYNAMIC)
+#define ITR_REG_ALIGN(setting) __ALIGN_MASK(setting, ~I40E_ITR_MASK)
+#define ITR_IS_DYNAMIC(setting) (!!((setting) & I40E_ITR_DYNAMIC))
+
+#define I40E_ITR_RX_DEF            (I40E_ITR_20K | I40E_ITR_DYNAMIC)
+#define I40E_ITR_TX_DEF            (I40E_ITR_20K | I40E_ITR_DYNAMIC)
+
 /* 0x40 is the enable bit for interrupt rate limiting, and must be set if
  * the value of the rate limit is non-zero
  */
 #define INTRL_ENA                  BIT(6)
+#define I40E_MAX_INTRL             0x3B    /* reg uses 4 usec resolution */
 #define INTRL_REG_TO_USEC(intrl) ((intrl & ~INTRL_ENA) << 2)
+
 /**
  * i40e_intrl_usec_to_reg - convert interrupt rate limit to register
  * @intrl: interrupt rate limit to convert
@@ -342,6 +347,7 @@ struct i40e_tx_queue_stats {
        u64 tx_done_old;
        u64 tx_linearize;
        u64 tx_force_wb;
+       int prev_pkt_ctr;
 };
 
 struct i40e_rx_queue_stats {
@@ -389,8 +395,7 @@ struct i40e_ring {
         * these values always store the USER setting, and must be converted
         * before programming to a register.
         */
-       u16 rx_itr_setting;
-       u16 tx_itr_setting;
+       u16 itr_setting;
 
        u16 count;                      /* Number of descriptors */
        u16 reg_idx;                    /* HW register index of the ring */
@@ -454,21 +459,21 @@ static inline void clear_ring_build_skb_enabled(struct i40e_ring *ring)
        ring->flags &= ~I40E_RXR_FLAGS_BUILD_SKB_ENABLED;
 }
 
-enum i40e_latency_range {
-       I40E_LOWEST_LATENCY = 0,
-       I40E_LOW_LATENCY = 1,
-       I40E_BULK_LATENCY = 2,
-};
+#define I40E_ITR_ADAPTIVE_MIN_INC       0x0002
+#define I40E_ITR_ADAPTIVE_MIN_USECS     0x0002
+#define I40E_ITR_ADAPTIVE_MAX_USECS     0x007e
+#define I40E_ITR_ADAPTIVE_LATENCY       0x8000
+#define I40E_ITR_ADAPTIVE_BULK          0x0000
+#define ITR_IS_BULK(x) (!((x) & I40E_ITR_ADAPTIVE_LATENCY))
 
 struct i40e_ring_container {
-       /* array of pointers to rings */
-       struct i40e_ring *ring;
+       struct i40e_ring *ring;         /* pointer to linked list of ring(s) */
+       unsigned long next_update;      /* jiffies value of next update */
        unsigned int total_bytes;       /* total bytes processed this int */
        unsigned int total_packets;     /* total packets processed this int */
-       unsigned long last_itr_update;  /* jiffies of last ITR update */
        u16 count;
-       enum i40e_latency_range latency_range;
-       u16 itr;
+       u16 target_itr;                 /* target ITR setting for ring(s) */
+       u16 current_itr;                /* current ITR setting for ring(s) */
 };
 
 /* iterator for handling rings in ring container */
@@ -500,7 +505,8 @@ void i40e_free_tx_resources(struct i40e_ring *tx_ring);
 void i40e_free_rx_resources(struct i40e_ring *rx_ring);
 int i40e_napi_poll(struct napi_struct *napi, int budget);
 void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector);
-u32 i40e_get_tx_pending(struct i40e_ring *ring);
+u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw);
+void i40e_detect_recover_hung(struct i40e_vsi *vsi);
 int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
 bool __i40e_chk_linearize(struct sk_buff *skb);
 
similarity index 98%
rename from i40e-dkms/i40e-2.2.4/src/i40e_type.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_type.h
index a380f7d91a6a830146c9cad2a7c4218a8eba7ad4..a1a1240f7beaa0a8c60a8facb1ece1abdcac50e1 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -407,6 +407,7 @@ enum i40e_nvmupd_cmd {
        I40E_NVMUPD_STATUS,
        I40E_NVMUPD_EXEC_AQ,
        I40E_NVMUPD_GET_AQ_RESULT,
+       I40E_NVMUPD_GET_AQ_EVENT,
 };
 
 enum i40e_nvmupd_state {
@@ -426,15 +427,21 @@ enum i40e_nvmupd_state {
 
 #define I40E_NVM_MOD_PNT_MASK 0xFF
 
-#define I40E_NVM_TRANS_SHIFT   8
-#define I40E_NVM_TRANS_MASK    (0xf << I40E_NVM_TRANS_SHIFT)
-#define I40E_NVM_CON           0x0
-#define I40E_NVM_SNT           0x1
-#define I40E_NVM_LCB           0x2
-#define I40E_NVM_SA            (I40E_NVM_SNT | I40E_NVM_LCB)
-#define I40E_NVM_ERA           0x4
-#define I40E_NVM_CSUM          0x8
-#define I40E_NVM_EXEC          0xf
+#define I40E_NVM_TRANS_SHIFT                   8
+#define I40E_NVM_TRANS_MASK                    (0xf << I40E_NVM_TRANS_SHIFT)
+#define I40E_NVM_PRESERVATION_FLAGS_SHIFT      12
+#define I40E_NVM_PRESERVATION_FLAGS_MASK \
+                               (0x3 << I40E_NVM_PRESERVATION_FLAGS_SHIFT)
+#define I40E_NVM_PRESERVATION_FLAGS_SELECTED   0x01
+#define I40E_NVM_PRESERVATION_FLAGS_ALL                0x02
+#define I40E_NVM_CON                           0x0
+#define I40E_NVM_SNT                           0x1
+#define I40E_NVM_LCB                           0x2
+#define I40E_NVM_SA                            (I40E_NVM_SNT | I40E_NVM_LCB)
+#define I40E_NVM_ERA                           0x4
+#define I40E_NVM_CSUM                          0x8
+#define I40E_NVM_AQE                           0xe
+#define I40E_NVM_EXEC                          0xf
 
 #define I40E_NVM_ADAPT_SHIFT   16
 #define I40E_NVM_ADAPT_MASK    (0xffffULL << I40E_NVM_ADAPT_SHIFT)
@@ -458,6 +465,7 @@ struct i40e_nvm_access {
 #define I40E_MODULE_SFF_8472_COMP      0x5E
 #define I40E_MODULE_SFF_8472_SWAP      0x5C
 #define I40E_MODULE_SFF_ADDR_MODE      0x04
+#define I40E_MODULE_SFF_DIAG_CAPAB     0x40
 #define I40E_MODULE_TYPE_QSFP_PLUS     0x0D
 #define I40E_MODULE_TYPE_QSFP28                0x11
 #define I40E_MODULE_QSFP_MAX_LEN       640
@@ -616,6 +624,7 @@ struct i40e_hw {
        /* state of nvm update process */
        enum i40e_nvmupd_state nvmupd_state;
        struct i40e_aq_desc nvm_wb_desc;
+       struct i40e_aq_desc nvm_aq_event_desc;
        struct i40e_virt_mem nvm_buff;
        bool nvm_release_on_done;
        u16 nvm_wait_opcode;
@@ -638,6 +647,7 @@ struct i40e_hw {
 #define I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE BIT_ULL(0)
 #define I40E_HW_FLAG_802_1AD_CAPABLE        BIT_ULL(1)
 #define I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE  BIT_ULL(2)
+#define I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK BIT_ULL(3)
        u64 flags;
 
        /* Used in set switch config AQ command */
@@ -1331,6 +1341,8 @@ struct i40e_hw_port_stats {
 #define I40E_SR_PCIE_ALT_MODULE_MAX_SIZE       1024
 #define I40E_SR_CONTROL_WORD_1_SHIFT           0x06
 #define I40E_SR_CONTROL_WORD_1_MASK    (0x03 << I40E_SR_CONTROL_WORD_1_SHIFT)
+#define I40E_SR_CONTROL_WORD_1_NVM_BANK_VALID  BIT(5)
+#define I40E_SR_NVM_MAP_STRUCTURE_TYPE         BIT(12)
 
 /* Shadow RAM related */
 #define I40E_SR_SECTOR_SIZE_IN_WORDS   0x800
similarity index 98%
rename from i40e-dkms/i40e-2.2.4/src/i40e_virtchnl_pf.c
rename to i40e-dkms/i40e-2.4.6/src/i40e_virtchnl_pf.c
index 19accdd8fe27b9ca96e813cc6b133733e33a35ca..6c7549f79b67d82558bc9698e0522a3aa13f17a3 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -79,13 +79,13 @@ static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf)
        if (vf->link_forced) {
                pfe.event_data.link_event.link_status = vf->link_up;
                pfe.event_data.link_event.link_speed =
-                       (vf->link_up ? I40E_LINK_SPEED_40GB : 0);
+                       (vf->link_up ? VIRTCHNL_LINK_SPEED_40GB : 0);
        } else {
 #endif
                pfe.event_data.link_event.link_status =
                        ls->link_info & I40E_AQ_LINK_UP;
                pfe.event_data.link_event.link_speed =
-                       (enum virtchnl_link_speed)ls->link_speed;
+                       i40e_virtchnl_link_speed(ls->link_speed);
 #ifdef HAVE_NDO_SET_VF_LINK_STATE
        }
 #endif
@@ -1587,39 +1587,39 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
                                  VIRTCHNL_VF_OFFLOAD_RSS_REG |
                                  VIRTCHNL_VF_OFFLOAD_VLAN;
 
-       vfres->vf_offload_flags = VIRTCHNL_VF_OFFLOAD_L2;
+       vfres->vf_cap_flags = VIRTCHNL_VF_OFFLOAD_L2;
        vsi = pf->vsi[vf->lan_vsi_idx];
        if (!vsi->info.pvid)
-               vfres->vf_offload_flags |= VIRTCHNL_VF_OFFLOAD_VLAN;
+               vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_VLAN;
        if (i40e_vf_client_capable(pf, vf->vf_id) &&
            (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_IWARP)) {
-               vfres->vf_offload_flags |= VIRTCHNL_VF_OFFLOAD_IWARP;
+               vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_IWARP;
                set_bit(I40E_VF_STATE_IWARPENA, &vf->vf_states);
        } else {
                clear_bit(I40E_VF_STATE_IWARPENA, &vf->vf_states);
        }
 
        if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
-               vfres->vf_offload_flags |= VIRTCHNL_VF_OFFLOAD_RSS_PF;
+               vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_RSS_PF;
        } else {
                if ((pf->hw_features & I40E_HW_RSS_AQ_CAPABLE) &&
                    (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_RSS_AQ))
-                       vfres->vf_offload_flags |= VIRTCHNL_VF_OFFLOAD_RSS_AQ;
+                       vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_RSS_AQ;
                else
-                       vfres->vf_offload_flags |= VIRTCHNL_VF_OFFLOAD_RSS_REG;
+                       vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_RSS_REG;
        }
        if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
                if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
-                       vfres->vf_offload_flags |=
+                       vfres->vf_cap_flags |=
                                VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2;
        }
 
        if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_ENCAP)
-               vfres->vf_offload_flags |= VIRTCHNL_VF_OFFLOAD_ENCAP;
+               vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_ENCAP;
 
        if ((pf->hw_features & I40E_HW_OUTER_UDP_CSUM_CAPABLE) &&
            (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM))
-               vfres->vf_offload_flags |= VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM;
+               vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM;
 
        if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_RX_POLLING) {
                if (pf->flags & I40E_FLAG_MFP_ENABLED) {
@@ -1629,17 +1629,17 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
                        aq_ret = I40E_ERR_PARAM;
                        goto err;
                }
-               vfres->vf_offload_flags |= VIRTCHNL_VF_OFFLOAD_RX_POLLING;
+               vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_RX_POLLING;
        }
 
        if (pf->hw_features & I40E_HW_WB_ON_ITR_CAPABLE) {
                if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR)
-                       vfres->vf_offload_flags |=
+                       vfres->vf_cap_flags |=
                                        VIRTCHNL_VF_OFFLOAD_WB_ON_ITR;
        }
 
        if (vf->driver_caps & VIRTCHNL_VF_OFFLOAD_REQ_QUEUES)
-               vfres->vf_offload_flags |= VIRTCHNL_VF_OFFLOAD_REQ_QUEUES;
+               vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_REQ_QUEUES;
 
        vfres->num_vsis = num_vsis;
        vfres->num_queue_pairs = vf->num_queue_pairs;
@@ -1663,7 +1663,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
         * negotiated
         */
        if (pf->vf_base_mode_only)
-               vfres->vf_offload_flags &= VF_BASE_MODE_OFFLOADS;
+               vfres->vf_cap_flags &= VF_BASE_MODE_OFFLOADS;
 err:
        /* send the response back to the VF */
        ret = i40e_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_VF_RESOURCES,
@@ -2063,8 +2063,9 @@ error_param:
  * @msglen: msg length
  *
  * VFs get a default number of queues but can use this message to request a
- * different number.  Will respond with either the number requested or the
- * maximum we can support.
+ * different number.  If the request is successful, PF will reset the VF and
+ * return 0.  If unsuccessful, PF will send message informing VF of number of
+ * available queues and return result of sending VF a message.
  **/
 static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg, int msglen)
 {
@@ -2095,11 +2096,15 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg, int msglen)
                         pf->queues_left);
                vfres->num_queue_pairs = pf->queues_left + cur_pairs;
        } else {
+               /* successful request */
                vf->num_req_queues = req_pairs;
+               i40e_vc_notify_vf_reset(vf);
+               i40e_reset_vf(vf, false);
+               return 0;
        }
 
        return i40e_vc_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 0,
-                                     (u8 *)vfres, sizeof(vfres));
+                                     (u8 *)vfres, sizeof(*vfres));
 }
 
 /**
@@ -2767,6 +2772,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode,
                break;
        case VIRTCHNL_OP_GET_VF_RESOURCES:
                ret = i40e_vc_get_vf_resources_msg(vf, msg);
+               i40e_vc_notify_vf_link_state(vf);
                break;
        case VIRTCHNL_OP_RESET_VF:
                i40e_vc_reset_vf_msg(vf);
@@ -3364,7 +3370,7 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
                pfe.event_data.link_event.link_status =
                        ls->link_info & I40E_AQ_LINK_UP;
                pfe.event_data.link_event.link_speed =
-                       (enum virtchnl_link_speed)ls->link_speed;
+                       i40e_virtchnl_link_speed(ls->link_speed);
                break;
        case IFLA_VF_LINK_STATE_ENABLE:
                vf->link_forced = true;
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/i40e_virtchnl_pf.h
rename to i40e-dkms/i40e-2.4.6/src/i40e_virtchnl_pf.h
index 8f20b4745fb7f96486bbc43289fe0ae2b8d7d87f..8f48651eca73f23af5b370ff1175925f6e77612e 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
similarity index 98%
rename from i40e-dkms/i40e-2.2.4/src/kcompat.c
rename to i40e-dkms/i40e-2.4.6/src/kcompat.c
index 3b12bca6d0490e15f5d5464a6be0243acc1b51d3..c825e938fd9bde0729ee7ae019a8b5128f9e4682 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -1453,112 +1453,6 @@ int __kc_pcie_capability_clear_word(struct pci_dev *dev, int pos,
 }
 #endif /* < 3.7.0 */
 
-/******************************************************************************
- * ripped from linux/net/ipv6/exthdrs_core.c, GPL2, no direct copyright,
- * inferred copyright from kernel
- */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) )
-int __kc_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
-                      int target, unsigned short *fragoff, int *flags)
-{
-       unsigned int start = skb_network_offset(skb) + sizeof(struct ipv6hdr);
-       u8 nexthdr = ipv6_hdr(skb)->nexthdr;
-       unsigned int len;
-       bool found;
-
-#define __KC_IP6_FH_F_FRAG     BIT(0)
-#define __KC_IP6_FH_F_AUTH     BIT(1)
-#define __KC_IP6_FH_F_SKIP_RH  BIT(2)
-
-       if (fragoff)
-               *fragoff = 0;
-
-       if (*offset) {
-               struct ipv6hdr _ip6, *ip6;
-
-               ip6 = skb_header_pointer(skb, *offset, sizeof(_ip6), &_ip6);
-               if (!ip6 || (ip6->version != 6)) {
-                       printk(KERN_ERR "IPv6 header not found\n");
-                       return -EBADMSG;
-               }
-               start = *offset + sizeof(struct ipv6hdr);
-               nexthdr = ip6->nexthdr;
-       }
-       len = skb->len - start;
-
-       do {
-               struct ipv6_opt_hdr _hdr, *hp;
-               unsigned int hdrlen;
-               found = (nexthdr == target);
-
-               if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
-                       if (target < 0 || found)
-                               break;
-                       return -ENOENT;
-               }
-
-               hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
-               if (!hp)
-                       return -EBADMSG;
-
-               if (nexthdr == NEXTHDR_ROUTING) {
-                       struct ipv6_rt_hdr _rh, *rh;
-
-                       rh = skb_header_pointer(skb, start, sizeof(_rh),
-                                               &_rh);
-                       if (!rh)
-                               return -EBADMSG;
-
-                       if (flags && (*flags & __KC_IP6_FH_F_SKIP_RH) &&
-                           rh->segments_left == 0)
-                               found = false;
-               }
-
-               if (nexthdr == NEXTHDR_FRAGMENT) {
-                       unsigned short _frag_off;
-                       __be16 *fp;
-
-                       if (flags)      /* Indicate that this is a fragment */
-                               *flags |= __KC_IP6_FH_F_FRAG;
-                       fp = skb_header_pointer(skb,
-                                               start+offsetof(struct frag_hdr,
-                                                              frag_off),
-                                               sizeof(_frag_off),
-                                               &_frag_off);
-                       if (!fp)
-                               return -EBADMSG;
-
-                       _frag_off = ntohs(*fp) & ~0x7;
-                       if (_frag_off) {
-                               if (target < 0 &&
-                                   ((!ipv6_ext_hdr(hp->nexthdr)) ||
-                                    hp->nexthdr == NEXTHDR_NONE)) {
-                                       if (fragoff)
-                                               *fragoff = _frag_off;
-                                       return hp->nexthdr;
-                               }
-                               return -ENOENT;
-                       }
-                       hdrlen = 8;
-               } else if (nexthdr == NEXTHDR_AUTH) {
-                       if (flags && (*flags & __KC_IP6_FH_F_AUTH) && (target < 0))
-                               break;
-                       hdrlen = (hp->hdrlen + 2) << 2;
-               } else
-                       hdrlen = ipv6_optlen(hp);
-
-               if (!found) {
-                       nexthdr = hp->nexthdr;
-                       len -= hdrlen;
-                       start += hdrlen;
-               }
-       } while (!found);
-
-       *offset = start;
-       return nexthdr;
-}
-#endif /* < 3.8.0 */
-
 /******************************************************************************/
 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) )
 #ifdef CONFIG_XPS
@@ -1817,7 +1711,7 @@ int __kc_pci_vfs_assigned(struct pci_dev __maybe_unused *dev)
 
 /*****************************************************************************/
 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) )
-const unsigned char pcie_link_speed[] = {
+static const unsigned char pcie_link_speed[] = {
        PCI_SPEED_UNKNOWN,      /* 0 */
        PCIE_SPEED_2_5GT,       /* 1 */
        PCIE_SPEED_5_0GT,       /* 2 */
@@ -1903,6 +1797,110 @@ void __kc_netdev_rss_key_fill(void *buffer, size_t len)
 #endif /* 3.13.0 */
 
 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) )
+/******************************************************************************
+ * ripped from linux/net/ipv6/exthdrs_core.c, GPL2, no direct copyright,
+ * inferred copyright from kernel
+ */
+int __kc_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
+                      int target, unsigned short *fragoff, int *flags)
+{
+       unsigned int start = skb_network_offset(skb) + sizeof(struct ipv6hdr);
+       u8 nexthdr = ipv6_hdr(skb)->nexthdr;
+       unsigned int len;
+       bool found;
+
+#define __KC_IP6_FH_F_FRAG     BIT(0)
+#define __KC_IP6_FH_F_AUTH     BIT(1)
+#define __KC_IP6_FH_F_SKIP_RH  BIT(2)
+
+       if (fragoff)
+               *fragoff = 0;
+
+       if (*offset) {
+               struct ipv6hdr _ip6, *ip6;
+
+               ip6 = skb_header_pointer(skb, *offset, sizeof(_ip6), &_ip6);
+               if (!ip6 || (ip6->version != 6)) {
+                       printk(KERN_ERR "IPv6 header not found\n");
+                       return -EBADMSG;
+               }
+               start = *offset + sizeof(struct ipv6hdr);
+               nexthdr = ip6->nexthdr;
+       }
+       len = skb->len - start;
+
+       do {
+               struct ipv6_opt_hdr _hdr, *hp;
+               unsigned int hdrlen;
+               found = (nexthdr == target);
+
+               if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
+                       if (target < 0 || found)
+                               break;
+                       return -ENOENT;
+               }
+
+               hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
+               if (!hp)
+                       return -EBADMSG;
+
+               if (nexthdr == NEXTHDR_ROUTING) {
+                       struct ipv6_rt_hdr _rh, *rh;
+
+                       rh = skb_header_pointer(skb, start, sizeof(_rh),
+                                               &_rh);
+                       if (!rh)
+                               return -EBADMSG;
+
+                       if (flags && (*flags & __KC_IP6_FH_F_SKIP_RH) &&
+                           rh->segments_left == 0)
+                               found = false;
+               }
+
+               if (nexthdr == NEXTHDR_FRAGMENT) {
+                       unsigned short _frag_off;
+                       __be16 *fp;
+
+                       if (flags)      /* Indicate that this is a fragment */
+                               *flags |= __KC_IP6_FH_F_FRAG;
+                       fp = skb_header_pointer(skb,
+                                               start+offsetof(struct frag_hdr,
+                                                              frag_off),
+                                               sizeof(_frag_off),
+                                               &_frag_off);
+                       if (!fp)
+                               return -EBADMSG;
+
+                       _frag_off = ntohs(*fp) & ~0x7;
+                       if (_frag_off) {
+                               if (target < 0 &&
+                                   ((!ipv6_ext_hdr(hp->nexthdr)) ||
+                                    hp->nexthdr == NEXTHDR_NONE)) {
+                                       if (fragoff)
+                                               *fragoff = _frag_off;
+                                       return hp->nexthdr;
+                               }
+                               return -ENOENT;
+                       }
+                       hdrlen = 8;
+               } else if (nexthdr == NEXTHDR_AUTH) {
+                       if (flags && (*flags & __KC_IP6_FH_F_AUTH) && (target < 0))
+                               break;
+                       hdrlen = (hp->hdrlen + 2) << 2;
+               } else
+                       hdrlen = ipv6_optlen(hp);
+
+               if (!found) {
+                       nexthdr = hp->nexthdr;
+                       len -= hdrlen;
+                       start += hdrlen;
+               }
+       } while (!found);
+
+       *offset = start;
+       return nexthdr;
+}
+
 int __kc_pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
                               int minvec, int maxvec)
 {
@@ -2089,7 +2087,7 @@ void __kc_dev_addr_unsync_dev(struct dev_addr_list **list, int *count,
 #endif /* NETDEV_HW_ADDR_T_MULTICAST  */
 #endif /* HAVE_SET_RX_MODE */
 void *__kc_devm_kmemdup(struct device *dev, const void *src, size_t len,
-                       unsigned int gfp)
+                       gfp_t gfp)
 {
        void *p;
 
@@ -2380,4 +2378,23 @@ int _kc_eth_platform_get_mac_address(struct device *dev __maybe_unused,
 #endif
 }
 #endif /* !(RHEL_RELEASE >= 7.3) */
-#endif
+#endif /* < 4.5.0 */
+
+/******************************************************************************/
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) )
+#ifdef ETHTOOL_GLINKSETTINGS
+void _kc_ethtool_intersect_link_masks(struct ethtool_link_ksettings *dst,
+                                     struct ethtool_link_ksettings *src)
+{
+       unsigned int size = BITS_TO_LONGS(__ETHTOOL_LINK_MODE_MASK_NBITS);
+       unsigned int idx = 0;
+
+       for (; idx < size; idx++) {
+               dst->link_modes.supported[idx] &=
+                       src->link_modes.supported[idx];
+               dst->link_modes.advertising[idx] &=
+                       src->link_modes.advertising[idx];
+       }
+}
+#endif /* ETHTOOL_GKLINKSETTINGS */
+#endif /* 4.15.0 */
similarity index 97%
rename from i40e-dkms/i40e-2.2.4/src/kcompat.h
rename to i40e-dkms/i40e-2.4.6/src/kcompat.h
index 08d6e2f57693ef8e1a4ea450a2dbec013ee6de8b..f63da5bede1f54178415638f6e72f9e3ef1677e6 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -866,9 +866,13 @@ struct _kc_ethtool_pauseparam {
 #elif (LINUX_VERSION_CODE == KERNEL_VERSION(4,4,21))
 /* SLES12 SP2 GA is 4.4.21-69 */
 #define SLE_VERSION_CODE SLE_VERSION(12,2,0)
-/* SLES12 SP3 Beta3 is 4.4.68-2 */
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,68))
+/* SLES12 SP3 GM is 4.4.73-5 and update kernel is 4.4.82-6.3 */
+#elif ((LINUX_VERSION_CODE == KERNEL_VERSION(4,4,73)) || \
+       (LINUX_VERSION_CODE == KERNEL_VERSION(4,4,82)))
 #define SLE_VERSION_CODE SLE_VERSION(12,3,0)
+/* SLES15 Beta1 is 4.12.14-2 */
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,14))
+#define SLE_VERSION_CODE SLE_VERSION(15,0,0)
 /* new SLES kernels must be added here with >= based on kernel
  * the idea is to order from newest to oldest and just catch all
  * of them using the >=
@@ -2187,6 +2191,17 @@ static inline int _kc_request_irq(unsigned int irq, new_handler_t handler, unsig
 #define request_irq(irq, handler, flags, devname, dev_id) _kc_request_irq((irq), (handler), (flags), (devname), (dev_id))
 
 #define irq_handler_t new_handler_t
+
+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) )
+#ifndef skb_checksum_help
+static inline int __kc_skb_checksum_help(struct sk_buff *skb)
+{
+       return skb_checksum_help(skb, 0);
+}
+#define skb_checksum_help(skb) __kc_skb_checksum_help((skb))
+#endif
+#endif /* < 2.6.19 && >= 2.6.11 */
+
 /* pci_restore_state and pci_save_state handles MSI/PCIE from 2.6.19 */
 #if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,4)))
 #define PCIE_CONFIG_SPACE_LEN 256
@@ -4428,6 +4443,12 @@ static inline void hash_del(struct hlist_node *node)
 }
 #endif /* RHEL >= 6.6 */
 
+/* We don't have @flags support prior to 3.7, so we'll simply ignore the flags
+ * parameter on these older kernels.
+ */
+#define __setup_timer(_timer, _fn, _data, _flags)      \
+       setup_timer((_timer), (_fn), (_data))           \
+
 #else /* >= 3.7.0 */
 #include <linux/hashtable.h>
 #define HAVE_CONST_STRUCT_PCI_ERROR_HANDLERS
@@ -4468,9 +4489,6 @@ static inline bool __kc_is_link_local_ether_addr(const u8 *addr)
 }
 #define is_link_local_ether_addr(addr) __kc_is_link_local_ether_addr(addr)
 #endif /* is_link_local_ether_addr */
-int __kc_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
-                      int target, unsigned short *fragoff, int *flags);
-#define ipv6_find_hdr(a, b, c, d, e) __kc_ipv6_find_hdr((a), (b), (c), (d), (e))
 
 #ifndef FLOW_MAC_EXT
 #define FLOW_MAC_EXT   0x40000000
@@ -4893,6 +4911,11 @@ static inline void __kc_skb_set_hash(struct sk_buff __maybe_unused *skb,
 #endif /* HAVE_VXLAN_CHECKS */
 #endif /* !(RHEL_RELEASE_CODE >= 7.0 && SLE_VERSION_CODE >= 12.0) */
 
+#if ((RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) ||\
+     (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(12,0,0)))
+#define HAVE_NDO_DFWD_OPS
+#endif
+
 #ifndef pci_enable_msix_range
 extern int __kc_pci_enable_msix_range(struct pci_dev *dev,
                                      struct msix_entry *entries,
@@ -4917,7 +4940,9 @@ static inline void __kc_ether_addr_copy(u8 *dst, const u8 *src)
 #endif
 }
 #endif /* ether_addr_copy */
-
+int __kc_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
+                      int target, unsigned short *fragoff, int *flags);
+#define ipv6_find_hdr(a, b, c, d, e) __kc_ipv6_find_hdr((a), (b), (c), (d), (e))
 #else /* >= 3.14.0 */
 
 /* for ndo_dfwd_ ops add_station, del_station and _start_xmit */
@@ -5043,12 +5068,16 @@ static inline void __kc_dev_mc_unsync(struct net_device __maybe_unused *dev,
 #define SKB_GSO_UDP_TUNNEL_CSUM 0
 #endif
 extern void *__kc_devm_kmemdup(struct device *dev, const void *src, size_t len,
-                              unsigned int gfp);
+                              gfp_t gfp);
 #define devm_kmemdup __kc_devm_kmemdup
 
 #else
 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0) )
 #define HAVE_PCI_ERROR_HANDLER_RESET_NOTIFY
+#if (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(15,0,0)))
+#undef HAVE_PCI_ERROR_HANDLER_RESET_NOTIFY
+#define HAVE_PCI_ERROR_HANDLER_RESET_PREPARE
+#endif /* SLES15 */
 #endif /* >= 3.16.0 && < 4.13.0 */
 #define HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
 #endif /* 3.16.0 */
@@ -5136,6 +5165,13 @@ extern unsigned int __kc_eth_get_headlen(unsigned char *data, unsigned int max_l
 #define HAVE_NDO_FEATURES_CHECK
 #endif /* 3.18.4 */
 
+/*****************************************************************************/
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,18,13) )
+#ifndef WRITE_ONCE
+#define WRITE_ONCE(x, val) ({ ACCESS_ONCE(x) = (val); })
+#endif
+#endif /* 3.18.13 */
+
 /*****************************************************************************/
 #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) )
 /* netdev_phys_port_id renamed to netdev_phys_item_id */
@@ -5431,6 +5467,17 @@ extern int _kc_eth_platform_get_mac_address(struct device *dev __maybe_unused,
 
 /*****************************************************************************/
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0))
+#if !(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,3))
+static inline unsigned char *skb_checksum_start(const struct sk_buff *skb)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+       return skb->head + skb->csum_start;
+#else /* < 2.6.22 */
+       return skb_transport_header(skb);
+#endif
+}
+#endif
+
 #if !(UBUNTU_VERSION_CODE && \
                UBUNTU_VERSION_CODE >= UBUNTU_VERSION(4,4,0,21)) && \
        !(RHEL_RELEASE_CODE && \
@@ -5461,6 +5508,13 @@ static inline void page_ref_inc(struct page *page)
 #endif
 
 #else /* 4.6.0 */
+#if (UBUNTU_VERSION_CODE && \
+     UBUNTU_VERSION_CODE >= UBUNTU_VERSION(4,4,0,21)) || \
+     (RHEL_RELEASE_CODE && \
+      RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) || \
+     (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(12,3,0))
+#define HAVE_DEVLINK_SUPPORT
+#endif /* UBUNTU 4,4,0,21, RHEL 7.3, SLES12 SP3 */
 #define HAVE_PAGE_COUNT_BULK_UPDATE
 #endif /* 4.6.0 */
 
@@ -5553,7 +5607,13 @@ pci_release_mem_regions(struct pci_dev *pdev)
 #define HAVE_NETDEVICE_MIN_MAX_MTU
 #endif
 
-#if !(SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,3,0)))
+#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5)))
+#define HAVE_RHEL7_EXTENDED_MIN_MAX_MTU
+#define HAVE_NETDEVICE_MIN_MAX_MTU
+#endif
+
+#if (!(SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,3,0))) && \
+     !(RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5))))
 #ifndef dma_map_page_attrs
 #define dma_map_page_attrs __kc_dma_map_page_attrs
 static inline dma_addr_t __kc_dma_map_page_attrs(struct device *dev,
@@ -5592,7 +5652,10 @@ static inline void __page_frag_cache_drain(struct page *page,
 #endif
        __free_pages(page, compound_order(page));
 }
-#endif /* !SLE_VERSION(12,3,0) */
+#endif /* !SLE_VERSION(12,3,0) && !RHEL_VERSION(7,5) */
+#ifndef page_frag_free
+#define page_frag_free __free_page_frag
+#endif
 #ifndef ETH_MIN_MTU
 #define ETH_MIN_MTU 68
 #endif /* ETH_MIN_MTU */
@@ -5608,12 +5671,14 @@ static inline void __page_frag_cache_drain(struct page *page,
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0))
 #ifdef CONFIG_NET_RX_BUSY_POLL
 #define HAVE_NDO_BUSY_POLL
-#if (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,3,0)))
+#if ((SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(12,3,0))) || \
+     (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5))))
 #define HAVE_VOID_NDO_GET_STATS64
 #endif
 #endif
 #else /* > 4.11 */
 #define HAVE_VOID_NDO_GET_STATS64
+#define HAVE_VM_OPS_FAULT_NO_VMA
 #endif /* 4.11.0 */
 
 /*****************************************************************************/
@@ -5622,12 +5687,46 @@ static inline void __page_frag_cache_drain(struct page *page,
 #define HAVE_HWTSTAMP_FILTER_NTP_ALL
 #define HAVE_NDO_SETUP_TC_CHAIN_INDEX
 #define HAVE_PCI_ERROR_HANDLER_RESET_PREPARE
+#define HAVE_PTP_CLOCK_DO_AUX_WORK
 #endif /* 4.13.0 */
 
 /*****************************************************************************/
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0))
+#ifndef ethtool_link_ksettings_del_link_mode
+#define ethtool_link_ksettings_del_link_mode(ptr, name, mode)          \
+       __clear_bit(ETHTOOL_LINK_MODE_ ## mode ## _BIT, (ptr)->link_modes.name)
+#endif
+#if (SLE_VERSION_CODE && (SLE_VERSION_CODE >= SLE_VERSION(15,0,0)))
+#define HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
+#endif
+
+#if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,5)))
+#define HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
+#define HAVE_RHEL7_NETDEV_OPS_EXT_NDO_SETUP_TC
+#endif
+
+#define TIMER_DATA_TYPE                unsigned long
+#define TIMER_FUNC_TYPE                void (*)(TIMER_DATA_TYPE)
+
+#define timer_setup(timer, callback, flags)                            \
+       __setup_timer((timer), (TIMER_FUNC_TYPE)(callback),             \
+                     (TIMER_DATA_TYPE)(timer), (flags))
+
+#define from_timer(var, callback_timer, timer_fieldname) \
+       container_of(callback_timer, typeof(*var), timer_fieldname)
+
 #else /* > 4.14 */
 #define HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
 #endif /* 4.14.0 */
 
+/*****************************************************************************/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0))
+#define TC_SETUP_QDISC_MQPRIO TC_SETUP_MQPRIO
+#ifdef ETHTOOL_GLINKSETTINGS
+void _kc_ethtool_intersect_link_masks(struct ethtool_link_ksettings *dst,
+                                     struct ethtool_link_ksettings *src);
+#define ethtool_intersect_link_masks _kc_ethtool_intersect_link_masks
+#endif /* ETHTOOL_GLINKSETTINGS */
+#endif /* 4.15.0 */
+
 #endif /* _KCOMPAT_H_ */
similarity index 99%
rename from i40e-dkms/i40e-2.2.4/src/virtchnl.h
rename to i40e-dkms/i40e-2.4.6/src/virtchnl.h
index 8cf91d4d6330b9dec9bce483087c1bb237c7b6a9..ac123b29ba6f73256a5b132bd716b7cea00c51ad 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel(R) 40-10 Gigabit Ethernet Connection Network Driver
- * Copyright(c) 2013 - 2017 Intel Corporation.
+ * Copyright(c) 2013 - 2018 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -224,7 +224,7 @@ struct virtchnl_vsi_resource {
 
 VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);
 
-/* VF offload flags
+/* VF capability flags
  * VIRTCHNL_VF_OFFLOAD_L2 flag is inclusive of base mode L2 offloads including
  * TX/RX Checksum offloading and TSO for non-tunnelled packets.
  */
@@ -253,7 +253,7 @@ struct virtchnl_vf_resource {
        u16 max_vectors;
        u16 max_mtu;
 
-       u32 vf_offload_flags;
+       u32 vf_cap_flags;
        u32 rss_key_size;
        u32 rss_lut_size;
 
@@ -333,8 +333,8 @@ VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_vsi_queue_config_info);
  * additional queues must be negotiated.  This is a best effort request as it
  * is possible the PF does not have enough queues left to support the request.
  * If the PF cannot support the number requested it will respond with the
- * maximum number it is able to support; otherwise it will respond with the
- * number requested.
+ * maximum number it is able to support.  If the request is successful, PF will
+ * then reset the VF to institute required changes.
  */
 
 /* VF resource request */