* Re: [dpdk-dev] [PATCH v1 1/1] doc: announce ethdev ABI change for rte_eth_dev_info.
@ 2018-11-22 12:11 4% ` Ferruh Yigit
2018-11-22 17:15 4% ` Thomas Monjalon
2018-11-22 18:27 4% ` Ferruh Yigit
1 sibling, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-11-22 12:11 UTC (permalink / raw)
To: Ian Stokes, dev; +Cc: stephen, arybchenko
On 11/22/2018 12:09 PM, Ian Stokes wrote:
> Maximum and minimum MTU values vary between hardware devices. In
> hardware agnostic DPDK applications access to such information would
> allow a more accurate way of validating and setting supported MTU values on
> a per device basis rather than using a defined default for all devices.
>
> The following solution was proposed:
>
> http://mails.dpdk.org/archives/dev/2018-September/110959.html
>
> This patch adds a depreciation notice for ``rte_eth_dev_info`` as new
> members will be added to represent min and max MTU values. These can be
> added to fit a hole in the existing structure for amd64 but not for 32 bit,
> as such ABI change will occur as size of the structure will be impacted.
>
> Signed-off-by: Ian Stokes <ian.stokes@intel.com>
Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
> doc/guides/rel_notes/deprecation.rst | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 34b28234c..da2b1ce15 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -49,6 +49,18 @@ Deprecation Notices
> Target release for removal of the legacy API will be defined once most
> PMDs have switched to rte_flow.
>
> +* ethdev: Maximum and minimum MTU values vary between hardware devices. In
> + hardware agnostic DPDK applications access to such information would allow
> + a more accurate way of validating and setting supported MTU values on a per
> + device basis rather than using a defined default for all devices. To
> + resolve this, the following members will be added to ``rte_eth_dev_info``.
> + Note: these can be added to fit a hole in the existing structure for amd64
> + but not for 32 bit, as such ABI change will occur as size of the structure
> + will increase.
> +
> + - Member ``uint16_t min_mtu`` the minimum MTU allowed.
> + - Member ``uint16_t max_mtu`` the maximum MTU allowed.
> +
> * pdump: As we changed to use generic IPC, some changes in APIs and structure
> are expected in subsequent release.
>
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v1 1/1] doc: announce ethdev ABI change for rte_eth_dev_info.
2018-11-22 12:11 4% ` Ferruh Yigit
@ 2018-11-22 17:15 4% ` Thomas Monjalon
2018-11-24 17:37 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-11-22 17:15 UTC (permalink / raw)
To: Ian Stokes; +Cc: dev, Ferruh Yigit, stephen, arybchenko
22/11/2018 13:11, Ferruh Yigit:
> On 11/22/2018 12:09 PM, Ian Stokes wrote:
> > Maximum and minimum MTU values vary between hardware devices. In
> > hardware agnostic DPDK applications access to such information would
> > allow a more accurate way of validating and setting supported MTU values on
> > a per device basis rather than using a defined default for all devices.
> >
> > The following solution was proposed:
> >
> > http://mails.dpdk.org/archives/dev/2018-September/110959.html
> >
> > This patch adds a depreciation notice for ``rte_eth_dev_info`` as new
> > members will be added to represent min and max MTU values. These can be
> > added to fit a hole in the existing structure for amd64 but not for 32 bit,
> > as such ABI change will occur as size of the structure will be impacted.
> >
> > Signed-off-by: Ian Stokes <ian.stokes@intel.com>
>
> Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
[...]
> > +* ethdev: Maximum and minimum MTU values vary between hardware devices. In
> > + hardware agnostic DPDK applications access to such information would allow
> > + a more accurate way of validating and setting supported MTU values on a per
> > + device basis rather than using a defined default for all devices. To
> > + resolve this, the following members will be added to ``rte_eth_dev_info``.
> > + Note: these can be added to fit a hole in the existing structure for amd64
> > + but not for 32 bit, as such ABI change will occur as size of the structure
> > + will increase.
> > +
> > + - Member ``uint16_t min_mtu`` the minimum MTU allowed.
> > + - Member ``uint16_t max_mtu`` the maximum MTU allowed.
> > +
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v1 1/1] doc: announce ethdev ABI change for rte_eth_dev_info.
2018-11-22 12:11 4% ` Ferruh Yigit
@ 2018-11-22 18:27 4% ` Ferruh Yigit
2018-11-23 8:08 4% ` Andrew Rybchenko
1 sibling, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-11-22 18:27 UTC (permalink / raw)
To: Ian Stokes, dev
Cc: stephen, arybchenko, Qi Zhang, Shahaf Shuler, Alejandro Lucero,
Rahul Lakkireddy
On 11/22/2018 12:09 PM, Ian Stokes wrote:
> Maximum and minimum MTU values vary between hardware devices. In
> hardware agnostic DPDK applications access to such information would
> allow a more accurate way of validating and setting supported MTU values on
> a per device basis rather than using a defined default for all devices.
>
> The following solution was proposed:
>
> http://mails.dpdk.org/archives/dev/2018-September/110959.html
>
> This patch adds a depreciation notice for ``rte_eth_dev_info`` as new
> members will be added to represent min and max MTU values. These can be
> added to fit a hole in the existing structure for amd64 but not for 32 bit,
> as such ABI change will occur as size of the structure will be impacted.
>
> Signed-off-by: Ian Stokes <ian.stokes@intel.com>
> ---
> doc/guides/rel_notes/deprecation.rst | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 34b28234c..da2b1ce15 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -49,6 +49,18 @@ Deprecation Notices
> Target release for removal of the legacy API will be defined once most
> PMDs have switched to rte_flow.
>
> +* ethdev: Maximum and minimum MTU values vary between hardware devices. In
> + hardware agnostic DPDK applications access to such information would allow
> + a more accurate way of validating and setting supported MTU values on a per
> + device basis rather than using a defined default for all devices. To
> + resolve this, the following members will be added to ``rte_eth_dev_info``.
> + Note: these can be added to fit a hole in the existing structure for amd64
> + but not for 32 bit, as such ABI change will occur as size of the structure
> + will increase.
> +
> + - Member ``uint16_t min_mtu`` the minimum MTU allowed.
> + - Member ``uint16_t max_mtu`` the maximum MTU allowed.
> +
> * pdump: As we changed to use generic IPC, some changes in APIs and structure
> are expected in subsequent release.
>
>
cc'ed a few more folks.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v1 1/1] doc: announce ethdev ABI change for rte_eth_dev_info.
2018-11-22 18:27 4% ` Ferruh Yigit
@ 2018-11-23 8:08 4% ` Andrew Rybchenko
0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2018-11-23 8:08 UTC (permalink / raw)
To: Ferruh Yigit, Ian Stokes, dev
Cc: stephen, Qi Zhang, Shahaf Shuler, Alejandro Lucero, Rahul Lakkireddy
On 11/22/18 9:27 PM, Ferruh Yigit wrote:
> On 11/22/2018 12:09 PM, Ian Stokes wrote:
>> Maximum and minimum MTU values vary between hardware devices. In
>> hardware agnostic DPDK applications access to such information would
>> allow a more accurate way of validating and setting supported MTU values on
>> a per device basis rather than using a defined default for all devices.
>>
>> The following solution was proposed:
>>
>> http://mails.dpdk.org/archives/dev/2018-September/110959.html
>>
>> This patch adds a depreciation notice for ``rte_eth_dev_info`` as new
>> members will be added to represent min and max MTU values. These can be
>> added to fit a hole in the existing structure for amd64 but not for 32 bit,
>> as such ABI change will occur as size of the structure will be impacted.
>>
>> Signed-off-by: Ian Stokes <ian.stokes@intel.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH] libs/power: add p-state driver compatibility
@ 2018-11-23 11:33 1% Liang Ma
2018-12-10 16:08 0% ` Burakov, Anatoly
2018-12-14 11:13 1% ` [dpdk-dev] [PATCH v2] " Liang Ma
0 siblings, 2 replies; 200+ results
From: Liang Ma @ 2018-11-23 11:33 UTC (permalink / raw)
To: david.hunt; +Cc: dev, lei.a.yao, ktraynor, Liang Ma
Previously, in order to use the power library, it was necessary
for the user to disable the intel_pstate driver by adding
“intel_pstate=disable” to the kernel command line for the system,
which causes the acpi_cpufreq driver to be loaded in its place.
This patch adds the ability for the power library use the intel-pstate
driver.
It adds a new suite of functions behind the current power library API,
and will seamlessly set up the user facing API function pointers to
the relevant functions depending on whether the system is running with
acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
using kvm. The library API and ABI is unchanged.
Signed-off-by: Liang Ma <liang.j.ma@intel.com>
---
lib/librte_power/Makefile | 2 +
lib/librte_power/meson.build | 4 +-
lib/librte_power/power_pstate_cpufreq.c | 778 ++++++++++++++++++++++++++++++++
lib/librte_power/power_pstate_cpufreq.h | 218 +++++++++
lib/librte_power/rte_power.c | 43 +-
lib/librte_power/rte_power.h | 3 +-
6 files changed, 1039 insertions(+), 9 deletions(-)
create mode 100644 lib/librte_power/power_pstate_cpufreq.c
create mode 100644 lib/librte_power/power_pstate_cpufreq.h
diff --git a/lib/librte_power/Makefile b/lib/librte_power/Makefile
index 9bec668..ab77152 100644
--- a/lib/librte_power/Makefile
+++ b/lib/librte_power/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
# library name
LIB = librte_power.a
+CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 -fno-strict-aliasing
LDLIBS += -lrte_eal -lrte_timer
@@ -17,6 +18,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_POWER) := rte_power.c power_acpi_cpufreq.c
SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_kvm_vm.c guest_channel.c
SRCS-$(CONFIG_RTE_LIBRTE_POWER) += rte_power_empty_poll.c
+SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_pstate_cpufreq.c
# install this header file
SYMLINK-$(CONFIG_RTE_LIBRTE_POWER)-include := rte_power.h rte_power_empty_poll.h
diff --git a/lib/librte_power/meson.build b/lib/librte_power/meson.build
index 9ed8b56..14a2128 100644
--- a/lib/librte_power/meson.build
+++ b/lib/librte_power/meson.build
@@ -6,6 +6,6 @@ if host_machine.system() != 'linux'
endif
sources = files('rte_power.c', 'power_acpi_cpufreq.c',
'power_kvm_vm.c', 'guest_channel.c',
- 'rte_power_empty_poll.c')
+ 'rte_power_empty_poll.c',
+ 'power_pstate_cpufreq.c')
headers = files('rte_power.h','rte_power_empty_poll.h')
-deps += ['timer']
diff --git a/lib/librte_power/power_pstate_cpufreq.c b/lib/librte_power/power_pstate_cpufreq.c
new file mode 100644
index 0000000..f1dada8
--- /dev/null
+++ b/lib/librte_power/power_pstate_cpufreq.c
@@ -0,0 +1,778 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <rte_memcpy.h>
+#include <rte_atomic.h>
+
+#include "power_pstate_cpufreq.h"
+#include "power_common.h"
+
+
+#ifdef RTE_LIBRTE_POWER_DEBUG
+#define POWER_DEBUG_TRACE(fmt, args...) do { \
+ RTE_LOG(ERR, POWER, "%s: " fmt, __func__, ## args); \
+} while (0)
+#else
+#define POWER_DEBUG_TRACE(fmt, args...)
+#endif
+
+#define FOPEN_OR_ERR_RET(f, retval) do { \
+ if ((f) == NULL) { \
+ RTE_LOG(ERR, POWER, "File not openned\n"); \
+ return retval; \
+ } \
+} while (0)
+
+#define FOPS_OR_NULL_GOTO(ret, label) do { \
+ if ((ret) == NULL) { \
+ RTE_LOG(ERR, POWER, "fgets returns nothing\n"); \
+ goto label; \
+ } \
+} while (0)
+
+#define FOPS_OR_ERR_GOTO(ret, label) do { \
+ if ((ret) < 0) { \
+ RTE_LOG(ERR, POWER, "File operations failed\n"); \
+ goto label; \
+ } \
+} while (0)
+
+
+#define POWER_CONVERT_TO_DECIMAL 10
+#define BUS_FREQ 100000
+
+#define POWER_GOVERNOR_PERF "performance"
+#define POWER_SYSFILE_GOVERNOR \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_governor"
+#define POWER_SYSFILE_MAX_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_max_freq"
+#define POWER_SYSFILE_MIN_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_min_freq"
+#define POWER_SYSFILE_CUR_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq"
+#define POWER_SYSFILE_BASE_MAX_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_max_freq"
+#define POWER_SYSFILE_BASE_MIN_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_min_freq"
+#define POWER_MSR_PATH "/dev/cpu/%u/msr"
+
+/*
+ * MSR related
+ */
+#define PLATFORM_INFO 0x0CE
+#define NON_TURBO_MASK 0xFF00
+#define NON_TURBO_OFFSET 0x8
+
+
+enum power_state {
+ POWER_IDLE = 0,
+ POWER_ONGOING,
+ POWER_USED,
+ POWER_UNKNOWN
+};
+
+struct pstate_power_info {
+ unsigned int lcore_id; /**< Logical core id */
+ uint32_t freqs[RTE_MAX_LCORE_FREQS]; /**< Frequency array */
+ uint32_t nb_freqs; /**< number of available freqs */
+ FILE *f_cur_min; /**< FD of scaling_min */
+ FILE *f_cur_max; /**< FD of scaling_max */
+ char governor_ori[32]; /**< Original governor name */
+ uint32_t curr_idx; /**< Freq index in freqs array */
+ uint32_t non_turbo_max_ratio; /**< Non Turbo Max ratio */
+ uint32_t sys_max_freq; /**< system wide max freq */
+ volatile uint32_t state; /**< Power in use state */
+ uint16_t turbo_available; /**< Turbo Boost available */
+ uint16_t turbo_enable; /**< Turbo Boost enable/disable */
+} __rte_cache_aligned;
+
+
+static struct pstate_power_info lcore_power_info[RTE_MAX_LCORE];
+
+/**
+ * It is to read the specific MSR.
+ */
+
+static int32_t
+power_rdmsr(int msr, uint64_t *val, unsigned int lcore_id)
+{
+ int fd;
+ int ret;
+ char fullpath[PATH_MAX];
+
+ snprintf(fullpath, sizeof(fullpath), POWER_MSR_PATH, lcore_id);
+
+ fd = open(fullpath, O_RDONLY);
+
+ if (fd < 0) {
+
+ if (errno == EACCES)
+ RTE_LOG(ERR, POWER, "No access to %s\n", fullpath);
+
+ if (errno == ENXIO)
+ RTE_LOG(ERR, POWER, "%s Not Exist!\n", fullpath);
+
+ return fd;
+ }
+
+ ret = pread(fd, val, sizeof(uint64_t), msr);
+
+ close(fd);
+
+ POWER_DEBUG_TRACE("MSR Path %s, offset 0x%X for lcore %u\n",
+ fullpath, msr, lcore_id);
+
+ POWER_DEBUG_TRACE("Ret value %d, content is 0x%lx\n", ret, *val);
+
+ return ret;
+}
+
+/**
+ * It is to fopen the sys file for the future setting the lcore frequency.
+ */
+static int
+power_init_for_setting_freq(struct pstate_power_info *pi)
+{
+ FILE *f_min, *f_max;
+ char fullpath_min[PATH_MAX];
+ char fullpath_max[PATH_MAX];
+ uint64_t max_non_turbo = 0;
+
+ snprintf(fullpath_min, sizeof(fullpath_min), POWER_SYSFILE_MIN_FREQ,
+ pi->lcore_id);
+
+ f_min = fopen(fullpath_min, "rw+");
+ FOPEN_OR_ERR_RET(f_min, -1);
+
+ snprintf(fullpath_max, sizeof(fullpath_max), POWER_SYSFILE_MAX_FREQ,
+ pi->lcore_id);
+
+ f_max = fopen(fullpath_max, "rw+");
+ FOPEN_OR_ERR_RET(f_max, -1);
+
+ pi->f_cur_min = f_min;
+ pi->f_cur_max = f_max;
+
+ /* Add MSR read to detect turbo status */
+
+ if (power_rdmsr(PLATFORM_INFO, &max_non_turbo, pi->lcore_id) < 0)
+ return -1;
+
+ max_non_turbo = (max_non_turbo&NON_TURBO_MASK)>>NON_TURBO_OFFSET;
+
+ POWER_DEBUG_TRACE("no turbo perf %lu\n", max_non_turbo);
+
+ pi->non_turbo_max_ratio = max_non_turbo;
+
+ return 0;
+}
+
+static int
+set_freq_internal(struct pstate_power_info *pi, uint32_t idx)
+{
+ uint32_t target_freq = 0;
+
+ if (idx >= RTE_MAX_LCORE_FREQS || idx >= pi->nb_freqs) {
+ RTE_LOG(ERR, POWER, "Invalid frequency index %u, which "
+ "should be less than %u\n", idx, pi->nb_freqs);
+ return -1;
+ }
+
+ /* Check if it is the same as current */
+ if (idx == pi->curr_idx)
+ return 0;
+
+
+ /* Because Intel Pstate Driver only allow user change min/max hint
+ * User need change the min/max as same value.
+ */
+ if (fseek(pi->f_cur_min, 0, SEEK_SET) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to set file position indicator to 0 "
+ "for setting frequency for lcore %u\n",
+ pi->lcore_id);
+ return -1;
+ }
+
+ if (fseek(pi->f_cur_max, 0, SEEK_SET) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to set file position indicator to 0 "
+ "for setting frequency for lcore %u\n",
+ pi->lcore_id);
+ return -1;
+ }
+
+ /* Turbo is available and enabled, first freq bucket is sys max freq */
+ if (pi->turbo_available && pi->turbo_enable && (idx == 0))
+
+ target_freq = pi->sys_max_freq;
+
+ else
+
+ target_freq = pi->freqs[idx];
+
+
+ /* Decrease freq, the min freq should be updated first */
+ if (idx > pi->curr_idx) {
+
+ if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ POWER_DEBUG_TRACE("Freqency[%u] to be set for lcore %u\n",
+ target_freq, pi->lcore_id);
+
+ fflush(pi->f_cur_min);
+ fflush(pi->f_cur_max);
+
+ }
+
+ /* Increase freq, the max freq should be updated first */
+ if (idx < pi->curr_idx) {
+
+ if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ fflush(pi->f_cur_max);
+ fflush(pi->f_cur_min);
+ }
+
+ pi->curr_idx = idx;
+
+ return 1;
+}
+
+/**
+ * It is to check the current scaling governor by reading sys file, and then
+ * set it into 'performance' if it is not by writing the sys file. The original
+ * governor will be saved for rolling back.
+ */
+static int
+power_set_governor_performance(struct pstate_power_info *pi)
+{
+ FILE *f;
+ int ret = -1;
+ char buf[BUFSIZ];
+ char fullpath[PATH_MAX];
+ char *s;
+ int val;
+
+ snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_GOVERNOR,
+ pi->lcore_id);
+ f = fopen(fullpath, "rw+");
+ FOPEN_OR_ERR_RET(f, ret);
+
+ s = fgets(buf, sizeof(buf), f);
+ FOPS_OR_NULL_GOTO(s, out);
+
+ /* Check if current governor is performance */
+ if (strncmp(buf, POWER_GOVERNOR_PERF,
+ sizeof(POWER_GOVERNOR_PERF)) == 0) {
+ ret = 0;
+ POWER_DEBUG_TRACE("Power management governor of lcore %u is "
+ "already performance\n", pi->lcore_id);
+ goto out;
+ }
+ /* Save the original governor */
+ snprintf(pi->governor_ori, sizeof(pi->governor_ori), "%s", buf);
+
+ /* Write 'performance' to the governor */
+ val = fseek(f, 0, SEEK_SET);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ val = fputs(POWER_GOVERNOR_PERF, f);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ ret = 0;
+ RTE_LOG(INFO, POWER, "Power management governor of lcore %u has been "
+ "set to performance successfully\n", pi->lcore_id);
+out:
+ fclose(f);
+
+ return ret;
+}
+
+/**
+ * It is to check the governor and then set the original governor back if
+ * needed by writing the sys file.
+ */
+static int
+power_set_governor_original(struct pstate_power_info *pi)
+{
+ FILE *f;
+ int ret = -1;
+ char buf[BUFSIZ];
+ char fullpath[PATH_MAX];
+ char *s;
+ int val;
+
+ snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_GOVERNOR,
+ pi->lcore_id);
+ f = fopen(fullpath, "rw+");
+ FOPEN_OR_ERR_RET(f, ret);
+
+ s = fgets(buf, sizeof(buf), f);
+ FOPS_OR_NULL_GOTO(s, out);
+
+ /* Check if the governor to be set is the same as current */
+ if (strncmp(buf, pi->governor_ori, sizeof(pi->governor_ori)) == 0) {
+ ret = 0;
+ POWER_DEBUG_TRACE("Power management governor of lcore %u "
+ "has already been set to %s\n",
+ pi->lcore_id, pi->governor_ori);
+ goto out;
+ }
+
+ /* Write back the original governor */
+ val = fseek(f, 0, SEEK_SET);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ val = fputs(pi->governor_ori, f);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ ret = 0;
+ RTE_LOG(INFO, POWER, "Power management governor of lcore %u "
+ "has been set back to %s successfully\n",
+ pi->lcore_id, pi->governor_ori);
+out:
+ fclose(f);
+
+ return ret;
+}
+
+/**
+ * It is to get the available frequencies of the specific lcore by reading the
+ * sys file.
+ */
+static int
+power_get_available_freqs(struct pstate_power_info *pi)
+{
+ FILE *f_min, *f_max;
+ int ret = -1;
+ char *p_min, *p_max;
+ char buf_min[BUFSIZ];
+ char buf_max[BUFSIZ];
+ char fullpath_min[PATH_MAX];
+ char fullpath_max[PATH_MAX];
+ char *s_min, *s_max;
+ uint32_t sys_min_freq = 0, sys_max_freq = 0, base_max_freq = 0;
+ uint32_t i, num_freqs = 0;
+
+ snprintf(fullpath_max, sizeof(fullpath_max),
+ POWER_SYSFILE_BASE_MAX_FREQ,
+ pi->lcore_id);
+ snprintf(fullpath_min, sizeof(fullpath_min),
+ POWER_SYSFILE_BASE_MIN_FREQ,
+ pi->lcore_id);
+
+ f_min = fopen(fullpath_min, "r");
+ FOPEN_OR_ERR_RET(f_min, ret);
+
+ s_min = fgets(buf_min, sizeof(buf_min), f_min);
+ FOPS_OR_NULL_GOTO(s_min, out);
+
+ f_max = fopen(fullpath_max, "r");
+ FOPEN_OR_ERR_RET(f_max, ret);
+
+ s_max = fgets(buf_max, sizeof(buf_max), f_max);
+ FOPS_OR_NULL_GOTO(s_max, out);
+
+
+ /* Strip the line break if there is */
+ p_min = strchr(buf_min, '\n');
+ if (p_min != NULL)
+ *p_min = 0;
+
+ p_max = strchr(buf_max, '\n');
+ if (p_max != NULL)
+ *p_max = 0;
+
+ sys_min_freq = strtoul(buf_min, &p_min, POWER_CONVERT_TO_DECIMAL);
+ sys_max_freq = strtoul(buf_max, &p_max, POWER_CONVERT_TO_DECIMAL);
+
+ if (sys_max_freq < sys_min_freq)
+ goto out;
+
+
+ pi->sys_max_freq = sys_max_freq;
+
+ base_max_freq = pi->non_turbo_max_ratio*BUS_FREQ;
+
+ POWER_DEBUG_TRACE("sys min %u, sys max %u, base_max %u\n",
+ sys_min_freq,
+ sys_max_freq,
+ base_max_freq);
+
+ if (base_max_freq < sys_max_freq)
+
+ pi->turbo_available = 1;
+ else
+ pi->turbo_available = 0;
+
+
+ /* If turbo is available then there is one extra freq bucket
+ * to store the sys max freq which value is base_max +1
+ */
+ num_freqs = (base_max_freq - sys_min_freq)/BUS_FREQ + 1
+ + pi->turbo_available;
+
+ /* Generate the freq bucket array.
+ * If turbo is available the freq bucket[0] value is base_max +1
+ * the bucket[1] is base_max, bucket[2] is base_max - BUS_FREQ
+ * and so on.
+ * If turbo is not available bucket[0] is base_max and so on
+ */
+ for (i = 0, pi->nb_freqs = 0; i < num_freqs; i++) {
+
+ if ((i == 0) && pi->turbo_available)
+ pi->freqs[pi->nb_freqs++] = base_max_freq + 1;
+ else
+ pi->freqs[pi->nb_freqs++] =
+ base_max_freq - (i - pi->turbo_available)*BUS_FREQ;
+ }
+
+ ret = 0;
+
+ POWER_DEBUG_TRACE("%d frequency(s) of lcore %u are available\n",
+ num_freqs, pi->lcore_id);
+
+ fclose(f_min);
+ fclose(f_max);
+
+
+out:
+ return ret;
+}
+
+int
+power_pstate_cpufreq_init(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Lcore id %u can not exceeds %u\n",
+ lcore_id, RTE_MAX_LCORE - 1U);
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (rte_atomic32_cmpset(&(pi->state), POWER_IDLE, POWER_ONGOING)
+ == 0) {
+ RTE_LOG(INFO, POWER, "Power management of lcore %u is "
+ "in use\n", lcore_id);
+ return -1;
+ }
+
+ pi->lcore_id = lcore_id;
+ /* Check and set the governor */
+ if (power_set_governor_performance(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set governor of lcore %u to "
+ "performance\n", lcore_id);
+ goto fail;
+ }
+ /* Init for setting lcore frequency */
+ if (power_init_for_setting_freq(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot init for setting frequency for "
+ "lcore %u\n", lcore_id);
+ goto fail;
+ }
+
+ /* Get the available frequencies */
+ if (power_get_available_freqs(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot get available frequencies of "
+ "lcore %u\n", lcore_id);
+ goto fail;
+ }
+
+
+ /* Set freq to max by default */
+ if (power_pstate_cpufreq_freq_max(lcore_id) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set frequency of lcore %u "
+ "to max\n", lcore_id);
+ goto fail;
+ }
+
+ RTE_LOG(INFO, POWER, "Initialized successfully for lcore %u "
+ "power management\n", lcore_id);
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_USED);
+
+ return 0;
+
+fail:
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
+
+ return -1;
+}
+
+int
+power_pstate_cpufreq_exit(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Lcore id %u can not exceeds %u\n",
+ lcore_id, RTE_MAX_LCORE - 1U);
+ return -1;
+ }
+ pi = &lcore_power_info[lcore_id];
+
+ if (rte_atomic32_cmpset(&(pi->state), POWER_USED, POWER_ONGOING)
+ == 0) {
+ RTE_LOG(INFO, POWER, "Power management of lcore %u is "
+ "not used\n", lcore_id);
+ return -1;
+ }
+
+ /* Close FD of setting freq */
+ fclose(pi->f_cur_min);
+ fclose(pi->f_cur_max);
+ pi->f_cur_min = NULL;
+ pi->f_cur_max = NULL;
+
+ /* Set the governor back to the original */
+ if (power_set_governor_original(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set the governor of %u back "
+ "to the original\n", lcore_id);
+ goto fail;
+ }
+
+ RTE_LOG(INFO, POWER, "Power management of lcore %u has exited from "
+ "'performance' mode and been set back to the "
+ "original\n", lcore_id);
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_IDLE);
+
+ return 0;
+
+fail:
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
+
+ return -1;
+}
+
+
+uint32_t
+power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (num < pi->nb_freqs) {
+ RTE_LOG(ERR, POWER, "Buffer size is not enough\n");
+ return 0;
+ }
+ rte_memcpy(freqs, pi->freqs, pi->nb_freqs * sizeof(uint32_t));
+
+ return pi->nb_freqs;
+}
+
+uint32_t
+power_pstate_cpufreq_get_freq(unsigned int lcore_id)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return RTE_POWER_INVALID_FREQ_INDEX;
+ }
+
+ return lcore_power_info[lcore_id].curr_idx;
+}
+
+
+int
+power_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ return set_freq_internal(&(lcore_power_info[lcore_id]), index);
+}
+
+int
+power_pstate_cpufreq_freq_up(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (pi->curr_idx == 0)
+ return 0;
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->curr_idx - 1);
+}
+
+int
+power_pstate_cpufreq_freq_down(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (pi->curr_idx + 1 == pi->nb_freqs)
+ return 0;
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->curr_idx + 1);
+}
+
+int
+power_pstate_cpufreq_freq_max(unsigned int lcore_id)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ /* Frequencies in the array are from high to low. */
+ if (lcore_power_info[lcore_id].turbo_available) {
+ if (lcore_power_info[lcore_id].turbo_enable)
+ /* Set to Turbo */
+ return set_freq_internal(
+ &lcore_power_info[lcore_id], 0);
+ else
+ /* Set to max non-turbo */
+ return set_freq_internal(
+ &lcore_power_info[lcore_id], 1);
+ } else
+ return set_freq_internal(&lcore_power_info[lcore_id], 0);
+}
+
+
+int
+power_pstate_cpufreq_freq_min(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->nb_freqs - 1);
+}
+
+
+int
+power_pstate_turbo_status(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ return pi->turbo_enable;
+}
+
+int
+power_pstate_enable_turbo(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ if (pi->turbo_available)
+ pi->turbo_enable = 1;
+ else {
+ pi->turbo_enable = 0;
+ RTE_LOG(ERR, POWER,
+ "Failed to enable turbo on lcore %u\n",
+ lcore_id);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+power_pstate_disable_turbo(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ pi->turbo_enable = 0;
+
+
+ return 0;
+}
+
+
+int power_pstate_get_capabilities(unsigned int lcore_id,
+ struct rte_power_core_capabilities *caps)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+ if (caps == NULL) {
+ RTE_LOG(ERR, POWER, "Invalid argument\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ caps->capabilities = 0;
+ caps->turbo = !!(pi->turbo_available);
+
+ return 0;
+}
diff --git a/lib/librte_power/power_pstate_cpufreq.h b/lib/librte_power/power_pstate_cpufreq.h
new file mode 100644
index 0000000..0fc917a
--- /dev/null
+++ b/lib/librte_power/power_pstate_cpufreq.h
@@ -0,0 +1,218 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#ifndef _POWER_PSTATE_CPUFREQ_H
+#define _POWER_PSTATE_CPUFREQ_H
+
+/**
+ * @file
+ * RTE Power Management via Intel Pstate driver
+ */
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_string_fns.h>
+#include "rte_power.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize power management for a specific lcore. It will check and set the
+ * governor to performance for the lcore, get the available frequencies, and
+ * prepare to set new lcore frequency.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_init(unsigned int lcore_id);
+
+/**
+ * Exit power management on a specific lcore. It will set the governor to which
+ * is before initialized.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_exit(unsigned int lcore_id);
+
+/**
+ * Get the available frequencies of a specific lcore. The return value will be
+ * the minimal one of the total number of available frequencies and the number
+ * of buffer. The index of available frequencies used in other interfaces
+ * should be in the range of 0 to this return value.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param freqs
+ * The buffer array to save the frequencies.
+ * @param num
+ * The number of frequencies to get.
+ *
+ * @return
+ * The number of available frequencies.
+ */
+uint32_t power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs,
+ uint32_t num);
+
+/**
+ * Return the current index of available frequencies of a specific lcore. It
+ * will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)' if error.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * The current index of available frequencies.
+ */
+uint32_t power_pstate_cpufreq_get_freq(unsigned int lcore_id);
+
+/**
+ * Set the new frequency for a specific lcore by indicating the index of
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param index
+ * The index of available frequencies.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index);
+
+/**
+ * Scale up the frequency of a specific lcore according to the available
+ * frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_up(unsigned int lcore_id);
+
+/**
+ * Scale down the frequency of a specific lcore according to the available
+ * frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_down(unsigned int lcore_id);
+
+/**
+ * Scale up the frequency of a specific lcore to the highest according to the
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_max(unsigned int lcore_id);
+
+/**
+ * Scale down the frequency of a specific lcore to the lowest according to the
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_min(unsigned int lcore_id);
+
+/**
+ * Get the turbo status of a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 Turbo Boost is enabled on this lcore.
+ * - 0 Turbo Boost is disabled on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_turbo_status(unsigned int lcore_id);
+
+/**
+ * Enable Turbo Boost on a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 Turbo Boost is enabled successfully on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_enable_turbo(unsigned int lcore_id);
+
+/**
+ * Disable Turbo Boost on a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 Turbo Boost disabled successfully on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_disable_turbo(unsigned int lcore_id);
+
+/**
+ * Returns power capabilities for a specific lcore.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param caps
+ * pointer to rte_power_core_capabilities object.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_get_capabilities(unsigned int lcore_id,
+ struct rte_power_core_capabilities *caps);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_power/rte_power.c b/lib/librte_power/rte_power.c
index 208b791..54a48db 100644
--- a/lib/librte_power/rte_power.c
+++ b/lib/librte_power/rte_power.c
@@ -7,6 +7,7 @@
#include "rte_power.h"
#include "power_acpi_cpufreq.h"
#include "power_kvm_vm.h"
+#include "power_pstate_cpufreq.h"
#include "power_common.h"
enum power_management_env global_default_env = PM_ENV_NOT_SET;
@@ -29,6 +30,8 @@ rte_power_get_capabilities_t rte_power_get_capabilities;
int
rte_power_set_env(enum power_management_env env)
{
+
+
if (rte_atomic32_cmpset(&global_env_cfg_status, 0, 1) == 0) {
return 0;
}
@@ -56,6 +59,19 @@ rte_power_set_env(enum power_management_env env)
rte_power_freq_enable_turbo = power_kvm_vm_enable_turbo;
rte_power_freq_disable_turbo = power_kvm_vm_disable_turbo;
rte_power_get_capabilities = power_kvm_vm_get_capabilities;
+ } else if (env == PM_ENV_PSTATE_CPUFREQ) {
+ rte_power_freqs = power_pstate_cpufreq_freqs;
+ rte_power_get_freq = power_pstate_cpufreq_get_freq;
+ rte_power_set_freq = power_pstate_cpufreq_set_freq;
+ rte_power_freq_up = power_pstate_cpufreq_freq_up;
+ rte_power_freq_down = power_pstate_cpufreq_freq_down;
+ rte_power_freq_min = power_pstate_cpufreq_freq_min;
+ rte_power_freq_max = power_pstate_cpufreq_freq_max;
+ rte_power_turbo_status = power_pstate_turbo_status;
+ rte_power_freq_enable_turbo = power_pstate_enable_turbo;
+ rte_power_freq_disable_turbo = power_pstate_disable_turbo;
+ rte_power_get_capabilities = power_pstate_get_capabilities;
+
} else {
RTE_LOG(ERR, POWER, "Invalid Power Management Environment(%d) set\n",
env);
@@ -84,12 +100,15 @@ rte_power_init(unsigned int lcore_id)
{
int ret = -1;
- if (global_default_env == PM_ENV_ACPI_CPUFREQ) {
+ if (global_default_env == PM_ENV_ACPI_CPUFREQ)
return power_acpi_cpufreq_init(lcore_id);
- }
- if (global_default_env == PM_ENV_KVM_VM) {
+
+ if (global_default_env == PM_ENV_KVM_VM)
return power_kvm_vm_init(lcore_id);
- }
+
+ if (global_default_env == PM_ENV_PSTATE_CPUFREQ)
+ return power_pstate_cpufreq_init(lcore_id);
+
/* Auto detect Environment */
RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power "
"management...\n");
@@ -99,13 +118,23 @@ rte_power_init(unsigned int lcore_id)
goto out;
}
- RTE_LOG(INFO, POWER, "Attempting to initialise VM power management...\n");
+ RTE_LOG(INFO, POWER, "Attempting to initialise PSTAT power "
+ "management...\n");
+ ret = power_pstate_cpufreq_init(lcore_id);
+ if (ret == 0) {
+ rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
+ goto out;
+ }
+
+ RTE_LOG(INFO, POWER, "Attempting to initialise VM power "
+ "management...\n");
ret = power_kvm_vm_init(lcore_id);
if (ret == 0) {
rte_power_set_env(PM_ENV_KVM_VM);
goto out;
}
- RTE_LOG(ERR, POWER, "Unable to set Power Management Environment for lcore "
+ RTE_LOG(ERR, POWER, "Unable to set Power Management "
+ "Environment for lcore "
"%u\n", lcore_id);
out:
return ret;
@@ -118,6 +147,8 @@ rte_power_exit(unsigned int lcore_id)
return power_acpi_cpufreq_exit(lcore_id);
if (global_default_env == PM_ENV_KVM_VM)
return power_kvm_vm_exit(lcore_id);
+ if (global_default_env == PM_ENV_PSTATE_CPUFREQ)
+ return power_pstate_cpufreq_exit(lcore_id);
RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit "
"gracefully\n");
diff --git a/lib/librte_power/rte_power.h b/lib/librte_power/rte_power.h
index d70bc0b..c5e8f6b 100644
--- a/lib/librte_power/rte_power.h
+++ b/lib/librte_power/rte_power.h
@@ -20,7 +20,8 @@ extern "C" {
#endif
/* Power Management Environment State */
-enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM};
+enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM,
+ PM_ENV_PSTATE_CPUFREQ};
/**
* Set the default power management implementation. If this is not called prior
--
2.7.5
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH] doc: announce kvargs API change
@ 2018-11-23 13:17 0% ` Maxime Coquelin
0 siblings, 0 replies; 200+ results
From: Maxime Coquelin @ 2018-11-23 13:17 UTC (permalink / raw)
To: Thomas Monjalon, dev; +Cc: olivier.matz
On 11/21/18 4:45 PM, Thomas Monjalon wrote:
> In some usages, kvlist is processed one time in rte_kvargs_process(),
> and it is processed a second time if need to check whether it was matched.
> In order to simplify implementation of kvargs checks, a new callback
> may be used for "no match" cases.
>
> The change of the function prototype would be as below:
>
> int
> rte_kvargs_process(const struct rte_kvargs *kvlist,
> const char *key_match,
> - arg_handler_t handler,
> + arg_handler_t match_handler,
> + arg_handler_t no_match_handler,
> void *opaque_arg)
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> doc/guides/rel_notes/deprecation.rst | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 34b28234c..7af65cd4b 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -11,6 +11,10 @@ API and ABI deprecation notices are to be posted here.
> Deprecation Notices
> -------------------
>
> +* kvargs: The function ``rte_kvargs_process`` will get a new parameter
> + for a function pointer called in case of no match of the key.
> + It will ease implementation of default values or check for mandatory keys.
> +
> * eal: both declaring and identifying devices will be streamlined in v18.11.
> New functions will appear to query a specific port from buses, classes of
> device and device drivers. Device declaration will be made coherent with the
>
Acked-by: Maxime Coquelin <maxime.coquelin@redhat.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v1 1/1] doc: announce ethdev ABI change for rte_eth_dev_info.
2018-11-22 17:15 4% ` Thomas Monjalon
@ 2018-11-24 17:37 4% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-11-24 17:37 UTC (permalink / raw)
To: Ian Stokes; +Cc: dev, Ferruh Yigit, stephen, arybchenko
22/11/2018 18:15, Thomas Monjalon:
> 22/11/2018 13:11, Ferruh Yigit:
> > On 11/22/2018 12:09 PM, Ian Stokes wrote:
> > > Maximum and minimum MTU values vary between hardware devices. In
> > > hardware agnostic DPDK applications access to such information would
> > > allow a more accurate way of validating and setting supported MTU values on
> > > a per device basis rather than using a defined default for all devices.
> > >
> > > The following solution was proposed:
> > >
> > > http://mails.dpdk.org/archives/dev/2018-September/110959.html
> > >
> > > This patch adds a depreciation notice for ``rte_eth_dev_info`` as new
> > > members will be added to represent min and max MTU values. These can be
> > > added to fit a hole in the existing structure for amd64 but not for 32 bit,
> > > as such ABI change will occur as size of the structure will be impacted.
> > >
> > > Signed-off-by: Ian Stokes <ian.stokes@intel.com>
> >
> > Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
> Acked-by: Thomas Monjalon <thomas@monjalon.net>
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Applied
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2] doc: announce Linux support change
@ 2018-11-24 18:44 5% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-11-24 18:44 UTC (permalink / raw)
To: dev; +Cc: ktraynor, techboard, Stephen Hemminger
It was agreed by the Technical Board to increase the minimal
supported Linux version, and written in Linux guide.
An announce was missing in the deprecation notices.
Fixes: 8c58f1b83759 ("doc: note minimun Linux version increase for 19.02")
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
v2: This is a revised version of the deprecation proposed by Stephen
in January, and discussed/changed/approved in 18.11.
Already applied.
---
doc/guides/rel_notes/deprecation.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 55a4c4089..b48486d36 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -11,6 +11,12 @@ API and ABI deprecation notices are to be posted here.
Deprecation Notices
-------------------
+* linux: Linux kernel version 3.2 (which is the current minimum required
+ version for the DPDK) is not maintained anymore. Therefore the planned
+ minimum required kernel version for DPDK 19.02 will be the next oldest
+ Long Term Stable (LTS) version which is 3.16, but compatibility for
+ recent distribution kernels will be kept.
+
* kvargs: The function ``rte_kvargs_process`` will get a new parameter
for returning key match count. It will ease handling of no-match case.
--
2.19.0
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCH v1] doc: update release notes for 18.11
@ 2018-11-26 10:51 4% John McNamara
2018-11-26 23:15 4% ` [dpdk-dev] [PATCH v2] " John McNamara
0 siblings, 1 reply; 200+ results
From: John McNamara @ 2018-11-26 10:51 UTC (permalink / raw)
To: dev; +Cc: marko.kovacevic, John McNamara
Fix grammar, spelling and formatting of DPDK 18.11 release notes.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/rel_notes/release_18_11.rst | 299 ++++++++++++++++-----------------
1 file changed, 149 insertions(+), 150 deletions(-)
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 373dcc0..da07cad 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -48,7 +48,7 @@ New Features
- eventdev (lib, PMDs)
- etc
* Other libs
- * Apps, Examples, Tools (if significative)
+ * Apps, Examples, Tools (if significant)
This section is a comment. Do not overwrite or remove it.
Also, make sure to start the actual text at the margin.
@@ -56,40 +56,42 @@ New Features
* **Added support for using externally allocated memory in DPDK.**
- DPDK has gained support for creating new ``rte_malloc`` heaps referencing
+ DPDK has added support for creating new ``rte_malloc`` heaps referencing
memory that was created outside of DPDK's own page allocator, and using that
memory natively with any other DPDK library or data structure.
-* **Added check for ensuring allocated memory addressable by devices.**
+* **Added check for ensuring allocated memory is addressable by devices.**
Some devices can have addressing limitations so a new function,
- ``rte_mem_check_dma_mask``, has been added for checking allocated memory is
- not out of the device range. Because now memory can be dynamically allocated
- after initialization, a dma mask is kept and any new allocated memory will be
- checked out against that dma mask and rejected if out of range. If more than
- one device has addressing limitations, the dma mask is the more restricted one.
+ ``rte_mem_check_dma_mask()``, has been added for checking that allocated
+ memory is not out of the device range. Since memory can now be allocated
+ dynamically after initialization, a DMA mask is stored and any new allocated
+ memory will be checked against it and rejected if it is out of range. If
+ more than one device has addressing limitations, the DMA mask is the more
+ restrictive one.
-* **Updated the C11 memory model version of ring library.**
+* **Updated the C11 memory model version of the ring library.**
- The latency is decreased for architectures using the C11 memory model
- version of the ring library.
+ Added changes to decrease latency for architectures using the C11 memory
+ model version of the ring library.
- On Cavium ThunderX2 platform, the changes decreased latency by 27~29%
- and 3~15% for MPMC and SPSC cases respectively (with 2 lcores). The
+ On Cavium ThunderX2 platform, the changes decreased latency by 27-29%
+ and 3-15% for MPMC and SPSC cases respectively (with 2 lcores). The
real improvements may vary with the number of contending lcores and
- the size of ring.
+ the size of the ring.
* **Added hot-unplug handle mechanism.**
- ``rte_dev_hotplug_handle_enable`` and ``rte_dev_hotplug_handle_disable`` are
- for enabling or disabling hotplug handle mechanism.
+ Added ``rte_dev_hotplug_handle_enable()`` and
+ ``rte_dev_hotplug_handle_disable()`` for enabling or disabling the hotplug
+ handle mechanism.
-* **Support device multi-process hotplug.**
+* **Added support for device multi-process hotplug.**
- Hotplug and hot-unplug for devices will now be supported in multiprocessing
- scenario. Any ethdev devices created in the primary process will be regarded
- as shared and will be available for all DPDK processes. Synchronization
- between processes will be done using DPDK IPC.
+ Added support for hotplug and hot-unplug in a multiprocessing scenario. Any
+ ethdev devices created in the primary process will be regarded as shared and
+ will be available for all DPDK processes. Synchronization between processes
+ will be done using DPDK IPC.
* **Added new Flow API actions to rewrite fields in packet headers.**
@@ -105,9 +107,10 @@ New Features
Added new Flow API action to swap the source and destination MAC
addresses in the outermost Ethernet header.
-* **Add support to offload more flow match and actions for CXGBE PMD**
+* **Add support to offload more flow match and actions for CXGBE PMD.**
- Flow API support has been enhanced for CXGBE Poll Mode Driver to offload:
+ The Flow API support has been enhanced for the CXGBE Poll Mode Driver to
+ offload:
* Match items: destination MAC address.
* Action items: push/pop/rewrite vlan header,
@@ -116,6 +119,7 @@ New Features
swap MAC addresses in outermost Ethernet header.
* **Added a devarg to use the latest supported vector path in i40e.**
+
A new devarg ``use-latest-supported-vec`` was introduced to allow users to
choose the latest vector path that the platform supported. For example, users
can use AVX2 vector path on BDW/HSW to get better performance.
@@ -133,8 +137,8 @@ New Features
* **Added NXP ENETC PMD.**
- Added the new enetc driver for NXP enetc platform. See the
- "ENETC Poll Mode Driver" document for more details on this new driver.
+ Added the new enetc driver for the NXP enetc platform. See the
+ :doc:`../nics/enetc` nic driver guide for more details on this new driver.
* **Added Ethernet poll mode driver for Aquantia aQtion family of 10G devices.**
@@ -147,17 +151,18 @@ New Features
Updated the mlx5 driver including the following changes:
* Improved security of PMD to prevent the NIC from getting stuck when
- application misbehaves.
- * reworked flow engine to supported e-switch flow rules (transfer attribute).
- * Supported header re-write(L2-L4), VXLAN encap/decap, count ,match
+ the application misbehaves.
+ * Reworked flow engine to supported e-switch flow rules (transfer attribute).
+ * Added support for header re-write(L2-L4), VXLAN encap/decap, count, match
on TCP flags and multiple flow groups with e-switch flow rules.
- * Supported match on medatada, VXLAN and MPLS encap/decap with flow rules.
- * Supported RTE_ETH_DEV_CLOSE_REMOVE flag to provide better support for
- representors.
- * Supported meson build.
+ * Added support for match on metadata, VXLAN and MPLS encap/decap with flow
+ rules.
+ * Added support for ``RTE_ETH_DEV_CLOSE_REMOVE`` flag to provide better
+ support for representors.
+ * Added support for meson build.
* Fixed build issue with PPC.
- * Supported BlueField VF.
- * Supported externally allocated static memory for DMA.
+ * Added support for BlueField VF.
+ * Added support for externally allocated static memory for DMA.
* **Updated Solarflare network PMD.**
@@ -173,36 +178,38 @@ New Features
* Added AVX2-based vectorized Rx handler.
* Added VLAN and checksum offloads to the simple Tx handler.
- * Added the count flow action.
+ * Added the "count" flow action.
* Enabled the virtual address IOVA mode.
-* **Updated failsafe driver.**
+* **Updated the failsafe driver.**
Updated the failsafe driver including the following changes:
- * Support for Rx and Tx queues start and stop.
- * Support for Rx and Tx queues deferred start.
- * Support for runtime Rx and Tx queues setup.
- * Support multicast MAC address set.
+ * Added support for Rx and Tx queues start and stop.
+ * Added support for Rx and Tx queues deferred start.
+ * Added support for runtime Rx and Tx queues setup.
+ * Added support multicast MAC address set.
+
+* **Added a devarg to use a PCAP interface physical MAC address.**
-* **Added a devarg to use PCAP interface physical MAC address.**
- A new devarg ``phy_mac`` was introduced to allow users to use physical
+ A new devarg ``phy_mac`` was introduced to allow users to use the physical
MAC address of the selected PCAP interface.
* **Added TAP Rx/Tx queues sharing with a secondary process.**
- A secondary process can attach a TAP device created in the primary process,
- probe the queues, and process Rx/Tx in a secondary process.
+ Added support to allow a secondary process to attach a TAP device created
+ in the primary process, probe the queues, and process Rx/Tx in a secondary
+ process.
* **Added classification and metering support to SoftNIC PMD.**
Added support for flow classification (rte_flow API), and metering and
policing (rte_mtr API) to the SoftNIC PMD.
-* **Added Crypto support to Softnic PMD.**
+* **Added Crypto support to the Softnic PMD.**
The Softnic is now capable of processing symmetric crypto workloads such
- as cipher, cipher-authentication chaining, and aead encryption and
+ as cipher, cipher-authentication chaining, and AEAD encryption and
decryption. This is achieved by calling DPDK Cryptodev APIs.
* **Added cryptodev port to port library.**
@@ -212,12 +219,12 @@ New Features
* **Added symmetric cryptographic actions to the pipeline library.**
- In the pipeline library an added symmetric crypto action parsing and action
- handler are implemented. The action allows automatically preparing the crypto
- operation with the rules specified such as algorithm, key, and IV, etc for
- the cryptodev port to process.
+ In the pipeline library support was added for symmetric crypto action
+ parsing and an action handler was implemented. The action allows automatic
+ preparation of the crypto operation with the rules specified such as
+ algorithm, key, and IV, etc. for the cryptodev port to process.
-* **Added support for GEN3 devices to Intel QAT driver .**
+* **Added support for GEN3 devices to Intel QAT driver.**
Added support for the third generation of Intel QuickAssist devices.
@@ -225,26 +232,26 @@ New Features
The QAT PMD was updated with additional support for:
- * AES-CMAC algorithm.
+ * The AES-CMAC algorithm.
* **Updated the AESNI MB PMD.**
- The AESNI MB PMD has been updated with additional support for AES-GCM
- algorithm support.
-
-* **Added NXP CAAM JR PMD.**
-
- Added the new caam job ring driver for NXP platforms. See the
- "NXP CAAM JOB RING (caam_jr)" document for more details on this new driver.
+ The AESNI MB PMD has been updated with additional support for the AES-GCM
+ algorithm.
* **Added support for Dynamic Huffman Encoding to Intel QAT comp PMD.**
The Intel QuickAssist (QAT) compression PMD has been updated with support
for Dynamic Huffman Encoding for the Deflate algorithm.
+* **Added NXP CAAM JR PMD.**
+
+ Added the new caam job ring driver for NXP platforms. See the
+ "NXP CAAM JOB RING (caam_jr)" document for more details on this new driver.
+
* **Added Event Ethernet Tx Adapter.**
- Added event ethernet Tx adapter library that provides configuration and
+ Added event ethernet Tx adapter library that provides configuration and
data path APIs for the ethernet transmit stage of an event driven packet
processing application. These APIs abstract the implementation of the
transmit stage and allow the application to use eventdev PMD support or
@@ -260,23 +267,23 @@ New Features
* **Added extendable bucket feature to hash library (rte_hash).**
- This new “extendable bucket” feature provides 100% insertion guarantee to
+ This new "extendable bucket" feature provides 100% insertion guarantee to
the capacity specified by the user by extending hash table with extra
buckets when needed to accommodate the unlikely event of intensive hash
- collisions. In addition, the internal hashing algorithm was changed to use
+ collisions. In addition, the internal hashing algorithm was changed to use
partial-key hashing to improve memory efficiency and lookup performance.
* **Added lock free reader/writer concurrency to hash library (rte_hash).**
Lock free reader/writer concurrency prevents the readers from getting
- blocked due to a pre-empted writer thread. This allows the hash library
- to be used in scenarios where the writer thread runs on control plane.
+ blocked due to a preempted writer thread. This allows the hash library
+ to be used in scenarios where the writer thread runs on the control plane.
-* **Added Traffic Pattern Aware Power Control Library**
+* **Added Traffic Pattern Aware Power Control Library.**
- Added an experimental library. This extend Power Library and provide
- empty_poll APIs. This feature measure how many times empty_poll are
- executed per core, use the number of empty polls as a hint for system
+ Added an experimental library that extends the Power Library and provides
+ empty_poll APIs. This feature measures how many times empty_polls are
+ executed per core and uses the number of empty polls as a hint for system
power management.
See the :doc:`../prog_guide/power_man` section of the DPDK Programmers
@@ -292,27 +299,27 @@ New Features
* **Added Telemetry API.**
- Added the telemetry API which allows applications to transparently expose
- their telemetry via a UNIX socket in JSON. The JSON can be consumed by any
+ Added a new telemetry API which allows applications to transparently expose
+ their telemetry in JSON via a UNIX socket. The JSON can be consumed by any
Service Assurance agent, such as CollectD.
* **Updated KNI kernel module, rte_kni library, and KNI sample application.**
Updated the KNI kernel module with a new kernel module parameter,
``carrier=[on|off]`` to allow the user to control the default carrier
- state of KNI kernel network interfaces. The default carrier state
+ state of the KNI kernel network interfaces. The default carrier state
is now set to ``off``, so the interfaces cannot be used until the
carrier state is set to ``on`` via ``rte_kni_update_link`` or
by writing ``1`` to ``/sys/devices/virtual/net/<iface>/carrier``.
In previous versions the default carrier state was left undefined.
See :doc:`../prog_guide/kernel_nic_interface` for more information.
- Added the new API function ``rte_kni_update_link`` to allow the user
+ Also added the new API function ``rte_kni_update_link()`` to allow the user
to set the carrier state of the KNI kernel network interface.
- Added a new command line flag ``-m`` to the KNI sample application to
+ Also added a new command line flag ``-m`` to the KNI sample application to
monitor and automatically reflect the physical NIC carrier state to the
- KNI kernel network interface with the new ``rte_kni_update_link`` API.
+ KNI kernel network interface with the new ``rte_kni_update_link()`` API.
See :doc:`../sample_app_ug/kernel_nic_interface` for more information.
* **Added ability to switch queue deferred start flag on testpmd app.**
@@ -322,7 +329,7 @@ New Features
the specified port. The port must be stopped before the command call in order
to reconfigure queues.
-* **Add a new sample for vDPA**
+* **Add a new sample application for vDPA.**
The vdpa sample application creates vhost-user sockets by using the
vDPA backend. vDPA stands for vhost Data Path Acceleration which utilizes
@@ -337,12 +344,12 @@ New Features
computation to the NIST Cryptographic Algorithm Validation Program (CAVP)
test vectors.
-* **Allow unit test binary to take parameters from the environment**
+* **Allow unit test binary to take parameters from the environment.**
The unit test "test", or "dpdk-test", binary is often called from scripts,
- which can make passing additional parameters, such as a coremask, to it more
- awkward. Support has been added to the application to allow it to take
- additional command-line parameter values from the "DPDK_TEST_PARAMS"
+ which can make passing additional parameters, such as a coremask,
+ difficult. Support has been added to the application to allow it to take
+ additional command-line parameter values from the ``DPDK_TEST_PARAMS``
environment variable to make this application easier to use.
@@ -364,13 +371,14 @@ API Changes
for any users of memseg-walk-related functions, as they will now have to skip
externally allocated segments in most cases if the intent is to only iterate
over internal DPDK memory.
- ``socket_id`` parameter across the entire DPDK has gained additional meaning,
- as some socket ID's will now be representing externally allocated memory. No
- changes will be required for existing code as backwards compatibility will be
- kept, and those who do not use this feature will not see these extra socket
- ID's. Any new API's must not check socket ID parameters themselves, and must
- instead leave it to the memory subsystem to decide whether socket ID is a
- valid one.
+
+ In addition the ``socket_id`` parameter across the entire DPDK has gained
+ additional meaning, as some socket ID's will now be representing externally
+ allocated memory. No changes will be required for existing code as backwards
+ compatibility will be kept, and those who do not use this feature will not
+ see these extra socket ID's. Any new API's must not check socket ID
+ parameters themselves, and must instead leave it to the memory subsystem to
+ decide whether socket ID is a valid one.
* eal: The following devargs functions, which were deprecated in 18.05,
were removed in 18.11:
@@ -387,8 +395,8 @@ API Changes
``rte_dev_remove`` or ``rte_eal_hotplug_remove``.
* eal: The scope of ``rte_eal_hotplug_add()``/``rte_dev_probe()``
- and ``rte_eal_hotplug_remove()``/``rte_dev_remove()`` is extended.
- In multi-process model, they will guarantee that the device is
+ and ``rte_eal_hotplug_remove()``/``rte_dev_remove()`` has been extended.
+ In the multi-process model, they will guarantee that the device is
attached or detached on all processes.
* mbuf: The ``__rte_mbuf_raw_free()`` and ``__rte_pktmbuf_prefree_seg()``
@@ -396,42 +404,43 @@ API Changes
``rte_mbuf_raw_free()`` and ``rte_pktmbuf_prefree_seg()``.
* ethdev: The deprecated functions attach/detach were removed in 18.11.
- ``rte_eth_dev_attach`` can be replaced by ``RTE_ETH_FOREACH_MATCHING_DEV``
- and ``rte_dev_probe`` or ``rte_eal_hotplug_add``.
- ``rte_eth_dev_detach`` can be replaced by
- ``rte_dev_remove`` or ``rte_eal_hotplug_remove``.
+ ``rte_eth_dev_attach()`` can be replaced by ``RTE_ETH_FOREACH_MATCHING_DEV``
+ and ``rte_dev_probe()`` or ``rte_eal_hotplug_add()``.
+ ``rte_eth_dev_detach()`` can be replaced by
+ ``rte_dev_remove()`` or ``rte_eal_hotplug_remove()``.
* ethdev: A call to ``rte_eth_dev_release_port()`` has been added in
``rte_eth_dev_close()``. As a consequence, a closed port is freed
and seen as invalid because of its state ``RTE_ETH_DEV_UNUSED``.
- This new behaviour is enabled per driver for a migration period.
+ This new behavior is enabled per driver for a migration period.
-* A new device flag, RTE_ETH_DEV_NOLIVE_MAC_ADDR, changes the order of
- actions inside rte_eth_dev_start regarding MAC set. Some NICs do not
+* A new device flag, ``RTE_ETH_DEV_NOLIVE_MAC_ADDR``, changes the order of
+ actions inside ``rte_eth_dev_start()`` regarding MAC set. Some NICs do not
support MAC changes once the port has started and with this new device
flag the MAC can be properly configured in any case. This is particularly
important for bonding.
-* The default behaviour of CRC strip offload changed. Without any specific Rx
- offload flag, default behavior by PMD is now to strip CRC.
- DEV_RX_OFFLOAD_CRC_STRIP offload flag has been removed.
- To request keeping CRC, application should set ``DEV_RX_OFFLOAD_KEEP_CRC`` Rx
- offload.
+* The default behavior of CRC strip offload has changed in this
+ release. Without any specific Rx offload flag, default behavior by a PMD is
+ now to strip CRC. ``DEV_RX_OFFLOAD_CRC_STRIP`` offload flag has been removed.
+ To request keeping CRC, application should set ``DEV_RX_OFFLOAD_KEEP_CRC``
+ Rx offload.
-* eventdev: Type of 2nd parameter to ``rte_event_eth_rx_adapter_caps_get()``
- has been changed from uint8_t to uint16_t.
+* eventdev: The type of the second parameter to
+ ``rte_event_eth_rx_adapter_caps_get()`` has been changed from uint8_t to
+ uint16_t.
* kni: By default, interface carrier status is ``off`` which means there won't
- be any traffic. It can be set to ``on`` via ``rte_kni_update_link()`` API
- or via ``sysfs`` interface:
- ``echo 1 > /sys/class/net/vEth0/carrier``.
+ be any traffic. It can be set to ``on`` via ``rte_kni_update_link()`` API or
+ via ``sysfs`` interface: ``echo 1 > /sys/class/net/vEth0/carrier``.
+
Note interface should be ``up`` to be able to read/write sysfs interface.
When KNI sample application is used, ``-m`` parameter can be used to
automatically update the carrier status for the interface.
-* kni: When ethtool support enabled (``CONFIG_RTE_KNI_KMOD_ETHTOOL=y``)
- ethtool commands ``ETHTOOL_GSET & ETHTOOL_SSET`` are no more supported for the
- kernels that has ``ETHTOOL_GLINKSETTINGS & ETHTOOL_SLINKSETTINGS`` support.
+* kni: When ethtool support is enabled (``CONFIG_RTE_KNI_KMOD_ETHTOOL=y``)
+ ethtool commands ``ETHTOOL_GSET & ETHTOOL_SSET`` are no longer supported for
+ kernels that have ``ETHTOOL_GLINKSETTINGS & ETHTOOL_SLINKSETTINGS`` support.
This means ``ethtool "-a|--show-pause", "-s|--change"`` won't work, and
``ethtool <iface>`` output will have less information.
@@ -451,42 +460,30 @@ ABI Changes
=========================================================
* eal: added ``legacy_mem`` and ``single_file_segments`` values to
- ``rte_config`` structure on account of improving DPDK usability when
- using either ``--legacy-mem`` or ``--single-file-segments`` flags.
+ ``rte_config`` structure on account of improving DPDK usability when
+ using either ``--legacy-mem`` or ``--single-file-segments`` flags.
* eal: EAL library ABI version was changed due to previously announced work on
- supporting external memory in DPDK:
- - structure ``rte_memseg_list`` now has a new field indicating length
- of memory addressed by the segment list
- - structure ``rte_memseg_list`` now has a new flag indicating whether
- the memseg list refers to external memory
- - structure ``rte_malloc_heap`` now has a new field indicating socket
- ID the malloc heap belongs to
- - structure ``rte_mem_config`` has had its ``malloc_heaps`` array
- resized from ``RTE_MAX_NUMA_NODES`` to ``RTE_MAX_HEAPS`` value
- - structure ``rte_malloc_heap`` now has a ``heap_name`` member
- - structure ``rte_eal_memconfig`` has been extended to contain next
- socket ID for externally allocated segments
-
-* eal: Added ``dma_maskbits`` to ``rte_mem_config`` for keeping more restricted
- dma mask based on devices addressing limitations.
-
-* eal: The structure ``rte_device`` got a new field to reference a ``rte_bus``.
- It is changing the size of the ``struct rte_device`` and the inherited
- device structures of all buses.
+ supporting external memory in DPDK:
+ - Structure ``rte_memseg_list`` now has a new field indicating length
+ of memory addressed by the segment list
+ - Structure ``rte_memseg_list`` now has a new flag indicating whether
+ the memseg list refers to external memory
+ - Structure ``rte_malloc_heap`` now has a new field indicating socket
+ ID the malloc heap belongs to
+ - Structure ``rte_mem_config`` has had its ``malloc_heaps`` array
+ resized from ``RTE_MAX_NUMA_NODES`` to ``RTE_MAX_HEAPS`` value
+ - Structure ``rte_malloc_heap`` now has a ``heap_name`` member
+ - Structure ``rte_eal_memconfig`` has been extended to contain next
+ socket ID for externally allocated segments
-Removed Items
--------------
+* eal: Added ``dma_maskbits`` to ``rte_mem_config`` for keeping the most
+ restrictive DMA mask based on the devices addressing limitations.
-.. This section should contain removed items in this release. Sample format:
-
- * Add a short 1-2 sentence description of the removed item
- in the past tense.
-
- This section is a comment. Do not overwrite or remove it.
- Also, make sure to start the actual text at the margin.
- =========================================================
+* eal: The structure ``rte_device`` has a new field to reference a
+ ``rte_bus``. It thus changes the size of the ``struct rte_device`` and the
+ inherited device structures of all buses.
Shared Library Versions
@@ -578,18 +575,20 @@ Known Issues
Also, make sure to start the actual text at the margin.
=========================================================
-* When using SR-IOV (VF) support with netvsc PMD and the Mellanox mlx5 bifurcated
- driver; the Linux netvsc device must be brought up before the netvsc device is
- unbound and passed to the DPDK.
+* When using SR-IOV (VF) support with netvsc PMD and the Mellanox mlx5
+ bifurcated driver the Linux netvsc device must be brought up before the
+ netvsc device is unbound and passed to the DPDK.
-* IBM Power8 is not supported by this release of DPDK. IBM Power9 is supported.
+* IBM Power8 is not supported in this release of DPDK. IBM Power9 is
+ supported.
-* ``AVX-512`` support has been disabled for ``GCC`` builds [1] because of a crash [2].
- This can affect ``native`` machine type build targets on the platforms that support
- ``AVX512F`` like ``Intel Skylake`` processors, and can cause a possible performance drop.
- The immediate workaround is to use ``clang`` compiler on these platforms.
- Issue has been identified as a GCC defect and reported to GCC community [3]. Further
- actions will be taken based on the GCC defect result.
+* ``AVX-512`` support has been disabled for ``GCC`` builds [1] because of a
+ crash [2]. This can affect ``native`` machine type build targets on the
+ platforms that support ``AVX512F`` like ``Intel Skylake`` processors, and
+ can cause a possible performance drop. The immediate workaround is to use
+ ``clang`` compiler on these platforms. The issue has been identified as a
+ GCC defect and reported to the GCC community [3]. Further actions will be
+ taken based on the GCC defect result.
[1]: Commit 8d07c82b239f ("mk: disable gcc AVX512F support")
[2]: https://bugs.dpdk.org/show_bug.cgi?id=97
@@ -661,7 +660,7 @@ Tested Platforms
* Device id (pf/vf): 8086:1572 / 8086:154c
* Driver version: 2.4.6 (i40e)
- * Intel Corporation Ethernet Connection X722 for 10GbE SFP+ (4x10G)
+ * Intel(R) Corporation Ethernet Connection X722 for 10GbE SFP+ (4x10G)
* Firmware version: 3.33 0x80000fd5 0.0.0
* Device id (pf/vf): 8086:37d0 / 8086:37cd
--
2.7.5
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH] fix dpdk.org URLs
@ 2018-11-26 17:55 2% Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-11-26 17:55 UTC (permalink / raw)
To: Jerin Jacob, John McNamara, Marko Kovacevic, John Griffin,
Fiona Trahe, Deepak Kumar Jain, Bruce Richardson, John Daley,
Hyong Youb Kim, Erik Gabriel Carrillo, Amr Mokhtar
Cc: dev
The DPDK website has a new URL scheme since June 2018.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
app/test-eventdev/test_order_atq.c | 2 +-
app/test-eventdev/test_order_queue.c | 2 +-
app/test-eventdev/test_perf_atq.c | 2 +-
app/test-eventdev/test_perf_queue.c | 2 +-
app/test-eventdev/test_pipeline_atq.c | 2 +-
app/test-eventdev/test_pipeline_queue.c | 2 +-
doc/build-sdk-meson.txt | 2 +-
doc/guides/contributing/documentation.rst | 4 ++--
doc/guides/contributing/patches.rst | 14 +++++++-------
doc/guides/contributing/stable.rst | 6 +++---
doc/guides/cryptodevs/qat.rst | 4 ++--
doc/guides/freebsd_gsg/install_from_ports.rst | 2 +-
doc/guides/howto/flow_bifurcation.rst | 2 +-
doc/guides/linux_gsg/nic_perf_intel_platform.rst | 2 +-
doc/guides/nics/enic.rst | 2 +-
doc/guides/prog_guide/cryptodev_lib.rst | 2 +-
doc/guides/prog_guide/event_timer_adapter.rst | 4 ++--
doc/guides/prog_guide/switch_representation.rst | 4 ++--
doc/guides/rel_notes/release_18_05.rst | 10 +++++-----
doc/guides/tools/testbbdev.rst | 3 ++-
license/exceptions.txt | 2 +-
21 files changed, 38 insertions(+), 37 deletions(-)
diff --git a/app/test-eventdev/test_order_atq.c b/app/test-eventdev/test_order_atq.c
index 35debcfdc..4a8546e7f 100644
--- a/app/test-eventdev/test_order_atq.c
+++ b/app/test-eventdev/test_order_atq.c
@@ -7,7 +7,7 @@
#include "test_order_common.h"
-/* See http://dpdk.org/doc/guides/tools/testeventdev.html for test details */
+/* See http://doc.dpdk.org/guides/tools/testeventdev.html for test details */
static inline __attribute__((always_inline)) void
order_atq_process_stage_0(struct rte_event *const ev)
diff --git a/app/test-eventdev/test_order_queue.c b/app/test-eventdev/test_order_queue.c
index 17f7b9845..a272c7a57 100644
--- a/app/test-eventdev/test_order_queue.c
+++ b/app/test-eventdev/test_order_queue.c
@@ -7,7 +7,7 @@
#include "test_order_common.h"
-/* See http://dpdk.org/doc/guides/tools/testeventdev.html for test details */
+/* See http://doc.dpdk.org/guides/tools/testeventdev.html for test details */
static inline __attribute__((always_inline)) void
order_queue_process_stage_0(struct rte_event *const ev)
diff --git a/app/test-eventdev/test_perf_atq.c b/app/test-eventdev/test_perf_atq.c
index 9715a2ce8..b76ca605b 100644
--- a/app/test-eventdev/test_perf_atq.c
+++ b/app/test-eventdev/test_perf_atq.c
@@ -4,7 +4,7 @@
#include "test_perf_common.h"
-/* See http://dpdk.org/doc/guides/tools/testeventdev.html for test details */
+/* See http://doc.dpdk.org/guides/tools/testeventdev.html for test details */
static inline int
atq_nb_event_queues(struct evt_options *opt)
diff --git a/app/test-eventdev/test_perf_queue.c b/app/test-eventdev/test_perf_queue.c
index 04ce94192..8efdec6f9 100644
--- a/app/test-eventdev/test_perf_queue.c
+++ b/app/test-eventdev/test_perf_queue.c
@@ -4,7 +4,7 @@
#include "test_perf_common.h"
-/* See http://dpdk.org/doc/guides/tools/testeventdev.html for test details */
+/* See http://doc.dpdk.org/guides/tools/testeventdev.html for test details */
static inline int
perf_queue_nb_event_queues(struct evt_options *opt)
diff --git a/app/test-eventdev/test_pipeline_atq.c b/app/test-eventdev/test_pipeline_atq.c
index c60635bf6..fc4cb3bb7 100644
--- a/app/test-eventdev/test_pipeline_atq.c
+++ b/app/test-eventdev/test_pipeline_atq.c
@@ -5,7 +5,7 @@
#include "test_pipeline_common.h"
-/* See http://dpdk.org/doc/guides/tools/testeventdev.html for test details */
+/* See http://doc.dpdk.org/guides/tools/testeventdev.html for test details */
static __rte_always_inline int
pipeline_atq_nb_event_queues(struct evt_options *opt)
diff --git a/app/test-eventdev/test_pipeline_queue.c b/app/test-eventdev/test_pipeline_queue.c
index 25217008c..e35e9eb4c 100644
--- a/app/test-eventdev/test_pipeline_queue.c
+++ b/app/test-eventdev/test_pipeline_queue.c
@@ -5,7 +5,7 @@
#include "test_pipeline_common.h"
-/* See http://dpdk.org/doc/guides/tools/testeventdev.html for test details */
+/* See http://doc.dpdk.org/guides/tools/testeventdev.html for test details */
static __rte_always_inline int
pipeline_queue_nb_event_queues(struct evt_options *opt)
diff --git a/doc/build-sdk-meson.txt b/doc/build-sdk-meson.txt
index a4dd09194..29a8bd387 100644
--- a/doc/build-sdk-meson.txt
+++ b/doc/build-sdk-meson.txt
@@ -4,7 +4,7 @@ INSTALLING DPDK USING THE MESON BUILD SYSTEM
NOTE: Compiling and installing DPDK using ``meson`` and ``ninja``, rather
than using ``make`` (GNU make) is EXPERIMENTAL. Official builds of DPDK
should always be done using ``make``, as described in the ``Getting Started
-Guide`` documentation, and at "http://dpdk.org/doc/quick-start".
+Guide`` documentation, and at "http://core.dpdk.org/doc/quick-start".
Summary
--------
diff --git a/doc/guides/contributing/documentation.rst b/doc/guides/contributing/documentation.rst
index 0165990ed..c28a95c34 100644
--- a/doc/guides/contributing/documentation.rst
+++ b/doc/guides/contributing/documentation.rst
@@ -83,7 +83,7 @@ added to by the developer.
* **API documentation**
The API documentation explains how to use the public DPDK functions.
- The `API index page <http://dpdk.org/doc/api/>`_ shows the generated API documentation with related groups of functions.
+ The `API index page <http://doc.dpdk.org/api/>`_ shows the generated API documentation with related groups of functions.
The API documentation should be updated via Doxygen comments when new functions are added.
@@ -653,7 +653,7 @@ The following are some guidelines for use of Doxygen in the DPDK API documentati
*/
In the API documentation the functions will be rendered as links, see the
- `online section of the rte_ethdev.h docs <http://dpdk.org/doc/api/rte__ethdev_8h.html>`_ that contains the above text.
+ `online section of the rte_ethdev.h docs <http://doc.dpdk.org/api/rte__ethdev_8h.html>`_ that contains the above text.
* The ``@see`` keyword can be used to create a *see also* link to another file or library.
This directive should be placed on one line at the bottom of the documentation section.
diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst
index ffeb50436..a64bb0368 100644
--- a/doc/guides/contributing/patches.rst
+++ b/doc/guides/contributing/patches.rst
@@ -28,9 +28,9 @@ The DPDK development process has the following features:
* All sub-repositories are merged into main repository for ``-rc1`` and ``-rc2`` versions of the release.
* After the ``-rc2`` release all patches should target the main repository.
-The mailing list for DPDK development is `dev@dpdk.org <http://dpdk.org/ml/archives/dev/>`_.
-Contributors will need to `register for the mailing list <http://dpdk.org/ml/listinfo/dev>`_ in order to submit patches.
-It is also worth registering for the DPDK `Patchwork <http://dpdk.org/dev/patchwork/project/dpdk/list/>`_
+The mailing list for DPDK development is `dev@dpdk.org <http://mails.dpdk.org/archives/dev/>`_.
+Contributors will need to `register for the mailing list <http://mails.dpdk.org/listinfo/dev>`_ in order to submit patches.
+It is also worth registering for the DPDK `Patchwork <http://patches.dpdk.org/project/dpdk/list/>`_
The development process requires some familiarity with the ``git`` version control system.
Refer to the `Pro Git Book <http://www.git-scm.com/book/>`_ for further information.
@@ -130,7 +130,7 @@ main repository::
git clone git://dpdk.org/dpdk
git clone http://dpdk.org/git/dpdk
-sub-repositories (`list <http://dpdk.org/browse/next>`_)::
+sub-repositories (`list <http://git.dpdk.org/next>`_)::
git clone git://dpdk.org/next/dpdk-next-*
git clone http://dpdk.org/git/next/dpdk-next-*
@@ -286,7 +286,7 @@ in the body of the commit message. For example::
Signed-off-by: Alex Smith <alex.smith@example.com>
-`Bugzilla <https://dpdk.org/tracker>`_
+`Bugzilla <https://bugs.dpdk.org>`_
is a bug- or issue-tracking system.
Bug-tracking systems allow individual or groups of developers
effectively to keep track of outstanding problems with their product.
@@ -308,7 +308,7 @@ Patch for Stable Releases
~~~~~~~~~~~~~~~~~~~~~~~~~
All fix patches to the master branch that are candidates for backporting
-should also be CCed to the `stable@dpdk.org <http://dpdk.org/ml/listinfo/stable>`_
+should also be CCed to the `stable@dpdk.org <http://mails.dpdk.org/listinfo/stable>`_
mailing list.
In the commit message body the Cc: stable@dpdk.org should be inserted as follows::
@@ -509,7 +509,7 @@ If the patch is in relation to a previous email thread you can add it to the sam
git send-email --to dev@dpdk.org --in-reply-to <1234-foo@bar.com> 000*.patch
The Message ID can be found in the raw text of emails or at the top of each Patchwork patch,
-`for example <http://dpdk.org/dev/patchwork/patch/7646/>`_.
+`for example <http://patches.dpdk.org/patch/7646/>`_.
Shallow threading (``--thread --no-chain-reply-to``) is preferred for a patch series.
Once submitted your patches will appear on the mailing list and in Patchwork.
diff --git a/doc/guides/contributing/stable.rst b/doc/guides/contributing/stable.rst
index 1746c0461..2ac4f0a88 100644
--- a/doc/guides/contributing/stable.rst
+++ b/doc/guides/contributing/stable.rst
@@ -96,7 +96,7 @@ The Stable and LTS release are coordinated on the stable@dpdk.org mailing
list.
All fix patches to the master branch that are candidates for backporting
-should also be CCed to the `stable@dpdk.org <http://dpdk.org/ml/listinfo/stable>`_
+should also be CCed to the `stable@dpdk.org <http://mails.dpdk.org/listinfo/stable>`_
mailing list.
@@ -107,10 +107,10 @@ A Stable Release will be released by:
* Tagging the release with YY.MM.n (year, month, number).
* Uploading a tarball of the release to dpdk.org.
-* Sending an announcement to the `announce@dpdk.org <http://dpdk.org/ml/listinfo/announce>`_
+* Sending an announcement to the `announce@dpdk.org <http://mails.dpdk.org/listinfo/announce>`_
list.
-Stable releases are available on the `dpdk.org download page <http://dpdk.org/download>`_.
+Stable releases are available on the `dpdk.org download page <http://core.dpdk.org/download/>`_.
ABI
diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst
index 1db98685a..9fb9f01d1 100644
--- a/doc/guides/cryptodevs/qat.rst
+++ b/doc/guides/cryptodevs/qat.rst
@@ -7,7 +7,7 @@ Intel(R) QuickAssist (QAT) Crypto Poll Mode Driver
QAT documentation consists of three parts:
* Details of the symmetric crypto service below.
-* Details of the `compression service <http://dpdk.org/doc/guides/compressdevs/qat_comp.html>`_
+* Details of the `compression service <http://doc.dpdk.org/guides/compressdevs/qat_comp.html>`_
in the compressdev drivers section.
* Details of building the common QAT infrastructure and the PMDs to support the
above services. See :ref:`building_qat` below.
@@ -124,7 +124,7 @@ Configuring and Building the DPDK QAT PMDs
Further information on configuring, building and installing DPDK is described
-`here <http://dpdk.org/doc/guides/linux_gsg/build_dpdk.html>`_.
+`here <http://doc.dpdk.org/guides/linux_gsg/build_dpdk.html>`_.
Quick instructions for QAT cryptodev PMD are as follows:
diff --git a/doc/guides/freebsd_gsg/install_from_ports.rst b/doc/guides/freebsd_gsg/install_from_ports.rst
index d6ce847f6..253328eb1 100644
--- a/doc/guides/freebsd_gsg/install_from_ports.rst
+++ b/doc/guides/freebsd_gsg/install_from_ports.rst
@@ -62,7 +62,7 @@ environmental variables should be set as below:
.. note::
To install a copy of the DPDK compiled using gcc, please download the
- official DPDK package from http://dpdk.org/ and install manually using
+ official DPDK package from http://core.dpdk.org/download/ and install manually using
the instructions given in the next chapter, :ref:`building_from_source`
An example application can therefore be copied to a user's home directory and
diff --git a/doc/guides/howto/flow_bifurcation.rst b/doc/guides/howto/flow_bifurcation.rst
index bc9a0934d..eabf4d730 100644
--- a/doc/guides/howto/flow_bifurcation.rst
+++ b/doc/guides/howto/flow_bifurcation.rst
@@ -268,4 +268,4 @@ The typical procedure to achieve this is as follows:
'not involved', while ``00`` or no mask means 'involved'.
* For more details of the configuration, refer to the
- `cloud filter test plan <http://dpdk.org/browse/tools/dts/tree/test_plans/cloud_filter_test_plan.rst>`_
+ `cloud filter test plan <http://git.dpdk.org/tools/dts/tree/test_plans/cloud_filter_test_plan.rst>`_
diff --git a/doc/guides/linux_gsg/nic_perf_intel_platform.rst b/doc/guides/linux_gsg/nic_perf_intel_platform.rst
index 987cd0a5a..cf5c9e0db 100644
--- a/doc/guides/linux_gsg/nic_perf_intel_platform.rst
+++ b/doc/guides/linux_gsg/nic_perf_intel_platform.rst
@@ -64,7 +64,7 @@ This aligns with the previous output which showed that each channel has one memo
Network Interface Card Requirements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Use a `DPDK supported <http://dpdk.org/doc/nics>`_ high end NIC such as the Intel XL710 40GbE.
+Use a `DPDK supported <http://core.dpdk.org/supported/>`_ high end NIC such as the Intel XL710 40GbE.
Make sure each NIC has been flashed the latest version of NVM/firmware.
diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst
index 746d89123..bc38f51aa 100644
--- a/doc/guides/nics/enic.rst
+++ b/doc/guides/nics/enic.rst
@@ -14,7 +14,7 @@ How to obtain ENIC PMD integrated DPDK
--------------------------------------
ENIC PMD support is integrated into the DPDK suite. dpdk-<version>.tar.gz
-should be downloaded from http://dpdk.org
+should be downloaded from http://core.dpdk.org/download/
Configuration information
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 90d01e936..8ee33c875 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -1043,4 +1043,4 @@ Asymmetric Crypto Device API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The cryptodev Library API is described in the
-`DPDK API Reference <http://dpdk.org/doc/api/>`_
+`DPDK API Reference <http://doc.dpdk.org/api/>`_
diff --git a/doc/guides/prog_guide/event_timer_adapter.rst b/doc/guides/prog_guide/event_timer_adapter.rst
index 7bbbdfe90..3b4446ee9 100644
--- a/doc/guides/prog_guide/event_timer_adapter.rst
+++ b/doc/guides/prog_guide/event_timer_adapter.rst
@@ -5,7 +5,7 @@ Event Timer Adapter Library
===========================
The DPDK
-`Event Device library <http://dpdk.org/doc/guides/prog_guide/eventdev.html>`_
+`Event Device library <http://doc.dpdk.org/guides/prog_guide/eventdev.html>`_
introduces an event driven programming model which presents applications with
an alternative to the polling model traditionally used in DPDK
applications. Event devices can be coupled with arbitrary components to provide
@@ -21,7 +21,7 @@ The Event Timer Adapter library is designed to interface with hardware or
software implementations of the timer mechanism; it will query an eventdev PMD
to determine which implementation should be used. The default software
implementation manages timers using the DPDK
-`Timer library <http://dpdk.org/doc/guides/prog_guide/timer_lib.html>`_.
+`Timer library <http://doc.dpdk.org/guides/prog_guide/timer_lib.html>`_.
Examples of using the API are presented in the `API Overview`_ and
`Processing Timer Expiry Events`_ sections. Code samples are abstracted and
diff --git a/doc/guides/prog_guide/switch_representation.rst b/doc/guides/prog_guide/switch_representation.rst
index f5ee516f6..e5c78c234 100644
--- a/doc/guides/prog_guide/switch_representation.rst
+++ b/doc/guides/prog_guide/switch_representation.rst
@@ -349,7 +349,7 @@ interconnection without introducing new concepts and whole new API to
implement them. This is described in `flow API (rte_flow)`_.
.. [6] `Generic flow API (rte_flow)
- <http://dpdk.org/doc/guides/prog_guide/rte_flow.html>`_
+ <http://doc.dpdk.org/guides/prog_guide/rte_flow.html>`_
Flow API (rte_flow)
-------------------
@@ -737,7 +737,7 @@ Examples in subsequent sections apply to hypervisor applications only and
are based on port representors **A**, **B** and **C**.
.. [2] `Flow syntax
- <http://dpdk.org/doc/guides/testpmd_app_ug/testpmd_funcs.html#flow-syntax>`_
+ <http://doc.dpdk.org/guides/testpmd_app_ug/testpmd_funcs.html#flow-syntax>`_
Associating VF 1 with Physical Port 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 8dc22b011..3413d8de1 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -594,7 +594,7 @@ Known Issues
The issue is explained in more detail, including potential workarounds,
in the Bugzilla entry referenced below.
- Bugzilla entry: https://dpdk.org/tracker/show_bug.cgi?id=50
+ Bugzilla entry: https://bugs.dpdk.org/show_bug.cgi?id=50
* **pdump is not compatible with old applications.**
@@ -619,21 +619,21 @@ Known Issues
needs to be run per-shell session, or before every test run. This change
can also be made persistent by adding ``kern.coredump=0`` to ``/etc/sysctl.conf``.
- Bugzilla entry: https://dpdk.org/tracker/show_bug.cgi?id=53
+ Bugzilla entry: https://bugs.dpdk.org/show_bug.cgi?id=53
* **ixgbe PMD crash on hotplug detach when no VF created.**
ixgbe PMD uninit path cause null pointer dereference because of port representor
cleanup when number of VF is zero.
- Bugzilla entry: https://dpdk.org/tracker/show_bug.cgi?id=57
+ Bugzilla entry: https://bugs.dpdk.org/show_bug.cgi?id=57
* **Bonding PMD may fail to accept new slave ports in certain conditions.**
In certain conditions when using testpmd,
bonding may fail to register new slave ports.
- Bugzilla entry: https://dpdk.org/tracker/show_bug.cgi?id=52.
+ Bugzilla entry: https://bugs.dpdk.org/show_bug.cgi?id=52.
* **Unexpected performance regression in Vhost library.**
@@ -641,7 +641,7 @@ Known Issues
drop. However, in some setups, bigger performance drops have been measured
when running micro-benchmarks.
- Bugzilla entry: https://dpdk.org/tracker/show_bug.cgi?id=48
+ Bugzilla entry: https://bugs.dpdk.org/show_bug.cgi?id=48
Shared Library Versions
diff --git a/doc/guides/tools/testbbdev.rst b/doc/guides/tools/testbbdev.rst
index 234a64f53..5caa90239 100644
--- a/doc/guides/tools/testbbdev.rst
+++ b/doc/guides/tools/testbbdev.rst
@@ -62,7 +62,8 @@ The following are the command-line options:
``-e EAL_PARAMS, --eal_params EAL_PARAMS``
Specifies EAL arguments which are passed to the test app. For more details,
- refer to DPDK documentation at http://dpdk.org/doc.
+ refer to DPDK documentation at
+ http://doc.dpdk.org/guides/linux_gsg/linux_eal_parameters.html.
``-t TIMEOUT, --timeout TIMEOUT``
Specifies timeout in seconds. If not specified timeout is set to 300 seconds.
diff --git a/license/exceptions.txt b/license/exceptions.txt
index f2ef03706..f1cfa462f 100644
--- a/license/exceptions.txt
+++ b/license/exceptions.txt
@@ -1,7 +1,7 @@
This file will record any exceptions in DPDK Project with respect to DPDK
IP License policy as defined in DPDK Charter available at:
- http://dpdk.org/about/charter#ip
+ https://www.dpdk.org/charter/
Note that following licenses are not exceptions:-
- BSD-3-Clause
--
2.19.0
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v2] doc: update release notes for 18.11
2018-11-26 10:51 4% [dpdk-dev] [PATCH v1] doc: update release notes for 18.11 John McNamara
@ 2018-11-26 23:15 4% ` John McNamara
0 siblings, 0 replies; 200+ results
From: John McNamara @ 2018-11-26 23:15 UTC (permalink / raw)
To: dev; +Cc: marko.kovacevic, John McNamara
Fix grammar, spelling and formatting of DPDK 18.11 release notes.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/rel_notes/release_18_11.rst | 298 ++++++++++++++++-----------------
1 file changed, 148 insertions(+), 150 deletions(-)
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 373dcc0..bbb0307 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -48,7 +48,7 @@ New Features
- eventdev (lib, PMDs)
- etc
* Other libs
- * Apps, Examples, Tools (if significative)
+ * Apps, Examples, Tools (if significant)
This section is a comment. Do not overwrite or remove it.
Also, make sure to start the actual text at the margin.
@@ -56,40 +56,42 @@ New Features
* **Added support for using externally allocated memory in DPDK.**
- DPDK has gained support for creating new ``rte_malloc`` heaps referencing
+ DPDK has added support for creating new ``rte_malloc`` heaps referencing
memory that was created outside of DPDK's own page allocator, and using that
memory natively with any other DPDK library or data structure.
-* **Added check for ensuring allocated memory addressable by devices.**
+* **Added check for ensuring allocated memory is addressable by devices.**
Some devices can have addressing limitations so a new function,
- ``rte_mem_check_dma_mask``, has been added for checking allocated memory is
- not out of the device range. Because now memory can be dynamically allocated
- after initialization, a dma mask is kept and any new allocated memory will be
- checked out against that dma mask and rejected if out of range. If more than
- one device has addressing limitations, the dma mask is the more restricted one.
+ ``rte_mem_check_dma_mask()``, has been added for checking that allocated
+ memory is not out of the device range. Since memory can now be allocated
+ dynamically after initialization, a DMA mask is stored and any new allocated
+ memory will be checked against it and rejected if it is out of range. If
+ more than one device has addressing limitations, the DMA mask is the more
+ restrictive one.
-* **Updated the C11 memory model version of ring library.**
+* **Updated the C11 memory model version of the ring library.**
- The latency is decreased for architectures using the C11 memory model
- version of the ring library.
+ Added changes to decrease latency for architectures using the C11 memory
+ model version of the ring library.
- On Cavium ThunderX2 platform, the changes decreased latency by 27~29%
- and 3~15% for MPMC and SPSC cases respectively (with 2 lcores). The
+ On Cavium ThunderX2 platform, the changes decreased latency by 27-29%
+ and 3-15% for MPMC and SPSC cases respectively (with 2 lcores). The
real improvements may vary with the number of contending lcores and
- the size of ring.
+ the size of the ring.
* **Added hot-unplug handle mechanism.**
- ``rte_dev_hotplug_handle_enable`` and ``rte_dev_hotplug_handle_disable`` are
- for enabling or disabling hotplug handle mechanism.
+ Added ``rte_dev_hotplug_handle_enable()`` and
+ ``rte_dev_hotplug_handle_disable()`` for enabling or disabling the hotplug
+ handle mechanism.
-* **Support device multi-process hotplug.**
+* **Added support for device multi-process hotplug.**
- Hotplug and hot-unplug for devices will now be supported in multiprocessing
- scenario. Any ethdev devices created in the primary process will be regarded
- as shared and will be available for all DPDK processes. Synchronization
- between processes will be done using DPDK IPC.
+ Added support for hotplug and hot-unplug in a multiprocessing scenario. Any
+ ethdev devices created in the primary process will be regarded as shared and
+ will be available for all DPDK processes. Synchronization between processes
+ will be done using DPDK IPC.
* **Added new Flow API actions to rewrite fields in packet headers.**
@@ -105,9 +107,10 @@ New Features
Added new Flow API action to swap the source and destination MAC
addresses in the outermost Ethernet header.
-* **Add support to offload more flow match and actions for CXGBE PMD**
+* **Add support to offload more flow match and actions for CXGBE PMD.**
- Flow API support has been enhanced for CXGBE Poll Mode Driver to offload:
+ The Flow API support has been enhanced for the CXGBE Poll Mode Driver to
+ offload:
* Match items: destination MAC address.
* Action items: push/pop/rewrite vlan header,
@@ -116,6 +119,7 @@ New Features
swap MAC addresses in outermost Ethernet header.
* **Added a devarg to use the latest supported vector path in i40e.**
+
A new devarg ``use-latest-supported-vec`` was introduced to allow users to
choose the latest vector path that the platform supported. For example, users
can use AVX2 vector path on BDW/HSW to get better performance.
@@ -133,8 +137,8 @@ New Features
* **Added NXP ENETC PMD.**
- Added the new enetc driver for NXP enetc platform. See the
- "ENETC Poll Mode Driver" document for more details on this new driver.
+ Added the new enetc driver for the NXP enetc platform. See the
+ :doc:`../nics/enetc` nic driver guide for more details on this new driver.
* **Added Ethernet poll mode driver for Aquantia aQtion family of 10G devices.**
@@ -147,17 +151,18 @@ New Features
Updated the mlx5 driver including the following changes:
* Improved security of PMD to prevent the NIC from getting stuck when
- application misbehaves.
- * reworked flow engine to supported e-switch flow rules (transfer attribute).
- * Supported header re-write(L2-L4), VXLAN encap/decap, count ,match
+ the application misbehaves.
+ * Reworked flow engine to supported e-switch flow rules (transfer attribute).
+ * Added support for header re-write(L2-L4), VXLAN encap/decap, count, match
on TCP flags and multiple flow groups with e-switch flow rules.
- * Supported match on medatada, VXLAN and MPLS encap/decap with flow rules.
- * Supported RTE_ETH_DEV_CLOSE_REMOVE flag to provide better support for
- representors.
- * Supported meson build.
+ * Added support for match on metadata, VXLAN and MPLS encap/decap with flow
+ rules.
+ * Added support for ``RTE_ETH_DEV_CLOSE_REMOVE`` flag to provide better
+ support for representors.
+ * Added support for meson build.
* Fixed build issue with PPC.
- * Supported BlueField VF.
- * Supported externally allocated static memory for DMA.
+ * Added support for BlueField VF.
+ * Added support for externally allocated static memory for DMA.
* **Updated Solarflare network PMD.**
@@ -173,36 +178,38 @@ New Features
* Added AVX2-based vectorized Rx handler.
* Added VLAN and checksum offloads to the simple Tx handler.
- * Added the count flow action.
+ * Added the "count" flow action.
* Enabled the virtual address IOVA mode.
-* **Updated failsafe driver.**
+* **Updated the failsafe driver.**
Updated the failsafe driver including the following changes:
- * Support for Rx and Tx queues start and stop.
- * Support for Rx and Tx queues deferred start.
- * Support for runtime Rx and Tx queues setup.
- * Support multicast MAC address set.
+ * Added support for Rx and Tx queues start and stop.
+ * Added support for Rx and Tx queues deferred start.
+ * Added support for runtime Rx and Tx queues setup.
+ * Added support multicast MAC address set.
+
+* **Added a devarg to use a PCAP interface physical MAC address.**
-* **Added a devarg to use PCAP interface physical MAC address.**
- A new devarg ``phy_mac`` was introduced to allow users to use physical
+ A new devarg ``phy_mac`` was introduced to allow users to use the physical
MAC address of the selected PCAP interface.
* **Added TAP Rx/Tx queues sharing with a secondary process.**
- A secondary process can attach a TAP device created in the primary process,
- probe the queues, and process Rx/Tx in a secondary process.
+ Added support to allow a secondary process to attach a TAP device created
+ in the primary process, probe the queues, and process Rx/Tx in a secondary
+ process.
* **Added classification and metering support to SoftNIC PMD.**
Added support for flow classification (rte_flow API), and metering and
policing (rte_mtr API) to the SoftNIC PMD.
-* **Added Crypto support to Softnic PMD.**
+* **Added Crypto support to the Softnic PMD.**
The Softnic is now capable of processing symmetric crypto workloads such
- as cipher, cipher-authentication chaining, and aead encryption and
+ as cipher, cipher-authentication chaining, and AEAD encryption and
decryption. This is achieved by calling DPDK Cryptodev APIs.
* **Added cryptodev port to port library.**
@@ -212,12 +219,12 @@ New Features
* **Added symmetric cryptographic actions to the pipeline library.**
- In the pipeline library an added symmetric crypto action parsing and action
- handler are implemented. The action allows automatically preparing the crypto
- operation with the rules specified such as algorithm, key, and IV, etc for
- the cryptodev port to process.
+ In the pipeline library support was added for symmetric crypto action
+ parsing and an action handler was implemented. The action allows automatic
+ preparation of the crypto operation with the rules specified such as
+ algorithm, key, and IV, etc. for the cryptodev port to process.
-* **Added support for GEN3 devices to Intel QAT driver .**
+* **Added support for GEN3 devices to Intel QAT driver.**
Added support for the third generation of Intel QuickAssist devices.
@@ -225,26 +232,25 @@ New Features
The QAT PMD was updated with additional support for:
- * AES-CMAC algorithm.
+ * The AES-CMAC algorithm.
* **Updated the AESNI MB PMD.**
- The AESNI MB PMD has been updated with additional support for AES-GCM
- algorithm support.
+ The AESNI MB PMD has been updated with additional support for the AES-GCM
+ algorithm.
* **Added NXP CAAM JR PMD.**
Added the new caam job ring driver for NXP platforms. See the
- "NXP CAAM JOB RING (caam_jr)" document for more details on this new driver.
+ :doc:`../cryptodevs/caam_jr` document for more details on this new driver.
* **Added support for Dynamic Huffman Encoding to Intel QAT comp PMD.**
The Intel QuickAssist (QAT) compression PMD has been updated with support
for Dynamic Huffman Encoding for the Deflate algorithm.
-
* **Added Event Ethernet Tx Adapter.**
- Added event ethernet Tx adapter library that provides configuration and
+ Added event ethernet Tx adapter library that provides configuration and
data path APIs for the ethernet transmit stage of an event driven packet
processing application. These APIs abstract the implementation of the
transmit stage and allow the application to use eventdev PMD support or
@@ -260,23 +266,23 @@ New Features
* **Added extendable bucket feature to hash library (rte_hash).**
- This new “extendable bucket” feature provides 100% insertion guarantee to
+ This new "extendable bucket" feature provides 100% insertion guarantee to
the capacity specified by the user by extending hash table with extra
buckets when needed to accommodate the unlikely event of intensive hash
- collisions. In addition, the internal hashing algorithm was changed to use
+ collisions. In addition, the internal hashing algorithm was changed to use
partial-key hashing to improve memory efficiency and lookup performance.
* **Added lock free reader/writer concurrency to hash library (rte_hash).**
Lock free reader/writer concurrency prevents the readers from getting
- blocked due to a pre-empted writer thread. This allows the hash library
- to be used in scenarios where the writer thread runs on control plane.
+ blocked due to a preempted writer thread. This allows the hash library
+ to be used in scenarios where the writer thread runs on the control plane.
-* **Added Traffic Pattern Aware Power Control Library**
+* **Added Traffic Pattern Aware Power Control Library.**
- Added an experimental library. This extend Power Library and provide
- empty_poll APIs. This feature measure how many times empty_poll are
- executed per core, use the number of empty polls as a hint for system
+ Added an experimental library that extends the Power Library and provides
+ empty_poll APIs. This feature measures how many times empty_polls are
+ executed per core and uses the number of empty polls as a hint for system
power management.
See the :doc:`../prog_guide/power_man` section of the DPDK Programmers
@@ -292,27 +298,27 @@ New Features
* **Added Telemetry API.**
- Added the telemetry API which allows applications to transparently expose
- their telemetry via a UNIX socket in JSON. The JSON can be consumed by any
+ Added a new telemetry API which allows applications to transparently expose
+ their telemetry in JSON via a UNIX socket. The JSON can be consumed by any
Service Assurance agent, such as CollectD.
* **Updated KNI kernel module, rte_kni library, and KNI sample application.**
Updated the KNI kernel module with a new kernel module parameter,
``carrier=[on|off]`` to allow the user to control the default carrier
- state of KNI kernel network interfaces. The default carrier state
+ state of the KNI kernel network interfaces. The default carrier state
is now set to ``off``, so the interfaces cannot be used until the
carrier state is set to ``on`` via ``rte_kni_update_link`` or
by writing ``1`` to ``/sys/devices/virtual/net/<iface>/carrier``.
In previous versions the default carrier state was left undefined.
See :doc:`../prog_guide/kernel_nic_interface` for more information.
- Added the new API function ``rte_kni_update_link`` to allow the user
+ Also added the new API function ``rte_kni_update_link()`` to allow the user
to set the carrier state of the KNI kernel network interface.
- Added a new command line flag ``-m`` to the KNI sample application to
+ Also added a new command line flag ``-m`` to the KNI sample application to
monitor and automatically reflect the physical NIC carrier state to the
- KNI kernel network interface with the new ``rte_kni_update_link`` API.
+ KNI kernel network interface with the new ``rte_kni_update_link()`` API.
See :doc:`../sample_app_ug/kernel_nic_interface` for more information.
* **Added ability to switch queue deferred start flag on testpmd app.**
@@ -322,7 +328,7 @@ New Features
the specified port. The port must be stopped before the command call in order
to reconfigure queues.
-* **Add a new sample for vDPA**
+* **Add a new sample application for vDPA.**
The vdpa sample application creates vhost-user sockets by using the
vDPA backend. vDPA stands for vhost Data Path Acceleration which utilizes
@@ -337,12 +343,12 @@ New Features
computation to the NIST Cryptographic Algorithm Validation Program (CAVP)
test vectors.
-* **Allow unit test binary to take parameters from the environment**
+* **Allow unit test binary to take parameters from the environment.**
The unit test "test", or "dpdk-test", binary is often called from scripts,
- which can make passing additional parameters, such as a coremask, to it more
- awkward. Support has been added to the application to allow it to take
- additional command-line parameter values from the "DPDK_TEST_PARAMS"
+ which can make passing additional parameters, such as a coremask,
+ difficult. Support has been added to the application to allow it to take
+ additional command-line parameter values from the ``DPDK_TEST_PARAMS``
environment variable to make this application easier to use.
@@ -364,13 +370,14 @@ API Changes
for any users of memseg-walk-related functions, as they will now have to skip
externally allocated segments in most cases if the intent is to only iterate
over internal DPDK memory.
- ``socket_id`` parameter across the entire DPDK has gained additional meaning,
- as some socket ID's will now be representing externally allocated memory. No
- changes will be required for existing code as backwards compatibility will be
- kept, and those who do not use this feature will not see these extra socket
- ID's. Any new API's must not check socket ID parameters themselves, and must
- instead leave it to the memory subsystem to decide whether socket ID is a
- valid one.
+
+ In addition the ``socket_id`` parameter across the entire DPDK has gained
+ additional meaning, as some socket ID's will now be representing externally
+ allocated memory. No changes will be required for existing code as backwards
+ compatibility will be kept, and those who do not use this feature will not
+ see these extra socket ID's. Any new API's must not check socket ID
+ parameters themselves, and must instead leave it to the memory subsystem to
+ decide whether socket ID is a valid one.
* eal: The following devargs functions, which were deprecated in 18.05,
were removed in 18.11:
@@ -387,8 +394,8 @@ API Changes
``rte_dev_remove`` or ``rte_eal_hotplug_remove``.
* eal: The scope of ``rte_eal_hotplug_add()``/``rte_dev_probe()``
- and ``rte_eal_hotplug_remove()``/``rte_dev_remove()`` is extended.
- In multi-process model, they will guarantee that the device is
+ and ``rte_eal_hotplug_remove()``/``rte_dev_remove()`` has been extended.
+ In the multi-process model, they will guarantee that the device is
attached or detached on all processes.
* mbuf: The ``__rte_mbuf_raw_free()`` and ``__rte_pktmbuf_prefree_seg()``
@@ -396,42 +403,43 @@ API Changes
``rte_mbuf_raw_free()`` and ``rte_pktmbuf_prefree_seg()``.
* ethdev: The deprecated functions attach/detach were removed in 18.11.
- ``rte_eth_dev_attach`` can be replaced by ``RTE_ETH_FOREACH_MATCHING_DEV``
- and ``rte_dev_probe`` or ``rte_eal_hotplug_add``.
- ``rte_eth_dev_detach`` can be replaced by
- ``rte_dev_remove`` or ``rte_eal_hotplug_remove``.
+ ``rte_eth_dev_attach()`` can be replaced by ``RTE_ETH_FOREACH_MATCHING_DEV``
+ and ``rte_dev_probe()`` or ``rte_eal_hotplug_add()``.
+ ``rte_eth_dev_detach()`` can be replaced by
+ ``rte_dev_remove()`` or ``rte_eal_hotplug_remove()``.
* ethdev: A call to ``rte_eth_dev_release_port()`` has been added in
``rte_eth_dev_close()``. As a consequence, a closed port is freed
and seen as invalid because of its state ``RTE_ETH_DEV_UNUSED``.
- This new behaviour is enabled per driver for a migration period.
+ This new behavior is enabled per driver for a migration period.
-* A new device flag, RTE_ETH_DEV_NOLIVE_MAC_ADDR, changes the order of
- actions inside rte_eth_dev_start regarding MAC set. Some NICs do not
+* A new device flag, ``RTE_ETH_DEV_NOLIVE_MAC_ADDR``, changes the order of
+ actions inside ``rte_eth_dev_start()`` regarding MAC set. Some NICs do not
support MAC changes once the port has started and with this new device
flag the MAC can be properly configured in any case. This is particularly
important for bonding.
-* The default behaviour of CRC strip offload changed. Without any specific Rx
- offload flag, default behavior by PMD is now to strip CRC.
- DEV_RX_OFFLOAD_CRC_STRIP offload flag has been removed.
- To request keeping CRC, application should set ``DEV_RX_OFFLOAD_KEEP_CRC`` Rx
- offload.
+* The default behavior of CRC strip offload has changed in this
+ release. Without any specific Rx offload flag, default behavior by a PMD is
+ now to strip CRC. ``DEV_RX_OFFLOAD_CRC_STRIP`` offload flag has been removed.
+ To request keeping CRC, application should set ``DEV_RX_OFFLOAD_KEEP_CRC``
+ Rx offload.
-* eventdev: Type of 2nd parameter to ``rte_event_eth_rx_adapter_caps_get()``
- has been changed from uint8_t to uint16_t.
+* eventdev: The type of the second parameter to
+ ``rte_event_eth_rx_adapter_caps_get()`` has been changed from uint8_t to
+ uint16_t.
* kni: By default, interface carrier status is ``off`` which means there won't
- be any traffic. It can be set to ``on`` via ``rte_kni_update_link()`` API
- or via ``sysfs`` interface:
- ``echo 1 > /sys/class/net/vEth0/carrier``.
+ be any traffic. It can be set to ``on`` via ``rte_kni_update_link()`` API or
+ via ``sysfs`` interface: ``echo 1 > /sys/class/net/vEth0/carrier``.
+
Note interface should be ``up`` to be able to read/write sysfs interface.
When KNI sample application is used, ``-m`` parameter can be used to
automatically update the carrier status for the interface.
-* kni: When ethtool support enabled (``CONFIG_RTE_KNI_KMOD_ETHTOOL=y``)
- ethtool commands ``ETHTOOL_GSET & ETHTOOL_SSET`` are no more supported for the
- kernels that has ``ETHTOOL_GLINKSETTINGS & ETHTOOL_SLINKSETTINGS`` support.
+* kni: When ethtool support is enabled (``CONFIG_RTE_KNI_KMOD_ETHTOOL=y``)
+ ethtool commands ``ETHTOOL_GSET & ETHTOOL_SSET`` are no longer supported for
+ kernels that have ``ETHTOOL_GLINKSETTINGS & ETHTOOL_SLINKSETTINGS`` support.
This means ``ethtool "-a|--show-pause", "-s|--change"`` won't work, and
``ethtool <iface>`` output will have less information.
@@ -451,42 +459,30 @@ ABI Changes
=========================================================
* eal: added ``legacy_mem`` and ``single_file_segments`` values to
- ``rte_config`` structure on account of improving DPDK usability when
- using either ``--legacy-mem`` or ``--single-file-segments`` flags.
+ ``rte_config`` structure on account of improving DPDK usability when
+ using either ``--legacy-mem`` or ``--single-file-segments`` flags.
* eal: EAL library ABI version was changed due to previously announced work on
- supporting external memory in DPDK:
- - structure ``rte_memseg_list`` now has a new field indicating length
- of memory addressed by the segment list
- - structure ``rte_memseg_list`` now has a new flag indicating whether
- the memseg list refers to external memory
- - structure ``rte_malloc_heap`` now has a new field indicating socket
- ID the malloc heap belongs to
- - structure ``rte_mem_config`` has had its ``malloc_heaps`` array
- resized from ``RTE_MAX_NUMA_NODES`` to ``RTE_MAX_HEAPS`` value
- - structure ``rte_malloc_heap`` now has a ``heap_name`` member
- - structure ``rte_eal_memconfig`` has been extended to contain next
- socket ID for externally allocated segments
-
-* eal: Added ``dma_maskbits`` to ``rte_mem_config`` for keeping more restricted
- dma mask based on devices addressing limitations.
+ supporting external memory in DPDK:
-* eal: The structure ``rte_device`` got a new field to reference a ``rte_bus``.
- It is changing the size of the ``struct rte_device`` and the inherited
- device structures of all buses.
+ - Structure ``rte_memseg_list`` now has a new field indicating length
+ of memory addressed by the segment list
+ - Structure ``rte_memseg_list`` now has a new flag indicating whether
+ the memseg list refers to external memory
+ - Structure ``rte_malloc_heap`` now has a new field indicating socket
+ ID the malloc heap belongs to
+ - Structure ``rte_mem_config`` has had its ``malloc_heaps`` array
+ resized from ``RTE_MAX_NUMA_NODES`` to ``RTE_MAX_HEAPS`` value
+ - Structure ``rte_malloc_heap`` now has a ``heap_name`` member
+ - Structure ``rte_eal_memconfig`` has been extended to contain next
+ socket ID for externally allocated segments
+* eal: Added ``dma_maskbits`` to ``rte_mem_config`` for keeping the most
+ restrictive DMA mask based on the devices addressing limitations.
-Removed Items
--------------
-
-.. This section should contain removed items in this release. Sample format:
-
- * Add a short 1-2 sentence description of the removed item
- in the past tense.
-
- This section is a comment. Do not overwrite or remove it.
- Also, make sure to start the actual text at the margin.
- =========================================================
+* eal: The structure ``rte_device`` has a new field to reference a
+ ``rte_bus``. It thus changes the size of the ``struct rte_device`` and the
+ inherited device structures of all buses.
Shared Library Versions
@@ -578,22 +574,24 @@ Known Issues
Also, make sure to start the actual text at the margin.
=========================================================
-* When using SR-IOV (VF) support with netvsc PMD and the Mellanox mlx5 bifurcated
- driver; the Linux netvsc device must be brought up before the netvsc device is
- unbound and passed to the DPDK.
+* When using SR-IOV (VF) support with netvsc PMD and the Mellanox mlx5
+ bifurcated driver the Linux netvsc device must be brought up before the
+ netvsc device is unbound and passed to the DPDK.
-* IBM Power8 is not supported by this release of DPDK. IBM Power9 is supported.
+* IBM Power8 is not supported in this release of DPDK. IBM Power9 is
+ supported.
-* ``AVX-512`` support has been disabled for ``GCC`` builds [1] because of a crash [2].
- This can affect ``native`` machine type build targets on the platforms that support
- ``AVX512F`` like ``Intel Skylake`` processors, and can cause a possible performance drop.
- The immediate workaround is to use ``clang`` compiler on these platforms.
- Issue has been identified as a GCC defect and reported to GCC community [3]. Further
- actions will be taken based on the GCC defect result.
+* ``AVX-512`` support has been disabled for ``GCC`` builds [1] because of a
+ crash [2]. This can affect ``native`` machine type build targets on the
+ platforms that support ``AVX512F`` like ``Intel Skylake`` processors, and
+ can cause a possible performance drop. The immediate workaround is to use
+ ``clang`` compiler on these platforms. The issue has been identified as a
+ GCC defect and reported to the GCC community [3]. Further actions will be
+ taken based on the GCC defect result.
- [1]: Commit 8d07c82b239f ("mk: disable gcc AVX512F support")
- [2]: https://bugs.dpdk.org/show_bug.cgi?id=97
- [3]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88096
+ * [1]: Commit 8d07c82b239f ("mk: disable gcc AVX512F support")
+ * [2]: https://bugs.dpdk.org/show_bug.cgi?id=97
+ * [3]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88096
Tested Platforms
@@ -661,7 +659,7 @@ Tested Platforms
* Device id (pf/vf): 8086:1572 / 8086:154c
* Driver version: 2.4.6 (i40e)
- * Intel Corporation Ethernet Connection X722 for 10GbE SFP+ (4x10G)
+ * Intel(R) Corporation Ethernet Connection X722 for 10GbE SFP+ (4x10G)
* Firmware version: 3.33 0x80000fd5 0.0.0
* Device id (pf/vf): 8086:37d0 / 8086:37cd
--
2.7.5
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH 0/3] lib/librte_meter: add RFC4115 trTCM meter support
@ 2018-11-27 15:20 3% Eelco Chaudron
2018-11-27 15:21 7% ` [dpdk-dev] [PATCH 3/3] lib/librte_meter: update abi to include new rfc4115 function Eelco Chaudron
0 siblings, 1 reply; 200+ results
From: Eelco Chaudron @ 2018-11-27 15:20 UTC (permalink / raw)
To: cristian.dumitrescu; +Cc: dev
This patch adds support for RFC4115 trTCM meters.
Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Eelco Chaudron (3):
lib/librte_meter: add RFC4115 trTCM meter support
test/test_meter: update meter test to include RFC4115 meters
lib/librte_meter: update abi to include new rfc4115 function
lib/librte_meter/Makefile | 2
lib/librte_meter/meson.build | 2
lib/librte_meter/rte_meter.c | 40 ++++++
lib/librte_meter/rte_meter.h | 193 +++++++++++++++++++++++++++--
lib/librte_meter/rte_meter_version.map | 9 +
test/test/test_meter.c | 212 ++++++++++++++++++++++++++++++++
6 files changed, 440 insertions(+), 18 deletions(-)
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH 3/3] lib/librte_meter: update abi to include new rfc4115 function
2018-11-27 15:20 3% [dpdk-dev] [PATCH 0/3] lib/librte_meter: add RFC4115 trTCM meter support Eelco Chaudron
@ 2018-11-27 15:21 7% ` Eelco Chaudron
[not found] ` <CAJFAV8zUyBqEovvaChs3TO+Ah15T3davXPPkpDzzE2-fMQGD2g@mail.gmail.com>
0 siblings, 1 reply; 200+ results
From: Eelco Chaudron @ 2018-11-27 15:21 UTC (permalink / raw)
To: cristian.dumitrescu; +Cc: dev
Update the ABI to include the new RFC4115 meter functions
---
lib/librte_meter/Makefile | 2 +-
lib/librte_meter/meson.build | 2 +-
lib/librte_meter/rte_meter_version.map | 9 +++++++++
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/lib/librte_meter/Makefile b/lib/librte_meter/Makefile
index 2dc071e8e..79ad79744 100644
--- a/lib/librte_meter/Makefile
+++ b/lib/librte_meter/Makefile
@@ -16,7 +16,7 @@ LDLIBS += -lrte_eal
EXPORT_MAP := rte_meter_version.map
-LIBABIVER := 2
+LIBABIVER := 3
#
# all source are stored in SRCS-y
diff --git a/lib/librte_meter/meson.build b/lib/librte_meter/meson.build
index 947bc19e2..422123e20 100644
--- a/lib/librte_meter/meson.build
+++ b/lib/librte_meter/meson.build
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 2
+version = 3
sources = files('rte_meter.c')
headers = files('rte_meter.h')
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index cb79f0c2b..4b460d580 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -17,3 +17,12 @@ DPDK_18.08 {
rte_meter_srtcm_profile_config;
rte_meter_trtcm_profile_config;
};
+
+EXPERIMENTAL {
+ global:
+
+ rte_meter_trtcm_rfc4115_color_aware_check;
+ rte_meter_trtcm_rfc4115_color_blind_check;
+ rte_meter_trtcm_rfc4115_config;
+ rte_meter_trtcm_rfc4115_profile_config;
+};
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH 3/3] lib/librte_meter: update abi to include new rfc4115 function
[not found] ` <CAJFAV8zUyBqEovvaChs3TO+Ah15T3davXPPkpDzzE2-fMQGD2g@mail.gmail.com>
@ 2018-11-28 9:27 7% ` Eelco Chaudron
2018-11-28 10:09 9% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Eelco Chaudron @ 2018-11-28 9:27 UTC (permalink / raw)
To: David Marchand; +Cc: cristian.dumitrescu, dev
On 28 Nov 2018, at 9:38, David Marchand wrote:
> Hello Eelco,
>
> On Tue, Nov 27, 2018 at 4:22 PM Eelco Chaudron <echaudro@redhat.com>
> wrote:
>
>> Update the ABI to include the new RFC4115 meter functions
>> ---
>> lib/librte_meter/Makefile | 2 +-
>> lib/librte_meter/meson.build | 2 +-
>> lib/librte_meter/rte_meter_version.map | 9 +++++++++
>> 3 files changed, 11 insertions(+), 2 deletions(-)
>>
>> diff --git a/lib/librte_meter/Makefile b/lib/librte_meter/Makefile
>> index 2dc071e8e..79ad79744 100644
>> --- a/lib/librte_meter/Makefile
>> +++ b/lib/librte_meter/Makefile
>> @@ -16,7 +16,7 @@ LDLIBS += -lrte_eal
>>
>> EXPORT_MAP := rte_meter_version.map
>>
>> -LIBABIVER := 2
>> +LIBABIVER := 3
>>
>> #
>> # all source are stored in SRCS-y
>>
>
> As far as I understood the policy around the EXPERIMENTAL section, you
> don't need to bump the library version.
Thought I would add the new function as none experimental, i.e. next
version, but checkpatch did not allow me to do this.
Tried to find info on what the right process was, as these functions are
just another meter implementation using similar existing APIs. If anyone
has any background on this please point me to it.
I changed the library version as an existing data structure changed
(which in theory should not change the location of the data), but the
ABI check popped warnings so I decided to increase the version.
>
> + you should squash this into the first patch.
I’ll do this on the next version.
Thanks,
Eelco
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH 3/3] lib/librte_meter: update abi to include new rfc4115 function
2018-11-28 9:27 7% ` Eelco Chaudron
@ 2018-11-28 10:09 9% ` Thomas Monjalon
2018-11-28 12:40 4% ` Eelco Chaudron
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-11-28 10:09 UTC (permalink / raw)
To: Eelco Chaudron; +Cc: dev, David Marchand, cristian.dumitrescu
28/11/2018 10:27, Eelco Chaudron:
> On 28 Nov 2018, at 9:38, David Marchand wrote:
> > On Tue, Nov 27, 2018 at 4:22 PM Eelco Chaudron <echaudro@redhat.com>
> > wrote:
> >> --- a/lib/librte_meter/Makefile
> >> +++ b/lib/librte_meter/Makefile
> >> -LIBABIVER := 2
> >> +LIBABIVER := 3
> >
> > As far as I understood the policy around the EXPERIMENTAL section, you
> > don't need to bump the library version.
>
> Thought I would add the new function as none experimental, i.e. next
> version, but checkpatch did not allow me to do this.
>
> Tried to find info on what the right process was, as these functions are
> just another meter implementation using similar existing APIs. If anyone
> has any background on this please point me to it.
It is documented here:
http://doc.dpdk.org/guides/contributing/versioning.html
The case for "similar API" is not handled specifically so far.
So you need to introduce it as experimental.
> I changed the library version as an existing data structure changed
> (which in theory should not change the location of the data), but the
> ABI check popped warnings so I decided to increase the version.
It deserves to analyze why the ABI check raises a warning.
If it really needs to bump the ABI version, you should justify it
in the commit message, and explain what changed in the ABI section
of the release notes, plus update the version in the release notes.
^ permalink raw reply [relevance 9%]
* [dpdk-dev] [PATCH] version: 19.02-rc0
@ 2018-11-28 10:44 9% Thomas Monjalon
2018-11-28 11:16 0% ` Ferruh Yigit
2018-11-28 14:52 9% ` [dpdk-dev] [PATCH v2 1/2] " Thomas Monjalon
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2018-11-28 10:44 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, marko.kovacevic
Start version numbering for a new release cycle,
and introduce a template file for release notes.
The release notes comments are updated to mandate
a scope label for API and ABI changes.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
doc/guides/rel_notes/index.rst | 1 +
doc/guides/rel_notes/release_19_02.rst | 209 ++++++++++++++++++++
lib/librte_eal/common/include/rte_version.h | 8 +-
meson.build | 2 +-
4 files changed, 215 insertions(+), 5 deletions(-)
create mode 100644 doc/guides/rel_notes/release_19_02.rst
diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index 1243e985c..ccfd38bcf 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -8,6 +8,7 @@ Release Notes
:maxdepth: 1
:numbered:
+ release_19_02
release_18_11
release_18_08
release_18_05
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
new file mode 100644
index 000000000..387e20e38
--- /dev/null
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -0,0 +1,209 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright 2018 The DPDK contributors
+
+DPDK Release 19.02
+==================
+
+.. **Read this first.**
+
+ The text in the sections below explains how to update the release notes.
+
+ Use proper spelling, capitalization and punctuation in all sections.
+
+ Variable and config names should be quoted as fixed width text:
+ ``LIKE_THIS``.
+
+ Build the docs and view the output file to ensure the changes are correct::
+
+ make doc-guides-html
+
+ xdg-open build/doc/html/guides/rel_notes/release_19_02.html
+
+
+New Features
+------------
+
+.. This section should contain new features added in this release.
+ Sample format:
+
+ * **Add a title in the past tense with a full stop.**
+
+ Add a short 1-2 sentence description in the past tense.
+ The description should be enough to allow someone scanning
+ the release notes to understand the new feature.
+
+ If the feature adds a lot of sub-features you can use a bullet list
+ like this:
+
+ * Added feature foo to do something.
+ * Enhanced feature bar to do something else.
+
+ Refer to the previous release notes for examples.
+
+ Suggested order in release notes items:
+ * Core libs (EAL, mempool, ring, mbuf, buses)
+ * Device abstraction libs and PMDs
+ - ethdev (lib, PMDs)
+ - cryptodev (lib, PMDs)
+ - eventdev (lib, PMDs)
+ - etc
+ * Other libs
+ * Apps, Examples, Tools (if significant)
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Removed Items
+-------------
+
+.. This section should contain removed items in this release. Sample format:
+
+ * Add a short 1-2 sentence description of the removed item
+ in the past tense.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+ * sample: Add a short 1-2 sentence description of the API change.
+ Start with a scope label like "ethdev:".
+ Use fixed width quotes for ``function_names`` or ``struct_names``.
+ Use the past tense.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+ * sample: Add a short 1-2 sentence description of the ABI change.
+ Start with a scope label like "ethdev:".
+ that was announced in the previous releases and made in this release.
+ Use fixed width quotes for ``function_names`` or ``struct_names``.
+ Use the past tense.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Shared Library Versions
+-----------------------
+
+.. Update any library version updated in this release
+ and prepend with a ``+`` sign, like this:
+
+ libfoo.so.1
+ + libupdated.so.2
+ libbar.so.1
+
+ This section is a comment. Do not overwrite or remove it.
+ =========================================================
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+ librte_acl.so.2
+ librte_bbdev.so.1
+ librte_bitratestats.so.2
+ librte_bpf.so.1
+ librte_bus_dpaa.so.2
+ librte_bus_fslmc.so.2
+ librte_bus_ifpga.so.2
+ librte_bus_pci.so.2
+ librte_bus_vdev.so.2
+ librte_bus_vmbus.so.2
+ librte_cfgfile.so.2
+ librte_cmdline.so.2
+ librte_compressdev.so.1
+ librte_cryptodev.so.5
+ librte_distributor.so.1
+ librte_eal.so.9
+ librte_efd.so.1
+ librte_ethdev.so.11
+ librte_eventdev.so.6
+ librte_flow_classify.so.1
+ librte_gro.so.1
+ librte_gso.so.1
+ librte_hash.so.2
+ librte_ip_frag.so.1
+ librte_jobstats.so.1
+ librte_kni.so.2
+ librte_kvargs.so.1
+ librte_latencystats.so.1
+ librte_lpm.so.2
+ librte_mbuf.so.4
+ librte_member.so.1
+ librte_mempool.so.5
+ librte_meter.so.2
+ librte_metrics.so.1
+ librte_net.so.1
+ librte_pci.so.1
+ librte_pdump.so.2
+ librte_pipeline.so.3
+ librte_pmd_bnxt.so.2
+ librte_pmd_bond.so.2
+ librte_pmd_i40e.so.2
+ librte_pmd_ixgbe.so.2
+ librte_pmd_dpaa2_qdma.so.1
+ librte_pmd_ring.so.2
+ librte_pmd_softnic.so.1
+ librte_pmd_vhost.so.2
+ librte_port.so.3
+ librte_power.so.1
+ librte_rawdev.so.1
+ librte_reorder.so.1
+ librte_ring.so.2
+ librte_sched.so.1
+ librte_security.so.1
+ librte_table.so.3
+ librte_timer.so.1
+ librte_vhost.so.4
+
+
+Known Issues
+------------
+
+.. This section should contain new known issues in this release. Sample format:
+
+ * **Add title in present tense with full stop.**
+
+ Add a short 1-2 sentence description of the known issue
+ in the present tense. Add information on any known workarounds.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Tested Platforms
+----------------
+
+.. This section should contain a list of platforms that were tested
+ with this release.
+
+ The format is:
+
+ * <vendor> platform with <vendor> <type of devices> combinations
+
+ * List of CPU
+ * List of OS
+ * List of devices
+ * Other relevant details...
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
diff --git a/lib/librte_eal/common/include/rte_version.h b/lib/librte_eal/common/include/rte_version.h
index f01c227f5..b790579a7 100644
--- a/lib/librte_eal/common/include/rte_version.h
+++ b/lib/librte_eal/common/include/rte_version.h
@@ -27,12 +27,12 @@ extern "C" {
/**
* Major version/year number i.e. the yy in yy.mm.z
*/
-#define RTE_VER_YEAR 18
+#define RTE_VER_YEAR 19
/**
* Minor version/month number i.e. the mm in yy.mm.z
*/
-#define RTE_VER_MONTH 11
+#define RTE_VER_MONTH 2
/**
* Patch level number i.e. the z in yy.mm.z
@@ -42,14 +42,14 @@ extern "C" {
/**
* Extra string to be appended to version number
*/
-#define RTE_VER_SUFFIX ""
+#define RTE_VER_SUFFIX "-rc"
/**
* Patch release number
* 0-15 = release candidates
* 16 = release
*/
-#define RTE_VER_RELEASE 16
+#define RTE_VER_RELEASE 0
/**
* Macro to compute a version number usable for comparisons
diff --git a/meson.build b/meson.build
index 4122be83d..863f4e596 100644
--- a/meson.build
+++ b/meson.build
@@ -2,7 +2,7 @@
# Copyright(c) 2017 Intel Corporation
project('DPDK', 'C',
- version: '18.11.0',
+ version: '19.02.0-rc0'
license: 'BSD',
default_options: ['buildtype=release', 'default_library=static'],
meson_version: '>= 0.41'
--
2.19.0
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH] version: 19.02-rc0
2018-11-28 10:44 9% [dpdk-dev] [PATCH] version: 19.02-rc0 Thomas Monjalon
@ 2018-11-28 11:16 0% ` Ferruh Yigit
2018-11-28 12:45 0% ` Thomas Monjalon
2018-11-28 14:52 9% ` [dpdk-dev] [PATCH v2 1/2] " Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-11-28 11:16 UTC (permalink / raw)
To: Thomas Monjalon, dev; +Cc: john.mcnamara, marko.kovacevic
On 11/28/2018 10:44 AM, Thomas Monjalon wrote:
> Start version numbering for a new release cycle,
> and introduce a template file for release notes.
>
> The release notes comments are updated to mandate
> a scope label for API and ABI changes.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> doc/guides/rel_notes/index.rst | 1 +
> doc/guides/rel_notes/release_19_02.rst | 209 ++++++++++++++++++++
What do you think about storing the release notes template in git repo, this
helps creating new ones for next release also makes easier to track/view what
has been changed in the release notes template?
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 3/3] lib/librte_meter: update abi to include new rfc4115 function
2018-11-28 10:09 9% ` Thomas Monjalon
@ 2018-11-28 12:40 4% ` Eelco Chaudron
2018-11-28 12:51 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Eelco Chaudron @ 2018-11-28 12:40 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, David Marchand, cristian.dumitrescu
On 28 Nov 2018, at 11:09, Thomas Monjalon wrote:
> 28/11/2018 10:27, Eelco Chaudron:
>> On 28 Nov 2018, at 9:38, David Marchand wrote:
>>> On Tue, Nov 27, 2018 at 4:22 PM Eelco Chaudron <echaudro@redhat.com>
>>> wrote:
>>>> --- a/lib/librte_meter/Makefile
>>>> +++ b/lib/librte_meter/Makefile
>>>> -LIBABIVER := 2
>>>> +LIBABIVER := 3
>>>
>>> As far as I understood the policy around the EXPERIMENTAL section,
>>> you
>>> don't need to bump the library version.
>>
>> Thought I would add the new function as none experimental, i.e. next
>> version, but checkpatch did not allow me to do this.
>>
>> Tried to find info on what the right process was, as these functions
>> are
>> just another meter implementation using similar existing APIs. If
>> anyone
>> has any background on this please point me to it.
>
> It is documented here:
> http://doc.dpdk.org/guides/contributing/versioning.html
>
> The case for "similar API" is not handled specifically so far.
> So you need to introduce it as experimental.
Thanks for the clarification, will update the APIs with
__rte_experimental in the next iteration.
>> I changed the library version as an existing data structure changed
>> (which in theory should not change the location of the data), but the
>> ABI check popped warnings so I decided to increase the version.
>
> It deserves to analyze why the ABI check raises a warning.
> If it really needs to bump the ABI version, you should justify it
> in the commit message, and explain what changed in the ABI section
> of the release notes, plus update the version in the release notes.
Will look at it more closely and update it for the next iteration.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] version: 19.02-rc0
2018-11-28 11:16 0% ` Ferruh Yigit
@ 2018-11-28 12:45 0% ` Thomas Monjalon
2018-11-28 13:24 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-11-28 12:45 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, john.mcnamara, marko.kovacevic
28/11/2018 12:16, Ferruh Yigit:
> On 11/28/2018 10:44 AM, Thomas Monjalon wrote:
> > Start version numbering for a new release cycle,
> > and introduce a template file for release notes.
> >
> > The release notes comments are updated to mandate
> > a scope label for API and ABI changes.
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> > doc/guides/rel_notes/index.rst | 1 +
> > doc/guides/rel_notes/release_19_02.rst | 209 ++++++++++++++++++++
>
> What do you think about storing the release notes template in git repo, this
> helps creating new ones for next release also makes easier to track/view what
> has been changed in the release notes template?
If something is changed in the release notes, it should be updated
in the template, with a risk of forgetting.
And the list of libraries would need to be updated too.
I feel it would be more complications.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 3/3] lib/librte_meter: update abi to include new rfc4115 function
2018-11-28 12:40 4% ` Eelco Chaudron
@ 2018-11-28 12:51 4% ` Thomas Monjalon
2018-11-28 13:17 4% ` Eelco Chaudron
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-11-28 12:51 UTC (permalink / raw)
To: Eelco Chaudron; +Cc: dev, David Marchand, cristian.dumitrescu
28/11/2018 13:40, Eelco Chaudron:
>
> On 28 Nov 2018, at 11:09, Thomas Monjalon wrote:
>
> > 28/11/2018 10:27, Eelco Chaudron:
> >> On 28 Nov 2018, at 9:38, David Marchand wrote:
> >>> On Tue, Nov 27, 2018 at 4:22 PM Eelco Chaudron <echaudro@redhat.com>
> >>> wrote:
> >>>> --- a/lib/librte_meter/Makefile
> >>>> +++ b/lib/librte_meter/Makefile
> >>>> -LIBABIVER := 2
> >>>> +LIBABIVER := 3
> >>>
> >>> As far as I understood the policy around the EXPERIMENTAL section,
> >>> you
> >>> don't need to bump the library version.
> >>
> >> Thought I would add the new function as none experimental, i.e. next
> >> version, but checkpatch did not allow me to do this.
> >>
> >> Tried to find info on what the right process was, as these functions
> >> are
> >> just another meter implementation using similar existing APIs. If
> >> anyone
> >> has any background on this please point me to it.
> >
> > It is documented here:
> > http://doc.dpdk.org/guides/contributing/versioning.html
> >
> > The case for "similar API" is not handled specifically so far.
> > So you need to introduce it as experimental.
>
> Thanks for the clarification, will update the APIs with
> __rte_experimental in the next iteration.
You should also add this on top of the doxygen comment:
* @warning
* @b EXPERIMENTAL: this API may change without prior notice
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 3/3] lib/librte_meter: update abi to include new rfc4115 function
2018-11-28 12:51 4% ` Thomas Monjalon
@ 2018-11-28 13:17 4% ` Eelco Chaudron
0 siblings, 0 replies; 200+ results
From: Eelco Chaudron @ 2018-11-28 13:17 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, David Marchand, cristian.dumitrescu
On 28 Nov 2018, at 13:51, Thomas Monjalon wrote:
> 28/11/2018 13:40, Eelco Chaudron:
>>
>> On 28 Nov 2018, at 11:09, Thomas Monjalon wrote:
>>
>>> 28/11/2018 10:27, Eelco Chaudron:
>>>> On 28 Nov 2018, at 9:38, David Marchand wrote:
>>>>> On Tue, Nov 27, 2018 at 4:22 PM Eelco Chaudron <echaudro@redhat.com>
>>>>> wrote:
>>>>>> --- a/lib/librte_meter/Makefile
>>>>>> +++ b/lib/librte_meter/Makefile
>>>>>> -LIBABIVER := 2
>>>>>> +LIBABIVER := 3
>>>>>
>>>>> As far as I understood the policy around the EXPERIMENTAL section,
>>>>> you
>>>>> don't need to bump the library version.
>>>>
>>>> Thought I would add the new function as none experimental, i.e. next
>>>> version, but checkpatch did not allow me to do this.
>>>>
>>>> Tried to find info on what the right process was, as these functions
>>>> are
>>>> just another meter implementation using similar existing APIs. If
>>>> anyone
>>>> has any background on this please point me to it.
>>>
>>> It is documented here:
>>> http://doc.dpdk.org/guides/contributing/versioning.html
>>>
>>> The case for "similar API" is not handled specifically so far.
>>> So you need to introduce it as experimental.
>>
>> Thanks for the clarification, will update the APIs with
>> __rte_experimental in the next iteration.
>
> You should also add this on top of the doxygen comment:
>
> * @warning
> * @b EXPERIMENTAL: this API may change without prior notice
Thanks, done!
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] version: 19.02-rc0
2018-11-28 12:45 0% ` Thomas Monjalon
@ 2018-11-28 13:24 0% ` Ferruh Yigit
2018-11-28 13:35 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-11-28 13:24 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, john.mcnamara, marko.kovacevic
On 11/28/2018 12:45 PM, Thomas Monjalon wrote:
> 28/11/2018 12:16, Ferruh Yigit:
>> On 11/28/2018 10:44 AM, Thomas Monjalon wrote:
>>> Start version numbering for a new release cycle,
>>> and introduce a template file for release notes.
>>>
>>> The release notes comments are updated to mandate
>>> a scope label for API and ABI changes.
>>>
>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>>> ---
>>> doc/guides/rel_notes/index.rst | 1 +
>>> doc/guides/rel_notes/release_19_02.rst | 209 ++++++++++++++++++++
>>
>> What do you think about storing the release notes template in git repo, this
>> helps creating new ones for next release also makes easier to track/view what
>> has been changed in the release notes template?
>
> If something is changed in the release notes, it should be updated
> in the template, with a risk of forgetting.
> And the list of libraries would need to be updated too.
> I feel it would be more complications.
OK, I see the concern.
What about doing rc0 release notes in two patches:
1- Copy-paste from previous release notes, strip the context.
2- Update the template as desired.
Overall I think this is good to have, if you think this is just extra overhead,
forget about it.
Thanks,
ferruh
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] version: 19.02-rc0
2018-11-28 13:24 0% ` Ferruh Yigit
@ 2018-11-28 13:35 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-11-28 13:35 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, john.mcnamara, marko.kovacevic
28/11/2018 14:24, Ferruh Yigit:
> On 11/28/2018 12:45 PM, Thomas Monjalon wrote:
> > 28/11/2018 12:16, Ferruh Yigit:
> >> On 11/28/2018 10:44 AM, Thomas Monjalon wrote:
> >>> Start version numbering for a new release cycle,
> >>> and introduce a template file for release notes.
> >>>
> >>> The release notes comments are updated to mandate
> >>> a scope label for API and ABI changes.
> >>>
> >>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> >>> ---
> >>> doc/guides/rel_notes/index.rst | 1 +
> >>> doc/guides/rel_notes/release_19_02.rst | 209 ++++++++++++++++++++
> >>
> >> What do you think about storing the release notes template in git repo, this
> >> helps creating new ones for next release also makes easier to track/view what
> >> has been changed in the release notes template?
> >
> > If something is changed in the release notes, it should be updated
> > in the template, with a risk of forgetting.
> > And the list of libraries would need to be updated too.
> > I feel it would be more complications.
>
> OK, I see the concern.
>
> What about doing rc0 release notes in two patches:
> 1- Copy-paste from previous release notes, strip the context.
It is not only strip the context, I change version number
and add back the removed section.
> 2- Update the template as desired.
>
> Overall I think this is good to have, if you think this is just extra overhead,
> forget about it.
I understand you want to track the changes done in the template.
I will send a v2 with changes split.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2 1/2] version: 19.02-rc0
2018-11-28 10:44 9% [dpdk-dev] [PATCH] version: 19.02-rc0 Thomas Monjalon
2018-11-28 11:16 0% ` Ferruh Yigit
@ 2018-11-28 14:52 9% ` Thomas Monjalon
2018-11-28 14:52 18% ` [dpdk-dev] [PATCH v2 2/2] doc: improve release notes template Thomas Monjalon
2018-11-30 17:01 0% ` [dpdk-dev] [PATCH v2 1/2] version: 19.02-rc0 Ferruh Yigit
1 sibling, 2 replies; 200+ results
From: Thomas Monjalon @ 2018-11-28 14:52 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, marko.kovacevic
Start version numbering for a new release cycle,
and introduce a template file for release notes.
The release notes comments are updated to mandate
a scope label for API and ABI changes.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/rel_notes/index.rst | 1 +
doc/guides/rel_notes/release_19_02.rst | 207 ++++++++++++++++++++
lib/librte_eal/common/include/rte_version.h | 8 +-
meson.build | 2 +-
4 files changed, 213 insertions(+), 5 deletions(-)
create mode 100644 doc/guides/rel_notes/release_19_02.rst
diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index 1243e985c..ccfd38bcf 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -8,6 +8,7 @@ Release Notes
:maxdepth: 1
:numbered:
+ release_19_02
release_18_11
release_18_08
release_18_05
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
new file mode 100644
index 000000000..cbb2ddb78
--- /dev/null
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -0,0 +1,207 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright 2018 The DPDK contributors
+
+DPDK Release 19.02
+==================
+
+.. **Read this first.**
+
+ The text in the sections below explains how to update the release notes.
+
+ Use proper spelling, capitalization and punctuation in all sections.
+
+ Variable and config names should be quoted as fixed width text:
+ ``LIKE_THIS``.
+
+ Build the docs and view the output file to ensure the changes are correct::
+
+ make doc-guides-html
+
+ xdg-open build/doc/html/guides/rel_notes/release_19_02.html
+
+
+New Features
+------------
+
+.. This section should contain new features added in this release.
+ Sample format:
+
+ * **Add a title in the past tense with a full stop.**
+
+ Add a short 1-2 sentence description in the past tense.
+ The description should be enough to allow someone scanning
+ the release notes to understand the new feature.
+
+ If the feature adds a lot of sub-features you can use a bullet list
+ like this:
+
+ * Added feature foo to do something.
+ * Enhanced feature bar to do something else.
+
+ Refer to the previous release notes for examples.
+
+ Suggested order in release notes items:
+ * Core libs (EAL, mempool, ring, mbuf, buses)
+ * Device abstraction libs and PMDs
+ - ethdev (lib, PMDs)
+ - cryptodev (lib, PMDs)
+ - eventdev (lib, PMDs)
+ - etc
+ * Other libs
+ * Apps, Examples, Tools (if significant)
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+ * Add a short 1-2 sentence description of the API change.
+ Use fixed width quotes for ``function_names`` or ``struct_names``.
+ Use the past tense.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+ * Add a short 1-2 sentence description of the ABI change
+ that was announced in the previous releases and made in this release.
+ Use fixed width quotes for ``function_names`` or ``struct_names``.
+ Use the past tense.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Removed Items
+-------------
+
+.. This section should contain removed items in this release. Sample format:
+
+ * Add a short 1-2 sentence description of the removed item
+ in the past tense.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Shared Library Versions
+-----------------------
+
+.. Update any library version updated in this release
+ and prepend with a ``+`` sign, like this:
+
+ librte_acl.so.2
+ + librte_cfgfile.so.2
+ librte_cmdline.so.2
+
+ This section is a comment. Do not overwrite or remove it.
+ =========================================================
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+ librte_acl.so.2
+ librte_bbdev.so.1
+ librte_bitratestats.so.2
+ librte_bpf.so.1
+ librte_bus_dpaa.so.2
+ librte_bus_fslmc.so.2
+ librte_bus_ifpga.so.2
+ librte_bus_pci.so.2
+ librte_bus_vdev.so.2
+ librte_bus_vmbus.so.2
+ librte_cfgfile.so.2
+ librte_cmdline.so.2
+ librte_compressdev.so.1
+ librte_cryptodev.so.5
+ librte_distributor.so.1
+ librte_eal.so.9
+ librte_efd.so.1
+ librte_ethdev.so.11
+ librte_eventdev.so.6
+ librte_flow_classify.so.1
+ librte_gro.so.1
+ librte_gso.so.1
+ librte_hash.so.2
+ librte_ip_frag.so.1
+ librte_jobstats.so.1
+ librte_kni.so.2
+ librte_kvargs.so.1
+ librte_latencystats.so.1
+ librte_lpm.so.2
+ librte_mbuf.so.4
+ librte_member.so.1
+ librte_mempool.so.5
+ librte_meter.so.2
+ librte_metrics.so.1
+ librte_net.so.1
+ librte_pci.so.1
+ librte_pdump.so.2
+ librte_pipeline.so.3
+ librte_pmd_bnxt.so.2
+ librte_pmd_bond.so.2
+ librte_pmd_i40e.so.2
+ librte_pmd_ixgbe.so.2
+ librte_pmd_dpaa2_qdma.so.1
+ librte_pmd_ring.so.2
+ librte_pmd_softnic.so.1
+ librte_pmd_vhost.so.2
+ librte_port.so.3
+ librte_power.so.1
+ librte_rawdev.so.1
+ librte_reorder.so.1
+ librte_ring.so.2
+ librte_sched.so.1
+ librte_security.so.1
+ librte_table.so.3
+ librte_timer.so.1
+ librte_vhost.so.4
+
+
+Known Issues
+------------
+
+.. This section should contain new known issues in this release. Sample format:
+
+ * **Add title in present tense with full stop.**
+
+ Add a short 1-2 sentence description of the known issue
+ in the present tense. Add information on any known workarounds.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Tested Platforms
+----------------
+
+.. This section should contain a list of platforms that were tested
+ with this release.
+
+ The format is:
+
+ * <vendor> platform with <vendor> <type of devices> combinations
+
+ * List of CPU
+ * List of OS
+ * List of devices
+ * Other relevant details...
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
diff --git a/lib/librte_eal/common/include/rte_version.h b/lib/librte_eal/common/include/rte_version.h
index f01c227f5..b790579a7 100644
--- a/lib/librte_eal/common/include/rte_version.h
+++ b/lib/librte_eal/common/include/rte_version.h
@@ -27,12 +27,12 @@ extern "C" {
/**
* Major version/year number i.e. the yy in yy.mm.z
*/
-#define RTE_VER_YEAR 18
+#define RTE_VER_YEAR 19
/**
* Minor version/month number i.e. the mm in yy.mm.z
*/
-#define RTE_VER_MONTH 11
+#define RTE_VER_MONTH 2
/**
* Patch level number i.e. the z in yy.mm.z
@@ -42,14 +42,14 @@ extern "C" {
/**
* Extra string to be appended to version number
*/
-#define RTE_VER_SUFFIX ""
+#define RTE_VER_SUFFIX "-rc"
/**
* Patch release number
* 0-15 = release candidates
* 16 = release
*/
-#define RTE_VER_RELEASE 16
+#define RTE_VER_RELEASE 0
/**
* Macro to compute a version number usable for comparisons
diff --git a/meson.build b/meson.build
index 4122be83d..863f4e596 100644
--- a/meson.build
+++ b/meson.build
@@ -2,7 +2,7 @@
# Copyright(c) 2017 Intel Corporation
project('DPDK', 'C',
- version: '18.11.0',
+ version: '19.02.0-rc0'
license: 'BSD',
default_options: ['buildtype=release', 'default_library=static'],
meson_version: '>= 0.41'
--
2.19.0
^ permalink raw reply [relevance 9%]
* [dpdk-dev] [PATCH v2 2/2] doc: improve release notes template
2018-11-28 14:52 9% ` [dpdk-dev] [PATCH v2 1/2] " Thomas Monjalon
@ 2018-11-28 14:52 18% ` Thomas Monjalon
2018-11-30 17:01 0% ` [dpdk-dev] [PATCH v2 1/2] version: 19.02-rc0 Ferruh Yigit
1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-11-28 14:52 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, marko.kovacevic
Some comments are added to encourage classifying API and ABI changes
with scope labels.
The section "removed items" is moved just after the "new features".
The sample for shared library versions is replaced with foo/bar names.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/rel_notes/release_19_02.rst | 67 ++++++++++++++------------
1 file changed, 35 insertions(+), 32 deletions(-)
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index cbb2ddb78..a94fa86a7 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -55,35 +55,6 @@ New Features
=========================================================
-API Changes
------------
-
-.. This section should contain API changes. Sample format:
-
- * Add a short 1-2 sentence description of the API change.
- Use fixed width quotes for ``function_names`` or ``struct_names``.
- Use the past tense.
-
- This section is a comment. Do not overwrite or remove it.
- Also, make sure to start the actual text at the margin.
- =========================================================
-
-
-ABI Changes
------------
-
-.. This section should contain ABI changes. Sample format:
-
- * Add a short 1-2 sentence description of the ABI change
- that was announced in the previous releases and made in this release.
- Use fixed width quotes for ``function_names`` or ``struct_names``.
- Use the past tense.
-
- This section is a comment. Do not overwrite or remove it.
- Also, make sure to start the actual text at the margin.
- =========================================================
-
-
Removed Items
-------------
@@ -97,15 +68,47 @@ Removed Items
=========================================================
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+ * sample: Add a short 1-2 sentence description of the API change
+ which was announced in the previous releases and made in this release.
+ Start with a scope label like "ethdev:".
+ Use fixed width quotes for ``function_names`` or ``struct_names``.
+ Use the past tense.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+ * sample: Add a short 1-2 sentence description of the ABI change
+ which was announced in the previous releases and made in this release.
+ Start with a scope label like "ethdev:".
+ Use fixed width quotes for ``function_names`` or ``struct_names``.
+ Use the past tense.
+
+ This section is a comment. Do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
Shared Library Versions
-----------------------
.. Update any library version updated in this release
and prepend with a ``+`` sign, like this:
- librte_acl.so.2
- + librte_cfgfile.so.2
- librte_cmdline.so.2
+ libfoo.so.1
+ + libupdated.so.2
+ libbar.so.1
This section is a comment. Do not overwrite or remove it.
=========================================================
--
2.19.0
^ permalink raw reply [relevance 18%]
* [dpdk-dev] [PATCH] helloworld: Windows DPDK sample application is compiled and built using eal and kvargs libraries in order to add windows support in the mainline repository.
@ 2018-11-29 5:05 1% Pallavi Kadam
0 siblings, 0 replies; 200+ results
From: Pallavi Kadam @ 2018-11-29 5:05 UTC (permalink / raw)
To: dev
Signed-off-by: Pallavi Kadam <pallavi.kadam@intel.com>
---
[RFC] This is a large patch that contains changes to build the HelloWorld
sample application on Windows. It also contains changes to build the
librte_eal and librte_kvargs libraries which are required to build the
sample application. To merge these changes, this patch will be split up
into multiple smaller patches and sent for review.
lib/librte_eal/common/eal_common_errno.c | 9 +
lib/librte_eal/common/eal_common_log.c | 2 +
lib/librte_eal/common/eal_common_options.c | 2 +
lib/librte_eal/common/eal_common_timer.c | 2 +
.../common/include/arch/x86/rte_byteorder.h | 14 +
.../common/include/arch/x86/rte_rtm.h | 22 +-
lib/librte_eal/common/include/rte_common.h | 11 +
.../common/include/rte_malloc_heap.h | 3 +
lib/librte_eal/common/include/rte_random.h | 4 +
.../common/include/rte_string_fns.h | 2 +
lib/librte_eal/common/malloc_elem.h | 3 +
lib/librte_eal/common/malloc_heap.c | 2 +
lib/librte_eal/common/malloc_heap.h | 4 +
lib/librte_eal/windows/eal/eal.c | 697 +++++++++
lib/librte_eal/windows/eal/eal_alarm.c | 29 +
lib/librte_eal/windows/eal/eal_debug.c | 102 ++
lib/librte_eal/windows/eal/eal_fbarray.c | 1273 +++++++++++++++++
lib/librte_eal/windows/eal/eal_filesystem.h | 97 ++
.../windows/eal/eal_hugepage_info.c | 20 +
lib/librte_eal/windows/eal/eal_interrupts.c | 90 ++
lib/librte_eal/windows/eal/eal_lcore.c | 83 ++
lib/librte_eal/windows/eal/eal_log.c | 415 ++++++
lib/librte_eal/windows/eal/eal_memalloc.c | 995 +++++++++++++
lib/librte_eal/windows/eal/eal_memory.c | 140 ++
lib/librte_eal/windows/eal/eal_proc.c | 1003 +++++++++++++
lib/librte_eal/windows/eal/eal_thread.c | 167 +++
lib/librte_eal/windows/eal/eal_timer.c | 40 +
.../windows/eal/linux-emu/_rand48.c | 46 +
.../windows/eal/linux-emu/drand48.c | 62 +
lib/librte_eal/windows/eal/linux-emu/fork.c | 111 ++
lib/librte_eal/windows/eal/linux-emu/getopt.c | 407 ++++++
.../windows/eal/linux-emu/lrand48.c | 23 +
lib/librte_eal/windows/eal/linux-emu/mman.c | 179 +++
lib/librte_eal/windows/eal/linux-emu/setenv.c | 26 +
.../windows/eal/linux-emu/srand48.c | 30 +
.../windows/eal/linux-emu/termios.c | 11 +
lib/librte_eal/windows/eal/linux-emu/unistd.c | 21 +
lib/librte_eal/windows/eal/malloc_heap.c | 1068 ++++++++++++++
lib/librte_eal/windows/eal/malloc_mp.c | 645 +++++++++
.../windows/include_override/dirent.h | 950 ++++++++++++
.../windows/include_override/getopt.h | 252 ++++
.../windows/include_override/net/ethernet.h | 405 ++++++
.../windows/include_override/netinet/in.h | 48 +
.../windows/include_override/netinet/tcp.h | 4 +
.../windows/include_override/pthread.h | 65 +
.../windows/include_override/rand48.h | 32 +
.../windows/include_override/sched.h | 21 +
.../windows/include_override/sys/_iovec.h | 48 +
.../include_override/sys/_sockaddr_storage.h | 54 +
.../windows/include_override/sys/_termios.h | 222 +++
.../windows/include_override/sys/_types.h | 105 ++
.../windows/include_override/sys/cdefs.h | 3 +
.../windows/include_override/sys/mman.h | 63 +
.../include_override/sys/netbsd/queue.h | 846 +++++++++++
.../windows/include_override/sys/queue.h | 11 +
.../windows/include_override/syslog.h | 217 +++
.../windows/include_override/termios.h | 1 +
.../windows/include_override/unistd.h | 30 +
.../windows/include_override/x86intrin.h | 1 +
.../rte_override/exec-env/rte_interrupts.h | 3 +
lib/librte_eal/windows/rte_override/rte_acl.h | 7 +
.../windows/rte_override/rte_atomic.h | 744 ++++++++++
.../windows/rte_override/rte_bus_pci.h | 25 +
.../windows/rte_override/rte_byteorder.h | 10 +
.../windows/rte_override/rte_common.h | 56 +
.../windows/rte_override/rte_common.h.sav | 372 +++++
.../windows/rte_override/rte_config.h | 328 +++++
.../windows/rte_override/rte_cpuflags.h | 3 +
.../windows/rte_override/rte_cycles.h | 26 +
.../windows/rte_override/rte_debug.h | 22 +
lib/librte_eal/windows/rte_override/rte_io.h | 8 +
.../windows/rte_override/rte_lcore.h | 15 +
.../windows/rte_override/rte_log.h.sav | 6 +
.../windows/rte_override/rte_memcpy.h | 3 +
.../windows/rte_override/rte_memory.h | 20 +
.../windows/rte_override/rte_pause.h | 10 +
lib/librte_eal/windows/rte_override/rte_pci.h | 7 +
.../windows/rte_override/rte_per_lcore.h | 29 +
.../windows/rte_override/rte_prefetch.h | 29 +
lib/librte_eal/windows/rte_override/rte_rtm.h | 8 +
.../windows/rte_override/rte_rwlock.h | 40 +
.../windows/rte_override/rte_spinlock.h | 271 ++++
.../windows/rte_override/rte_vect.h | 5 +
.../windows/rte_override/rte_wincompat.h | 347 +++++
.../windows/rte_override/rte_windows.h | 497 +++++++
mk/exec-env/windows/DpdkRteLib.props | 46 +
mk/exec-env/windows/dpdk.sln | 43 +
.../windows/helloworld/helloworld.vcxproj | 98 ++
.../helloworld/helloworld.vcxproj.filters | 22 +
.../helloworld/helloworld.vcxproj.user | 4 +
.../windows/librte_eal/librte_eal.vcxproj | 187 +++
.../librte_eal/librte_eal.vcxproj.filters | 297 ++++
.../librte_eal/librte_eal.vcxproj.user | 4 +
.../librte_kvargs/librte_kvargs.vcxproj | 91 ++
.../librte_kvargs.vcxproj.filters | 33 +
.../librte_kvargs/librte_kvargs.vcxproj.user | 4 +
96 files changed, 14955 insertions(+), 3 deletions(-)
create mode 100644 lib/librte_eal/windows/eal/eal.c
create mode 100644 lib/librte_eal/windows/eal/eal_alarm.c
create mode 100644 lib/librte_eal/windows/eal/eal_debug.c
create mode 100644 lib/librte_eal/windows/eal/eal_fbarray.c
create mode 100644 lib/librte_eal/windows/eal/eal_filesystem.h
create mode 100644 lib/librte_eal/windows/eal/eal_hugepage_info.c
create mode 100644 lib/librte_eal/windows/eal/eal_interrupts.c
create mode 100644 lib/librte_eal/windows/eal/eal_lcore.c
create mode 100644 lib/librte_eal/windows/eal/eal_log.c
create mode 100644 lib/librte_eal/windows/eal/eal_memalloc.c
create mode 100644 lib/librte_eal/windows/eal/eal_memory.c
create mode 100644 lib/librte_eal/windows/eal/eal_proc.c
create mode 100644 lib/librte_eal/windows/eal/eal_thread.c
create mode 100644 lib/librte_eal/windows/eal/eal_timer.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/_rand48.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/drand48.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/fork.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/getopt.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/lrand48.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/mman.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/setenv.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/srand48.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/termios.c
create mode 100644 lib/librte_eal/windows/eal/linux-emu/unistd.c
create mode 100644 lib/librte_eal/windows/eal/malloc_heap.c
create mode 100644 lib/librte_eal/windows/eal/malloc_mp.c
create mode 100644 lib/librte_eal/windows/include_override/dirent.h
create mode 100644 lib/librte_eal/windows/include_override/getopt.h
create mode 100644 lib/librte_eal/windows/include_override/net/ethernet.h
create mode 100644 lib/librte_eal/windows/include_override/netinet/in.h
create mode 100644 lib/librte_eal/windows/include_override/netinet/tcp.h
create mode 100644 lib/librte_eal/windows/include_override/pthread.h
create mode 100644 lib/librte_eal/windows/include_override/rand48.h
create mode 100644 lib/librte_eal/windows/include_override/sched.h
create mode 100644 lib/librte_eal/windows/include_override/sys/_iovec.h
create mode 100644 lib/librte_eal/windows/include_override/sys/_sockaddr_storage.h
create mode 100644 lib/librte_eal/windows/include_override/sys/_termios.h
create mode 100644 lib/librte_eal/windows/include_override/sys/_types.h
create mode 100644 lib/librte_eal/windows/include_override/sys/cdefs.h
create mode 100644 lib/librte_eal/windows/include_override/sys/mman.h
create mode 100644 lib/librte_eal/windows/include_override/sys/netbsd/queue.h
create mode 100644 lib/librte_eal/windows/include_override/sys/queue.h
create mode 100644 lib/librte_eal/windows/include_override/syslog.h
create mode 100644 lib/librte_eal/windows/include_override/termios.h
create mode 100644 lib/librte_eal/windows/include_override/unistd.h
create mode 100644 lib/librte_eal/windows/include_override/x86intrin.h
create mode 100644 lib/librte_eal/windows/rte_override/exec-env/rte_interrupts.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_acl.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_atomic.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_bus_pci.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_byteorder.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_common.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_common.h.sav
create mode 100644 lib/librte_eal/windows/rte_override/rte_config.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_cpuflags.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_cycles.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_debug.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_io.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_lcore.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_log.h.sav
create mode 100644 lib/librte_eal/windows/rte_override/rte_memcpy.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_memory.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_pause.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_pci.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_per_lcore.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_prefetch.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_rtm.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_rwlock.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_spinlock.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_vect.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_wincompat.h
create mode 100644 lib/librte_eal/windows/rte_override/rte_windows.h
create mode 100644 mk/exec-env/windows/DpdkRteLib.props
create mode 100644 mk/exec-env/windows/dpdk.sln
create mode 100644 mk/exec-env/windows/helloworld/helloworld.vcxproj
create mode 100644 mk/exec-env/windows/helloworld/helloworld.vcxproj.filters
create mode 100644 mk/exec-env/windows/helloworld/helloworld.vcxproj.user
create mode 100644 mk/exec-env/windows/librte_eal/librte_eal.vcxproj
create mode 100644 mk/exec-env/windows/librte_eal/librte_eal.vcxproj.filters
create mode 100644 mk/exec-env/windows/librte_eal/librte_eal.vcxproj.user
create mode 100644 mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj
create mode 100644 mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.filters
create mode 100644 mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.user
diff --git a/lib/librte_eal/common/eal_common_errno.c b/lib/librte_eal/common/eal_common_errno.c
index c63a943b3..b6fec8cd5 100644
--- a/lib/librte_eal/common/eal_common_errno.c
+++ b/lib/librte_eal/common/eal_common_errno.c
@@ -27,7 +27,12 @@ rte_strerror(int errnum)
static const char *sep = "";
#endif
#define RETVAL_SZ 256
+#ifdef _WIN64
+ typedef char c_retval[RETVAL_SZ];
+ RTE_DEFINE_PER_LCORE(static c_retval, retval);
+#else
static RTE_DEFINE_PER_LCORE(char[RETVAL_SZ], retval);
+#endif
char *ret = RTE_PER_LCORE(retval);
/* since some implementations of strerror_r throw an error
@@ -41,9 +46,13 @@ rte_strerror(int errnum)
case E_RTE_NO_CONFIG:
return "Missing rte_config structure";
default:
+#ifdef _WIN64
+ strerror_s(RTE_PER_LCORE(retval), RETVAL_SZ, errnum);
+#else
if (strerror_r(errnum, ret, RETVAL_SZ) != 0)
snprintf(ret, RETVAL_SZ, "Unknown error%s %d",
sep, errnum);
+#endif
}
return ret;
diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index c714a4bd2..28407ce77 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -28,8 +28,10 @@ struct rte_eal_opt_loglevel {
/** Next list entry */
TAILQ_ENTRY(rte_eal_opt_loglevel) next;
/** Compiled regular expression obtained from the option */
+#ifndef _WIN64
regex_t re_match;
/** Glob match string option */
+#endif // !_WIN64
char *pattern;
/** Log level value obtained from the option */
uint32_t level;
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index e31eca5c0..17f2ae6a2 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -11,7 +11,9 @@
#include <limits.h>
#include <errno.h>
#include <getopt.h>
+#ifndef _WIN64
#include <dlfcn.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c
index dcf26bfea..f6c965b64 100644
--- a/lib/librte_eal/common/eal_common_timer.c
+++ b/lib/librte_eal/common/eal_common_timer.c
@@ -33,6 +33,7 @@ rte_delay_us_block(unsigned int us)
rte_pause();
}
+#ifndef _WIN64
void __rte_experimental
rte_delay_us_sleep(unsigned int us)
{
@@ -54,6 +55,7 @@ rte_delay_us_sleep(unsigned int us)
ind = 1 - ind;
}
}
+#endif
uint64_t
rte_get_tsc_hz(void)
diff --git a/lib/librte_eal/common/include/arch/x86/rte_byteorder.h b/lib/librte_eal/common/include/arch/x86/rte_byteorder.h
index a2dfecc1f..0f39af5c2 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_byteorder.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_byteorder.h
@@ -26,10 +26,16 @@ extern "C" {
static inline uint16_t rte_arch_bswap16(uint16_t _x)
{
uint16_t x = _x;
+#ifndef _WIN64
asm volatile ("xchgb %b[x1],%h[x2]"
: [x1] "=Q" (x)
: [x2] "0" (x)
);
+#else
+ __asm {
+ /* Add appropriate __asm here */
+ }
+#endif
return x;
}
@@ -41,9 +47,17 @@ static inline uint16_t rte_arch_bswap16(uint16_t _x)
static inline uint32_t rte_arch_bswap32(uint32_t _x)
{
uint32_t x = _x;
+#ifndef _WIN64
asm volatile ("bswap %[x]"
: [x] "+r" (x)
);
+#else
+ __asm {
+ mov eax, x
+ bswap eax
+ mov x, eax
+ }
+#endif
return x;
}
diff --git a/lib/librte_eal/common/include/arch/x86/rte_rtm.h b/lib/librte_eal/common/include/arch/x86/rte_rtm.h
index eb0f8e81e..8056b25de 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_rtm.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_rtm.h
@@ -29,29 +29,45 @@ static __attribute__((__always_inline__)) inline
unsigned int rte_xbegin(void)
{
unsigned int ret = RTE_XBEGIN_STARTED;
-
+#ifndef _WIN64
asm volatile(".byte 0xc7,0xf8 ; .long 0" : "+a" (ret) :: "memory");
+#else
+ /* Add appropriate asm here for Windows compilers */
+#endif
return ret;
}
static __attribute__((__always_inline__)) inline
void rte_xend(void)
{
- asm volatile(".byte 0x0f,0x01,0xd5" ::: "memory");
+#ifndef _WIN64
+ asm volatile(".byte 0x0f,0x01,0xd5" ::: "memory");
+#else
+ /* Add appropriate asm here for Windows compilers */
+#endif
}
/* not an inline function to workaround a clang bug with -O0 */
+#ifndef _WIN64
#define rte_xabort(status) do { \
asm volatile(".byte 0xc6,0xf8,%P0" :: "i" (status) : "memory"); \
} while (0)
+#else
+#define rte_xabort(status) do { \
+ /* Add appropriate asm here for Windows compilers */ \
+} while (0)
+#endif
static __attribute__((__always_inline__)) inline
int rte_xtest(void)
{
unsigned char out;
-
+#ifndef _WIN64
asm volatile(".byte 0x0f,0x01,0xd6 ; setnz %0" :
"=r" (out) :: "memory");
+#else
+ /* Add appropriate asm here for Windows compilers */
+#endif
return out;
}
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index 66cdf60b2..3e24463be 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -103,8 +103,15 @@ typedef uint16_t unaligned_uint16_t;
* Priority number must be above 100.
* Lowest number is the first to run.
*/
+#ifndef _WIN64
#define RTE_INIT_PRIO(func, prio) \
static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void)
+#else
+/* Re-define this without the __attribute__ and static declarator */
+#define RTE_INIT_PRIO(func, prio) \
+void func(void)
+#endif
+
/**
* Run function before main() with low priority.
@@ -262,7 +269,11 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
static inline int
rte_is_aligned(void *ptr, unsigned align)
{
+#ifndef _WIN64
return RTE_PTR_ALIGN(ptr, align) == ptr;
+#else
+ return (((uintptr_t)ptr % align) == 0);
+#endif
}
/*********** Macros for compile type checks ********/
diff --git a/lib/librte_eal/common/include/rte_malloc_heap.h b/lib/librte_eal/common/include/rte_malloc_heap.h
index 4a7e0eb1d..3a23fcd59 100644
--- a/lib/librte_eal/common/include/rte_malloc_heap.h
+++ b/lib/librte_eal/common/include/rte_malloc_heap.h
@@ -20,6 +20,9 @@ struct malloc_elem;
/**
* Structure to hold malloc heap
*/
+#ifdef _WIN64
+RTE_CACHE_ALIGN
+#endif
struct malloc_heap {
rte_spinlock_t lock;
LIST_HEAD(, malloc_elem) free_head[RTE_HEAP_NUM_FREELISTS];
diff --git a/lib/librte_eal/common/include/rte_random.h b/lib/librte_eal/common/include/rte_random.h
index b2ca1c209..680d0774c 100644
--- a/lib/librte_eal/common/include/rte_random.h
+++ b/lib/librte_eal/common/include/rte_random.h
@@ -18,6 +18,10 @@ extern "C" {
#include <stdint.h>
#include <stdlib.h>
+#ifdef _WIN64
+#include "rand48.h"
+#endif
+
/**
* Seed the pseudo-random generator.
*
diff --git a/lib/librte_eal/common/include/rte_string_fns.h b/lib/librte_eal/common/include/rte_string_fns.h
index 9a2a1ff90..5615d1f3a 100644
--- a/lib/librte_eal/common/include/rte_string_fns.h
+++ b/lib/librte_eal/common/include/rte_string_fns.h
@@ -66,6 +66,7 @@ rte_strlcpy(char *dst, const char *src, size_t size)
#endif
#else /* non-BSD platforms */
+#ifndef _WIN64
#ifdef RTE_USE_LIBBSD
#include <bsd/string.h>
@@ -73,6 +74,7 @@ rte_strlcpy(char *dst, const char *src, size_t size)
#define strlcpy(dst, src, size) rte_strlcpy(dst, src, size)
#endif /* RTE_USE_LIBBSD */
+#endif /* WIN64 */
#endif /* BSDAPP */
/**
diff --git a/lib/librte_eal/common/malloc_elem.h b/lib/librte_eal/common/malloc_elem.h
index e2bda4c02..697b1b074 100644
--- a/lib/librte_eal/common/malloc_elem.h
+++ b/lib/librte_eal/common/malloc_elem.h
@@ -20,6 +20,9 @@ enum elem_state {
ELEM_PAD /* element is a padding-only header */
};
+#ifdef _WIN64
+RTE_CACHE_ALIGN
+#endif
struct malloc_elem {
struct malloc_heap *heap;
struct malloc_elem *volatile prev;
diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c
index c6a6d4f6b..5314ebd20 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -60,11 +60,13 @@ check_hugepage_sz(unsigned flags, uint64_t hugepage_sz)
case RTE_PGSIZE_1G:
check_flag = RTE_MEMZONE_1GB;
break;
+#ifndef _WIN64
case RTE_PGSIZE_4G:
check_flag = RTE_MEMZONE_4GB;
break;
case RTE_PGSIZE_16G:
check_flag = RTE_MEMZONE_16GB;
+#endif
}
return check_flag & flags;
diff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h
index e48996d52..df60ab62c 100644
--- a/lib/librte_eal/common/malloc_heap.h
+++ b/lib/librte_eal/common/malloc_heap.h
@@ -10,6 +10,10 @@
#include <rte_malloc.h>
#include <rte_malloc_heap.h>
+#ifdef _WIN64
+#include <rte_lcore.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/lib/librte_eal/windows/eal/eal.c b/lib/librte_eal/windows/eal/eal.c
new file mode 100644
index 000000000..b060bbb92
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal.c
@@ -0,0 +1,697 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <direct.h>
+
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_log.h>
+#include <rte_random.h>
+#include <rte_cycles.h>
+#include <rte_errno.h>
+#include <rte_windows.h>
+
+#include "eal_private.h"
+#include "eal_thread.h"
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_hugepages.h"
+#include "eal_options.h"
+#include "malloc_heap.h"
+#include "private.h"
+
+#define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
+
+/* Allow the application to print its usage message too if set */
+static rte_usage_hook_t rte_application_usage_hook = NULL;
+
+/* define fd variable here, because file needs to be kept open for the
+ * duration of the program, as we hold a write lock on it in the primary proc */
+
+static int mem_cfg_fd = -1; // INVALID_HANDLE_VALUE;
+/*
+static struct flock wr_lock = {
+ .l_type = F_WRLCK,
+ .l_whence = SEEK_SET,
+ .l_start = offsetof(struct rte_mem_config, memseg),
+ .l_len = sizeof(early_mem_config.memseg),
+};
+*/
+/* early configuration structure, when memory config is not mmapped */
+static struct rte_mem_config early_mem_config;
+
+/* Address of global and public configuration */
+static struct rte_config rte_config = {
+ .mem_config = &early_mem_config,
+};
+
+/* internal configuration (per-core) */
+struct lcore_config lcore_config[RTE_MAX_LCORE];
+
+/* internal configuration */
+struct internal_config internal_config;
+
+/* external function protoypes */
+/* these functions are created by the RTE_REGISTER_BUS macro */
+extern void businitfn_pci(void);
+extern void businitfn_vdev(void);
+
+/* these functions are created by the MEMPOOL_REGISTER_OPS macro */
+extern void mp_hdlr_init_ops_mp_mc(void);
+extern void mp_hdlr_init_ops_sp_sc(void);
+extern void mp_hdlr_init_ops_mp_sc(void);
+extern void mp_hdlr_init_ops_sp_mc(void);
+
+/* these functions are created by the EAL_REGISTER_TAILQ macro */
+extern void init_rte_mempool_tailq(void);
+extern void init_rte_ring_tailq(void);
+extern void init_rte_hash_tailq(void);
+extern void init_rte_fbk_hash_tailq(void);
+extern void init_rte_distributor_tailq(void);
+extern void init_rte_dist_burst_tailq(void);
+extern void init_rte_uio_tailq(void);
+extern void init_rte_lpm_tailq(void);
+extern void init_rte_lpm6_tailq(void);
+
+/* these functions are created by the RTE_PMD_REGISTER_PCI macro */
+extern void pciinitfn_net_i40e(void);
+
+/* these are more constructor-like function, that we'll need to call at the start */
+extern void rte_timer_init(void);
+extern void rte_log_init(void);
+extern void i40e_init_log(void);
+
+/* Return a pointer to the configuration structure */
+struct rte_config *
+rte_eal_get_configuration(void)
+{
+ return &rte_config;
+}
+
+/* Return mbuf pool ops name */
+const char *
+rte_eal_mbuf_user_pool_ops(void)
+{
+ return internal_config.user_mbuf_pool_ops_name;
+}
+
+enum rte_iova_mode
+rte_eal_iova_mode(void)
+{
+ return rte_eal_get_configuration()->iova_mode;
+}
+
+/* platform-specific runtime dir */
+static char runtime_dir[PATH_MAX];
+
+/* create memory configuration in shared/mmap memory. Take out
+ * a write lock on the memsegs, so we can auto-detect primary/secondary.
+ * This means we never close the file while running (auto-close on exit).
+ * We also don't lock the whole file, so that in future we can use read-locks
+ * on other parts, e.g. memzones, to detect if there are running secondary
+ * processes. */
+static void
+rte_eal_config_create(void)
+{
+ void *rte_mem_cfg_addr;
+ BOOL retval;
+
+ const char *pathname = eal_runtime_config_path();
+
+ if (internal_config.no_shconf)
+ return;
+
+ if (mem_cfg_fd < 0) {
+ mem_cfg_fd = _open(pathname, _O_CREAT | _O_RDWR | _O_TRUNC, _S_IREAD | _S_IWRITE);
+ if (mem_cfg_fd < 0)
+ rte_panic("Cannot open '%s' for rte_mem_config...Error: %d\n", pathname, errno);
+ }
+
+ /* Lock file for exclusive access */
+ OVERLAPPED sOverlapped = {0};
+ sOverlapped.Offset = sizeof(*rte_config.mem_config);
+ sOverlapped.OffsetHigh = 0;
+
+ HANDLE hWinFileHandle = (HANDLE)_get_osfhandle(mem_cfg_fd);
+ retval = LockFileEx(hWinFileHandle,
+ LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0,
+ sizeof(*rte_config.mem_config), 0, &sOverlapped);
+ if (!retval) {
+ _close(mem_cfg_fd);
+ rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary process running?\n", pathname);
+ }
+
+ rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
+ PROT_READ | PROT_WRITE, MAP_SHARED, (int)mem_cfg_fd, 0);
+
+ if (rte_mem_cfg_addr == MAP_FAILED) {
+ _close(mem_cfg_fd);
+ rte_exit(EXIT_FAILURE, "Cannot mmap memory for rte_config\n");
+ }
+
+ memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
+ rte_config.mem_config = (struct rte_mem_config *) rte_mem_cfg_addr;
+}
+
+/* attach to an existing shared memory config */
+static void
+rte_eal_config_attach(void)
+{
+ void *rte_mem_cfg_addr;
+ const char *pathname = eal_runtime_config_path();
+
+ if (internal_config.no_shconf)
+ return;
+
+ if (mem_cfg_fd < 0) {
+ mem_cfg_fd = _open(pathname, O_RDWR);
+ if (mem_cfg_fd < 0)
+ rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+ }
+
+ rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config), PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
+ _close(mem_cfg_fd);
+
+ if (rte_mem_cfg_addr == MAP_FAILED)
+ rte_panic("Cannot mmap memory for rte_config\n");
+
+ rte_config.mem_config = (struct rte_mem_config *) rte_mem_cfg_addr;
+}
+
+/* Detect if we are a primary or a secondary process */
+enum rte_proc_type_t
+eal_proc_type_detect(void)
+{
+ enum rte_proc_type_t ptype = RTE_PROC_PRIMARY;
+ const char *pathname = eal_runtime_config_path();
+
+ /* if we can open the file but not get a write-lock we are a secondary
+ * process. NOTE: if we get a file handle back, we keep that open
+ * and don't close it to prevent a race condition between multiple opens */
+ if ((mem_cfg_fd = _open(pathname, O_RDWR)) >= 0) {
+ OVERLAPPED sOverlapped = { 0 };
+ sOverlapped.Offset = sizeof(*rte_config.mem_config);
+ sOverlapped.OffsetHigh = 0;
+
+ HANDLE hWinFileHandle = (HANDLE)_get_osfhandle(mem_cfg_fd);
+
+ if (!LockFileEx(hWinFileHandle,
+ LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0,
+ sizeof(*rte_config.mem_config), 0, &sOverlapped))
+ ptype = RTE_PROC_SECONDARY;
+ }
+
+ RTE_LOG(INFO, EAL, "Auto-detected process type: %s\n",
+ ptype == RTE_PROC_PRIMARY ? "PRIMARY" : "SECONDARY");
+
+ return ptype;
+}
+
+/* Sets up rte_config structure with the pointer to shared memory config.*/
+static void
+rte_config_init(void)
+{
+ rte_config.process_type = internal_config.process_type;
+
+ switch (rte_config.process_type){
+ case RTE_PROC_PRIMARY:
+ rte_eal_config_create();
+ break;
+ case RTE_PROC_SECONDARY:
+ rte_eal_config_attach();
+ rte_eal_mcfg_wait_complete(rte_config.mem_config);
+ break;
+ case RTE_PROC_AUTO:
+ case RTE_PROC_INVALID:
+ rte_panic("Invalid process type\n");
+ }
+}
+
+/* display usage */
+static void
+eal_usage(const char *prgname)
+{
+ printf("\nUsage: %s ", prgname);
+ eal_common_usage();
+ /* Allow the application to print its usage message too if hook is set */
+ if ( rte_application_usage_hook ) {
+ printf("===== Application Usage =====\n\n");
+ rte_application_usage_hook(prgname);
+ }
+}
+
+/* Set a per-application usage message */
+rte_usage_hook_t
+rte_set_application_usage_hook( rte_usage_hook_t usage_func )
+{
+ rte_usage_hook_t old_func;
+
+ /* Will be NULL on the first call to denote the last usage routine. */
+ old_func = rte_application_usage_hook;
+ rte_application_usage_hook = usage_func;
+
+ return old_func;
+}
+
+static inline size_t
+eal_get_hugepage_mem_size(void)
+{
+ uint64_t size = 0;
+ size = (uint64_t)GetLargePageMinimum();
+
+ return (size < SIZE_MAX) ? (size_t)(size) : SIZE_MAX;
+}
+
+/* Parse the arguments for --log-level only */
+static void
+eal_log_level_parse(int argc, char **argv)
+{
+ int opt;
+ char **argvopt;
+ int option_index;
+
+ argvopt = argv;
+
+ eal_reset_internal_config(&internal_config);
+
+ while ((opt = getopt_long(argc, argvopt, eal_short_options,
+ eal_long_options, &option_index)) != EOF) {
+
+ int ret;
+
+ /* getopt is not happy, stop right now */
+ if (opt == '?')
+ break;
+
+ ret = (opt == OPT_LOG_LEVEL_NUM) ?
+ eal_parse_common_option(opt, optarg, &internal_config) : 0;
+
+ /* common parser is not happy */
+ if (ret < 0)
+ break;
+ }
+
+ optind = 0; /* reset getopt lib */
+}
+
+/* Parse the argument given in the command line of the application */
+static int
+eal_parse_args(int argc, char **argv)
+{
+ int opt, ret;
+ char **argvopt;
+ int option_index;
+ char *prgname = argv[0];
+
+ argvopt = argv;
+
+ while ((opt = getopt_long(argc, argvopt, eal_short_options,
+ eal_long_options, &option_index)) != EOF) {
+
+ int ret;
+
+ /* getopt is not happy, stop right now */
+ if (opt == '?') {
+ eal_usage(prgname);
+ return -1;
+ }
+
+ ret = eal_parse_common_option(opt, optarg, &internal_config);
+ /* common parser is not happy */
+ if (ret < 0) {
+ eal_usage(prgname);
+ return -1;
+ }
+ /* common parser handled this option */
+ if (ret == 0)
+ continue;
+
+ switch (opt) {
+ case 'h':
+ eal_usage(prgname);
+ exit(EXIT_SUCCESS);
+ default:
+ if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
+ RTE_LOG(ERR, EAL, "Option %c is not supported "
+ "on FreeBSD\n", opt);
+ } else if (opt >= OPT_LONG_MIN_NUM &&
+ opt < OPT_LONG_MAX_NUM) {
+ RTE_LOG(ERR, EAL, "Option %s is not supported "
+ "on FreeBSD\n",
+ eal_long_options[option_index].name);
+ } else {
+ RTE_LOG(ERR, EAL, "Option %d is not supported "
+ "on FreeBSD\n", opt);
+ }
+ eal_usage(prgname);
+ return -1;
+ }
+ }
+
+ /* create runtime data directory */
+ if (internal_config.no_shconf == 0 &&
+ eal_create_runtime_dir() < 0) {
+ RTE_LOG(ERR, EAL, "Cannot create runtime directory\n");
+ return ret = -1;
+ }
+
+ if (eal_adjust_config(&internal_config) != 0)
+ return -1;
+
+ /* sanity checks */
+ if (eal_check_common_options(&internal_config) != 0) {
+ eal_usage(prgname);
+ return -1;
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+ ret = optind-1;
+ optind = 0; /* reset getopt lib */
+ return ret;
+}
+
+static int
+check_socket(const struct rte_memseg_list *msl, void *arg)
+{
+ int *socket_id = arg;
+
+ return *socket_id == msl->socket_id;
+}
+
+static void
+eal_check_mem_on_local_socket(void)
+{
+ const struct rte_memseg *ms;
+ int i, socket_id;
+
+ socket_id = rte_lcore_to_socket_id(rte_config.master_lcore);
+
+ if (rte_memseg_list_walk(check_socket, &socket_id) == 0)
+ RTE_LOG(WARNING, EAL, "WARNING: Master core has no memory on local socket!\n");
+}
+
+static int
+sync_func(__attribute__((unused)) void *arg)
+{
+ return 0;
+}
+
+inline static void
+rte_eal_mcfg_complete(void)
+{
+ /* ALL shared mem_config related INIT DONE */
+ if (rte_config.process_type == RTE_PROC_PRIMARY)
+ rte_config.mem_config->magic = RTE_MAGIC;
+}
+
+/* return non-zero if hugepages are enabled. */
+int rte_eal_has_hugepages(void)
+{
+ return !internal_config.no_hugetlbfs;
+}
+
+/* Abstraction for port I/0 privilege */
+int
+rte_eal_iopl_init(void)
+{
+ // Not required on modern processors?
+ return -1;
+}
+
+static void rte_eal_init_alert(const char *msg)
+{
+ fprintf(stderr, "EAL: FATAL: %s\n", msg);
+ RTE_LOG(ERR, EAL, "%s\n", msg);
+}
+
+/* Register and initialize all buses */
+/* (This is a workaround for Windows in lieu of a constructor-like function) */
+static void
+eal_register_and_init_buses()
+{
+ businitfn_pci();
+ /* businitfn_vdev(); Not presently supported! */
+}
+
+/* Register and initialize all mempools */
+/* (This is a workaround for Windows in lieu of a constructor-like function) */
+static void
+eal_register_and_init_mempools()
+{
+ /* these functions are created by the MEMPOOL_REGISTER_OPS macro */
+ mp_hdlr_init_ops_mp_mc();
+ mp_hdlr_init_ops_sp_sc();
+ mp_hdlr_init_ops_mp_sc();
+ mp_hdlr_init_ops_sp_mc();
+}
+
+/* Register and initialize tailqs */
+/* (This is a workaround for Windows in lieu of a constructor-like function) */
+static void
+eal_register_and_init_tailq()
+{
+ /* these functions are created by the EAL_REGISTER_TAILQ macro */
+ init_rte_mempool_tailq();
+ init_rte_ring_tailq();
+ init_rte_hash_tailq();
+ init_rte_fbk_hash_tailq();
+ init_rte_distributor_tailq();
+ init_rte_dist_burst_tailq();
+ init_rte_uio_tailq();
+ init_rte_lpm_tailq();
+ init_rte_lpm6_tailq();
+}
+
+/* Register and initialize all supported PMDs */
+/* (This is a workaround for Windows in lieu of a constructor-like function) */
+static void
+eal_register_and_init_pmd()
+{
+ /* these functions are created by the RTE_PMD_REGISTER_PCI macro */
+ pciinitfn_net_i40e(); /* init the Intel 40GbE PMD */
+}
+
+/* Launch threads, called at application init(). */
+int
+rte_eal_init(int argc, char **argv)
+{
+ int i, fctret, ret;
+ pthread_t thread_id;
+ static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
+ char cpuset[RTE_CPU_AFFINITY_STR_LEN];
+
+ rte_timer_init(); /* Initialize timer function */
+
+ if (!rte_atomic32_test_and_set(&run_once))
+ return -1;
+
+ thread_id = pthread_self();
+
+ /* initialize all logs */
+ rte_eal_log_init(NULL, 0);
+ rte_log_init();
+
+ eal_log_level_parse(argc, argv);
+
+ /* set log level as early as possible */
+ rte_log_set_global_level(RTE_LOG_LEVEL);
+
+ /* create a map of all processors in the system */
+ eal_create_cpu_map();
+
+ if (rte_eal_cpu_init() < 0)
+ rte_panic("Cannot detect lcores\n");
+
+ fctret = eal_parse_args(argc, argv);
+ if (fctret < 0)
+ exit(1);
+
+ rte_config_init();
+
+ if (internal_config.no_hugetlbfs == 0 &&
+ internal_config.process_type != RTE_PROC_SECONDARY &&
+ eal_hugepage_info_init() < 0)
+ rte_panic("Cannot get hugepage information\n");
+
+ if (internal_config.memory == 0 && internal_config.force_sockets == 0) {
+ if (internal_config.no_hugetlbfs)
+ internal_config.memory = MEMSIZE_IF_NO_HUGE_PAGE;
+ else
+ internal_config.memory = eal_get_hugepage_mem_size();
+ }
+
+ if (internal_config.vmware_tsc_map == 1) {
+#ifdef RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT
+ rte_cycles_vmware_tsc_map = 1;
+ RTE_LOG (DEBUG, EAL, "Using VMWARE TSC MAP, "
+ "you must have monitor_control.pseudo_perfctr = TRUE\n");
+#else
+ RTE_LOG (WARNING, EAL, "Ignoring --vmware-tsc-map because "
+ "RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT is not set\n");
+#endif
+ }
+
+ rte_srand(rte_rdtsc());
+
+ /* in secondary processes, memory init may allocate additional fbarrays
+ * not present in primary processes, so to avoid any potential issues,
+ * initialize memzones first.
+ */
+ if (rte_eal_memzone_init() < 0)
+ rte_panic("Cannot init memzone\n");
+
+ if (rte_eal_memory_init() < 0)
+ rte_panic("Cannot init memory\n");
+
+ if (rte_eal_malloc_heap_init() < 0)
+ rte_panic("Cannot init malloc heap\n");
+
+ if (rte_eal_tailqs_init() < 0)
+ rte_panic("Cannot init tail queues for objects\n");
+
+ if (rte_eal_alarm_init() < 0)
+ rte_panic("Cannot init interrupt-handling thread\n");
+
+ if (rte_eal_intr_init() < 0)
+ rte_panic("Cannot init interrupt-handling thread\n");
+
+ if (rte_eal_timer_init() < 0)
+ rte_panic("Cannot init HPET or TSC timers\n");
+
+ eal_check_mem_on_local_socket();
+
+ eal_thread_init_master(rte_config.master_lcore);
+
+ ret = eal_thread_dump_affinity(cpuset, RTE_CPU_AFFINITY_STR_LEN);
+
+ RTE_LOG(DEBUG, EAL, "Master lcore %u is ready (tid=%p;cpuset=[%s%s])\n",
+ rte_config.master_lcore, thread_id, cpuset,
+ ret == 0 ? "" : "...");
+
+ RTE_LCORE_FOREACH_SLAVE(i) {
+
+ /*
+ * create communication pipes between master thread
+ * and children
+ */
+ if (pipe(lcore_config[i].pipe_master2slave) < 0)
+ rte_panic("Cannot create pipe\n");
+ if (pipe(lcore_config[i].pipe_slave2master) < 0)
+ rte_panic("Cannot create pipe\n");
+
+ lcore_config[i].state = WAIT;
+
+ /* create a thread for each lcore */
+ ret = pthread_create(&lcore_config[i].thread_id, NULL,
+ eal_thread_loop, NULL);
+ if (ret != 0)
+ rte_panic("Cannot create thread\n");
+ }
+
+ /*
+ * Launch a dummy function on all slave lcores, so that master lcore
+ * knows they are all ready when this function returns.
+ */
+ rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
+ rte_eal_mp_wait_lcore();
+
+#ifdef EAL_SERVICES_SUPPORT
+ /* Not supported on Windows, presently */
+ /* initialize services so vdevs register service during bus_probe. */
+ ret = rte_service_init();
+ if (ret) {
+ rte_eal_init_alert("rte_service_init() failed\n");
+ rte_errno = ENOEXEC;
+ return -1;
+ }
+#endif
+
+ /* Probe & Initialize PCI devices */
+ if (rte_bus_probe())
+ rte_panic("Cannot probe PCI\n");
+
+#ifdef EAL_SERVICES_SUPPORT
+ /* initialize default service/lcore mappings and start running. Ignore
+ * -ENOTSUP, as it indicates no service coremask passed to EAL.
+ */
+ ret = rte_service_start_with_defaults();
+ if (ret < 0 && ret != -ENOTSUP) {
+ rte_errno = ENOEXEC;
+ return -1;
+ }
+#endif
+ rte_eal_mcfg_complete();
+
+ return fctret;
+}
+
+/* get core role */
+enum rte_lcore_role_t
+rte_eal_lcore_role(unsigned lcore_id)
+{
+ return rte_config.lcore_role[lcore_id];
+}
+
+enum rte_proc_type_t
+rte_eal_process_type(void)
+{
+ return rte_config.process_type;
+}
+
+int
+eal_create_runtime_dir(void)
+{
+ char Directory[PATH_MAX];
+
+ GetTempPathA(sizeof(Directory), Directory);
+
+ char tmp[PATH_MAX];
+ int ret;
+
+
+ /* create DPDK subdirectory under runtime dir */
+ ret = snprintf(tmp, sizeof(tmp), "%s\\dpdk", Directory);
+ if (ret < 0 || ret == sizeof(tmp)) {
+ RTE_LOG(ERR, EAL, "Error creating DPDK runtime path name\n");
+ return -1;
+ }
+
+ /* create prefix-specific subdirectory under DPDK runtime dir */
+ ret = snprintf(runtime_dir, sizeof(runtime_dir), "%s\\%s",
+ tmp, internal_config.hugefile_prefix);
+ if (ret < 0 || ret == sizeof(runtime_dir)) {
+ RTE_LOG(ERR, EAL, "Error creating prefix-specific runtime path name\n");
+ return -1;
+ }
+
+ /* create the path if it doesn't exist. no "mkdir -p" here, so do it
+ * step by step.
+ */
+ ret = mkdir(tmp);
+ if (ret < 0 && errno != EEXIST) {
+ RTE_LOG(ERR, EAL, "Error creating '%s': %s\n",
+ tmp, strerror(errno));
+ return -1;
+ }
+
+ ret = mkdir(runtime_dir);
+ if (ret < 0 && errno != EEXIST) {
+ RTE_LOG(ERR, EAL, "Error creating '%s': %s\n",
+ runtime_dir, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+const char *
+eal_get_runtime_dir(void)
+{
+ return runtime_dir;
+}
diff --git a/lib/librte_eal/windows/eal/eal_alarm.c b/lib/librte_eal/windows/eal/eal_alarm.c
new file mode 100644
index 000000000..d881cc5dd
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_alarm.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_alarm.h>
+#include <rte_common.h>
+#include "eal_private.h"
+
+int
+rte_eal_alarm_init(void)
+{
+ return 0;
+}
+
+
+int
+rte_eal_alarm_set(uint64_t us __rte_unused,
+ rte_eal_alarm_callback cb_fn __rte_unused,
+ void *cb_arg __rte_unused)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn __rte_unused,
+ void *cb_arg __rte_unused)
+{
+ return -ENOTSUP;
+}
diff --git a/lib/librte_eal/windows/eal/eal_debug.c b/lib/librte_eal/windows/eal/eal_debug.c
new file mode 100644
index 000000000..c1cb810c5
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_debug.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_windows.h>
+#include <DbgHelp.h>
+
+#include <rte_log.h>
+#include <rte_debug.h>
+
+#define MAX_TRACE_STACK_FRAMES 1024
+
+/* dump the stack of the calling core */
+void rte_dump_stack(void)
+{
+ void *pCallingStack[MAX_TRACE_STACK_FRAMES];
+ WORD numFrames;
+ DWORD dwError;
+ HANDLE hProcess = GetCurrentProcess();
+
+ SymInitialize(hProcess, NULL, TRUE);
+ numFrames = RtlCaptureStackBackTrace(0, MAX_TRACE_STACK_FRAMES, pCallingStack, NULL);
+
+ for (int i = 0; i < numFrames; i++) {
+ DWORD64 dwAddress = (DWORD64)(pCallingStack[i]);
+ DWORD dwDisplacement;
+
+ char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
+ PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
+
+ pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+ pSymbol->MaxNameLen = MAX_SYM_NAME;
+
+ // Get the symbol information from the address
+ if (SymFromAddr(hProcess, dwAddress, NULL, pSymbol)) {
+ // Get the line number from the same address
+ IMAGEHLP_LINE64 line;
+
+ SymSetOptions(SYMOPT_LOAD_LINES);
+ line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
+
+ if (SymGetLineFromAddr64(hProcess, dwAddress, &dwDisplacement, &line))
+ printf("Currently at %s in %s: line: %lu: address: 0x%0X\n", pSymbol->Name, line.FileName, line.LineNumber, pSymbol->Address);
+ else
+ goto error;
+ }
+ else
+ goto error;
+
+ continue;
+error:
+ dwError = GetLastError();
+ printf("SymFromAddr()/SymGetLineFromAddr64() failed: Error: %d\n", dwError);
+ }
+
+ return;
+}
+
+/* not implemented in this environment */
+void rte_dump_registers(void)
+{
+ return;
+}
+
+/* call abort(), it will generate a coredump if enabled */
+void __rte_panic(const char *funcname, const char *format, ...)
+{
+ va_list ap;
+
+ rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
+ va_start(ap, format);
+ rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+ va_end(ap);
+ rte_dump_stack();
+ rte_dump_registers();
+ abort();
+}
+
+/*
+ * Like rte_panic this terminates the application. However, no traceback is
+ * provided and no core-dump is generated.
+ */
+void
+rte_exit(int exit_code, const char *format, ...)
+{
+ va_list ap;
+
+ if (exit_code != 0)
+ RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n Cause: ", exit_code);
+
+ va_start(ap, format);
+ rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+ va_end(ap);
+
+#ifndef RTE_EAL_ALWAYS_PANIC_ON_ERROR
+ exit(exit_code);
+#else
+ rte_dump_stack();
+ rte_dump_registers();
+ abort();
+#endif
+}
diff --git a/lib/librte_eal/windows/eal/eal_fbarray.c b/lib/librte_eal/windows/eal/eal_fbarray.c
new file mode 100644
index 000000000..8e3932b3f
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_fbarray.c
@@ -0,0 +1,1273 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Intel Corporation
+ */
+
+#include <inttypes.h>
+#include <limits.h>
+#include <assert.h>
+#include <sys/mman.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_errno.h>
+#include <rte_spinlock.h>
+#include <rte_tailq.h>
+
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+#include "rte_fbarray.h"
+
+#define MASK_SHIFT 6ULL
+#define MASK_ALIGN (1ULL << MASK_SHIFT)
+#define MASK_LEN_TO_IDX(x) ((x) >> MASK_SHIFT)
+#define MASK_LEN_TO_MOD(x) ((x) - RTE_ALIGN_FLOOR(x, MASK_ALIGN))
+#define MASK_GET_IDX(idx, mod) ((idx << MASK_SHIFT) + mod)
+
+/*
+ * This is a mask that is always stored at the end of array, to provide fast
+ * way of finding free/used spots without looping through each element.
+ */
+
+struct used_mask {
+ unsigned int n_masks;
+ uint64_t data[];
+};
+
+static size_t
+calc_mask_size(unsigned int len)
+{
+ /* mask must be multiple of MASK_ALIGN, even though length of array
+ * itself may not be aligned on that boundary.
+ */
+ len = RTE_ALIGN_CEIL(len, MASK_ALIGN);
+ return sizeof(struct used_mask) +
+ sizeof(uint64_t) * MASK_LEN_TO_IDX(len);
+}
+
+static size_t
+calc_data_size(size_t page_sz, unsigned int elt_sz, unsigned int len)
+{
+ size_t data_sz = elt_sz * len;
+ size_t msk_sz = calc_mask_size(len);
+ return RTE_ALIGN_CEIL(data_sz + msk_sz, page_sz);
+}
+
+static struct used_mask *
+get_used_mask(void *data, unsigned int elt_sz, unsigned int len)
+{
+ return (struct used_mask *) RTE_PTR_ADD(data, elt_sz * len);
+}
+
+static void *
+resize_and_map(int fd, size_t len)
+{
+ // Map the file to the process virtual space and return the address
+ void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED) {
+ RTE_LOG(ERR, EAL, "mmap() failed: %s\n", strerror(errno));
+ /* pass errno up the chain */
+ rte_errno = errno;
+ return NULL;
+ }
+
+ return addr;
+}
+
+static int
+find_next_n(const struct rte_fbarray *arr, unsigned int start, unsigned int n,
+ bool used)
+{
+ const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+ arr->len);
+ unsigned int msk_idx, lookahead_idx, first, first_mod;
+ unsigned int last, last_mod;
+ uint64_t last_msk, ignore_msk;
+
+ /*
+ * mask only has granularity of MASK_ALIGN, but start may not be aligned
+ * on that boundary, so construct a special mask to exclude anything we
+ * don't want to see to avoid confusing ctz.
+ */
+ first = MASK_LEN_TO_IDX(start);
+ first_mod = MASK_LEN_TO_MOD(start);
+ ignore_msk = ~((1ULL << first_mod) - 1);
+
+ /* array length may not be aligned, so calculate ignore mask for last
+ * mask index.
+ */
+ last = MASK_LEN_TO_IDX(arr->len);
+ last_mod = MASK_LEN_TO_MOD(arr->len);
+ last_msk = ~(-1ULL << last_mod);
+
+ for (msk_idx = first; msk_idx < msk->n_masks; msk_idx++) {
+ uint64_t cur_msk, lookahead_msk;
+ unsigned int run_start, clz, left;
+ bool found = false;
+ /*
+ * The process of getting n consecutive bits for arbitrary n is
+ * a bit involved, but here it is in a nutshell:
+ *
+ * 1. let n be the number of consecutive bits we're looking for
+ * 2. check if n can fit in one mask, and if so, do n-1
+ * rshift-ands to see if there is an appropriate run inside
+ * our current mask
+ * 2a. if we found a run, bail out early
+ * 2b. if we didn't find a run, proceed
+ * 3. invert the mask and count leading zeroes (that is, count
+ * how many consecutive set bits we had starting from the
+ * end of current mask) as k
+ * 3a. if k is 0, continue to next mask
+ * 3b. if k is not 0, we have a potential run
+ * 4. to satisfy our requirements, next mask must have n-k
+ * consecutive set bits right at the start, so we will do
+ * (n-k-1) rshift-ands and check if first bit is set.
+ *
+ * Step 4 will need to be repeated if (n-k) > MASK_ALIGN until
+ * we either run out of masks, lose the run, or find what we
+ * were looking for.
+ */
+ cur_msk = msk->data[msk_idx];
+ left = n;
+
+ /* if we're looking for free spaces, invert the mask */
+ if (!used)
+ cur_msk = ~cur_msk;
+
+ /* combine current ignore mask with last index ignore mask */
+ if (msk_idx == last)
+ ignore_msk |= last_msk;
+
+ /* if we have an ignore mask, ignore once */
+ if (ignore_msk) {
+ cur_msk &= ignore_msk;
+ ignore_msk = 0;
+ }
+
+ /* if n can fit in within a single mask, do a search */
+ if (n <= MASK_ALIGN) {
+ uint64_t tmp_msk = cur_msk;
+ unsigned int s_idx;
+ for (s_idx = 0; s_idx < n - 1; s_idx++)
+ tmp_msk &= tmp_msk >> 1ULL;
+ /* we found what we were looking for */
+ if (tmp_msk != 0) {
+ run_start = __builtin_ctzll(tmp_msk);
+ return MASK_GET_IDX(msk_idx, run_start);
+ }
+ }
+
+ /*
+ * we didn't find our run within the mask, or n > MASK_ALIGN,
+ * so we're going for plan B.
+ */
+
+ /* count leading zeroes on inverted mask */
+ if (~cur_msk == 0)
+ clz = sizeof(cur_msk) * 8;
+ else
+ clz = __builtin_clzll(~cur_msk);
+
+ /* if there aren't any runs at the end either, just continue */
+ if (clz == 0)
+ continue;
+
+ /* we have a partial run at the end, so try looking ahead */
+ run_start = MASK_ALIGN - clz;
+ left -= clz;
+
+ for (lookahead_idx = msk_idx + 1; lookahead_idx < msk->n_masks;
+ lookahead_idx++) {
+ unsigned int s_idx, need;
+ lookahead_msk = msk->data[lookahead_idx];
+
+ /* if we're looking for free space, invert the mask */
+ if (!used)
+ lookahead_msk = ~lookahead_msk;
+
+ /* figure out how many consecutive bits we need here */
+ need = RTE_MIN(left, MASK_ALIGN);
+
+ for (s_idx = 0; s_idx < need - 1; s_idx++)
+ lookahead_msk &= lookahead_msk >> 1ULL;
+
+ /* if first bit is not set, we've lost the run */
+ if ((lookahead_msk & 1) == 0) {
+ /*
+ * we've scanned this far, so we know there are
+ * no runs in the space we've lookahead-scanned
+ * as well, so skip that on next iteration.
+ */
+ ignore_msk = ~((1ULL << need) - 1);
+ msk_idx = lookahead_idx;
+ break;
+ }
+
+ left -= need;
+
+ /* check if we've found what we were looking for */
+ if (left == 0) {
+ found = true;
+ break;
+ }
+ }
+
+ /* we didn't find anything, so continue */
+ if (!found)
+ continue;
+
+ return MASK_GET_IDX(msk_idx, run_start);
+ }
+ /* we didn't find anything */
+ rte_errno = used ? ENOENT : ENOSPC;
+ return -1;
+}
+
+static int
+find_next(const struct rte_fbarray *arr, unsigned int start, bool used)
+{
+ const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+ arr->len);
+ unsigned int idx, first, first_mod;
+ unsigned int last, last_mod;
+ uint64_t last_msk, ignore_msk;
+
+ /*
+ * mask only has granularity of MASK_ALIGN, but start may not be aligned
+ * on that boundary, so construct a special mask to exclude anything we
+ * don't want to see to avoid confusing ctz.
+ */
+ first = MASK_LEN_TO_IDX(start);
+ first_mod = MASK_LEN_TO_MOD(start);
+ ignore_msk = ~((1ULL << first_mod) - 1ULL);
+
+ /* array length may not be aligned, so calculate ignore mask for last
+ * mask index.
+ */
+ last = MASK_LEN_TO_IDX(arr->len);
+ last_mod = MASK_LEN_TO_MOD(arr->len);
+ last_msk = ~(-(1ULL) << last_mod);
+
+ for (idx = first; idx < msk->n_masks; idx++) {
+ uint64_t cur = msk->data[idx];
+ int found;
+
+ /* if we're looking for free entries, invert mask */
+ if (!used)
+ cur = ~cur;
+
+ if (idx == last)
+ cur &= last_msk;
+
+ /* ignore everything before start on first iteration */
+ if (idx == first)
+ cur &= ignore_msk;
+
+ /* check if we have any entries */
+ if (cur == 0)
+ continue;
+
+ /*
+ * find first set bit - that will correspond to whatever it is
+ * that we're looking for.
+ */
+ found = __builtin_ctzll(cur);
+ return MASK_GET_IDX(idx, found);
+ }
+ /* we didn't find anything */
+ rte_errno = used ? ENOENT : ENOSPC;
+ return -1;
+}
+
+static int
+find_contig(const struct rte_fbarray *arr, unsigned int start, bool used)
+{
+ const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+ arr->len);
+ unsigned int idx, first, first_mod;
+ unsigned int last, last_mod;
+ uint64_t last_msk;
+ unsigned int need_len, result = 0;
+
+ /* array length may not be aligned, so calculate ignore mask for last
+ * mask index.
+ */
+ last = MASK_LEN_TO_IDX(arr->len);
+ last_mod = MASK_LEN_TO_MOD(arr->len);
+ last_msk = ~(-(1ULL) << last_mod);
+
+ first = MASK_LEN_TO_IDX(start);
+ first_mod = MASK_LEN_TO_MOD(start);
+ for (idx = first; idx < msk->n_masks; idx++, result += need_len) {
+ uint64_t cur = msk->data[idx];
+ unsigned int run_len;
+
+ need_len = MASK_ALIGN;
+
+ /* if we're looking for free entries, invert mask */
+ if (!used)
+ cur = ~cur;
+
+ /* if this is last mask, ignore everything after last bit */
+ if (idx == last)
+ cur &= last_msk;
+
+ /* ignore everything before start on first iteration */
+ if (idx == first) {
+ cur >>= first_mod;
+ /* at the start, we don't need the full mask len */
+ need_len -= first_mod;
+ }
+
+ /* we will be looking for zeroes, so invert the mask */
+ cur = ~cur;
+
+ /* if mask is zero, we have a complete run */
+ if (cur == 0)
+ continue;
+
+ /*
+ * see if current run ends before mask end.
+ */
+ run_len = __builtin_ctzll(cur);
+
+ /* add however many zeroes we've had in the last run and quit */
+ if (run_len < need_len) {
+ result += run_len;
+ break;
+ }
+ }
+ return result;
+}
+
+static int
+find_prev_n(const struct rte_fbarray *arr, unsigned int start, unsigned int n,
+ bool used)
+{
+ const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+ arr->len);
+ unsigned int msk_idx, lookbehind_idx, first, first_mod;
+ uint64_t ignore_msk;
+
+ /*
+ * mask only has granularity of MASK_ALIGN, but start may not be aligned
+ * on that boundary, so construct a special mask to exclude anything we
+ * don't want to see to avoid confusing ctz.
+ */
+ first = MASK_LEN_TO_IDX(start);
+ first_mod = MASK_LEN_TO_MOD(start);
+ /* we're going backwards, so mask must start from the top */
+ ignore_msk = first_mod == MASK_ALIGN - 1 ?
+ -1ULL : /* prevent overflow */
+ ~(-1ULL << (first_mod + 1));
+
+ /* go backwards, include zero */
+ msk_idx = first;
+ do {
+ uint64_t cur_msk, lookbehind_msk;
+ unsigned int run_start, run_end, ctz, left;
+ bool found = false;
+ /*
+ * The process of getting n consecutive bits from the top for
+ * arbitrary n is a bit involved, but here it is in a nutshell:
+ *
+ * 1. let n be the number of consecutive bits we're looking for
+ * 2. check if n can fit in one mask, and if so, do n-1
+ * lshift-ands to see if there is an appropriate run inside
+ * our current mask
+ * 2a. if we found a run, bail out early
+ * 2b. if we didn't find a run, proceed
+ * 3. invert the mask and count trailing zeroes (that is, count
+ * how many consecutive set bits we had starting from the
+ * start of current mask) as k
+ * 3a. if k is 0, continue to next mask
+ * 3b. if k is not 0, we have a potential run
+ * 4. to satisfy our requirements, next mask must have n-k
+ * consecutive set bits at the end, so we will do (n-k-1)
+ * lshift-ands and check if last bit is set.
+ *
+ * Step 4 will need to be repeated if (n-k) > MASK_ALIGN until
+ * we either run out of masks, lose the run, or find what we
+ * were looking for.
+ */
+ cur_msk = msk->data[msk_idx];
+ left = n;
+
+ /* if we're looking for free spaces, invert the mask */
+ if (!used)
+ cur_msk = ~cur_msk;
+
+ /* if we have an ignore mask, ignore once */
+ if (ignore_msk) {
+ cur_msk &= ignore_msk;
+ ignore_msk = 0;
+ }
+
+ /* if n can fit in within a single mask, do a search */
+ if (n <= MASK_ALIGN) {
+ uint64_t tmp_msk = cur_msk;
+ unsigned int s_idx;
+ for (s_idx = 0; s_idx < n - 1; s_idx++)
+ tmp_msk &= tmp_msk << 1ULL;
+ /* we found what we were looking for */
+ if (tmp_msk != 0) {
+ /* clz will give us offset from end of mask, and
+ * we only get the end of our run, not start,
+ * so adjust result to point to where start
+ * would have been.
+ */
+ run_start = MASK_ALIGN -
+ __builtin_clzll(tmp_msk) - n;
+ return MASK_GET_IDX(msk_idx, run_start);
+ }
+ }
+
+ /*
+ * we didn't find our run within the mask, or n > MASK_ALIGN,
+ * so we're going for plan B.
+ */
+
+ /* count trailing zeroes on inverted mask */
+ if (~cur_msk == 0)
+ ctz = sizeof(cur_msk) * 8;
+ else
+ ctz = __builtin_ctzll(~cur_msk);
+
+ /* if there aren't any runs at the start either, just
+ * continue
+ */
+ if (ctz == 0)
+ continue;
+
+ /* we have a partial run at the start, so try looking behind */
+ run_end = MASK_GET_IDX(msk_idx, ctz);
+ left -= ctz;
+
+ /* go backwards, include zero */
+ lookbehind_idx = msk_idx - 1;
+
+ /* we can't lookbehind as we've run out of masks, so stop */
+ if (msk_idx == 0)
+ break;
+
+ do {
+ const uint64_t last_bit = 1ULL << (MASK_ALIGN - 1);
+ unsigned int s_idx, need;
+
+ lookbehind_msk = msk->data[lookbehind_idx];
+
+ /* if we're looking for free space, invert the mask */
+ if (!used)
+ lookbehind_msk = ~lookbehind_msk;
+
+ /* figure out how many consecutive bits we need here */
+ need = RTE_MIN(left, MASK_ALIGN);
+
+ for (s_idx = 0; s_idx < need - 1; s_idx++)
+ lookbehind_msk &= lookbehind_msk << 1ULL;
+
+ /* if last bit is not set, we've lost the run */
+ if ((lookbehind_msk & last_bit) == 0) {
+ /*
+ * we've scanned this far, so we know there are
+ * no runs in the space we've lookbehind-scanned
+ * as well, so skip that on next iteration.
+ */
+ ignore_msk = -1ULL << need;
+ msk_idx = lookbehind_idx;
+ break;
+ }
+
+ left -= need;
+
+ /* check if we've found what we were looking for */
+ if (left == 0) {
+ found = true;
+ break;
+ }
+ } while ((lookbehind_idx--) != 0); /* decrement after check to
+ * include zero
+ */
+
+ /* we didn't find anything, so continue */
+ if (!found)
+ continue;
+
+ /* we've found what we were looking for, but we only know where
+ * the run ended, so calculate start position.
+ */
+ return run_end - n;
+ } while (msk_idx-- != 0); /* decrement after check to include zero */
+ /* we didn't find anything */
+ rte_errno = used ? ENOENT : ENOSPC;
+ return -1;
+}
+
+static int
+find_prev(const struct rte_fbarray *arr, unsigned int start, bool used)
+{
+ const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+ arr->len);
+ unsigned int idx, first, first_mod;
+ uint64_t ignore_msk;
+
+ /*
+ * mask only has granularity of MASK_ALIGN, but start may not be aligned
+ * on that boundary, so construct a special mask to exclude anything we
+ * don't want to see to avoid confusing clz.
+ */
+ first = MASK_LEN_TO_IDX(start);
+ first_mod = MASK_LEN_TO_MOD(start);
+ /* we're going backwards, so mask must start from the top */
+ ignore_msk = first_mod == MASK_ALIGN - 1 ?
+ -1ULL : /* prevent overflow */
+ ~(-1ULL << (first_mod + 1));
+
+ /* go backwards, include zero */
+ idx = first;
+ do {
+ uint64_t cur = msk->data[idx];
+ int found;
+
+ /* if we're looking for free entries, invert mask */
+ if (!used)
+ cur = ~cur;
+
+ /* ignore everything before start on first iteration */
+ if (idx == first)
+ cur &= ignore_msk;
+
+ /* check if we have any entries */
+ if (cur == 0)
+ continue;
+
+ /*
+ * find last set bit - that will correspond to whatever it is
+ * that we're looking for. we're counting trailing zeroes, thus
+ * the value we get is counted from end of mask, so calculate
+ * position from start of mask.
+ */
+ found = MASK_ALIGN - __builtin_clzll(cur) - 1;
+
+ return MASK_GET_IDX(idx, found);
+ } while (idx-- != 0); /* decrement after check to include zero*/
+
+ /* we didn't find anything */
+ rte_errno = used ? ENOENT : ENOSPC;
+ return -1;
+}
+
+static int
+find_rev_contig(const struct rte_fbarray *arr, unsigned int start, bool used)
+{
+ const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+ arr->len);
+ unsigned int idx, first, first_mod;
+ unsigned int need_len, result = 0;
+
+ first = MASK_LEN_TO_IDX(start);
+ first_mod = MASK_LEN_TO_MOD(start);
+
+ /* go backwards, include zero */
+ idx = first;
+ do {
+ uint64_t cur = msk->data[idx];
+ unsigned int run_len;
+
+ need_len = MASK_ALIGN;
+
+ /* if we're looking for free entries, invert mask */
+ if (!used)
+ cur = ~cur;
+
+ /* ignore everything after start on first iteration */
+ if (idx == first) {
+ unsigned int end_len = MASK_ALIGN - first_mod - 1;
+ cur <<= end_len;
+ /* at the start, we don't need the full mask len */
+ need_len -= end_len;
+ }
+
+ /* we will be looking for zeroes, so invert the mask */
+ cur = ~cur;
+
+ /* if mask is zero, we have a complete run */
+ if (cur == 0)
+ goto endloop;
+
+ /*
+ * see where run ends, starting from the end.
+ */
+ run_len = __builtin_clzll(cur);
+
+ /* add however many zeroes we've had in the last run and quit */
+ if (run_len < need_len) {
+ result += run_len;
+ break;
+ }
+endloop:
+ result += need_len;
+ } while (idx-- != 0); /* decrement after check to include zero */
+ return result;
+}
+
+static int
+set_used(struct rte_fbarray *arr, unsigned int idx, bool used)
+{
+ struct used_mask *msk;
+ uint64_t msk_bit = 1ULL << MASK_LEN_TO_MOD(idx);
+ unsigned int msk_idx = MASK_LEN_TO_IDX(idx);
+ bool already_used;
+ int ret = -1;
+
+ if (arr == NULL || idx >= arr->len) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+ msk = get_used_mask(arr->data, arr->elt_sz, arr->len);
+ ret = 0;
+
+ /* prevent array from changing under us */
+ rte_rwlock_write_lock(&arr->rwlock);
+
+ already_used = (msk->data[msk_idx] & msk_bit) != 0;
+
+ /* nothing to be done */
+ if (used == already_used)
+ goto out;
+
+ if (used) {
+ msk->data[msk_idx] |= msk_bit;
+ arr->count++;
+ } else {
+ msk->data[msk_idx] &= ~msk_bit;
+ arr->count--;
+ }
+out:
+ rte_rwlock_write_unlock(&arr->rwlock);
+
+ return ret;
+}
+
+static int
+fully_validate(const char *name, unsigned int elt_sz, unsigned int len)
+{
+ if (name == NULL || elt_sz == 0 || len == 0 || len > INT_MAX) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ if (strnlen(name, RTE_FBARRAY_NAME_LEN) == RTE_FBARRAY_NAME_LEN) {
+ rte_errno = ENAMETOOLONG;
+ return -1;
+ }
+ return 0;
+}
+
+int __rte_experimental
+rte_fbarray_init(struct rte_fbarray *arr, const char *name, unsigned int len,
+ unsigned int elt_sz)
+{
+ size_t page_sz, mmap_len;
+ char path[PATH_MAX];
+ struct used_mask *msk;
+ void *data = NULL;
+ int fd = -1;
+ BOOL retval;
+ HANDLE hWinFileHandle;
+
+ if (arr == NULL) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ if (fully_validate(name, elt_sz, len))
+ return -1;
+
+ page_sz = sysconf(_SC_PAGESIZE);
+ if (page_sz == (size_t)-1)
+ goto fail;
+
+ /* calculate our memory limits */
+ mmap_len = calc_data_size(page_sz, elt_sz, len);
+
+ if (internal_config.no_shconf) {
+ /* remap virtual area as writable */
+ void *new_data = mmap(data, mmap_len, PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (new_data == MAP_FAILED) {
+ RTE_LOG(DEBUG, EAL, "%s(): couldn't remap anonymous memory: %s\n",
+ __func__, strerror(errno));
+ goto fail;
+ }
+ } else {
+ eal_get_fbarray_path(path, sizeof(path), name);
+
+ /*
+ * Each fbarray is unique to process namespace, i.e. the
+ * filename depends on process prefix. Try to take out a lock
+ * and see if we succeed. If we don't, someone else is using it
+ * already.
+ */
+ fd = _open(path, O_CREAT | O_RDWR | _O_TRUNC, _S_IREAD | _S_IWRITE);
+ if (fd < 0) {
+ RTE_LOG(DEBUG, EAL, "%s(): couldn't open %s: %s\n",
+ __func__, path, strerror(errno));
+ rte_errno = errno;
+ goto fail;
+ }
+
+ /* Lock file for exclusive access */
+ OVERLAPPED sOverlapped = { 0 };
+ sOverlapped.Offset = 0;
+ sOverlapped.OffsetHigh = 0;
+
+ hWinFileHandle = (HANDLE)_get_osfhandle(fd);
+ retval = LockFileEx(hWinFileHandle,
+ LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0,
+ mmap_len, 0, &sOverlapped);
+ if (!retval) {
+ RTE_LOG(DEBUG, EAL, "%s(): couldn't lock %s: %s\n",
+ __func__, path, strerror(errno));
+ rte_errno = EBUSY;
+ goto fail;
+ }
+
+
+ /* take out a non-exclusive lock, so that other processes could
+ * still attach to it, but no other process could reinitialize
+ * it.
+ */
+ retval = UnlockFileEx(hWinFileHandle, 0, mmap_len, 0, &sOverlapped);
+ if (!retval) {
+ RTE_LOG(DEBUG, EAL, "%s(): couldn't unlock %s: %s\n",
+ __func__, path, strerror(errno));
+ rte_errno = EBUSY;
+ goto fail;
+ }else {
+ retval = LockFileEx(hWinFileHandle,
+ LOCKFILE_FAIL_IMMEDIATELY, 0,
+ mmap_len, 0, &sOverlapped);
+ if(!retval){
+ rte_errno = errno;
+ goto fail;
+ }
+ }
+ data = resize_and_map(fd, mmap_len);
+ if (data == NULL)
+ goto fail;
+
+ /* we've mmap'ed the file, we can now close the fd */
+ _close(fd);
+ }
+
+ /* initialize the data */
+ memset(data, 0, mmap_len);
+
+ /* populate data structure */
+ strlcpy(arr->name, name, sizeof(arr->name));
+ arr->data = data;
+ arr->len = len;
+ arr->elt_sz = elt_sz;
+ arr->count = 0;
+
+ msk = get_used_mask(data, elt_sz, len);
+ msk->n_masks = MASK_LEN_TO_IDX(RTE_ALIGN_CEIL(len, MASK_ALIGN));
+
+ rte_rwlock_init(&arr->rwlock);
+
+ return 0;
+fail:
+ if (data)
+ munmap(data, mmap_len);
+ if (fd >= 0)
+ _close(fd);
+ return -1;
+}
+
+int __rte_experimental
+rte_fbarray_attach(struct rte_fbarray *arr)
+{
+ size_t page_sz, mmap_len;
+ char path[PATH_MAX];
+ void *data = NULL;
+ int fd = -1;
+ BOOL retval;
+
+ if (arr == NULL) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * we don't need to synchronize attach as two values we need (element
+ * size and array length) are constant for the duration of life of
+ * the array, so the parts we care about will not race.
+ */
+
+ if (fully_validate(arr->name, arr->elt_sz, arr->len))
+ return -1;
+
+ page_sz = sysconf(_SC_PAGESIZE);
+ if (page_sz == (size_t)-1)
+ goto fail;
+
+ mmap_len = calc_data_size(page_sz, arr->elt_sz, arr->len);
+
+ data = eal_get_virtual_area(arr->data, &mmap_len, page_sz, 0, 0);
+ if (data == NULL)
+ goto fail;
+
+ eal_get_fbarray_path(path, sizeof(path), arr->name);
+
+ fd = open(path, O_RDWR);
+ if (fd < 0) {
+ rte_errno = errno;
+ goto fail;
+ }
+
+ /* lock the file, to let others know we're using it */
+ /* Lock file for exclusive access */
+ OVERLAPPED sOverlapped = { 0 };
+ sOverlapped.Offset = 0;
+ sOverlapped.OffsetHigh = 0;
+
+ HANDLE hWinFileHandle = (HANDLE)_get_osfhandle(fd);
+ retval = LockFileEx(hWinFileHandle, LOCKFILE_FAIL_IMMEDIATELY, 0, mmap_len, 0, &sOverlapped);
+ if (!retval) {
+ rte_errno = errno;
+ goto fail;
+ }
+ data = resize_and_map(fd, mmap_len);
+ if (data == NULL)
+ goto fail;
+
+ close(fd);
+
+ /* we're done */
+
+ return 0;
+fail:
+ if (data)
+ munmap(data, mmap_len);
+ if (fd >= 0)
+ close(fd);
+ return -1;
+}
+
+int __rte_experimental
+rte_fbarray_detach(struct rte_fbarray *arr)
+{
+ if (arr == NULL) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * we don't need to synchronize detach as two values we need (element
+ * size and total capacity) are constant for the duration of life of
+ * the array, so the parts we care about will not race. if the user is
+ * detaching while doing something else in the same process, we can't
+ * really do anything about it, things will blow up either way.
+ */
+
+ size_t page_sz = sysconf(_SC_PAGESIZE);
+
+ if (page_sz == (size_t)-1)
+ return -1;
+
+ /* this may already be unmapped (e.g. repeated call from previously
+ * failed destroy(), but this is on user, we can't (easily) know if this
+ * is still mapped.
+ */
+ munmap(arr->data, calc_data_size(page_sz, arr->elt_sz, arr->len));
+
+ return 0;
+}
+
+int __rte_experimental
+rte_fbarray_destroy(struct rte_fbarray *arr)
+{
+ int fd, ret;
+ char path[PATH_MAX];
+ BOOL retval;
+
+ ret = rte_fbarray_detach(arr);
+ if (ret)
+ return ret;
+
+ /* try deleting the file */
+ eal_get_fbarray_path(path, sizeof(path), arr->name);
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ RTE_LOG(ERR, EAL, "Could not open fbarray file: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ OVERLAPPED sOverLapped = { 0 };
+ sOverLapped.Offset = 0;
+ sOverLapped.OffsetHigh = 0;
+
+ HANDLE hWinFileHandle = (HANDLE)_get_osfhandle(fd);
+
+ retval = LockFileEx(hWinFileHandle, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, sizeof(*arr), 0, &sOverLapped);
+
+ if (!retval) {
+ RTE_LOG(DEBUG, EAL, "Cannot destroy fbarray - another process is using it\n");
+ rte_errno = EBUSY;
+ ret = -1;
+ } else {
+ ret = 0;
+ unlink(path);
+ memset(arr, 0, sizeof(*arr));
+ }
+ close(fd);
+
+ return ret;
+}
+
+void * __rte_experimental
+rte_fbarray_get(const struct rte_fbarray *arr, unsigned int idx)
+{
+ void *ret = NULL;
+ if (arr == NULL) {
+ rte_errno = EINVAL;
+ return NULL;
+ }
+
+ if (idx >= arr->len) {
+ rte_errno = EINVAL;
+ return NULL;
+ }
+
+ ret = RTE_PTR_ADD(arr->data, idx * arr->elt_sz);
+
+ return ret;
+}
+
+int __rte_experimental
+rte_fbarray_set_used(struct rte_fbarray *arr, unsigned int idx)
+{
+ return set_used(arr, idx, true);
+}
+
+int __rte_experimental
+rte_fbarray_set_free(struct rte_fbarray *arr, unsigned int idx)
+{
+ return set_used(arr, idx, false);
+}
+
+int __rte_experimental
+rte_fbarray_is_used(struct rte_fbarray *arr, unsigned int idx)
+{
+ struct used_mask *msk;
+ int msk_idx;
+ uint64_t msk_bit;
+ int ret = -1;
+
+ if (arr == NULL || idx >= arr->len) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ /* prevent array from changing under us */
+ rte_rwlock_read_lock(&arr->rwlock);
+
+ msk = get_used_mask(arr->data, arr->elt_sz, arr->len);
+ msk_idx = MASK_LEN_TO_IDX(idx);
+ msk_bit = 1ULL << MASK_LEN_TO_MOD(idx);
+
+ ret = (msk->data[msk_idx] & msk_bit) != 0;
+
+ rte_rwlock_read_unlock(&arr->rwlock);
+
+ return ret;
+}
+
+static int
+fbarray_find(struct rte_fbarray *arr, unsigned int start, bool next, bool used)
+{
+ int ret = -1;
+
+ if (arr == NULL || start >= arr->len) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ /* prevent array from changing under us */
+ rte_rwlock_read_lock(&arr->rwlock);
+
+ /* cheap checks to prevent doing useless work */
+ if (!used) {
+ if (arr->len == arr->count) {
+ rte_errno = ENOSPC;
+ goto out;
+ }
+ if (arr->count == 0) {
+ ret = start;
+ goto out;
+ }
+ } else {
+ if (arr->count == 0) {
+ rte_errno = ENOENT;
+ goto out;
+ }
+ if (arr->len == arr->count) {
+ ret = start;
+ goto out;
+ }
+ }
+ if (next)
+ ret = find_next(arr, start, used);
+ else
+ ret = find_prev(arr, start, used);
+out:
+ rte_rwlock_read_unlock(&arr->rwlock);
+ return ret;
+}
+
+int __rte_experimental
+rte_fbarray_find_next_free(struct rte_fbarray *arr, unsigned int start)
+{
+ return fbarray_find(arr, start, true, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_next_used(struct rte_fbarray *arr, unsigned int start)
+{
+ return fbarray_find(arr, start, true, true);
+}
+
+int __rte_experimental
+rte_fbarray_find_prev_free(struct rte_fbarray *arr, unsigned int start)
+{
+ return fbarray_find(arr, start, false, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_prev_used(struct rte_fbarray *arr, unsigned int start)
+{
+ return fbarray_find(arr, start, false, true);
+}
+
+static int
+fbarray_find_n(struct rte_fbarray *arr, unsigned int start, unsigned int n,
+ bool next, bool used)
+{
+ int ret = -1;
+
+ if (arr == NULL || start >= arr->len || n > arr->len || n == 0) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+ if (next && (arr->len - start) < n) {
+ rte_errno = used ? ENOENT : ENOSPC;
+ return -1;
+ }
+ if (!next && start < (n - 1)) {
+ rte_errno = used ? ENOENT : ENOSPC;
+ return -1;
+ }
+
+ /* prevent array from changing under us */
+ rte_rwlock_read_lock(&arr->rwlock);
+
+ /* cheap checks to prevent doing useless work */
+ if (!used) {
+ if (arr->len == arr->count || arr->len - arr->count < n) {
+ rte_errno = ENOSPC;
+ goto out;
+ }
+ if (arr->count == 0) {
+ ret = next ? start : start - n + 1;
+ goto out;
+ }
+ } else {
+ if (arr->count < n) {
+ rte_errno = ENOENT;
+ goto out;
+ }
+ if (arr->count == arr->len) {
+ ret = next ? start : start - n + 1;
+ goto out;
+ }
+ }
+
+ if (next)
+ ret = find_next_n(arr, start, n, used);
+ else
+ ret = find_prev_n(arr, start, n, used);
+out:
+ rte_rwlock_read_unlock(&arr->rwlock);
+ return ret;
+}
+
+int __rte_experimental
+rte_fbarray_find_next_n_free(struct rte_fbarray *arr, unsigned int start,
+ unsigned int n)
+{
+ return fbarray_find_n(arr, start, n, true, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_next_n_used(struct rte_fbarray *arr, unsigned int start,
+ unsigned int n)
+{
+ return fbarray_find_n(arr, start, n, true, true);
+}
+
+int __rte_experimental
+rte_fbarray_find_prev_n_free(struct rte_fbarray *arr, unsigned int start,
+ unsigned int n)
+{
+ return fbarray_find_n(arr, start, n, false, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_prev_n_used(struct rte_fbarray *arr, unsigned int start,
+ unsigned int n)
+{
+ return fbarray_find_n(arr, start, n, false, true);
+}
+
+static int
+fbarray_find_contig(struct rte_fbarray *arr, unsigned int start, bool next,
+ bool used)
+{
+ int ret = -1;
+
+ if (arr == NULL || start >= arr->len) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ /* prevent array from changing under us */
+ rte_rwlock_read_lock(&arr->rwlock);
+
+ /* cheap checks to prevent doing useless work */
+ if (used) {
+ if (arr->count == 0) {
+ ret = 0;
+ goto out;
+ }
+ if (next && arr->count == arr->len) {
+ ret = arr->len - start;
+ goto out;
+ }
+ if (!next && arr->count == arr->len) {
+ ret = start + 1;
+ goto out;
+ }
+ } else {
+ if (arr->len == arr->count) {
+ ret = 0;
+ goto out;
+ }
+ if (next && arr->count == 0) {
+ ret = arr->len - start;
+ goto out;
+ }
+ if (!next && arr->count == 0) {
+ ret = start + 1;
+ goto out;
+ }
+ }
+
+ if (next)
+ ret = find_contig(arr, start, used);
+ else
+ ret = find_rev_contig(arr, start, used);
+out:
+ rte_rwlock_read_unlock(&arr->rwlock);
+ return ret;
+}
+
+int __rte_experimental
+rte_fbarray_find_contig_free(struct rte_fbarray *arr, unsigned int start)
+{
+ return fbarray_find_contig(arr, start, true, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_contig_used(struct rte_fbarray *arr, unsigned int start)
+{
+ return fbarray_find_contig(arr, start, true, true);
+}
+
+int __rte_experimental
+rte_fbarray_find_rev_contig_free(struct rte_fbarray *arr, unsigned int start)
+{
+ return fbarray_find_contig(arr, start, false, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_rev_contig_used(struct rte_fbarray *arr, unsigned int start)
+{
+ return fbarray_find_contig(arr, start, false, true);
+}
+
+int __rte_experimental
+rte_fbarray_find_idx(const struct rte_fbarray *arr, const void *elt)
+{
+ void *end;
+ int ret = -1;
+
+ /*
+ * no need to synchronize as it doesn't matter if underlying data
+ * changes - we're doing pointer arithmetic here.
+ */
+
+ if (arr == NULL || elt == NULL) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+ end = RTE_PTR_ADD(arr->data, arr->elt_sz * arr->len);
+ if (elt < arr->data || elt >= end) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ ret = RTE_PTR_DIFF(elt, arr->data) / arr->elt_sz;
+
+ return ret;
+}
+
+void __rte_experimental
+rte_fbarray_dump_metadata(struct rte_fbarray *arr, FILE *f)
+{
+ struct used_mask *msk;
+ unsigned int i;
+
+ if (arr == NULL || f == NULL) {
+ rte_errno = EINVAL;
+ return;
+ }
+
+ if (fully_validate(arr->name, arr->elt_sz, arr->len)) {
+ fprintf(f, "Invalid file-backed array\n");
+ goto out;
+ }
+
+ /* prevent array from changing under us */
+ rte_rwlock_read_lock(&arr->rwlock);
+
+ fprintf(f, "File-backed array: %s\n", arr->name);
+ fprintf(f, "size: %i occupied: %i elt_sz: %i\n",
+ arr->len, arr->count, arr->elt_sz);
+
+ msk = get_used_mask(arr->data, arr->elt_sz, arr->len);
+
+ for (i = 0; i < msk->n_masks; i++)
+ fprintf(f, "msk idx %i: 0x%016" PRIx64 "\n", i, msk->data[i]);
+out:
+ rte_rwlock_read_unlock(&arr->rwlock);
+}
diff --git a/lib/librte_eal/windows/eal/eal_filesystem.h b/lib/librte_eal/windows/eal/eal_filesystem.h
new file mode 100644
index 000000000..2bfb8b9a1
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_filesystem.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+/**
+ * @file
+ * Stores functions and path defines for files and directories
+ * on the filesystem for Windows, that are used by the Windows EAL.
+ */
+
+#ifndef EAL_FILESYSTEM_H
+#define EAL_FILESYSTEM_H
+
+#include <rte_windows.h>
+#include "eal_internal_cfg.h"
+
+
+ /* sets up platform-specific runtime data dir */
+int
+eal_create_runtime_dir(void);
+
+/* returns runtime dir */
+const char *
+eal_get_runtime_dir(void);
+
+ /* define the default filename prefix for the %s values below */
+#define HUGEFILE_PREFIX_DEFAULT "rte"
+
+/* Path of rte config file */
+#define RUNTIME_CONFIG_FMT "%s\\%s.config"
+
+static inline const char *
+eal_runtime_config_path(void)
+{
+ static char buffer[PATH_MAX]; /* static so auto-zeroed */
+ char Directory[PATH_MAX];
+
+ GetTempPathA(sizeof(Directory), Directory);
+ snprintf(buffer, sizeof(buffer)-1, RUNTIME_CONFIG_FMT, Directory, internal_config.hugefile_prefix);
+
+ return buffer;
+}
+
+/* Path of file backed array*/
+#define FBARRAY_NAME_FMT "%s\\fbarray_%s"
+
+static inline const char *
+eal_get_fbarray_path(char *buffer, size_t buflen, const char *name) {
+ snprintf(buffer, buflen, FBARRAY_NAME_FMT, eal_get_runtime_dir(), name);
+ return buffer;
+}
+
+/** Path of primary/secondary communication unix socket file. */
+#define MP_SOCKET_FNAME "mp_socket"
+
+static inline const char *
+eal_mp_socket_path(void)
+{
+ static char buffer[PATH_MAX]; /* static so auto-zeroed */
+
+ snprintf(buffer, sizeof(buffer) - 1, "%s/%s", eal_get_runtime_dir(),
+ MP_SOCKET_FNAME);
+ return buffer;
+}
+
+/* Path of hugepage info file */
+#define HUGEPAGE_INFO_FMT "%s\\.%s_hugepage_info"
+
+static inline const char *
+eal_hugepage_info_path(void)
+{
+ static char buffer[PATH_MAX]; /* static so auto-zeroed */
+ TCHAR Directory[PATH_MAX];
+
+ GetSystemDirectory(Directory, sizeof(Directory));
+ snprintf(buffer, sizeof(buffer)-1, HUGEPAGE_INFO_FMT, Directory, internal_config.hugefile_prefix);
+ return buffer;
+}
+
+/* String format for hugepage map files */
+#define HUGEFILE_FMT "%s/%smap_%d"
+#define TEMP_HUGEFILE_FMT "%s/%smap_temp_%d"
+
+static inline const char *
+eal_get_hugefile_path(char *buffer, size_t buflen, const char *hugedir, int f_id)
+{
+ snprintf(buffer, buflen, HUGEFILE_FMT, hugedir, internal_config.hugefile_prefix, f_id);
+ buffer[buflen - 1] = '\0';
+ return buffer;
+}
+
+
+/** Function to read a single numeric value from a file on the filesystem.
+ * Used to read information from files on /sys */
+int eal_parse_sysfs_value(const char *filename, unsigned long *val);
+
+#endif /* EAL_FILESYSTEM_H */
diff --git a/lib/librte_eal/windows/eal/eal_hugepage_info.c b/lib/librte_eal/windows/eal/eal_hugepage_info.c
new file mode 100644
index 000000000..d417da6da
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_hugepage_info.c
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_log.h>
+#include "eal_internal_cfg.h"
+#include "eal_hugepages.h"
+
+
+/*
+ * Need to complete hugepage support on Windows
+ */
+int
+eal_hugepage_info_init(void)
+{
+ internal_config.num_hugepage_sizes = 1;
+ internal_config.hugepage_info[0].hugepage_sz = (uint64_t)GetLargePageMinimum();
+
+ return 0;
+}
diff --git a/lib/librte_eal/windows/eal/eal_interrupts.c b/lib/librte_eal/windows/eal/eal_interrupts.c
new file mode 100644
index 000000000..6be47d14e
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_interrupts.c
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_common.h>
+#include <rte_interrupts.h>
+#include "eal_private.h"
+
+int
+rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
+ rte_intr_callback_fn cb,
+ void *cb_arg)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
+ rte_intr_callback_fn cb_fn,
+ void *cb_arg)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_intr_enable(const struct rte_intr_handle *intr_handle)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_intr_disable(const struct rte_intr_handle *intr_handle)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_eal_intr_init(void)
+{
+ return 0;
+}
+
+int
+rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
+ int epfd, int op, unsigned int vec, void *data)
+{
+ RTE_SET_USED(intr_handle);
+ RTE_SET_USED(epfd);
+ RTE_SET_USED(op);
+ RTE_SET_USED(vec);
+ RTE_SET_USED(data);
+
+ return -ENOTSUP;
+}
+
+int
+rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
+{
+ RTE_SET_USED(intr_handle);
+ RTE_SET_USED(nb_efd);
+
+ return 0;
+}
+
+void
+rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
+{
+ RTE_SET_USED(intr_handle);
+}
+
+int
+rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
+{
+ RTE_SET_USED(intr_handle);
+ return 0;
+}
+
+int
+rte_intr_allow_others(struct rte_intr_handle *intr_handle)
+{
+ RTE_SET_USED(intr_handle);
+ return 1;
+}
+
+int
+rte_intr_cap_multiple(struct rte_intr_handle *intr_handle)
+{
+ RTE_SET_USED(intr_handle);
+ return 0;
+}
diff --git a/lib/librte_eal/windows/eal/eal_lcore.c b/lib/librte_eal/windows/eal/eal_lcore.c
new file mode 100644
index 000000000..e8222e896
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_lcore.c
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_windows.h>
+
+/* global data structure that contains the CPU map */
+static struct _win_cpu_map {
+ unsigned numTotalProcessors;
+ unsigned numProcessorSockets;
+ unsigned numProcessorCores;
+ unsigned reserved;
+ struct _win_lcore_map {
+ uint8_t socketid;
+ uint8_t coreid;
+ } win_lcore_map[RTE_MAX_LCORE];
+} win_cpu_map = { 0 };
+
+
+void eal_create_cpu_map()
+{
+ win_cpu_map.numTotalProcessors = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
+
+ LOGICAL_PROCESSOR_RELATIONSHIP lprocRel;
+ DWORD lprocInfoSize = 0;
+ BOOL bHyperThreadingEnabled = FALSE;
+
+ /* First get the processor package information */
+ lprocRel = RelationProcessorPackage;
+ /* Determine the size of buffer we need (pass NULL) */
+ GetLogicalProcessorInformationEx(lprocRel, NULL, &lprocInfoSize);
+ win_cpu_map.numProcessorSockets = lprocInfoSize / 48;
+
+ lprocInfoSize = 0;
+ /* Next get the processor core information */
+ lprocRel = RelationProcessorCore;
+ GetLogicalProcessorInformationEx(lprocRel, NULL, &lprocInfoSize);
+ win_cpu_map.numProcessorCores = lprocInfoSize / 48;
+
+ if (win_cpu_map.numTotalProcessors > win_cpu_map.numProcessorCores)
+ bHyperThreadingEnabled = TRUE;
+
+ /* Distribute the socket and core ids appropriately across the logical cores */
+ /* For now, split the cores equally across the sockets - might need to revisit this later */
+ unsigned lcore = 0;
+ for (unsigned socket=0; socket < win_cpu_map.numProcessorSockets; ++socket) {
+ for (unsigned core = 0; core < (win_cpu_map.numProcessorCores / win_cpu_map.numProcessorSockets); ++core) {
+ win_cpu_map.win_lcore_map[lcore].socketid = socket;
+ win_cpu_map.win_lcore_map[lcore].coreid = core;
+
+ lcore++;
+
+ if (bHyperThreadingEnabled) {
+ win_cpu_map.win_lcore_map[lcore].socketid = socket;
+ win_cpu_map.win_lcore_map[lcore].coreid = core;
+ lcore++;
+ }
+ }
+ }
+
+ return;
+}
+
+/* Check if a cpu is present by the presence of the cpu information for it */
+int
+eal_cpu_detected(unsigned lcore_id)
+{
+ return (lcore_id < win_cpu_map.numTotalProcessors);
+}
+
+/* Get CPU socket id (NUMA node) for a logical core */
+unsigned
+eal_cpu_socket_id(unsigned lcore_id)
+{
+ return win_cpu_map.win_lcore_map[lcore_id].socketid;
+}
+
+/* Get the cpu core id value */
+unsigned
+eal_cpu_core_id(unsigned lcore_id)
+{
+ return win_cpu_map.win_lcore_map[lcore_id].coreid;
+}
diff --git a/lib/librte_eal/windows/eal/eal_log.c b/lib/librte_eal/windows/eal/eal_log.c
new file mode 100644
index 000000000..0f5ae54a9
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_log.c
@@ -0,0 +1,415 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_per_lcore.h>
+
+#include "eal_private.h"
+
+/* global log structure */
+struct rte_logs rte_logs = {
+ .type = ~0,
+ .level = RTE_LOG_DEBUG,
+ .file = NULL,
+};
+
+struct rte_eal_opt_loglevel {
+ /** Next list entry */
+ TAILQ_ENTRY(rte_eal_opt_loglevel) next;
+ char *pattern;
+ /** Log level value obtained from the option */
+ uint32_t level;
+};
+
+TAILQ_HEAD(rte_eal_opt_loglevel_list, rte_eal_opt_loglevel);
+
+/** List of valid EAL log level options */
+static struct rte_eal_opt_loglevel_list opt_loglevel_list =
+TAILQ_HEAD_INITIALIZER(opt_loglevel_list);
+
+/* Stream to use for logging if rte_logs.file is NULL */
+static FILE *default_log_stream;
+
+/**
+* This global structure stores some informations about the message
+* that is currently being processed by one lcore
+*/
+struct log_cur_msg {
+ uint32_t loglevel; /**< log level - see rte_log.h */
+ uint32_t logtype; /**< log type - see rte_log.h */
+};
+
+struct rte_log_dynamic_type {
+ const char *name;
+ uint32_t loglevel;
+};
+
+/* per core log */
+static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg);
+
+/* default logs */
+
+/* Change the stream that will be used by logging system */
+int
+rte_openlog_stream(FILE *f)
+{
+ rte_logs.file = f;
+ return 0;
+}
+
+/* Set global log level */
+void
+rte_log_set_global_level(uint32_t level)
+{
+ rte_logs.level = (uint32_t)level;
+}
+
+/* Get global log level */
+uint32_t
+rte_log_get_global_level(void)
+{
+ return rte_logs.level;
+}
+
+int
+rte_log_get_level(uint32_t type)
+{
+ if (type >= rte_logs.dynamic_types_len)
+ return -1;
+
+ return rte_logs.dynamic_types[type].loglevel;
+}
+
+int
+rte_log_set_level(uint32_t type, uint32_t level)
+{
+ if (type >= rte_logs.dynamic_types_len)
+ return -1;
+ if (level > RTE_LOG_DEBUG)
+ return -1;
+
+ rte_logs.dynamic_types[type].loglevel = level;
+
+ return 0;
+}
+
+/* set log level by regular expression */
+int
+rte_log_set_level_regexp(const char *regex, uint32_t level)
+{
+ /* Not implemented in Windows */
+ return 0;
+}
+
+/*
+* Save the type string and the loglevel for later dynamic
+* logtypes which may register later.
+*/
+static int rte_log_save_level(int priority,
+ const char *regex, const char *pattern)
+{
+ /* Not implemented in Windows */
+ return 0;
+}
+
+int rte_log_save_regexp(const char *regex, int tmp)
+{
+ return rte_log_save_level(tmp, regex, NULL);
+}
+
+/* set log level based on glob (file match) pattern */
+int
+rte_log_set_level_pattern(const char *pattern, uint32_t level)
+{
+ size_t i;
+
+ if (level > RTE_LOG_DEBUG)
+ return -1;
+
+ for (i = 0; i < rte_logs.dynamic_types_len; i++) {
+ if (rte_logs.dynamic_types[i].name == NULL)
+ continue;
+ }
+
+ return 0;
+}
+
+int rte_log_save_pattern(const char *pattern, int priority)
+{
+ return rte_log_save_level(priority, NULL, pattern);
+}
+
+/* get the current loglevel for the message being processed */
+int rte_log_cur_msg_loglevel(void)
+{
+ return RTE_PER_LCORE(log_cur_msg).loglevel;
+}
+
+/* get the current logtype for the message being processed */
+int rte_log_cur_msg_logtype(void)
+{
+ return RTE_PER_LCORE(log_cur_msg).logtype;
+}
+
+static int
+rte_log_lookup(const char *name)
+{
+ size_t i;
+
+ for (i = 0; i < rte_logs.dynamic_types_len; i++) {
+ if (rte_logs.dynamic_types[i].name == NULL)
+ continue;
+ if (strcmp(name, rte_logs.dynamic_types[i].name) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+/* register an extended log type, assuming table is large enough, and id
+* is not yet registered.
+*/
+static int
+__rte_log_register(const char *name, int id)
+{
+ char *dup_name = strdup(name);
+
+ if (dup_name == NULL)
+ return -ENOMEM;
+
+ rte_logs.dynamic_types[id].name = dup_name;
+ rte_logs.dynamic_types[id].loglevel = RTE_LOG_DEBUG/*RTE_LOG_INFO*/;
+
+ return id;
+}
+
+/* register an extended log type */
+int
+rte_log_register(const char *name)
+{
+ struct rte_log_dynamic_type *new_dynamic_types;
+ int id, ret;
+
+ id = rte_log_lookup(name);
+ if (id >= 0)
+ return id;
+
+ new_dynamic_types = realloc(rte_logs.dynamic_types,
+ sizeof(struct rte_log_dynamic_type) *
+ (rte_logs.dynamic_types_len + 1));
+ if (new_dynamic_types == NULL)
+ return -ENOMEM;
+ rte_logs.dynamic_types = new_dynamic_types;
+
+ ret = __rte_log_register(name, rte_logs.dynamic_types_len);
+ if (ret < 0)
+ return ret;
+
+ rte_logs.dynamic_types_len++;
+
+ return ret;
+}
+
+/* Register an extended log type and try to pick its level from EAL options */
+int __rte_experimental
+rte_log_register_type_and_pick_level(const char *name, uint32_t level_def)
+{
+ struct rte_eal_opt_loglevel *opt_ll;
+ uint32_t level = level_def;
+ int type;
+
+ type = rte_log_register(name);
+ if (type < 0)
+ return type;
+
+ TAILQ_FOREACH(opt_ll, &opt_loglevel_list, next) {
+ if (opt_ll->level > RTE_LOG_DEBUG)
+ continue;
+ }
+ rte_logs.dynamic_types[type].loglevel = level;
+
+ return type;
+}
+
+struct logtype {
+ uint32_t log_id;
+ const char *logtype;
+};
+
+static const struct logtype logtype_strings[] = {
+ { RTE_LOGTYPE_EAL, "lib.eal" },
+{ RTE_LOGTYPE_MALLOC, "lib.malloc" },
+{ RTE_LOGTYPE_RING, "lib.ring" },
+{ RTE_LOGTYPE_MEMPOOL, "lib.mempool" },
+{ RTE_LOGTYPE_TIMER, "lib.timer" },
+{ RTE_LOGTYPE_PMD, "pmd" },
+{ RTE_LOGTYPE_HASH, "lib.hash" },
+{ RTE_LOGTYPE_LPM, "lib.lpm" },
+{ RTE_LOGTYPE_KNI, "lib.kni" },
+{ RTE_LOGTYPE_ACL, "lib.acl" },
+{ RTE_LOGTYPE_POWER, "lib.power" },
+{ RTE_LOGTYPE_METER, "lib.meter" },
+{ RTE_LOGTYPE_SCHED, "lib.sched" },
+{ RTE_LOGTYPE_PORT, "lib.port" },
+{ RTE_LOGTYPE_TABLE, "lib.table" },
+{ RTE_LOGTYPE_PIPELINE, "lib.pipeline" },
+{ RTE_LOGTYPE_MBUF, "lib.mbuf" },
+{ RTE_LOGTYPE_CRYPTODEV, "lib.cryptodev" },
+{ RTE_LOGTYPE_EFD, "lib.efd" },
+{ RTE_LOGTYPE_EVENTDEV, "lib.eventdev" },
+{ RTE_LOGTYPE_GSO, "lib.gso" },
+{ RTE_LOGTYPE_USER1, "user1" },
+{ RTE_LOGTYPE_USER2, "user2" },
+{ RTE_LOGTYPE_USER3, "user3" },
+{ RTE_LOGTYPE_USER4, "user4" },
+{ RTE_LOGTYPE_USER5, "user5" },
+{ RTE_LOGTYPE_USER6, "user6" },
+{ RTE_LOGTYPE_USER7, "user7" },
+{ RTE_LOGTYPE_USER8, "user8" }
+};
+
+
+void
+rte_log_init(void)
+{
+ uint32_t i;
+
+ rte_log_set_global_level(RTE_LOG_DEBUG);
+
+ rte_logs.dynamic_types = calloc(RTE_LOGTYPE_FIRST_EXT_ID,
+ sizeof(struct rte_log_dynamic_type));
+ if (rte_logs.dynamic_types == NULL)
+ return;
+
+ /* register legacy log types */
+ for (i = 0; i < RTE_DIM(logtype_strings); i++)
+ __rte_log_register(logtype_strings[i].logtype,
+ logtype_strings[i].log_id);
+
+ rte_logs.dynamic_types_len = RTE_LOGTYPE_FIRST_EXT_ID;
+}
+
+static const char *
+loglevel_to_string(uint32_t level)
+{
+ switch (level) {
+ case 0: return "disabled";
+ case RTE_LOG_EMERG: return "emerg";
+ case RTE_LOG_ALERT: return "alert";
+ case RTE_LOG_CRIT: return "critical";
+ case RTE_LOG_ERR: return "error";
+ case RTE_LOG_WARNING: return "warning";
+ case RTE_LOG_NOTICE: return "notice";
+ case RTE_LOG_INFO: return "info";
+ case RTE_LOG_DEBUG: return "debug";
+ default: return "unknown";
+ }
+}
+
+/* dump global level and registered log types */
+void
+rte_log_dump(FILE *f)
+{
+ size_t i;
+
+ fprintf(f, "global log level is %s\n",
+ loglevel_to_string(rte_log_get_global_level()));
+
+ for (i = 0; i < rte_logs.dynamic_types_len; i++) {
+ if (rte_logs.dynamic_types[i].name == NULL)
+ continue;
+ fprintf(f, "id %zu: %s, level is %s\n",
+ i, rte_logs.dynamic_types[i].name,
+ loglevel_to_string(rte_logs.dynamic_types[i].loglevel));
+ }
+}
+
+/*
+* Generates a log message The message will be sent in the stream
+* defined by the previous call to rte_openlog_stream().
+*/
+int
+rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)
+{
+ int ret;
+ FILE *f = rte_logs.file;
+ if (f == NULL) {
+ f = default_log_stream;
+ if (f == NULL) {
+ /*
+ * Grab the current value of stderr here, rather than
+ * just initializing default_log_stream to stderr. This
+ * ensures that we will always use the current value
+ * of stderr, even if the application closes and
+ * reopens it.
+ */
+ f = stderr;
+ }
+ }
+
+ if (level > rte_logs.level)
+ return 0;
+ if (logtype >= rte_logs.dynamic_types_len)
+ return -1;
+ if (level > rte_logs.dynamic_types[logtype].loglevel)
+ return 0;
+
+ /* save loglevel and logtype in a global per-lcore variable */
+ RTE_PER_LCORE(log_cur_msg).loglevel = level;
+ RTE_PER_LCORE(log_cur_msg).logtype = logtype;
+
+ ret = vfprintf(f, format, ap);
+ fflush(f);
+ return ret;
+}
+
+/*
+* Generates a log message The message will be sent in the stream
+* defined by the previous call to rte_openlog_stream().
+* No need to check level here, done by rte_vlog().
+*/
+int
+rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = rte_vlog(level, logtype, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*
+* Called by environment-specific initialization functions.
+*/
+void
+eal_log_set_default(FILE *default_log)
+{
+ default_log_stream = default_log;
+
+#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
+ RTE_LOG(NOTICE, EAL,
+ "Debug dataplane logs available - lower performance\n");
+#endif
+}
+
+/*
+* set the log to default function, called during eal init process,
+* once memzones are available.
+*/
+int
+rte_eal_log_init(const char *id, int facility)
+{
+ eal_log_set_default(stderr);
+ return 0;
+}
diff --git a/lib/librte_eal/windows/eal/eal_memalloc.c b/lib/librte_eal/windows/eal/eal_memalloc.c
new file mode 100644
index 000000000..66c0d1ca7
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_memalloc.c
@@ -0,0 +1,995 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Intel Corporation
+ */
+
+#define _FILE_OFFSET_BITS 64
+#include <errno.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/queue.h>
+#include <unistd.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <Intsafe.h>
+#include <process.h>
+
+#include <signal.h>
+#include <setjmp.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_eal_memconfig.h>
+#include <rte_eal.h>
+#include <rte_memory.h>
+#include <rte_spinlock.h>
+
+#include "eal_filesystem.h"
+#include "eal_internal_cfg.h"
+#include "eal_memalloc.h"
+#include "eal_private.h"
+
+const int anonymous_hugepages_supported =
+#ifdef MAP_HUGE_SHIFT
+ 1;
+#define RTE_MAP_HUGE_SHIFT MAP_HUGE_SHIFT
+#else
+ 0;
+#define RTE_MAP_HUGE_SHIFT 26
+#endif
+
+/*
+ * not all kernel version support fallocate on hugetlbfs, so fall back to
+ * ftruncate and disallow deallocation if fallocate is not supported.
+ */
+static int fallocate_supported = -1; /* unknown */
+
+/* for single-file segments, we need some kind of mechanism to keep track of
+ * which hugepages can be freed back to the system, and which cannot. we cannot
+ * use flock() because they don't allow locking parts of a file, and we cannot
+ * use fcntl() due to issues with their semantics, so we will have to rely on a
+ * bunch of lockfiles for each page.
+ *
+ * we cannot know how many pages a system will have in advance, but we do know
+ * that they come in lists, and we know lengths of these lists. so, simply store
+ * a malloc'd array of fd's indexed by list and segment index.
+ *
+ * they will be initialized at startup, and filled as we allocate/deallocate
+ * segments. also, use this to track memseg list proper fd.
+ */
+static struct {
+ int *fds; /**< dynamically allocated array of segment lock fd's */
+ int memseg_list_fd; /**< memseg list fd */
+ int len; /**< total length of the array */
+ int count; /**< entries used in an array */
+} fd_list[RTE_MAX_MEMSEG_LISTS];
+
+/** local copy of a memory map, used to synchronize memory hotplug in MP */
+static struct rte_memseg_list local_memsegs[RTE_MAX_MEMSEG_LISTS];
+
+static sigjmp_buf huge_jmpenv;
+
+/* Put setjmp into a wrap method to avoid compiling error. Any non-volatile,
+ * non-static local variable in the stack frame calling sigsetjmp might be
+ * clobbered by a call to longjmp.
+ */
+static int __rte_unused huge_wrap_sigsetjmp(void)
+{
+ return sigsetjmp(huge_jmpenv, 1);
+}
+
+static int
+get_seg_fd(char *path, int buflen, struct hugepage_info *hi,
+ unsigned int list_idx, unsigned int seg_idx)
+{
+ int fd;
+ BOOL ret;
+
+ if (internal_config.single_file_segments) {
+ /* create a hugepage file path */
+ eal_get_hugefile_path(path, buflen, hi->hugedir, list_idx);
+
+ fd = fd_list[list_idx].memseg_list_fd;
+
+ if (fd < 0) {
+ fd = _open(path, O_CREAT | O_RDWR, _S_IREAD | _S_IWRITE);
+ if (fd < 0) {
+ RTE_LOG(ERR, EAL, "%s(): open failed: %s\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ /* TODO dpdk-1808 take out a read lock and keep it indefinitely */
+
+ fd_list[list_idx].memseg_list_fd = fd;
+ }
+ } else {
+ /* create a hugepage file path */
+ eal_get_hugefile_path(path, buflen, hi->hugedir,
+ list_idx * RTE_MAX_MEMSEG_PER_LIST + seg_idx);
+ fd = _open(path, O_CREAT | O_RDWR, _S_IREAD | _S_IWRITE);
+ if (fd < 0) {
+ RTE_LOG(DEBUG, EAL, "%s(): open failed: %s\n", __func__,
+ strerror(errno));
+ return -1;
+ }
+ /* TODO dpdk-1808 take out a read lock */
+
+ }
+ return fd;
+}
+
+static int
+resize_hugefile(int fd, char *path, int list_idx, int seg_idx,
+ uint64_t fa_offset, uint64_t page_sz, bool grow)
+{
+ /* dpdk-1808 Not implemented in Windows*/
+ return 0;
+}
+
+static int
+alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
+ struct hugepage_info *hi, unsigned int list_idx,
+ unsigned int seg_idx)
+{
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+ int cur_socket_id = 0;
+#endif
+ uint64_t map_offset;
+ rte_iova_t iova;
+ void *va;
+ char path[PATH_MAX];
+ int ret = 0;
+ int fd;
+ size_t alloc_sz;
+ int flags;
+ void *new_addr;
+
+ alloc_sz = hi->hugepage_sz;
+ if (!internal_config.single_file_segments &&
+ internal_config.in_memory &&
+ anonymous_hugepages_supported) {
+ int log2, flags;
+
+ log2 = rte_log2_u32(alloc_sz);
+ /* as per mmap() manpage, all page sizes are log2 of page size
+ * shifted by MAP_HUGE_SHIFT
+ */
+ flags = (log2 << RTE_MAP_HUGE_SHIFT) | MAP_FIXED |
+ MAP_PRIVATE | MAP_ANONYMOUS;
+ fd = -1;
+ va = mmap(addr, alloc_sz, PROT_READ | PROT_WRITE, flags, -1, 0);
+
+ /* single-file segments codepath will never be active because
+ * in-memory mode is incompatible with it and it's stopped at
+ * EAL initialization stage, however the compiler doesn't know
+ * that and complains about map_offset being used uninitialized
+ * on failure codepaths while having in-memory mode enabled. so,
+ * assign a value here.
+ */
+ map_offset = 0;
+ } else {
+ /* takes out a read lock on segment or segment list */
+ fd = get_seg_fd(path, sizeof(path), hi, list_idx, seg_idx);
+ if (fd < 0) {
+ RTE_LOG(ERR, EAL, "Couldn't get fd on hugepage file\n");
+ return -1;
+ }
+
+ if (internal_config.single_file_segments) {
+ map_offset = seg_idx * alloc_sz;
+ ret = resize_hugefile(fd, path, list_idx, seg_idx,
+ map_offset, alloc_sz, true);
+ if (ret < 0)
+ goto resized;
+ } else {
+ map_offset = 0;
+ if (ftruncate(fd, alloc_sz) < 0) {
+ RTE_LOG(DEBUG, EAL, "%s(): ftruncate() failed: %s\n",
+ __func__, strerror(errno));
+ goto resized;
+ }
+ if (internal_config.hugepage_unlink) {
+ if (unlink(path)) {
+ RTE_LOG(DEBUG, EAL, "%s(): unlink() failed: %s\n",
+ __func__, strerror(errno));
+ goto resized;
+ }
+ }
+ }
+
+ /*
+ * map the segment, and populate page tables, the kernel fills
+ * this segment with zeros if it's a new page.
+ */
+ va = mmap(addr, alloc_sz, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_FIXED, fd,
+ map_offset);
+ }
+
+ if (va == MAP_FAILED) {
+ RTE_LOG(DEBUG, EAL, "%s(): mmap() failed: %s\n", __func__,
+ strerror(errno));
+ /* mmap failed, but the previous region might have been
+ * unmapped anyway. try to remap it
+ */
+ goto unmapped;
+ }
+ if (va != addr) {
+ RTE_LOG(DEBUG, EAL, "%s(): wrong mmap() address\n", __func__);
+ munmap(va, alloc_sz);
+ goto resized;
+ }
+
+ /* In linux, hugetlb limitations, like cgroup, are
+ * enforced at fault time instead of mmap(), even
+ * with the option of MAP_POPULATE. Kernel will send
+ * a SIGBUS signal. To avoid to be killed, save stack
+ * environment here, if SIGBUS happens, we can jump
+ * back here.
+ */
+ if (huge_wrap_sigsetjmp()) {
+ RTE_LOG(DEBUG, EAL, "SIGBUS: Cannot mmap more hugepages of size %uMB\n",
+ (unsigned int)(alloc_sz >> 20));
+ goto mapped;
+ }
+
+ /* we need to trigger a write to the page to enforce page fault and
+ * ensure that page is accessible to us, but we can't overwrite value
+ * that is already there, so read the old value, and write itback.
+ * kernel populates the page with zeroes initially.
+ */
+ *(volatile int *)addr = *(volatile int *)addr;
+
+ iova = rte_mem_virt2iova(addr);
+ if (iova == RTE_BAD_PHYS_ADDR) {
+ RTE_LOG(DEBUG, EAL, "%s(): can't get IOVA addr\n",
+ __func__);
+ goto mapped;
+ }
+
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+ move_pages(getpid(), 1, &addr, NULL, &cur_socket_id, 0);
+
+ if (cur_socket_id != socket_id) {
+ RTE_LOG(DEBUG, EAL,
+ "%s(): allocation happened on wrong socket (wanted %d, got %d)\n",
+ __func__, socket_id, cur_socket_id);
+ goto mapped;
+ }
+#endif
+ /* for non-single file segments that aren't in-memory, we can close fd
+ * here */
+ if (!internal_config.single_file_segments && !internal_config.in_memory)
+ close(fd);
+
+ ms->addr = addr;
+ ms->hugepage_sz = alloc_sz;
+ ms->len = alloc_sz;
+ ms->nchannel = rte_memory_get_nchannel();
+ ms->nrank = rte_memory_get_nrank();
+ ms->iova = iova;
+ ms->socket_id = socket_id;
+
+ return 0;
+
+mapped:
+ munmap(addr, alloc_sz);
+unmapped:
+ flags = MAP_FIXED;
+ new_addr = eal_get_virtual_area(addr, &alloc_sz, alloc_sz, 0, flags);
+ if (new_addr != addr) {
+ if (new_addr != NULL)
+ munmap(new_addr, alloc_sz);
+ /* we're leaving a hole in our virtual address space. if
+ * somebody else maps this hole now, we could accidentally
+ * override it in the future.
+ */
+ RTE_LOG(CRIT, EAL, "Can't mmap holes in our virtual address space\n");
+ }
+resized:
+ /* in-memory mode will never be single-file-segments mode */
+ if (internal_config.single_file_segments) {
+ resize_hugefile(fd, path, list_idx, seg_idx, map_offset,
+ alloc_sz, false);
+ /* ignore failure, can't make it any worse */
+ } else {
+
+ /* TODO dpdk-1808 only remove file if we can take out a write lock */
+ if (internal_config.hugepage_unlink == 0 &&
+ internal_config.in_memory == 0 )
+ unlink(path);
+ close(fd);
+ }
+ return -1;
+}
+
+static int
+free_seg(struct rte_memseg *ms, struct hugepage_info *hi,
+ unsigned int list_idx, unsigned int seg_idx)
+{
+ char path[PATH_MAX];
+ int fd;
+ BOOL ret;
+
+ /* erase page data */
+ memset(ms->addr, 0, ms->len);
+
+
+
+ /* if we've already unlinked the page, nothing needs to be done */
+ if (internal_config.hugepage_unlink) {
+ memset(ms, 0, sizeof(*ms));
+ return 0;
+ }
+
+ /* Avoid unmmaping already mapped memory to boost performance*/
+
+ return 0;
+}
+
+struct alloc_walk_param {
+ struct hugepage_info *hi;
+ struct rte_memseg **ms;
+ size_t page_sz;
+ unsigned int segs_allocated;
+ unsigned int n_segs;
+ int socket;
+ bool exact;
+};
+static int
+alloc_seg_walk(const struct rte_memseg_list *msl, void *arg)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ struct alloc_walk_param *wa = arg;
+ struct rte_memseg_list *cur_msl;
+ size_t page_sz;
+ BOOL ret;
+ int cur_idx, start_idx, j, dir_fd = -1;
+ unsigned int msl_idx, need, i;
+
+ if (msl->page_sz != wa->page_sz)
+ return 0;
+ if (msl->socket_id != wa->socket)
+ return 0;
+
+ page_sz = (size_t)msl->page_sz;
+
+ msl_idx = msl - mcfg->memsegs;
+ cur_msl = &mcfg->memsegs[msl_idx];
+
+ need = wa->n_segs;
+
+ /* try finding space in memseg list */
+ cur_idx = rte_fbarray_find_next_n_free(&cur_msl->memseg_arr, 0, need);
+ if (cur_idx < 0)
+ return 0;
+ start_idx = cur_idx;
+
+ /*
+ * TODO dpdk-1808
+ * do not allow any page allocations during the time we're allocating,
+ * because file creation and locking operations are not atomic,
+ * and we might be the first or the last ones to use a particular page,
+ * so we need to ensure atomicity of every operation.
+ *
+ * during init, we already hold a write lock, so don't try to take out
+ * another one.
+ */
+
+ for (i = 0; i < need; i++, cur_idx++) {
+ struct rte_memseg *cur;
+ void *map_addr;
+
+ cur = rte_fbarray_get(&cur_msl->memseg_arr, cur_idx);
+ map_addr = RTE_PTR_ADD(cur_msl->base_va,
+ cur_idx * page_sz);
+
+ if (alloc_seg(cur, map_addr, wa->socket, wa->hi,
+ msl_idx, cur_idx)) {
+ RTE_LOG(DEBUG, EAL, "attempted to allocate %i segments, but only %i were allocated\n",
+ need, i);
+
+ /* if exact number wasn't requested, stop */
+ if (!wa->exact)
+ goto out;
+
+ /* clean up */
+ for (j = start_idx; j < cur_idx; j++) {
+ struct rte_memseg *tmp;
+ struct rte_fbarray *arr =
+ &cur_msl->memseg_arr;
+
+ tmp = rte_fbarray_get(arr, j);
+ rte_fbarray_set_free(arr, j);
+
+ /* free_seg may attempt to create a file, which
+ * may fail.
+ */
+ if (free_seg(tmp, wa->hi, msl_idx, j))
+ RTE_LOG(DEBUG, EAL, "Cannot free page\n");
+ }
+ /* clear the list */
+ if (wa->ms)
+ memset(wa->ms, 0, sizeof(*wa->ms) * wa->n_segs);
+
+ if (dir_fd >= 0)
+ close(dir_fd);
+ return -1;
+ }
+ if (wa->ms)
+ wa->ms[i] = cur;
+
+ rte_fbarray_set_used(&cur_msl->memseg_arr, cur_idx);
+ }
+out:
+ wa->segs_allocated = i;
+ if (i > 0)
+ cur_msl->version++;
+ if (dir_fd >= 0)
+ close(dir_fd);
+ return 1;
+}
+
+struct free_walk_param {
+ struct hugepage_info *hi;
+ struct rte_memseg *ms;
+};
+static int
+free_seg_walk(const struct rte_memseg_list *msl, void *arg)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ struct rte_memseg_list *found_msl;
+ struct free_walk_param *wa = arg;
+ uintptr_t start_addr, end_addr;
+ int msl_idx, seg_idx, ret, dir_fd = -1;
+ BOOL retval;
+
+ start_addr = (uintptr_t) msl->base_va;
+ end_addr = start_addr + msl->memseg_arr.len * (size_t)msl->page_sz;
+
+ if ((uintptr_t)wa->ms->addr < start_addr ||
+ (uintptr_t)wa->ms->addr >= end_addr)
+ return 0;
+
+ msl_idx = msl - mcfg->memsegs;
+ seg_idx = RTE_PTR_DIFF(wa->ms->addr, start_addr) / msl->page_sz;
+
+ /* msl is const */
+ found_msl = &mcfg->memsegs[msl_idx];
+
+ /* Removing clean up and synchronization code*/
+ /* TODO dpdk-1808
+ * do not allow any page allocations during the time we're freeing,
+ * because file creation and locking operations are not atomic,
+ * and we might be the first or the last ones to use a particular page,
+ * so we need to ensure atomicity of every operation.
+ *
+ * during init, we already hold a write lock, so don't try to take out
+ * another one.
+ */
+
+ found_msl->version++;
+
+ rte_fbarray_set_free(&found_msl->memseg_arr, seg_idx);
+
+ ret = free_seg(wa->ms, wa->hi, msl_idx, seg_idx);
+
+ if (ret < 0)
+ return -1;
+
+ return 1;
+}
+
+int
+eal_memalloc_alloc_seg_bulk(struct rte_memseg **ms, int n_segs, size_t page_sz,
+ int socket, bool exact)
+{
+ int i, ret = -1;
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+ bool have_numa = false;
+ int oldpolicy;
+ struct bitmask *oldmask;
+#endif
+ struct alloc_walk_param wa;
+ struct hugepage_info *hi = NULL;
+
+ memset(&wa, 0, sizeof(wa));
+
+ /* dynamic allocation not supported in legacy mode */
+ if (internal_config.legacy_mem)
+ return -1;
+
+ for (i = 0; i < (int) RTE_DIM(internal_config.hugepage_info); i++) {
+ if (page_sz ==
+ internal_config.hugepage_info[i].hugepage_sz) {
+ hi = &internal_config.hugepage_info[i];
+ break;
+ }
+ }
+ if (!hi) {
+ RTE_LOG(ERR, EAL, "%s(): can't find relevant hugepage_info entry\n",
+ __func__);
+ return -1;
+ }
+
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+ if (check_numa()) {
+ oldmask = numa_allocate_nodemask();
+ prepare_numa(&oldpolicy, oldmask, socket);
+ have_numa = true;
+ }
+#endif
+
+ wa.exact = exact;
+ wa.hi = hi;
+ wa.ms = ms;
+ wa.n_segs = n_segs;
+ wa.page_sz = page_sz;
+ wa.socket = socket;
+ wa.segs_allocated = 0;
+
+ /* memalloc is locked, so it's safe to use thread-unsafe version */
+ ret = rte_memseg_list_walk_thread_unsafe(alloc_seg_walk, &wa);
+ if (ret == 0) {
+ RTE_LOG(ERR, EAL, "%s(): couldn't find suitable memseg_list\n",
+ __func__);
+ ret = -1;
+ } else if (ret > 0) {
+ ret = (int)wa.segs_allocated;
+ }
+
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+ if (have_numa)
+ restore_numa(&oldpolicy, oldmask);
+#endif
+ return ret;
+}
+
+struct rte_memseg *
+eal_memalloc_alloc_seg(size_t page_sz, int socket)
+{
+ struct rte_memseg *ms;
+ if (eal_memalloc_alloc_seg_bulk(&ms, 1, page_sz, socket, true) < 0)
+ return NULL;
+ /* return pointer to newly allocated memseg */
+ return ms;
+}
+
+int
+eal_memalloc_free_seg_bulk(struct rte_memseg **ms, int n_segs)
+{
+ int seg, ret = 0;
+
+ /* dynamic free not supported in legacy mode */
+ if (internal_config.legacy_mem)
+ return -1;
+
+ for (seg = 0; seg < n_segs; seg++) {
+ struct rte_memseg *cur = ms[seg];
+ struct hugepage_info *hi = NULL;
+ struct free_walk_param wa;
+ int i, walk_res;
+
+ /* if this page is marked as unfreeable, fail */
+ if (cur->flags & RTE_MEMSEG_FLAG_DO_NOT_FREE) {
+ RTE_LOG(DEBUG, EAL, "Page is not allowed to be freed\n");
+ ret = -1;
+ continue;
+ }
+
+ memset(&wa, 0, sizeof(wa));
+
+
+
+ wa.ms = cur;
+ wa.hi = hi;
+
+ /* memalloc is locked, so it's safe to use thread-unsafe version
+ */
+ walk_res = rte_memseg_list_walk_thread_unsafe(free_seg_walk,
+ &wa);
+ if (walk_res == 1)
+ continue;
+ if (walk_res == 0)
+ RTE_LOG(ERR, EAL, "Couldn't find memseg list\n");
+ ret = -1;
+ }
+ return ret;
+}
+
+int
+eal_memalloc_free_seg(struct rte_memseg *ms)
+{
+ /* dynamic free not supported in legacy mode */
+ if (internal_config.legacy_mem)
+ return -1;
+
+ return eal_memalloc_free_seg_bulk(&ms, 1);
+}
+
+static int
+sync_chunk(struct rte_memseg_list *primary_msl,
+ struct rte_memseg_list *local_msl, struct hugepage_info *hi,
+ unsigned int msl_idx, bool used, int start, int end)
+{
+ struct rte_fbarray *l_arr, *p_arr;
+ int i, ret, chunk_len, diff_len;
+
+ l_arr = &local_msl->memseg_arr;
+ p_arr = &primary_msl->memseg_arr;
+
+ /* we need to aggregate allocations/deallocations into bigger chunks,
+ * as we don't want to spam the user with per-page callbacks.
+ *
+ * to avoid any potential issues, we also want to trigger
+ * deallocation callbacks *before* we actually deallocate
+ * memory, so that the user application could wrap up its use
+ * before it goes away.
+ */
+
+ chunk_len = end - start;
+
+ /* find how many contiguous pages we can map/unmap for this chunk */
+ diff_len = used ?
+ rte_fbarray_find_contig_free(l_arr, start) :
+ rte_fbarray_find_contig_used(l_arr, start);
+
+ /* has to be at least one page */
+ if (diff_len < 1)
+ return -1;
+
+ diff_len = RTE_MIN(chunk_len, diff_len);
+
+ /* if we are freeing memory, notify the application */
+ if (!used) {
+ struct rte_memseg *ms;
+ void *start_va;
+ size_t len, page_sz;
+
+ ms = rte_fbarray_get(l_arr, start);
+ start_va = ms->addr;
+ page_sz = (size_t)primary_msl->page_sz;
+ len = page_sz * diff_len;
+
+ eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE,
+ start_va, len);
+ }
+
+ for (i = 0; i < diff_len; i++) {
+ struct rte_memseg *p_ms, *l_ms;
+ int seg_idx = start + i;
+
+ l_ms = rte_fbarray_get(l_arr, seg_idx);
+ p_ms = rte_fbarray_get(p_arr, seg_idx);
+
+ if (l_ms == NULL || p_ms == NULL)
+ return -1;
+
+ if (used) {
+ ret = alloc_seg(l_ms, p_ms->addr,
+ p_ms->socket_id, hi,
+ msl_idx, seg_idx);
+ if (ret < 0)
+ return -1;
+ rte_fbarray_set_used(l_arr, seg_idx);
+ } else {
+ ret = free_seg(l_ms, hi, msl_idx, seg_idx);
+ rte_fbarray_set_free(l_arr, seg_idx);
+ if (ret < 0)
+ return -1;
+ }
+ }
+
+ /* if we just allocated memory, notify the application */
+ if (used) {
+ struct rte_memseg *ms;
+ void *start_va;
+ size_t len, page_sz;
+
+ ms = rte_fbarray_get(l_arr, start);
+ start_va = ms->addr;
+ page_sz = (size_t)primary_msl->page_sz;
+ len = page_sz * diff_len;
+
+ eal_memalloc_mem_event_notify(RTE_MEM_EVENT_ALLOC,
+ start_va, len);
+ }
+
+ /* calculate how much we can advance until next chunk */
+ diff_len = used ?
+ rte_fbarray_find_contig_used(l_arr, start) :
+ rte_fbarray_find_contig_free(l_arr, start);
+ ret = RTE_MIN(chunk_len, diff_len);
+
+ return ret;
+}
+
+static int
+sync_status(struct rte_memseg_list *primary_msl,
+ struct rte_memseg_list *local_msl, struct hugepage_info *hi,
+ unsigned int msl_idx, bool used)
+{
+ struct rte_fbarray *l_arr, *p_arr;
+ int p_idx, l_chunk_len, p_chunk_len, ret;
+ int start, end;
+
+ /* this is a little bit tricky, but the basic idea is - walk both lists
+ * and spot any places where there are discrepancies. walking both lists
+ * and noting discrepancies in a single go is a hard problem, so we do
+ * it in two passes - first we spot any places where allocated segments
+ * mismatch (i.e. ensure that everything that's allocated in the primary
+ * is also allocated in the secondary), and then we do it by looking at
+ * free segments instead.
+ *
+ * we also need to aggregate changes into chunks, as we have to call
+ * callbacks per allocation, not per page.
+ */
+ l_arr = &local_msl->memseg_arr;
+ p_arr = &primary_msl->memseg_arr;
+
+ if (used)
+ p_idx = rte_fbarray_find_next_used(p_arr, 0);
+ else
+ p_idx = rte_fbarray_find_next_free(p_arr, 0);
+
+ while (p_idx >= 0) {
+ int next_chunk_search_idx;
+
+ if (used) {
+ p_chunk_len = rte_fbarray_find_contig_used(p_arr,
+ p_idx);
+ l_chunk_len = rte_fbarray_find_contig_used(l_arr,
+ p_idx);
+ } else {
+ p_chunk_len = rte_fbarray_find_contig_free(p_arr,
+ p_idx);
+ l_chunk_len = rte_fbarray_find_contig_free(l_arr,
+ p_idx);
+ }
+ /* best case scenario - no differences (or bigger, which will be
+ * fixed during next iteration), look for next chunk
+ */
+ if (l_chunk_len >= p_chunk_len) {
+ next_chunk_search_idx = p_idx + p_chunk_len;
+ goto next_chunk;
+ }
+
+ /* if both chunks start at the same point, skip parts we know
+ * are identical, and sync the rest. each call to sync_chunk
+ * will only sync contiguous segments, so we need to call this
+ * until we are sure there are no more differences in this
+ * chunk.
+ */
+ start = p_idx + l_chunk_len;
+ end = p_idx + p_chunk_len;
+ do {
+ ret = sync_chunk(primary_msl, local_msl, hi, msl_idx,
+ used, start, end);
+ start += ret;
+ } while (start < end && ret >= 0);
+ /* if ret is negative, something went wrong */
+ if (ret < 0)
+ return -1;
+
+ next_chunk_search_idx = p_idx + p_chunk_len;
+next_chunk:
+ /* skip to end of this chunk */
+ if (used) {
+ p_idx = rte_fbarray_find_next_used(p_arr,
+ next_chunk_search_idx);
+ } else {
+ p_idx = rte_fbarray_find_next_free(p_arr,
+ next_chunk_search_idx);
+ }
+ }
+ return 0;
+}
+
+static int
+sync_existing(struct rte_memseg_list *primary_msl,
+ struct rte_memseg_list *local_msl, struct hugepage_info *hi,
+ unsigned int msl_idx)
+{
+ int ret, dir_fd;
+
+ /* TODO dpdk-1808
+ * do not allow any page allocations during the time we're allocating,
+ * because file creation and locking operations are not atomic,
+ * and we might be the first or the last ones to use a particular page,
+ * so we need to ensure atomicity of every operation.
+ */
+
+
+ /* ensure all allocated space is the same in both lists */
+ ret = sync_status(primary_msl, local_msl, hi, msl_idx, true);
+ if (ret < 0)
+ goto fail;
+
+ /* ensure all unallocated space is the same in both lists */
+ ret = sync_status(primary_msl, local_msl, hi, msl_idx, false);
+ if (ret < 0)
+ goto fail;
+
+ /* update version number */
+ local_msl->version = primary_msl->version;
+
+ /* TODO dpdk-1808 Unlock and close the directory*/
+
+ return 0;
+fail:
+ /* TODO dpdk-1808 Unlock and close the directory*/
+ return -1;
+}
+
+static int
+sync_walk(const struct rte_memseg_list *msl, void *arg __rte_unused)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ struct rte_memseg_list *primary_msl, *local_msl;
+ struct hugepage_info *hi = NULL;
+ unsigned int i;
+ int msl_idx;
+
+ msl_idx = msl - mcfg->memsegs;
+ primary_msl = &mcfg->memsegs[msl_idx];
+ local_msl = &local_memsegs[msl_idx];
+
+ for (i = 0; i < RTE_DIM(internal_config.hugepage_info); i++) {
+ uint64_t cur_sz =
+ internal_config.hugepage_info[i].hugepage_sz;
+ uint64_t msl_sz = primary_msl->page_sz;
+ if (msl_sz == cur_sz) {
+ hi = &internal_config.hugepage_info[i];
+ break;
+ }
+ }
+ if (!hi) {
+ RTE_LOG(ERR, EAL, "Can't find relevant hugepage_info entry\n");
+ return -1;
+ }
+
+ /* if versions don't match, synchronize everything */
+ if (local_msl->version != primary_msl->version &&
+ sync_existing(primary_msl, local_msl, hi, msl_idx))
+ return -1;
+ return 0;
+}
+
+
+int
+eal_memalloc_sync_with_primary(void)
+{
+ /* nothing to be done in primary */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ return 0;
+
+ /* memalloc is locked, so it's safe to call thread-unsafe version */
+ if (rte_memseg_list_walk_thread_unsafe(sync_walk, NULL))
+ return -1;
+ return 0;
+}
+
+static int
+secondary_msl_create_walk(const struct rte_memseg_list *msl,
+ void *arg __rte_unused)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ struct rte_memseg_list *primary_msl, *local_msl;
+ char name[PATH_MAX];
+ int msl_idx, ret;
+
+ msl_idx = msl - mcfg->memsegs;
+ primary_msl = &mcfg->memsegs[msl_idx];
+ local_msl = &local_memsegs[msl_idx];
+
+ /* create distinct fbarrays for each secondary */
+ snprintf(name, RTE_FBARRAY_NAME_LEN, "%s_%i",
+ primary_msl->memseg_arr.name, _getpid());
+
+ ret = rte_fbarray_init(&local_msl->memseg_arr, name,
+ primary_msl->memseg_arr.len,
+ primary_msl->memseg_arr.elt_sz);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Cannot initialize local memory map\n");
+ return -1;
+ }
+ local_msl->base_va = primary_msl->base_va;
+
+ return 0;
+}
+
+static int
+secondary_lock_list_create_walk(const struct rte_memseg_list *msl,
+ void *arg __rte_unused)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ unsigned int i, len;
+ int msl_idx;
+ int *data;
+
+ msl_idx = msl - mcfg->memsegs;
+ len = msl->memseg_arr.len;
+
+ /* ensure we have space to store lock fd per each possible segment */
+ data = malloc(sizeof(int) * len);
+ if (data == NULL) {
+ RTE_LOG(ERR, EAL, "Unable to allocate space for lock descriptors\n");
+ return -1;
+ }
+ /* set all fd's as invalid */
+ for (i = 0; i < len; i++)
+ data[i] = -1;
+
+ fd_list[msl_idx].fds = data;
+ fd_list[msl_idx].len = len;
+ fd_list[msl_idx].count = 0;
+ fd_list[msl_idx].memseg_list_fd = -1;
+
+ return 0;
+}
+
+int
+eal_memalloc_init(void)
+{
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+ if (rte_memseg_list_walk(secondary_msl_create_walk, NULL) < 0)
+ return -1;
+
+ /* initialize all of the lock fd lists */
+ if (internal_config.single_file_segments)
+ if (rte_memseg_list_walk(secondary_lock_list_create_walk, NULL))
+ return -1;
+ return 0;
+}
+
+int
+eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
+{
+ int fd;
+ if (internal_config.single_file_segments) {
+ fd = fd_list[list_idx].memseg_list_fd;
+ }
+ else if (fd_list[list_idx].len == 0) {
+ /* list not initialized */
+ fd = -1;
+ }
+ else {
+ fd = fd_list[list_idx].fds[seg_idx];
+ }
+ if (fd < 0)
+ return -ENODEV;
+ return fd;
+}
+
+int
+eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+
+ /* fd_list not initialized? */
+ if (fd_list[list_idx].len == 0)
+ return -ENODEV;
+ if (internal_config.single_file_segments) {
+ size_t pgsz = mcfg->memsegs[list_idx].page_sz;
+
+ /* segment not active? */
+ if (fd_list[list_idx].memseg_list_fd < 0)
+ return -ENOENT;
+ *offset = pgsz * seg_idx;
+ }
+ else {
+ /* segment not active? */
+ if (fd_list[list_idx].fds[seg_idx] < 0)
+ return -ENOENT;
+ *offset = 0;
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/eal_memory.c b/lib/librte_eal/windows/eal/eal_memory.c
new file mode 100644
index 000000000..9077f5e9e
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_memory.c
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <inttypes.h>
+#include <fcntl.h>
+
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_log.h>
+#include <rte_string_fns.h>
+#include <rte_fbarray.h>
+#include <rte_errno.h>
+#include "eal_private.h"
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+
+#define EAL_PAGE_SIZE (getpagesize())
+
+/*
+ * Get physical address of any mapped virtual address in the current process.
+ */
+phys_addr_t
+rte_mem_virt2iova(const void *virtaddr)
+{
+ /* This function is only used by rte_mempool_virt2phy() when hugepages are disabled. */
+ /* Get pointer to global configuration and calculate physical address offset */
+ phys_addr_t physaddr;
+ struct rte_memseg *ms;
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ if (mcfg) {
+ ms = rte_fbarray_get(&mcfg->memsegs[0].memseg_arr, 0);
+ if(ms == NULL)
+ return RTE_BAD_PHYS_ADDR;
+ physaddr = (phys_addr_t)((uintptr_t)ms->phys_addr + RTE_PTR_DIFF(virtaddr, mcfg->memsegs[0].base_va));
+ return physaddr;
+ }
+ else
+ return RTE_BAD_PHYS_ADDR;
+}
+
+int
+rte_eal_hugepage_init(void)
+{
+ /* We have already initialized our memory whilst in the
+ * rte_pci_scan() call. Simply return here.
+ */
+ return 0;
+}
+
+int
+rte_eal_hugepage_attach(void)
+{
+ /* This function is called if our process is a secondary process
+ * and we need to attach to existing memory that has already
+ * been allocated.
+ * It has not been implemented on Windows
+ */
+ return 0;
+}
+
+static int
+alloc_va_space(struct rte_memseg_list *msl)
+{
+ uint64_t page_sz;
+ size_t mem_sz;
+ void *addr;
+ int flags = 0;
+
+#ifdef RTE_ARCH_PPC_64
+ flags |= MAP_HUGETLB;
+#endif
+
+ page_sz = msl->page_sz;
+ mem_sz = page_sz * msl->memseg_arr.len;
+
+ addr = eal_get_virtual_area(msl->base_va, &mem_sz, page_sz, 0, flags);
+ if (addr == NULL) {
+ if (rte_errno == EADDRNOTAVAIL)
+ RTE_LOG(ERR, EAL, "Could not mmap %llu bytes at [%p] - please use '--base-virtaddr' option\n",
+ (unsigned long long)mem_sz, msl->base_va);
+ else
+ RTE_LOG(ERR, EAL, "Cannot reserve memory\n");
+ return -1;
+ }
+ msl->base_va = addr;
+
+ return 0;
+}
+
+static int __rte_unused
+memseg_primary_init(void)
+{
+ /*
+ * Primary memory has already been initialized in store_memseg_info()
+ * Keeping the stub function for integration with common code.
+ */
+
+ return 0;
+}
+
+static int
+memseg_secondary_init(void)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ int msl_idx = 0;
+ struct rte_memseg_list *msl;
+
+ for (msl_idx = 0; msl_idx < RTE_MAX_MEMSEG_LISTS; msl_idx++) {
+
+ msl = &mcfg->memsegs[msl_idx];
+
+ /* skip empty memseg lists */
+ if (msl->memseg_arr.len == 0)
+ continue;
+
+ if (rte_fbarray_attach(&msl->memseg_arr)) {
+ RTE_LOG(ERR, EAL, "Cannot attach to primary process memseg lists\n");
+ return -1;
+ }
+
+ /* preallocate VA space */
+ if (alloc_va_space(msl)) {
+ RTE_LOG(ERR, EAL, "Cannot preallocate VA space for hugepage memory\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+int
+rte_eal_memseg_init(void)
+{
+ return rte_eal_process_type() == RTE_PROC_PRIMARY ? memseg_primary_init() : memseg_secondary_init();
+}
diff --git a/lib/librte_eal/windows/eal/eal_proc.c b/lib/librte_eal/windows/eal/eal_proc.c
new file mode 100644
index 000000000..773bef46d
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_proc.c
@@ -0,0 +1,1003 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2016-2018 Intel Corporation
+ */
+
+#include <winsock2.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <Intsafe.h>
+#include <unistd.h>
+
+#include <rte_alarm.h>
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_errno.h>
+#include <rte_lcore.h>
+#include <rte_log.h>
+#include <rte_tailq.h>
+
+#include "eal_private.h"
+#include "eal_filesystem.h"
+#include "eal_internal_cfg.h"
+
+static SOCKET mp_fd = INVALID_SOCKET;
+static char mp_filter[PATH_MAX]; /* Filter for secondary process sockets */
+static char mp_dir_path[PATH_MAX]; /* The directory path for all mp sockets */
+static INIT_ONCE initOnce_Lock = INIT_ONCE_STATIC_INIT;
+static INIT_ONCE initOnce_mp_mutex_action = INIT_ONCE_STATIC_INIT;
+static pthread_mutex_t mp_mutex_action;
+
+struct action_entry {
+ TAILQ_ENTRY(action_entry) next;
+ char action_name[RTE_MP_MAX_NAME_LEN];
+ rte_mp_t action;
+};
+
+/** Double linked list of actions. */
+TAILQ_HEAD(action_entry_list, action_entry);
+
+static struct action_entry_list action_entry_list =
+ TAILQ_HEAD_INITIALIZER(action_entry_list);
+
+enum mp_type {
+ MP_MSG, /* Share message with peers, will not block */
+ MP_REQ, /* Request for information, Will block for a reply */
+ MP_REP, /* Response to previously-received request */
+ MP_IGN, /* Response telling requester to ignore this response */
+};
+
+struct mp_msg_internal {
+ int type;
+ struct rte_mp_msg msg;
+};
+
+struct async_request_param {
+ rte_mp_async_reply_t clb;
+ struct rte_mp_reply user_reply;
+ struct timespec end;
+ int n_responses_processed;
+};
+
+struct pending_request {
+ TAILQ_ENTRY(pending_request) next;
+ enum {
+ REQUEST_TYPE_SYNC,
+ REQUEST_TYPE_ASYNC
+ } type;
+ char dst[PATH_MAX];
+ struct rte_mp_msg *request;
+ struct rte_mp_msg *reply;
+ int reply_received;
+ RTE_STD_C11
+ union {
+ struct {
+ struct async_request_param *param;
+ } async;
+ struct {
+ CONDITION_VARIABLE cond;
+ } sync;
+ };
+};
+
+TAILQ_HEAD(pending_request_list, pending_request);
+
+static struct {
+ struct pending_request_list requests;
+ HANDLE lock;
+} pending_requests = {
+ .requests = TAILQ_HEAD_INITIALIZER(pending_requests.requests)/*,
+ .lock = NULL*/
+ /**< used in async requests only */
+};
+
+/* forward declarations */
+static int
+mp_send(struct rte_mp_msg *msg, const char *peer, int type);
+
+/* for use with alarm callback */
+static void
+async_reply_handle(void *arg);
+
+/* for use with process_msg */
+static struct pending_request *
+async_reply_handle_thread_unsafe(void *arg);
+
+static void
+trigger_async_action(struct pending_request *req);
+
+static struct pending_request *
+find_pending_request(const char *dst, const char *act_name)
+{
+ struct pending_request *r;
+
+ TAILQ_FOREACH(r, &pending_requests.requests, next) {
+ if (!strcmp(r->dst, dst) &&
+ !strcmp(r->request->name, act_name))
+ break;
+ }
+
+ return r;
+}
+
+static void
+create_socket_path(const char *name, char *buf, int len)
+{
+ const char *prefix = eal_mp_socket_path();
+
+ if (strlen(name) > 0)
+ snprintf(buf, len, "%s_%s", prefix, name);
+ else
+ strlcpy(buf, prefix, len);
+}
+
+int
+rte_eal_primary_proc_alive(const char *config_file_path)
+{
+ int config_fd;
+
+ if (config_file_path)
+ config_fd = _open(config_file_path, O_RDONLY);
+ else {
+ const char *path;
+
+ path = eal_runtime_config_path();
+ config_fd = open(path, O_RDONLY);
+ }
+ if (config_fd < 0)
+ return 0;
+
+ int ret = 0;
+ /*lockf(config_fd, F_TEST, 0);*/
+ _close(config_fd);
+
+ return !!ret;
+}
+
+static struct action_entry *
+find_action_entry_by_name(const char *name)
+{
+ struct action_entry *entry;
+
+ TAILQ_FOREACH(entry, &action_entry_list, next) {
+ if (strncmp(entry->action_name, name, RTE_MP_MAX_NAME_LEN) == 0)
+ break;
+ }
+
+ return entry;
+}
+
+static int
+validate_action_name(const char *name)
+{
+ if (name == NULL) {
+ RTE_LOG(ERR, EAL, "Action name cannot be NULL\n");
+ rte_errno = EINVAL;
+ return -1;
+ }
+ if (strnlen(name, RTE_MP_MAX_NAME_LEN) == 0) {
+ RTE_LOG(ERR, EAL, "Length of action name is zero\n");
+ rte_errno = EINVAL;
+ return -1;
+ }
+ if (strnlen(name, RTE_MP_MAX_NAME_LEN) == RTE_MP_MAX_NAME_LEN) {
+ rte_errno = E2BIG;
+ return -1;
+ }
+ return 0;
+}
+
+int __rte_experimental
+rte_mp_action_register(const char *name, rte_mp_t action)
+{
+ struct action_entry *entry;
+
+ if (validate_action_name(name))
+ return -1;
+
+ entry = malloc(sizeof(struct action_entry));
+ if (entry == NULL) {
+ rte_errno = ENOMEM;
+ return -1;
+ }
+ strlcpy(entry->action_name, name, sizeof(entry->action_name));
+ entry->action = action;
+
+ pthread_mutex_lock(mp_mutex_action);
+ if (find_action_entry_by_name(name) != NULL) {
+ pthread_mutex_unlock(mp_mutex_action);
+ rte_errno = EEXIST;
+ free(entry);
+ return -1;
+ }
+ TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
+ pthread_mutex_unlock(mp_mutex_action);
+ return 0;
+}
+
+void __rte_experimental
+rte_mp_action_unregister(const char *name)
+{
+ struct action_entry *entry;
+
+ if (validate_action_name(name))
+ return;
+
+ pthread_mutex_lock(mp_mutex_action);
+ entry = find_action_entry_by_name(name);
+ if (entry == NULL) {
+ pthread_mutex_unlock(mp_mutex_action);
+ return;
+ }
+ TAILQ_REMOVE(&action_entry_list, entry, next);
+ pthread_mutex_unlock(mp_mutex_action);
+ free(entry);
+}
+
+static int
+read_msg(struct mp_msg_internal *m, struct sockaddr *s)
+{
+ /* Multiple process workflow is not supported in windows implemention*/
+ return 0;
+}
+
+static void
+process_msg(struct mp_msg_internal *m, struct sockaddr_in *s)
+{
+ struct pending_request *pending_req;
+ struct action_entry *entry;
+ struct rte_mp_msg *msg = &m->msg;
+ rte_mp_t action = NULL;
+
+ RTE_LOG(DEBUG, EAL, "msg: %s\n", msg->name);
+
+ if (m->type == MP_REP || m->type == MP_IGN) {
+ struct pending_request *req = NULL;
+
+ pthread_mutex_lock(pending_requests.lock);
+ pending_req = find_pending_request(s->sun_path, msg->name);
+ if (pending_req) {
+ memcpy(pending_req->reply, msg, sizeof(*msg));
+ /* -1 indicates that we've been asked to ignore */
+ pending_req->reply_received =
+ m->type == MP_REP ? 1 : -1;
+
+ if (pending_req->type == REQUEST_TYPE_SYNC)
+ pthread_cond_signal(&pending_req->sync.cond);
+ else if (pending_req->type == REQUEST_TYPE_ASYNC)
+ req = async_reply_handle_thread_unsafe(
+ pending_req);
+ } else
+ RTE_LOG(ERR, EAL, "Drop mp reply: %s\n", msg->name);
+ pthread_mutex_unlock(pending_requests.lock);
+
+ if (req != NULL)
+ trigger_async_action(req);
+ return;
+ }
+
+ pthread_mutex_lock(mp_mutex_action);
+ entry = find_action_entry_by_name(msg->name);
+ if (entry != NULL)
+ action = entry->action;
+ pthread_mutex_unlock(mp_mutex_action);
+
+ if (!action) {
+ if (m->type == MP_REQ && !internal_config.init_complete) {
+ /* if this is a request, and init is not yet complete,
+ * and callback wasn't registered, we should tell the
+ * requester to ignore our existence because we're not
+ * yet ready to process this request.
+ */
+ struct rte_mp_msg dummy;
+
+ memset(&dummy, 0, sizeof(dummy));
+ strlcpy(dummy.name, msg->name, sizeof(dummy.name));
+ /*mp_send(&dummy, s->sun_path, MP_IGN);*/
+ } else {
+ RTE_LOG(ERR, EAL, "Cannot find action: %s\n",
+ msg->name);
+ }
+ } /*else if (action(msg, s->sun_path) < 0) {
+ RTE_LOG(ERR, EAL, "Fail to handle message: %s\n", msg->name);
+ }*/
+}
+
+static void *
+mp_handle(void *arg __rte_unused)
+{
+ struct mp_msg_internal msg;
+ struct sockaddr sa;
+
+ while (1) {
+ if (read_msg(&msg, &sa) == 0)
+ process_msg(&msg, &sa);
+ }
+
+ return NULL;
+}
+
+static int
+timespec_cmp(const struct timespec *a, const struct timespec *b)
+{
+ if (a->tv_sec < b->tv_sec)
+ return -1;
+ if (a->tv_sec > b->tv_sec)
+ return 1;
+ if (a->tv_nsec < b->tv_nsec)
+ return -1;
+ if (a->tv_nsec > b->tv_nsec)
+ return 1;
+ return 0;
+}
+
+enum async_action {
+ ACTION_FREE, /**< free the action entry, but don't trigger callback */
+ ACTION_TRIGGER /**< trigger callback, then free action entry */
+};
+
+static enum async_action
+process_async_request(struct pending_request *sr, const struct timespec *now)
+{
+ struct async_request_param *param;
+ struct rte_mp_reply *reply;
+ bool timeout, last_msg;
+
+ param = sr->async.param;
+ reply = ¶m->user_reply;
+
+ /* did we timeout? */
+ timeout = timespec_cmp(¶m->end, now) <= 0;
+
+ /* if we received a response, adjust relevant data and copy mesasge. */
+ if (sr->reply_received == 1 && sr->reply) {
+ struct rte_mp_msg *msg, *user_msgs, *tmp;
+
+ msg = sr->reply;
+ user_msgs = reply->msgs;
+
+ tmp = realloc(user_msgs, sizeof(*msg) *
+ (reply->nb_received + 1));
+ if (!tmp) {
+ RTE_LOG(ERR, EAL, "Fail to alloc reply for request %s:%s\n",
+ sr->dst, sr->request->name);
+ /* this entry is going to be removed and its message
+ * dropped, but we don't want to leak memory, so
+ * continue.
+ */
+ } else {
+ user_msgs = tmp;
+ reply->msgs = user_msgs;
+ memcpy(&user_msgs[reply->nb_received],
+ msg, sizeof(*msg));
+ reply->nb_received++;
+ }
+
+ /* mark this request as processed */
+ param->n_responses_processed++;
+ } else if (sr->reply_received == -1) {
+ /* we were asked to ignore this process */
+ reply->nb_sent--;
+ } else if (timeout) {
+ /* count it as processed response, but don't increment
+ * nb_received.
+ */
+ param->n_responses_processed++;
+ }
+
+ free(sr->reply);
+
+ last_msg = param->n_responses_processed == reply->nb_sent;
+
+ return last_msg ? ACTION_TRIGGER : ACTION_FREE;
+}
+
+static void
+trigger_async_action(struct pending_request *sr)
+{
+ struct async_request_param *param;
+ struct rte_mp_reply *reply;
+
+ param = sr->async.param;
+ reply = ¶m->user_reply;
+
+ param->clb(sr->request, reply);
+
+ /* clean up */
+ free(sr->async.param->user_reply.msgs);
+ free(sr->async.param);
+ free(sr->request);
+ free(sr);
+}
+
+static struct pending_request *
+async_reply_handle_thread_unsafe(void *arg)
+{
+ struct pending_request *req = (struct pending_request *)arg;
+ enum async_action action;
+ struct timespec ts_now;
+
+ ts_now.tv_nsec = 0;
+ ts_now.tv_sec = 0;
+
+ action = process_async_request(req, &ts_now);
+
+ TAILQ_REMOVE(&pending_requests.requests, req, next);
+
+ if (rte_eal_alarm_cancel(async_reply_handle, req) < 0) {
+ /* if we failed to cancel the alarm because it's already in
+ * progress, don't proceed because otherwise we will end up
+ * handling the same message twice.
+ */
+ if (rte_errno == EINPROGRESS) {
+ RTE_LOG(DEBUG, EAL, "Request handling is already in progress\n");
+ goto no_trigger;
+ }
+ RTE_LOG(ERR, EAL, "Failed to cancel alarm\n");
+ }
+
+ if (action == ACTION_TRIGGER)
+ return req;
+no_trigger:
+ free(req);
+ return NULL;
+}
+
+static void
+async_reply_handle(void *arg)
+{
+ struct pending_request *req;
+
+ pending_requests.lock = WinCreateAndLockStaticMutex(pending_requests.lock, &initOnce_Lock);
+ req = async_reply_handle_thread_unsafe(arg);
+ ReleaseMutex(pending_requests.lock);
+
+ if (req != NULL)
+ trigger_async_action(req);
+}
+
+static int
+open_socket_fd(void)
+{
+ char peer_name[PATH_MAX] = {0};
+ struct sockaddr_in un;
+
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+ snprintf(peer_name, sizeof(peer_name),
+ "%d_%"PRIx64, _getpid(), rte_rdtsc());
+
+ mp_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (mp_fd < 0) {
+ RTE_LOG(ERR, EAL, "failed to create unix socket\n");
+ return -1;
+ }
+
+ memset(&un, 0, sizeof(un));
+ un.sin_family = AF_UNIX;
+
+ create_socket_path(peer_name, un.sin_path, sizeof(un.sin_path));
+
+ unlink(un.sun_path); /* May still exist since last run */
+
+ if (bind(mp_fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
+ RTE_LOG(ERR, EAL, "failed to bind %s: %s\n",
+ un.sun_path, strerror(errno));
+ close(mp_fd);
+ return -1;
+ }
+
+ RTE_LOG(INFO, EAL, "Multi-process socket %u\n", un.sin_port);
+ return mp_fd;
+}
+
+static int
+unlink_sockets(const char *filter)
+{
+ int dir_fd;
+ DIR *mp_dir;
+ struct dirent *ent;
+
+ mp_dir = opendir(mp_dir_path);
+ if (!mp_dir) {
+ RTE_LOG(ERR, EAL, "Unable to open directory %s\n", mp_dir_path);
+ return -1;
+ }
+ dir_fd = dirfd(mp_dir);
+
+ while ((ent = readdir(mp_dir))) {
+ if (fnmatch(filter, ent->d_name, 0) == 0)
+ unlinkat(dir_fd, ent->d_name, 0);
+ }
+
+ closedir(mp_dir);
+ return 0;
+}
+
+int
+rte_mp_channel_init(void)
+{
+ char path[PATH_MAX];
+ int dir_fd = -1;
+ pthread_t mp_handle_tid;
+
+ /* in no shared files mode, we do not have secondary processes support,
+ * so no need to initialize IPC.
+ */
+ if (internal_config.no_shconf) {
+ RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC will be disabled\n");
+ return 0;
+ }
+
+ /* create filter path */
+ create_socket_path("*", path, sizeof(path));
+ strlcpy(mp_filter, basename(path), sizeof(mp_filter));
+
+ /* path may have been modified, so recreate it */
+ create_socket_path("*", path, sizeof(path));
+ strlcpy(mp_dir_path, dirname(path), sizeof(mp_dir_path));
+
+ /* TODO dpdk-1808 open mp_dir_path in O_RDONLY the directory */
+
+ /* TODO dpdk-1808 lock the mp_dir_path directory with exculsive lock */
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
+ unlink_sockets(mp_filter)) {
+ RTE_LOG(ERR, EAL, "failed to unlink mp sockets\n");
+ close(dir_fd);
+ return -1;
+ }
+
+ if (open_socket_fd() < 0) {
+ close(dir_fd);
+ return -1;
+ }
+
+ if (rte_ctrl_thread_create(&mp_handle_tid, "rte_mp_handle",
+ NULL, mp_handle, NULL) < 0) {
+ RTE_LOG(ERR, EAL, "failed to create mp thead: %s\n",
+ strerror(errno));
+ close(mp_fd);
+ close(dir_fd);
+ mp_fd = -1;
+ return -1;
+ }
+
+ /* TODO dpdk-1808 unlock and close the mp_dir_path directory */
+
+ return 0;
+}
+
+/**
+ * Return -1, as fail to send message and it's caused by the local side.
+ * Return 0, as fail to send message and it's caused by the remote side.
+ * Return 1, as succeed to send message.
+ *
+ */
+static int
+send_msg(const char *dst_path, struct rte_mp_msg *msg, int type)
+{
+ /* Multiple process workflow is not supported in windows implemention*/
+
+ return 1;
+}
+
+static int
+mp_send(struct rte_mp_msg *msg, const char *peer, int type)
+{
+ int dir_fd, ret = 0;
+ DIR *mp_dir;
+ struct dirent *ent;
+
+ if (!peer && (rte_eal_process_type() == RTE_PROC_SECONDARY))
+ peer = eal_mp_socket_path();
+
+ if (peer) {
+ if (send_msg(peer, msg, type) < 0)
+ return -1;
+ else
+ return 0;
+ }
+
+ /* broadcast to all secondary processes */
+ mp_dir = opendir(mp_dir_path);
+ if (!mp_dir) {
+ RTE_LOG(ERR, EAL, "Unable to open directory %s\n",
+ mp_dir_path);
+ rte_errno = errno;
+ return -1;
+ }
+
+ /* TODO dpdk-1808 lock the directory to prevent processes spinning up while we send */
+
+
+ while ((ent = readdir(mp_dir))) {
+ char path[PATH_MAX];
+
+ /*if (fnmatch(mp_filter, ent->d_name, 0) != 0)
+ continue;*/
+
+ snprintf(path, sizeof(path), "%s/%s", mp_dir_path,
+ ent->d_name);
+ if (send_msg(path, msg, type) < 0)
+ ret = -1;
+ }
+ /* TODO dpdk-1808 unlock the dir */
+
+ /* dir_fd automatically closed on closedir */
+ closedir(mp_dir);
+ return ret;
+}
+
+static bool
+check_input(const struct rte_mp_msg *msg)
+{
+ if (msg == NULL) {
+ RTE_LOG(ERR, EAL, "Msg cannot be NULL\n");
+ rte_errno = EINVAL;
+ return false;
+ }
+
+ if (validate_action_name(msg->name))
+ return false;
+
+ if (msg->len_param > RTE_MP_MAX_PARAM_LEN) {
+ RTE_LOG(ERR, EAL, "Message data is too long\n");
+ rte_errno = E2BIG;
+ return false;
+ }
+
+ if (msg->num_fds > RTE_MP_MAX_FD_NUM) {
+ RTE_LOG(ERR, EAL, "Cannot send more than %d FDs\n",
+ RTE_MP_MAX_FD_NUM);
+ rte_errno = E2BIG;
+ return false;
+ }
+
+ return true;
+}
+
+int __rte_experimental
+rte_mp_sendmsg(struct rte_mp_msg *msg)
+{
+ if (!check_input(msg))
+ return -1;
+
+ RTE_LOG(DEBUG, EAL, "sendmsg: %s\n", msg->name);
+ return mp_send(msg, NULL, MP_MSG);
+}
+
+static int
+mp_request_async(const char *dst, struct rte_mp_msg *req,
+ struct async_request_param *param, const struct timespec *ts)
+{
+ struct rte_mp_msg *reply_msg;
+ struct pending_request *pending_req, *exist;
+ int ret;
+
+ pending_req = calloc(1, sizeof(*pending_req));
+ reply_msg = calloc(1, sizeof(*reply_msg));
+ if (pending_req == NULL || reply_msg == NULL) {
+ RTE_LOG(ERR, EAL, "Could not allocate space for sync request\n");
+ rte_errno = ENOMEM;
+ ret = -1;
+ goto fail;
+ }
+
+ pending_req->type = REQUEST_TYPE_ASYNC;
+ strlcpy(pending_req->dst, dst, sizeof(pending_req->dst));
+ pending_req->request = req;
+ pending_req->reply = reply_msg;
+ pending_req->async.param = param;
+
+ /* queue already locked by caller */
+
+ exist = find_pending_request(dst, req->name);
+ if (exist) {
+ RTE_LOG(ERR, EAL, "A pending request %s:%s\n", dst, req->name);
+ rte_errno = EEXIST;
+ ret = -1;
+ goto fail;
+ }
+
+ ret = send_msg(dst, req, MP_REQ);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Fail to send request %s:%s\n",
+ dst, req->name);
+ ret = -1;
+ goto fail;
+ } else if (ret == 0) {
+ ret = 0;
+ goto fail;
+ }
+ TAILQ_INSERT_TAIL(&pending_requests.requests, pending_req, next);
+
+ param->user_reply.nb_sent++;
+
+ if (rte_eal_alarm_set(ts->tv_sec * 1000000 + ts->tv_nsec / 1000,
+ async_reply_handle, pending_req) < 0) {
+ RTE_LOG(ERR, EAL, "Fail to set alarm for request %s:%s\n",
+ dst, req->name);
+ rte_panic("Fix the above shit to properly free all memory\n");
+ }
+
+ return 0;
+fail:
+ free(pending_req);
+ free(reply_msg);
+ return ret;
+}
+
+static int
+mp_request_sync(const char *dst, struct rte_mp_msg *req,
+ struct rte_mp_reply *reply, const struct timespec *ts)
+{
+ int ret;
+ struct rte_mp_msg msg, *tmp;
+ struct pending_request pending_req, *exist;
+
+ pending_req.type = REQUEST_TYPE_SYNC;
+ pending_req.reply_received = 0;
+ strlcpy(pending_req.dst, dst, sizeof(pending_req.dst));
+ pending_req.request = req;
+ pending_req.reply = &msg;
+ pthread_cond_init(&pending_req.sync.cond, NULL);
+
+ exist = find_pending_request(dst, req->name);
+ if (exist) {
+ RTE_LOG(ERR, EAL, "A pending request %s:%s\n", dst, req->name);
+ rte_errno = EEXIST;
+ return -1;
+ }
+
+ ret = send_msg(dst, req, MP_REQ);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Fail to send request %s:%s\n",
+ dst, req->name);
+ return -1;
+ } else if (ret == 0)
+ return 0;
+
+ TAILQ_INSERT_TAIL(&pending_requests.requests, &pending_req, next);
+
+ reply->nb_sent++;
+
+ do {
+ ret = pthread_cond_timedwait(&pending_req.sync.cond,
+ &pending_requests.lock, ts);
+ } while (ret != 0 && ret != ETIMEDOUT);
+
+ TAILQ_REMOVE(&pending_requests.requests, &pending_req, next);
+
+ if (pending_req.reply_received == 0) {
+ RTE_LOG(ERR, EAL, "Fail to recv reply for request %s:%s\n",
+ dst, req->name);
+ rte_errno = ETIMEDOUT;
+ return -1;
+ }
+ if (pending_req.reply_received == -1) {
+ RTE_LOG(DEBUG, EAL, "Asked to ignore response\n");
+ /* not receiving this message is not an error, so decrement
+ * number of sent messages
+ */
+ reply->nb_sent--;
+ return 0;
+ }
+
+ tmp = realloc(reply->msgs, sizeof(msg) * (reply->nb_received + 1));
+ if (!tmp) {
+ RTE_LOG(ERR, EAL, "Fail to alloc reply for request %s:%s\n",
+ dst, req->name);
+ rte_errno = ENOMEM;
+ return -1;
+ }
+ memcpy(&tmp[reply->nb_received], &msg, sizeof(msg));
+ reply->msgs = tmp;
+ reply->nb_received++;
+ return 0;
+}
+
+int __rte_experimental
+rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply,
+ const struct timespec *ts)
+{
+ int dir_fd, ret = 0;
+ DIR *mp_dir;
+ struct dirent *ent;
+ struct timeval now;
+ struct timespec end;
+
+ RTE_LOG(DEBUG, EAL, "request: %s\n", req->name);
+
+ if (check_input(req) == false)
+ return -1;
+
+ if (internal_config.no_shconf) {
+ RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n");
+ return 0;
+ }
+
+
+ end.tv_nsec =ts->tv_nsec % 1000000000;
+ end.tv_sec = ts->tv_sec +
+ (ts->tv_nsec / 1000000000);
+
+ reply->nb_sent = 0;
+ reply->nb_received = 0;
+ reply->msgs = NULL;
+
+ /* for secondary process, send request to the primary process only */
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+ pthread_mutex_lock(&pending_requests.lock);
+ ret = mp_request_sync(eal_mp_socket_path(), req, reply, &end);
+ pthread_mutex_unlock(pending_requests.lock);
+ return ret;
+ }
+
+
+ return ret;
+}
+
+int __rte_experimental
+rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts,
+ rte_mp_async_reply_t clb)
+{
+ struct rte_mp_msg *copy;
+ struct pending_request *dummy;
+ struct async_request_param *param;
+ struct rte_mp_reply *reply;
+ int dir_fd, ret = 0;
+ DIR *mp_dir;
+ struct dirent *ent;
+ /*struct timeval now;*/
+ struct timespec *end;
+ bool dummy_used = false;
+
+ RTE_LOG(DEBUG, EAL, "request: %s\n", req->name);
+
+ if (check_input(req) == false)
+ return -1;
+
+ if (internal_config.no_shconf) {
+ RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n");
+ return 0;
+ }
+
+ copy = calloc(1, sizeof(*copy));
+ dummy = calloc(1, sizeof(*dummy));
+ param = calloc(1, sizeof(*param));
+ if (copy == NULL || dummy == NULL || param == NULL) {
+ RTE_LOG(ERR, EAL, "Failed to allocate memory for async reply\n");
+ rte_errno = ENOMEM;
+ goto fail;
+ }
+
+ /* copy message */
+ memcpy(copy, req, sizeof(*copy));
+
+ param->n_responses_processed = 0;
+ param->clb = clb;
+ /*end = ¶m->end;*/
+ reply = ¶m->user_reply;
+
+ reply->nb_sent = 0;
+ reply->nb_received = 0;
+ reply->msgs = NULL;
+
+ /* we have to lock the request queue here, as we will be adding a bunch
+ * of requests to the queue at once, and some of the replies may arrive
+ * before we add all of the requests to the queue.
+ */
+ pending_requests.lock = WinCreateAndLockStaticMutex(pending_requests.lock,&initOnce_Lock);
+
+ /* we have to ensure that callback gets triggered even if we don't send
+ * anything, therefore earlier we have allocated a dummy request. fill
+ * it, and put it on the queue if we don't send any requests.
+ */
+ dummy->type = REQUEST_TYPE_ASYNC;
+ dummy->request = copy;
+ dummy->reply = NULL;
+ dummy->async.param = param;
+ dummy->reply_received = 1; /* short-circuit the timeout */
+
+ /* for secondary process, send request to the primary process only */
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+ ret = mp_request_async(eal_mp_socket_path(), copy, param, ts);
+
+ /* if we didn't send anything, put dummy request on the queue */
+ if (ret == 0 && reply->nb_sent == 0) {
+ TAILQ_INSERT_TAIL(&pending_requests.requests, dummy,
+ next);
+ dummy_used = true;
+ }
+
+ ReleaseMutex(pending_requests.lock);
+
+ /* if we couldn't send anything, clean up */
+ if (ret != 0)
+ goto fail;
+ return 0;
+ }
+
+ /* for primary process, broadcast request */
+ mp_dir = opendir(mp_dir_path);
+ if (!mp_dir) {
+ RTE_LOG(ERR, EAL, "Unable to open directory %s\n", mp_dir_path);
+ rte_errno = errno;
+ goto unlock_fail;
+ }
+ dir_fd = dirfd(mp_dir);
+ /* TODO dpdk-1808 blocking writelock */
+
+ /* TODO dpdk-1808 lock the directory to prevent processes spinning up while we send */
+
+ while ((ent = readdir(mp_dir))) {
+ char path[PATH_MAX];
+
+ if (fnmatch(mp_filter, ent->d_name, 0) != 0)
+ continue;
+
+ snprintf(path, sizeof(path), "%s/%s", mp_dir_path,
+ ent->d_name);
+
+ if (mp_request_async(path, copy, param, ts))
+ ret = -1;
+ }
+ /* if we didn't send anything, put dummy request on the queue */
+ if (ret == 0 && reply->nb_sent == 0) {
+ TAILQ_INSERT_HEAD(&pending_requests.requests, dummy, next);
+ dummy_used = true;
+ }
+
+ /* finally, unlock the queue */
+ ReleaseMutex(pending_requests.lock);
+
+ /* TODO dpdk-1808 unlock the directory */
+
+ /* dir_fd automatically closed on closedir */
+ closedir(mp_dir);
+
+ /* if dummy was unused, free it */
+ if (!dummy_used)
+ free(dummy);
+
+ return ret;
+closedir_fail:
+ closedir(mp_dir);
+unlock_fail:
+ ReleaseMutex(pending_requests.lock);
+fail:
+ free(dummy);
+ free(param);
+ free(copy);
+ return -1;
+}
+
+int __rte_experimental
+rte_mp_reply(struct rte_mp_msg *msg, const char *peer)
+{
+ RTE_LOG(DEBUG, EAL, "reply: %s\n", msg->name);
+
+ if (check_input(msg) == false)
+ return -1;
+
+ if (peer == NULL) {
+ RTE_LOG(ERR, EAL, "peer is not specified\n");
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ if (internal_config.no_shconf) {
+ RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n");
+ return 0;
+ }
+
+ return mp_send(msg, peer, MP_REP);
+}
diff --git a/lib/librte_eal/windows/eal/eal_thread.c b/lib/librte_eal/windows/eal/eal_thread.c
new file mode 100644
index 000000000..1a82eb4a2
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_thread.c
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <unistd.h>
+
+#include <rte_debug.h>
+#include <rte_atomic.h>
+#include <rte_log.h>
+#include <rte_memzone.h>
+#include <rte_per_lcore.h>
+
+#include "eal_private.h"
+#include "eal_thread.h"
+
+RTE_DEFINE_PER_LCORE(unsigned, _lcore_id) = LCORE_ID_ANY;
+RTE_DEFINE_PER_LCORE(unsigned, _socket_id) = (unsigned)SOCKET_ID_ANY;
+RTE_DEFINE_PER_LCORE(rte_cpuset_t, _cpuset);
+
+/*
+ * Send a message to a slave lcore identified by slave_id to call a
+ * function f with argument arg. Once the execution is done, the
+ * remote lcore switch in FINISHED state.
+ */
+int
+rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id)
+{
+ int n;
+ char c = 0;
+ int m2s = lcore_config[slave_id].pipe_master2slave[1];
+ int s2m = lcore_config[slave_id].pipe_slave2master[0];
+
+ if (lcore_config[slave_id].state != WAIT)
+ return -EBUSY;
+
+ lcore_config[slave_id].f = f;
+ lcore_config[slave_id].arg = arg;
+
+ /* send message */
+ n = 0;
+ while (n == 0 || (n < 0 && errno == EINTR))
+ n = write(m2s, &c, 1);
+ if (n < 0)
+ rte_panic("cannot write on configuration pipe\n");
+
+ /* wait ack */
+ do {
+ n = read(s2m, &c, 1);
+ } while (n < 0 && errno == EINTR);
+
+ if (n <= 0)
+ rte_panic("cannot read on configuration pipe\n");
+
+ return 0;
+}
+
+/* set affinity for current EAL thread */
+static int
+eal_thread_set_affinity(void)
+{
+ unsigned lcore_id = rte_lcore_id();
+
+ /* acquire system unique id */
+ rte_gettid();
+
+ /* update EAL thread core affinity */
+ return rte_thread_set_affinity(&lcore_config[lcore_id].cpuset);
+}
+
+void eal_thread_init_master(unsigned lcore_id)
+{
+ /* set the lcore ID in per-lcore memory area */
+ RTE_PER_LCORE(_lcore_id) = lcore_id;
+
+ /* set CPU affinity */
+ if (eal_thread_set_affinity() < 0)
+ rte_panic("cannot set affinity\n");
+}
+
+/* main loop of threads */
+void *
+eal_thread_loop(void *arg)
+{
+ char c;
+ int n, ret;
+ unsigned lcore_id;
+ pthread_t thread_id;
+ int m2s, s2m;
+ char cpuset[RTE_CPU_AFFINITY_STR_LEN];
+
+ memset((void *)cpuset, 0, sizeof(cpuset));
+
+ thread_id = pthread_self();
+
+ /* retrieve our lcore_id from the configuration structure */
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+ if (thread_id == lcore_config[lcore_id].thread_id)
+ break;
+ }
+ if (lcore_id == RTE_MAX_LCORE)
+ rte_panic("cannot retrieve lcore id\n");
+
+ m2s = lcore_config[lcore_id].pipe_master2slave[0];
+ s2m = lcore_config[lcore_id].pipe_slave2master[1];
+
+ /* set the lcore ID in per-lcore memory area */
+ RTE_PER_LCORE(_lcore_id) = lcore_id;
+
+ /* set CPU affinity */
+ if (eal_thread_set_affinity() < 0)
+ rte_panic("cannot set affinity\n");
+
+ ret = eal_thread_dump_affinity(cpuset, RTE_CPU_AFFINITY_STR_LEN);
+
+ RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%x;cpuset=[%s%s])\n",
+ lcore_id, (int)thread_id, cpuset, ret == 0 ? "" : "...");
+
+ /* read on our pipe to get commands */
+ while (1) {
+ void *fct_arg;
+
+ /* wait command */
+ do {
+ n = read(m2s, &c, 1);
+ } while (n < 0 && errno == EINTR);
+
+ if (n <= 0)
+ rte_panic("cannot read on configuration pipe\n");
+
+ lcore_config[lcore_id].state = RUNNING;
+
+ /* send ack */
+ n = 0;
+ while (n == 0 || (n < 0 && errno == EINTR))
+ n = write(s2m, &c, 1);
+ if (n < 0)
+ rte_panic("cannot write on configuration pipe\n");
+
+ if (lcore_config[lcore_id].f == NULL)
+ rte_panic("NULL function pointer\n");
+
+ /* call the function and store the return value */
+ fct_arg = lcore_config[lcore_id].arg;
+ ret = lcore_config[lcore_id].f(fct_arg);
+ lcore_config[lcore_id].ret = ret;
+ rte_wmb();
+ lcore_config[lcore_id].state = FINISHED;
+ }
+
+ /* never reached */
+ /* pthread_exit(NULL); */
+ /* return NULL; */
+}
+
+/* require calling thread tid by gettid() */
+int rte_sys_gettid(void)
+{
+ return 0; // (int)syscall(SYS_gettid);
+}
+
+int rte_thread_setname(pthread_t id, const char *name)
+{
+ int ret = 0;
+ RTE_SET_USED(id);
+ RTE_SET_USED(name);
+ return -ret;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/eal_timer.c b/lib/librte_eal/windows/eal/eal_timer.c
new file mode 100644
index 000000000..3bf57b053
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_timer.c
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_windows.h>
+
+#include <rte_cycles.h>
+
+#include "eal_private.h"
+
+enum timer_source eal_timer_source;
+
+uint64_t
+get_tsc_freq_arch(void)
+{
+ /* This function is not supported on Windows */
+ return 0;
+}
+
+uint64_t
+get_tsc_freq(void)
+{
+ uint64_t tsc_freq;
+ LARGE_INTEGER Frequency;
+
+ QueryPerformanceFrequency(&Frequency);
+ /* mulitply by 1K to obtain the true frequency of the CPU */
+ tsc_freq = ((uint64_t)Frequency.QuadPart * 1024);
+
+ return tsc_freq;
+}
+
+int
+rte_eal_timer_init(void)
+{
+ eal_timer_source = EAL_TIMER_TSC;
+
+ set_tsc_freq();
+ return 0;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/_rand48.c b/lib/librte_eal/windows/eal/linux-emu/_rand48.c
new file mode 100644
index 000000000..1694c19e1
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/_rand48.c
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#include "rand48.h"
+
+unsigned short _rand48_seed[3] = {
+ RAND48_SEED_0,
+ RAND48_SEED_1,
+ RAND48_SEED_2
+};
+unsigned short _rand48_mult[3] = {
+ RAND48_MULT_0,
+ RAND48_MULT_1,
+ RAND48_MULT_2
+};
+unsigned short _rand48_add = RAND48_ADD;
+
+void
+_dorand48(unsigned short xseed[3])
+{
+ unsigned long accu;
+ unsigned short temp[2];
+
+ accu = (unsigned long)_rand48_mult[0] * (unsigned long)xseed[0] +
+ (unsigned long)_rand48_add;
+ temp[0] = (unsigned short)accu; /* lower 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += (unsigned long)_rand48_mult[0] * (unsigned long)xseed[1] +
+ (unsigned long)_rand48_mult[1] * (unsigned long)xseed[0];
+ temp[1] = (unsigned short)accu; /* middle 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0];
+ xseed[0] = temp[0];
+ xseed[1] = temp[1];
+ xseed[2] = (unsigned short)accu;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/drand48.c b/lib/librte_eal/windows/eal/linux-emu/drand48.c
new file mode 100644
index 000000000..fec311d3a
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/drand48.c
@@ -0,0 +1,62 @@
+
+#define RAND48_SEED_0 (0x330e)
+#define RAND48_SEED_1 (0xabcd)
+#define RAND48_SEED_2 (0x1234)
+#define RAND48_MULT_0 (0xe66d)
+#define RAND48_MULT_1 (0xdeec)
+#define RAND48_MULT_2 (0x0005)
+#define RAND48_ADD (0x000b)
+
+unsigned short _rand48_seed[3] = {
+ RAND48_SEED_0,
+ RAND48_SEED_1,
+ RAND48_SEED_2
+};
+unsigned short _rand48_mult[3] = {
+ RAND48_MULT_0,
+ RAND48_MULT_1,
+ RAND48_MULT_2
+};
+unsigned short _rand48_add = RAND48_ADD;
+
+void
+_dorand48(unsigned short xseed[3])
+{
+ unsigned long accu;
+ unsigned short temp[2];
+
+ accu = (unsigned long)_rand48_mult[0] * (unsigned long)xseed[0] +
+ (unsigned long)_rand48_add;
+ temp[0] = (unsigned short)accu; /* lower 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += (unsigned long)_rand48_mult[0] * (unsigned long)xseed[1] +
+ (unsigned long)_rand48_mult[1] * (unsigned long)xseed[0];
+ temp[1] = (unsigned short)accu; /* middle 16 bits */
+ accu >>= sizeof(unsigned short) * 8;
+ accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0];
+ xseed[0] = temp[0];
+ xseed[1] = temp[1];
+ xseed[2] = (unsigned short)accu;
+}
+
+double erand48(unsigned short xseed[3])
+{
+ _dorand48(xseed);
+ return ldexp((double)xseed[0], -48) +
+ ldexp((double)xseed[1], -32) +
+ ldexp((double)xseed[2], -16);
+}
+
+double drand48() {
+ return erand48(_rand48_seed);
+}
+
+void srand48(long seed) {
+ _rand48_seed[0] = RAND48_SEED_0;
+ _rand48_seed[1] = (unsigned short)seed;
+ _rand48_seed[2] = (unsigned short)(seed >> 16);
+ _rand48_mult[0] = RAND48_MULT_0;
+ _rand48_mult[1] = RAND48_MULT_1;
+ _rand48_mult[2] = RAND48_MULT_2;
+ _rand48_add = RAND48_ADD;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/fork.c b/lib/librte_eal/windows/eal/linux-emu/fork.c
new file mode 100644
index 000000000..55bd96087
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/fork.c
@@ -0,0 +1,111 @@
+/*
+* fork.c
+* Experimental fork() on Windows. Requires NT 6 subsystem or
+* newer.
+*
+* Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* This software is provided 'as is' and without any warranty, express or
+* implied. In no event shall the authors be liable for any damages arising
+* from the use of this software.
+*/
+
+//#define _WIN32_WINNT 0x0600
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winnt.h>
+#include <winternl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include <process.h>
+
+typedef struct _SECTION_IMAGE_INFORMATION {
+ PVOID EntryPoint;
+ ULONG StackZeroBits;
+ ULONG StackReserved;
+ ULONG StackCommit;
+ ULONG ImageSubsystem;
+ WORD SubSystemVersionLow;
+ WORD SubSystemVersionHigh;
+ ULONG Unknown1;
+ ULONG ImageCharacteristics;
+ ULONG ImageMachineType;
+ ULONG Unknown2[3];
+} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
+
+typedef struct _RTL_USER_PROCESS_INFORMATION {
+ ULONG Size;
+ HANDLE Process;
+ HANDLE Thread;
+ CLIENT_ID ClientId;
+ SECTION_IMAGE_INFORMATION ImageInformation;
+} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
+
+#define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED 0x00000001
+#define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES 0x00000002
+#define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE 0x00000004
+
+#define RTL_CLONE_PARENT 0
+#define RTL_CLONE_CHILD 297
+
+typedef DWORD pid_t;
+
+typedef NTSTATUS(*RtlCloneUserProcess_f)(ULONG ProcessFlags,
+ PSECURITY_DESCRIPTOR ProcessSecurityDescriptor /* optional */,
+ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor /* optional */,
+ HANDLE DebugPort /* optional */,
+ PRTL_USER_PROCESS_INFORMATION ProcessInformation);
+
+pid_t fork(void)
+{
+ HMODULE mod;
+ RtlCloneUserProcess_f clone_p;
+ RTL_USER_PROCESS_INFORMATION process_info;
+ NTSTATUS result;
+
+ mod = GetModuleHandle((LPCWSTR)"ntdll.dll");
+ if (!mod)
+ return -ENOSYS;
+
+ clone_p = (RtlCloneUserProcess_f)GetProcAddress(mod, "RtlCloneUserProcess");
+ if (clone_p == NULL)
+ return -ENOSYS;
+
+ /* lets do this */
+ result = clone_p(RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED | RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, NULL, NULL, NULL, &process_info);
+
+ if (result == RTL_CLONE_PARENT)
+ {
+ HANDLE me, hp, ht, hcp = 0;
+ DWORD pi, ti, mi;
+ me = GetCurrentProcess();
+ pi = (DWORD)process_info.ClientId.UniqueProcess;
+ ti = (DWORD)process_info.ClientId.UniqueThread;
+
+ hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi);
+ ht = OpenThread(THREAD_ALL_ACCESS, FALSE, ti);
+ assert(hp);
+ assert(ht);
+
+ ResumeThread(ht);
+ CloseHandle(ht);
+ CloseHandle(hp);
+ return (pid_t)pi;
+ }
+ else if (result == RTL_CLONE_CHILD)
+ {
+ /* fix stdio */
+ AllocConsole();
+ return 0;
+ }
+ else
+ return -1;
+
+ /* NOTREACHED */
+ return -1;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/getopt.c b/lib/librte_eal/windows/eal/linux-emu/getopt.c
new file mode 100644
index 000000000..8383e85ae
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/getopt.c
@@ -0,0 +1,407 @@
+#include <getopt.h>
+
+#ifdef REPLACE_GETOPT
+int opterr = 1; /* if error message should be printed */
+int optind = 1; /* index into parent argv vector */
+int optopt = '?'; /* character checked for validity */
+#undef optreset /* see getopt.h */
+#define optreset __mingw_optreset
+int optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+#endif
+
+static char *place = EMSG; /* option letter processing */
+
+ /* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1; /* first option after non options (for permute) */
+
+ /* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+/*
+* parse_long_options --
+* Parse long options in argc/argv argument vector.
+* Returns -1 if short_too is set and the option does not match long_options.
+*/
+static int
+parse_long_options(char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int short_too)
+{
+ char *current_argv, *has_equal;
+ size_t current_argv_len;
+ int i, ambiguous, match;
+
+#define IDENTICAL_INTERPRETATION(_x, _y) \
+ (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
+ long_options[(_x)].flag == long_options[(_y)].flag && \
+ long_options[(_x)].val == long_options[(_y)].val)
+
+ current_argv = place;
+ match = -1;
+ ambiguous = 0;
+
+ optind++;
+
+ if ((has_equal = strchr(current_argv, '=')) != NULL) {
+ /* argument found (--option=arg) */
+ current_argv_len = has_equal - current_argv;
+ has_equal++;
+ }
+ else
+ current_argv_len = strlen(current_argv);
+
+ for (i = 0; long_options[i].name; i++) {
+ /* find matching long option */
+ if (strncmp(current_argv, long_options[i].name,
+ current_argv_len))
+ continue;
+
+ if (strlen(long_options[i].name) == current_argv_len) {
+ /* exact match */
+ match = i;
+ ambiguous = 0;
+ break;
+ }
+ /*
+ * If this is a known short option, don't allow
+ * a partial match of a single character.
+ */
+ if (short_too && current_argv_len == 1)
+ continue;
+
+ if (match == -1) /* partial match */
+ match = i;
+ else if (!IDENTICAL_INTERPRETATION(i, match))
+ ambiguous = 1;
+ }
+ if (ambiguous) {
+ /* ambiguous abbreviation */
+ if (PRINT_ERROR)
+ warnx(ambig, (int)current_argv_len,
+ current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ if (match != -1) { /* option found */
+ if (long_options[match].has_arg == no_argument
+ && has_equal) {
+ if (PRINT_ERROR)
+ warnx(noarg, (int)current_argv_len,
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ return (BADARG);
+ }
+ if (long_options[match].has_arg == required_argument ||
+ long_options[match].has_arg == optional_argument) {
+ if (has_equal)
+ optarg = has_equal;
+ else if (long_options[match].has_arg ==
+ required_argument) {
+ /*
+ * optional argument doesn't use next nargv
+ */
+ optarg = nargv[optind++];
+ }
+ }
+ if ((long_options[match].has_arg == required_argument)
+ && (optarg == NULL)) {
+ /*
+ * Missing argument; leading ':' indicates no error
+ * should be generated.
+ */
+ if (PRINT_ERROR)
+ warnx(recargstring,
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ --optind;
+ return (BADARG);
+ }
+ }
+ else { /* unknown option */
+ if (short_too) {
+ --optind;
+ return (-1);
+ }
+ if (PRINT_ERROR)
+ warnx(illoptstring, current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ if (idx)
+ *idx = match;
+ if (long_options[match].flag) {
+ *long_options[match].flag = long_options[match].val;
+ return (0);
+ }
+ else
+ return (long_options[match].val);
+#undef IDENTICAL_INTERPRETATION
+}
+
+#ifdef REPLACE_GETOPT
+/*
+* getopt --
+* Parse argc/argv argument vector.
+*
+* [eventually this will replace the BSD getopt]
+*/
+int
+getopt(int nargc, char * const *nargv, const char *options)
+{
+
+ /*
+ * We don't pass FLAG_PERMUTE to getopt_internal() since
+ * the BSD getopt(3) (unlike GNU) has never done this.
+ *
+ * Furthermore, since many privileged programs call getopt()
+ * before dropping privileges it makes sense to keep things
+ * as simple (and bug-free) as possible.
+ */
+ return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
+}
+#endif /* REPLACE_GETOPT */
+
+/*
+* getopt_internal --
+* Parse argc/argv argument vector. Called by user level routines.
+*/
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int flags)
+{
+ char *oli; /* option letter list index */
+ int optchar, short_too;
+ static int posixly_correct = -1;
+
+ if (options == NULL)
+ return (-1);
+
+ /*
+ * XXX Some GNU programs (like cvs) set optind to 0 instead of
+ * XXX using optreset. Work around this braindamage.
+ */
+ if (optind == 0)
+ optind = optreset = 1;
+
+ /*
+ * Disable GNU extensions if POSIXLY_CORRECT is set or options
+ * string begins with a '+'.
+ *
+ * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or
+ * optreset != 0 for GNU compatibility.
+ */
+ if (posixly_correct == -1 || optreset != 0)
+ posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+ if (*options == '-')
+ flags |= FLAG_ALLARGS;
+ else if (posixly_correct || *options == '+')
+ flags &= ~FLAG_PERMUTE;
+ if (*options == '+' || *options == '-')
+ options++;
+
+ optarg = NULL;
+ if (optreset)
+ nonopt_start = nonopt_end = -1;
+start:
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc) { /* end of argument vector */
+ place = EMSG;
+ if (nonopt_end != -1) {
+ /* do permutation, if we have to */
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ else if (nonopt_start != -1) {
+ /*
+ * If we skipped non-options, set optind
+ * to the first of them.
+ */
+ optind = nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ if (*(place = nargv[optind]) != '-' ||
+ (place[1] == '\0' && strchr(options, '-') == NULL)) {
+ place = EMSG; /* found non-option */
+ if (flags & FLAG_ALLARGS) {
+ /*
+ * GNU extension:
+ * return non-option as argument to option 1
+ */
+ optarg = nargv[optind++];
+ return (INORDER);
+ }
+ if (!(flags & FLAG_PERMUTE)) {
+ /*
+ * If no permutation wanted, stop parsing
+ * at first non-option.
+ */
+ return (-1);
+ }
+ /* do permutation */
+ if (nonopt_start == -1)
+ nonopt_start = optind;
+ else if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ nonopt_start = optind -
+ (nonopt_end - nonopt_start);
+ nonopt_end = -1;
+ }
+ optind++;
+ /* process next argument */
+ goto start;
+ }
+ if (nonopt_start != -1 && nonopt_end == -1)
+ nonopt_end = optind;
+
+ /*
+ * If we have "-" do nothing, if "--" we are done.
+ */
+ if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+ optind++;
+ place = EMSG;
+ /*
+ * We found an option (--), so if we skipped
+ * non-options, we have to permute.
+ */
+ if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ }
+
+ /*
+ * Check long options if:
+ * 1) we were passed some
+ * 2) the arg is not just "-"
+ * 3) either the arg starts with -- we are getopt_long_only()
+ */
+ if (long_options != NULL && place != nargv[optind] &&
+ (*place == '-' || (flags & FLAG_LONGONLY))) {
+ short_too = 0;
+ if (*place == '-')
+ place++; /* --foo long option */
+ else if (*place != ':' && strchr(options, *place) != NULL)
+ short_too = 1; /* could be short option too */
+
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, short_too);
+ if (optchar != -1) {
+ place = EMSG;
+ return (optchar);
+ }
+ }
+
+ if ((optchar = (int)*place++) == (int)':' ||
+ (optchar == (int)'-' && *place != '\0') ||
+ (oli = (char*)strchr(options, optchar)) == NULL) {
+ /*
+ * If the user specified "-" and '-' isn't listed in
+ * options, return -1 (non-option) as per POSIX.
+ * Otherwise, it is an unknown option character (or ':').
+ */
+ if (optchar == (int)'-' && *place == '\0')
+ return (-1);
+ if (!*place)
+ ++optind;
+ if (PRINT_ERROR)
+ warnx(illoptchar, optchar);
+ optopt = optchar;
+ return (BADCH);
+ }
+ if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+ /* -W long-option */
+ if (*place) /* no space */
+ /* NOTHING */;
+ else if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ }
+ else /* white space */
+ place = nargv[optind];
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, 0);
+ place = EMSG;
+ return (optchar);
+ }
+ if (*++oli != ':') { /* doesn't take argument */
+ if (!*place)
+ ++optind;
+ }
+ else { /* takes (optional) argument */
+ optarg = NULL;
+ if (*place) /* no white space */
+ optarg = place;
+ else if (oli[1] != ':') { /* arg not optional */
+ if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ }
+ else
+ optarg = nargv[optind];
+ }
+ place = EMSG;
+ ++optind;
+ }
+ /* dump back option letter */
+ return (optchar);
+}
+
+
+/*
+* getopt_long --
+* Parse argc/argv argument vector.
+*/
+int
+getopt_long(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE));
+}
+
+/*
+* getopt_long_only --
+* Parse argc/argv argument vector.
+*/
+int
+getopt_long_only(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE | FLAG_LONGONLY));
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/lrand48.c b/lib/librte_eal/windows/eal/linux-emu/lrand48.c
new file mode 100644
index 000000000..687d0f7b2
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/lrand48.c
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+
+long
+lrand48(void)
+{
+ _dorand48(_rand48_seed);
+ return ((long)_rand48_seed[2] << 15) + ((long)_rand48_seed[1] >> 1);
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/mman.c b/lib/librte_eal/windows/eal/linux-emu/mman.c
new file mode 100644
index 000000000..0a8d39038
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/mman.c
@@ -0,0 +1,179 @@
+#include <windows.h>
+#include <errno.h>
+#include <io.h>
+
+#include <sys/mman.h>
+
+#ifndef FILE_MAP_EXECUTE
+#define FILE_MAP_EXECUTE 0x0020
+#endif /* FILE_MAP_EXECUTE */
+
+static int __map_mman_error(const DWORD err, const int deferr)
+{
+ if (err == 0)
+ return 0;
+ //TODO: implement
+ return err;
+}
+
+static DWORD __map_mmap_prot_page(const int prot)
+{
+ DWORD protect = 0;
+
+ if (prot == PROT_NONE)
+ return protect;
+
+ if ((prot & PROT_EXEC) != 0)
+ {
+ protect = ((prot & PROT_WRITE) != 0) ?
+ PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
+ }
+ else
+ {
+ protect = ((prot & PROT_WRITE) != 0) ?
+ PAGE_READWRITE : PAGE_READONLY;
+ }
+
+ return protect;
+}
+
+static DWORD __map_mmap_prot_file(const int prot)
+{
+ DWORD desiredAccess = 0;
+
+ if (prot == PROT_NONE)
+ return desiredAccess;
+
+ if ((prot & PROT_READ) != 0)
+ desiredAccess |= FILE_MAP_READ;
+ if ((prot & PROT_WRITE) != 0)
+ desiredAccess |= FILE_MAP_WRITE;
+ if ((prot & PROT_EXEC) != 0)
+ desiredAccess |= FILE_MAP_EXECUTE;
+
+ return desiredAccess;
+}
+
+void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off)
+{
+ HANDLE fm, h;
+
+ void * map = MAP_FAILED;
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4293)
+#endif
+
+ const DWORD dwFileOffsetLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
+ (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
+ const DWORD dwFileOffsetHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
+ (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
+ const DWORD protect = __map_mmap_prot_page(prot);
+ const DWORD desiredAccess = __map_mmap_prot_file(prot);
+
+ const OffsetType maxSize = off + (OffsetType)len;
+
+ const DWORD dwMaxSizeLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
+ (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
+ const DWORD dwMaxSizeHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
+ (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+ errno = 0;
+
+ if (len == 0
+ /* Unsupported flag combinations */
+ || (flags & MAP_FIXED) != 0
+ /* Usupported protection combinations */
+ || prot == PROT_EXEC)
+ {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ h = ((flags & MAP_ANONYMOUS) == 0) ?
+ (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
+
+ if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
+ {
+ errno = EBADF;
+ return MAP_FAILED;
+ }
+
+ fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
+
+ if (fm == NULL)
+ {
+ errno = __map_mman_error(GetLastError(), EPERM);
+ return MAP_FAILED;
+ }
+
+ map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
+
+ CloseHandle(fm);
+
+ if (map == NULL)
+ {
+ errno = __map_mman_error(GetLastError(), EPERM);
+ return MAP_FAILED;
+ }
+
+ return map;
+}
+
+int munmap(void *addr, size_t len)
+{
+ if (UnmapViewOfFile(addr))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
+
+int _mprotect(void *addr, size_t len, int prot)
+{
+ DWORD newProtect = __map_mmap_prot_page(prot);
+ DWORD oldProtect = 0;
+
+ if (VirtualProtect(addr, len, newProtect, &oldProtect))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
+
+int msync(void *addr, size_t len, int flags)
+{
+ if (FlushViewOfFile(addr, len))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
+
+int mlock(const void *addr, size_t len)
+{
+ if (VirtualLock((LPVOID)addr, len))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
+
+int munlock(const void *addr, size_t len)
+{
+ if (VirtualUnlock((LPVOID)addr, len))
+ return 0;
+
+ errno = __map_mman_error(GetLastError(), EPERM);
+
+ return -1;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/setenv.c b/lib/librte_eal/windows/eal/linux-emu/setenv.c
new file mode 100644
index 000000000..bd54bfcb1
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/setenv.c
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <stdlib.h>
+
+int setenv(const char *name, const char *value, int overwrite)
+{
+ char * curenv;
+ size_t len;
+
+ // Does the environment variable already exist?
+ errno_t err = _dupenv_s(&curenv, &len, name);
+
+ // Free the allocated memory - it is okay to call free(NULL)
+ free(curenv);
+
+ if (err || overwrite)
+ {
+ char newval[128];
+ sprintf_s(newval, sizeof(newval), "%s=%s", name, value);
+ return _putenv(newval);
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/linux-emu/srand48.c b/lib/librte_eal/windows/eal/linux-emu/srand48.c
new file mode 100644
index 000000000..071ef1df9
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/srand48.c
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+extern unsigned short _rand48_mult[3];
+extern unsigned short _rand48_add;
+
+void
+srand48(long seed)
+{
+ _rand48_seed[0] = RAND48_SEED_0;
+ _rand48_seed[1] = (unsigned short)seed;
+ _rand48_seed[2] = (unsigned short)(seed >> 16);
+ _rand48_mult[0] = RAND48_MULT_0;
+ _rand48_mult[1] = RAND48_MULT_1;
+ _rand48_mult[2] = RAND48_MULT_2;
+ _rand48_add = RAND48_ADD;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/termios.c b/lib/librte_eal/windows/eal/linux-emu/termios.c
new file mode 100644
index 000000000..d81a26f53
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/termios.c
@@ -0,0 +1,11 @@
+#include <sys/_termios.h>
+
+int tcgetattr(int fd, struct termios *t)
+{
+ return 0;
+}
+
+int tcsetattr(int fd, int opt, struct termios *t)
+{
+ return 0;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/linux-emu/unistd.c b/lib/librte_eal/windows/eal/linux-emu/unistd.c
new file mode 100644
index 000000000..fa0eee9c9
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/unistd.c
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <unistd.h>
+#include <windows.h>
+
+int getpagesize(void)
+{
+ SYSTEM_INFO si;
+
+ GetSystemInfo(&si);
+
+ return si.dwPageSize;
+}
+
+int getdtablesize(void)
+{
+ // Return OPEN_MAX (256)
+ return 256;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/malloc_heap.c b/lib/librte_eal/windows/eal/malloc_heap.c
new file mode 100644
index 000000000..62b4c39c2
--- /dev/null
+++ b/lib/librte_eal/windows/eal/malloc_heap.c
@@ -0,0 +1,1068 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <rte_memory.h>
+#include <rte_errno.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_launch.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_common.h>
+#include <rte_string_fns.h>
+#include <rte_spinlock.h>
+#include <rte_memcpy.h>
+#include <rte_atomic.h>
+#include <rte_fbarray.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_memalloc.h"
+#include "malloc_elem.h"
+#include "malloc_heap.h"
+#include "malloc_mp.h"
+
+static unsigned
+check_hugepage_sz(unsigned flags, uint64_t hugepage_sz)
+{
+ unsigned check_flag = 0;
+
+ if (!(flags & ~RTE_MEMZONE_SIZE_HINT_ONLY))
+ return 1;
+
+ switch (hugepage_sz) {
+ case RTE_PGSIZE_256K:
+ check_flag = RTE_MEMZONE_256KB;
+ break;
+ case RTE_PGSIZE_2M:
+ check_flag = RTE_MEMZONE_2MB;
+ break;
+ case RTE_PGSIZE_16M:
+ check_flag = RTE_MEMZONE_16MB;
+ break;
+ case RTE_PGSIZE_256M:
+ check_flag = RTE_MEMZONE_256MB;
+ break;
+ case RTE_PGSIZE_512M:
+ check_flag = RTE_MEMZONE_512MB;
+ break;
+ case RTE_PGSIZE_1G:
+ check_flag = RTE_MEMZONE_1GB;
+ break;
+ }
+
+ return check_flag & flags;
+}
+
+/*
+ * Expand the heap with a memory area.
+ */
+static struct malloc_elem *
+malloc_heap_add_memory(struct malloc_heap *heap, struct rte_memseg_list *msl,
+ void *start, size_t len)
+{
+ struct malloc_elem *elem = start;
+
+ malloc_elem_init(elem, heap, msl, len);
+
+ malloc_elem_insert(elem);
+
+ elem = malloc_elem_join_adjacent_free(elem);
+
+ malloc_elem_free_list_insert(elem);
+
+ return elem;
+}
+
+static int
+malloc_add_seg(const struct rte_memseg_list *msl,
+ const struct rte_memseg *ms, size_t len, void *arg __rte_unused)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ struct rte_memseg_list *found_msl;
+ struct malloc_heap *heap;
+ int msl_idx;
+
+ heap = &mcfg->malloc_heaps[msl->socket_id];
+
+ /* msl is const, so find it */
+ msl_idx = msl - mcfg->memsegs;
+
+ if (msl_idx < 0 || msl_idx >= RTE_MAX_MEMSEG_LISTS)
+ return -1;
+
+ found_msl = &mcfg->memsegs[msl_idx];
+
+ malloc_heap_add_memory(heap, found_msl, ms->addr, len);
+
+ heap->total_size += len;
+
+ RTE_LOG(DEBUG, EAL, "Added %zuM to heap on socket %i\n", len >> 20,
+ msl->socket_id);
+ return 0;
+}
+
+/*
+ * Iterates through the freelist for a heap to find a free element
+ * which can store data of the required size and with the requested alignment.
+ * If size is 0, find the biggest available elem.
+ * Returns null on failure, or pointer to element on success.
+ */
+static struct malloc_elem *
+find_suitable_element(struct malloc_heap *heap, size_t size,
+ unsigned int flags, size_t align, size_t bound, bool contig)
+{
+ size_t idx;
+ struct malloc_elem *elem, *alt_elem = NULL;
+
+ for (idx = malloc_elem_free_list_index(size);
+ idx < RTE_HEAP_NUM_FREELISTS; idx++) {
+ for (elem = LIST_FIRST(&heap->free_head[idx]);
+ !!elem; elem = LIST_NEXT(elem, free_list)) {
+ if (malloc_elem_can_hold(elem, size, align, bound,
+ contig)) {
+ if (check_hugepage_sz(flags,
+ elem->msl->page_sz))
+ return elem;
+ if (alt_elem == NULL)
+ alt_elem = elem;
+ }
+ }
+ }
+
+ if ((alt_elem != NULL) && (flags & RTE_MEMZONE_SIZE_HINT_ONLY))
+ return alt_elem;
+
+ return NULL;
+}
+
+/*
+ * Iterates through the freelist for a heap to find a free element with the
+ * biggest size and requested alignment. Will also set size to whatever element
+ * size that was found.
+ * Returns null on failure, or pointer to element on success.
+ */
+static struct malloc_elem *
+find_biggest_element(struct malloc_heap *heap, size_t *size,
+ unsigned int flags, size_t align, bool contig)
+{
+ struct malloc_elem *elem, *max_elem = NULL;
+ size_t idx, max_size = 0;
+
+ for (idx = 0; idx < RTE_HEAP_NUM_FREELISTS; idx++) {
+ for (elem = LIST_FIRST(&heap->free_head[idx]);
+ !!elem; elem = LIST_NEXT(elem, free_list)) {
+ size_t cur_size;
+ if (!check_hugepage_sz(flags, elem->msl->page_sz))
+ continue;
+ if (contig) {
+ cur_size =
+ malloc_elem_find_max_iova_contig(elem,
+ align);
+ } else {
+ void *data_start = RTE_PTR_ADD(elem,
+ MALLOC_ELEM_HEADER_LEN);
+ void *data_end = RTE_PTR_ADD(elem, elem->size -
+ MALLOC_ELEM_TRAILER_LEN);
+ void *aligned = RTE_PTR_ALIGN_CEIL(data_start,
+ align);
+ /* check if aligned data start is beyond end */
+ if (aligned >= data_end)
+ continue;
+ cur_size = RTE_PTR_DIFF(data_end, aligned);
+ }
+ if (cur_size > max_size) {
+ max_size = cur_size;
+ max_elem = elem;
+ }
+ }
+ }
+
+ *size = max_size;
+ return max_elem;
+}
+
+/*
+ * Main function to allocate a block of memory from the heap.
+ * It locks the free list, scans it, and adds a new memseg if the
+ * scan fails. Once the new memseg is added, it re-scans and should return
+ * the new element after releasing the lock.
+ */
+static void *
+heap_alloc(struct malloc_heap *heap, const char *type __rte_unused, size_t size,
+ unsigned int flags, size_t align, size_t bound, bool contig)
+{
+ struct malloc_elem *elem;
+
+ size = RTE_CACHE_LINE_ROUNDUP(size);
+ align = RTE_CACHE_LINE_ROUNDUP(align);
+
+ elem = find_suitable_element(heap, size, flags, align, bound, contig);
+ if (elem != NULL) {
+ elem = malloc_elem_alloc(elem, size, align, bound, contig);
+
+ /* increase heap's count of allocated elements */
+ heap->alloc_count++;
+ }
+
+ return elem == NULL ? NULL : (void *)(&elem[1]);
+}
+
+static void *
+heap_alloc_biggest(struct malloc_heap *heap, const char *type __rte_unused,
+ unsigned int flags, size_t align, bool contig)
+{
+ struct malloc_elem *elem;
+ size_t size;
+
+ align = RTE_CACHE_LINE_ROUNDUP(align);
+
+ elem = find_biggest_element(heap, &size, flags, align, contig);
+ if (elem != NULL) {
+ elem = malloc_elem_alloc(elem, size, align, 0, contig);
+
+ /* increase heap's count of allocated elements */
+ heap->alloc_count++;
+ }
+
+ return elem == NULL ? NULL : (void *)(&elem[1]);
+}
+
+/* this function is exposed in malloc_mp.h */
+void
+rollback_expand_heap(struct rte_memseg **ms, int n_segs,
+ struct malloc_elem *elem, void *map_addr, size_t map_len)
+{
+ if (elem != NULL) {
+ malloc_elem_free_list_remove(elem);
+ malloc_elem_hide_region(elem, map_addr, map_len);
+ }
+
+ eal_memalloc_free_seg_bulk(ms, n_segs);
+}
+
+/* this function is exposed in malloc_mp.h */
+struct malloc_elem *
+alloc_pages_on_heap(struct malloc_heap *heap, uint64_t pg_sz, size_t elt_size,
+ int socket, unsigned int flags, size_t align, size_t bound,
+ bool contig, struct rte_memseg **ms, int n_segs)
+{
+ struct rte_memseg_list *msl;
+ struct malloc_elem *elem = NULL;
+ size_t alloc_sz;
+ int allocd_pages;
+ void *ret, *map_addr;
+
+ alloc_sz = (size_t)pg_sz * n_segs;
+
+ /* first, check if we're allowed to allocate this memory */
+ if (eal_memalloc_mem_alloc_validate(socket,
+ heap->total_size + alloc_sz) < 0) {
+ RTE_LOG(DEBUG, EAL, "User has disallowed allocation\n");
+ return NULL;
+ }
+
+ allocd_pages = eal_memalloc_alloc_seg_bulk(ms, n_segs, pg_sz,
+ socket, true);
+
+ /* make sure we've allocated our pages... */
+ if (allocd_pages < 0)
+ return NULL;
+
+ map_addr = ms[0]->addr;
+ msl = rte_mem_virt2memseg_list(map_addr);
+
+ /* check if we wanted contiguous memory but didn't get it */
+ if (contig && !eal_memalloc_is_contig(msl, map_addr, alloc_sz)) {
+ RTE_LOG(DEBUG, EAL, "%s(): couldn't allocate physically contiguous space\n",
+ __func__);
+ goto fail;
+ }
+
+ /* add newly minted memsegs to malloc heap */
+ elem = malloc_heap_add_memory(heap, msl, map_addr, alloc_sz);
+
+ /* try once more, as now we have allocated new memory */
+ ret = find_suitable_element(heap, elt_size, flags, align, bound,
+ contig);
+
+ if (ret == NULL)
+ goto fail;
+
+ return elem;
+
+fail:
+ rollback_expand_heap(ms, n_segs, elem, map_addr, alloc_sz);
+ return NULL;
+}
+
+static int
+try_expand_heap_primary(struct malloc_heap *heap, uint64_t pg_sz,
+ size_t elt_size, int socket, unsigned int flags, size_t align,
+ size_t bound, bool contig)
+{
+ struct malloc_elem *elem;
+ struct rte_memseg **ms;
+ void *map_addr;
+ size_t alloc_sz;
+ int n_segs;
+ bool callback_triggered = false;
+
+ alloc_sz = RTE_ALIGN_CEIL(align + elt_size +
+ MALLOC_ELEM_TRAILER_LEN, pg_sz);
+ n_segs = alloc_sz / pg_sz;
+
+ /* we can't know in advance how many pages we'll need, so we malloc */
+ ms = malloc(sizeof(*ms) * n_segs);
+
+ memset(ms, 0, sizeof(*ms) * n_segs);
+
+ if (ms == NULL)
+ return -1;
+
+ elem = alloc_pages_on_heap(heap, pg_sz, elt_size, socket, flags, align,
+ bound, contig, ms, n_segs);
+
+ if (elem == NULL)
+ goto free_ms;
+
+ map_addr = ms[0]->addr;
+
+ /* notify user about changes in memory map */
+ eal_memalloc_mem_event_notify(RTE_MEM_EVENT_ALLOC, map_addr, alloc_sz);
+
+ /* notify other processes that this has happened */
+ if (request_sync()) {
+ /* we couldn't ensure all processes have mapped memory,
+ * so free it back and notify everyone that it's been
+ * freed back.
+ *
+ * technically, we could've avoided adding memory addresses to
+ * the map, but that would've led to inconsistent behavior
+ * between primary and secondary processes, as those get
+ * callbacks during sync. therefore, force primary process to
+ * do alloc-and-rollback syncs as well.
+ */
+ callback_triggered = true;
+ goto free_elem;
+ }
+ heap->total_size += alloc_sz;
+
+ RTE_LOG(DEBUG, EAL, "Heap on socket %d was expanded by %zdMB\n",
+ socket, alloc_sz >> 20ULL);
+
+ free(ms);
+
+ return 0;
+
+free_elem:
+ if (callback_triggered)
+ eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE,
+ map_addr, alloc_sz);
+
+ rollback_expand_heap(ms, n_segs, elem, map_addr, alloc_sz);
+
+ request_sync();
+free_ms:
+ free(ms);
+
+ return -1;
+}
+
+static int
+try_expand_heap_secondary(struct malloc_heap *heap, uint64_t pg_sz,
+ size_t elt_size, int socket, unsigned int flags, size_t align,
+ size_t bound, bool contig)
+{
+ struct malloc_mp_req req;
+ int req_result;
+
+ memset(&req, 0, sizeof(req));
+
+ req.t = REQ_TYPE_ALLOC;
+ req.alloc_req.align = align;
+ req.alloc_req.bound = bound;
+ req.alloc_req.contig = contig;
+ req.alloc_req.flags = flags;
+ req.alloc_req.elt_size = elt_size;
+ req.alloc_req.page_sz = pg_sz;
+ req.alloc_req.socket = socket;
+ req.alloc_req.heap = heap; /* it's in shared memory */
+
+ req_result = request_to_primary(&req);
+
+ if (req_result != 0)
+ return -1;
+
+ if (req.result != REQ_RESULT_SUCCESS)
+ return -1;
+
+ return 0;
+}
+
+static int
+try_expand_heap(struct malloc_heap *heap, uint64_t pg_sz, size_t elt_size,
+ int socket, unsigned int flags, size_t align, size_t bound,
+ bool contig)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ int ret;
+
+ rte_rwlock_write_lock(&mcfg->memory_hotplug_lock);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ ret = try_expand_heap_primary(heap, pg_sz, elt_size, socket,
+ flags, align, bound, contig);
+ } else {
+ ret = try_expand_heap_secondary(heap, pg_sz, elt_size, socket,
+ flags, align, bound, contig);
+ }
+
+ rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);
+ return ret;
+}
+
+static int
+compare_pagesz(const void *a, const void *b)
+{
+ const struct rte_memseg_list * const*mpa = a;
+ const struct rte_memseg_list * const*mpb = b;
+ const struct rte_memseg_list *msla = *mpa;
+ const struct rte_memseg_list *mslb = *mpb;
+ uint64_t pg_sz_a = msla->page_sz;
+ uint64_t pg_sz_b = mslb->page_sz;
+
+ if (pg_sz_a < pg_sz_b)
+ return -1;
+ if (pg_sz_a > pg_sz_b)
+ return 1;
+ return 0;
+}
+
+static int
+alloc_more_mem_on_socket(struct malloc_heap *heap, size_t size, int socket,
+ unsigned int flags, size_t align, size_t bound, bool contig)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ struct rte_memseg_list *requested_msls[RTE_MAX_MEMSEG_LISTS];
+ struct rte_memseg_list *other_msls[RTE_MAX_MEMSEG_LISTS];
+ uint64_t requested_pg_sz[RTE_MAX_MEMSEG_LISTS];
+ uint64_t other_pg_sz[RTE_MAX_MEMSEG_LISTS];
+ uint64_t prev_pg_sz;
+ int i, n_other_msls, n_other_pg_sz, n_requested_msls, n_requested_pg_sz;
+ bool size_hint = (flags & RTE_MEMZONE_SIZE_HINT_ONLY) > 0;
+ unsigned int size_flags = flags & ~RTE_MEMZONE_SIZE_HINT_ONLY;
+ void *ret;
+
+ memset(requested_msls, 0, sizeof(requested_msls));
+ memset(other_msls, 0, sizeof(other_msls));
+ memset(requested_pg_sz, 0, sizeof(requested_pg_sz));
+ memset(other_pg_sz, 0, sizeof(other_pg_sz));
+
+ /*
+ * go through memseg list and take note of all the page sizes available,
+ * and if any of them were specifically requested by the user.
+ */
+ n_requested_msls = 0;
+ n_other_msls = 0;
+ for (i = 0; i < RTE_MAX_MEMSEG_LISTS; i++) {
+ struct rte_memseg_list *msl = &mcfg->memsegs[i];
+
+ if (msl->socket_id != socket)
+ continue;
+
+ if (msl->base_va == NULL)
+ continue;
+
+ /* if pages of specific size were requested */
+ if (size_flags != 0 && check_hugepage_sz(size_flags,
+ msl->page_sz))
+ requested_msls[n_requested_msls++] = msl;
+ else if (size_flags == 0 || size_hint)
+ other_msls[n_other_msls++] = msl;
+ }
+
+ /* sort the lists, smallest first */
+ qsort(requested_msls, n_requested_msls, sizeof(requested_msls[0]),
+ compare_pagesz);
+ qsort(other_msls, n_other_msls, sizeof(other_msls[0]),
+ compare_pagesz);
+
+ /* now, extract page sizes we are supposed to try */
+ prev_pg_sz = 0;
+ n_requested_pg_sz = 0;
+ for (i = 0; i < n_requested_msls; i++) {
+ uint64_t pg_sz = requested_msls[i]->page_sz;
+
+ if (prev_pg_sz != pg_sz) {
+ requested_pg_sz[n_requested_pg_sz++] = pg_sz;
+ prev_pg_sz = pg_sz;
+ }
+ }
+ prev_pg_sz = 0;
+ n_other_pg_sz = 0;
+ for (i = 0; i < n_other_msls; i++) {
+ uint64_t pg_sz = other_msls[i]->page_sz;
+
+ if (prev_pg_sz != pg_sz) {
+ other_pg_sz[n_other_pg_sz++] = pg_sz;
+ prev_pg_sz = pg_sz;
+ }
+ }
+
+ /* finally, try allocating memory of specified page sizes, starting from
+ * the smallest sizes
+ */
+ for (i = 0; i < n_requested_pg_sz; i++) {
+ uint64_t pg_sz = requested_pg_sz[i];
+
+ /*
+ * do not pass the size hint here, as user expects other page
+ * sizes first, before resorting to best effort allocation.
+ */
+ if (!try_expand_heap(heap, pg_sz, size, socket, size_flags,
+ align, bound, contig))
+ return 0;
+ }
+ if (n_other_pg_sz == 0)
+ return -1;
+
+ /* now, check if we can reserve anything with size hint */
+ ret = find_suitable_element(heap, size, flags, align, bound, contig);
+ if (ret != NULL)
+ return 0;
+
+ /*
+ * we still couldn't reserve memory, so try expanding heap with other
+ * page sizes, if there are any
+ */
+ for (i = 0; i < n_other_pg_sz; i++) {
+ uint64_t pg_sz = other_pg_sz[i];
+
+ if (!try_expand_heap(heap, pg_sz, size, socket, flags,
+ align, bound, contig))
+ return 0;
+ }
+ return -1;
+}
+
+/* this will try lower page sizes first */
+static void *
+heap_alloc_on_socket(const char *type, size_t size, int socket,
+ unsigned int flags, size_t align, size_t bound, bool contig)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ struct malloc_heap *heap = &mcfg->malloc_heaps[socket];
+ unsigned int size_flags = flags & ~RTE_MEMZONE_SIZE_HINT_ONLY;
+ void *ret;
+
+ rte_spinlock_lock(&(heap->lock));
+
+ align = align == 0 ? 1 : align;
+
+ /* for legacy mode, try once and with all flags */
+ if (internal_config.legacy_mem) {
+ ret = heap_alloc(heap, type, size, flags, align, bound, contig);
+ goto alloc_unlock;
+ }
+
+ /*
+ * we do not pass the size hint here, because even if allocation fails,
+ * we may still be able to allocate memory from appropriate page sizes,
+ * we just need to request more memory first.
+ */
+ ret = heap_alloc(heap, type, size, size_flags, align, bound, contig);
+ if (ret != NULL)
+ goto alloc_unlock;
+
+ if (!alloc_more_mem_on_socket(heap, size, socket, flags, align, bound,
+ contig)) {
+ ret = heap_alloc(heap, type, size, flags, align, bound, contig);
+
+ /* this should have succeeded */
+ if (ret == NULL)
+ RTE_LOG(ERR, EAL, "Error allocating from heap\n");
+ }
+alloc_unlock:
+ rte_spinlock_unlock(&(heap->lock));
+ return ret;
+}
+
+void *
+malloc_heap_alloc(const char *type, size_t size, int socket_arg,
+ unsigned int flags, size_t align, size_t bound, bool contig)
+{
+ int socket, i, cur_socket;
+ void *ret;
+
+ /* return NULL if size is 0 or alignment is not power-of-2 */
+ if (size == 0 || (align && !rte_is_power_of_2(align)))
+ return NULL;
+
+ if (!rte_eal_has_hugepages())
+ socket_arg = SOCKET_ID_ANY;
+
+ if (socket_arg == SOCKET_ID_ANY)
+ socket = malloc_get_numa_socket();
+ else
+ socket = socket_arg;
+
+ /* Check socket parameter */
+ if (socket >= RTE_MAX_NUMA_NODES)
+ return NULL;
+
+ ret = heap_alloc_on_socket(type, size, socket, flags, align, bound,
+ contig);
+ if (ret != NULL || socket_arg != SOCKET_ID_ANY)
+ return ret;
+
+ /* try other heaps */
+ for (i = 0; i < (int) rte_socket_count(); i++) {
+ cur_socket = rte_socket_id_by_idx(i);
+ if (cur_socket == socket)
+ continue;
+ ret = heap_alloc_on_socket(type, size, cur_socket, flags,
+ align, bound, contig);
+ if (ret != NULL)
+ return ret;
+ }
+ return NULL;
+}
+
+static void *
+heap_alloc_biggest_on_socket(const char *type, int socket, unsigned int flags,
+ size_t align, bool contig)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ struct malloc_heap *heap = &mcfg->malloc_heaps[socket];
+ void *ret;
+
+ rte_spinlock_lock(&(heap->lock));
+
+ align = align == 0 ? 1 : align;
+
+ ret = heap_alloc_biggest(heap, type, flags, align, contig);
+
+ rte_spinlock_unlock(&(heap->lock));
+
+ return ret;
+}
+
+void *
+malloc_heap_alloc_biggest(const char *type, int socket_arg, unsigned int flags,
+ size_t align, bool contig)
+{
+ int socket, i, cur_socket;
+ void *ret;
+
+ /* return NULL if align is not power-of-2 */
+ if ((align && !rte_is_power_of_2(align)))
+ return NULL;
+
+ if (!rte_eal_has_hugepages())
+ socket_arg = SOCKET_ID_ANY;
+
+ if (socket_arg == SOCKET_ID_ANY)
+ socket = malloc_get_numa_socket();
+ else
+ socket = socket_arg;
+
+ /* Check socket parameter */
+ if (socket >= RTE_MAX_NUMA_NODES)
+ return NULL;
+
+ ret = heap_alloc_biggest_on_socket(type, socket, flags, align,
+ contig);
+ if (ret != NULL || socket_arg != SOCKET_ID_ANY)
+ return ret;
+
+ /* try other heaps */
+ for (i = 0; i < (int) rte_socket_count(); i++) {
+ cur_socket = rte_socket_id_by_idx(i);
+ if (cur_socket == socket)
+ continue;
+ ret = heap_alloc_biggest_on_socket(type, cur_socket, flags,
+ align, contig);
+ if (ret != NULL)
+ return ret;
+ }
+ return NULL;
+}
+
+/* this function is exposed in malloc_mp.h */
+int
+malloc_heap_free_pages(void *aligned_start, size_t aligned_len)
+{
+ int n_segs, seg_idx, max_seg_idx;
+ struct rte_memseg_list *msl;
+ size_t page_sz;
+
+ msl = rte_mem_virt2memseg_list(aligned_start);
+ if (msl == NULL)
+ return -1;
+
+ page_sz = (size_t)msl->page_sz;
+ n_segs = aligned_len / page_sz;
+ seg_idx = RTE_PTR_DIFF(aligned_start, msl->base_va) / page_sz;
+ max_seg_idx = seg_idx + n_segs;
+
+ for (; seg_idx < max_seg_idx; seg_idx++) {
+ struct rte_memseg *ms;
+
+ ms = rte_fbarray_get(&msl->memseg_arr, seg_idx);
+ eal_memalloc_free_seg(ms);
+ }
+ return 0;
+}
+
+int
+malloc_heap_free(struct malloc_elem *elem)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ struct malloc_heap *heap;
+ void *start, *aligned_start, *end, *aligned_end;
+ size_t len, aligned_len, page_sz;
+ struct rte_memseg_list *msl;
+ unsigned int i, n_segs, before_space, after_space;
+ int ret;
+
+ if (!malloc_elem_cookies_ok(elem) || elem->state != ELEM_BUSY)
+ return -1;
+
+ /* elem may be merged with previous element, so keep heap address */
+ heap = elem->heap;
+ msl = elem->msl;
+ page_sz = (size_t)msl->page_sz;
+
+ rte_spinlock_lock(&(heap->lock));
+
+ /* mark element as free */
+ elem->state = ELEM_FREE;
+
+ elem = malloc_elem_free(elem);
+
+ /* anything after this is a bonus */
+ ret = 0;
+
+ /* ...of which we can't avail if we are in legacy mode */
+ if (internal_config.legacy_mem)
+ goto free_unlock;
+
+ /* Removed extra code to keep windows implementation simple. */
+
+free_unlock:
+ rte_spinlock_unlock(&(heap->lock));
+ return ret;
+}
+
+int
+malloc_heap_resize(struct malloc_elem *elem, size_t size)
+{
+ int ret;
+
+ if (!malloc_elem_cookies_ok(elem) || elem->state != ELEM_BUSY)
+ return -1;
+
+ rte_spinlock_lock(&(elem->heap->lock));
+
+ ret = malloc_elem_resize(elem, size);
+
+ rte_spinlock_unlock(&(elem->heap->lock));
+
+ return ret;
+}
+
+/*
+ * Function to retrieve data for heap on given socket
+ */
+int
+malloc_heap_get_stats(struct malloc_heap *heap,
+ struct rte_malloc_socket_stats *socket_stats)
+{
+ size_t idx;
+ struct malloc_elem *elem;
+
+ rte_spinlock_lock(&heap->lock);
+
+ /* Initialise variables for heap */
+ socket_stats->free_count = 0;
+ socket_stats->heap_freesz_bytes = 0;
+ socket_stats->greatest_free_size = 0;
+
+ /* Iterate through free list */
+ for (idx = 0; idx < RTE_HEAP_NUM_FREELISTS; idx++) {
+ for (elem = LIST_FIRST(&heap->free_head[idx]);
+ !!elem; elem = LIST_NEXT(elem, free_list))
+ {
+ socket_stats->free_count++;
+ socket_stats->heap_freesz_bytes += elem->size;
+ if (elem->size > socket_stats->greatest_free_size)
+ socket_stats->greatest_free_size = elem->size;
+ }
+ }
+ /* Get stats on overall heap and allocated memory on this heap */
+ socket_stats->heap_totalsz_bytes = heap->total_size;
+ socket_stats->heap_allocsz_bytes = (socket_stats->heap_totalsz_bytes -
+ socket_stats->heap_freesz_bytes);
+ socket_stats->alloc_count = heap->alloc_count;
+
+ rte_spinlock_unlock(&heap->lock);
+ return 0;
+}
+
+/*
+ * Function to retrieve data for heap on given socket
+ */
+void
+malloc_heap_dump(struct malloc_heap *heap, FILE *f)
+{
+ struct malloc_elem *elem;
+
+ rte_spinlock_lock(&heap->lock);
+
+ fprintf(f, "Heap size: 0x%zx\n", heap->total_size);
+ fprintf(f, "Heap alloc count: %u\n", heap->alloc_count);
+
+ elem = heap->first;
+ while (elem) {
+ malloc_elem_dump(elem, f);
+ elem = elem->next;
+ }
+
+ rte_spinlock_unlock(&heap->lock);
+}
+
+int
+rte_eal_malloc_heap_init(void)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+
+ if (register_mp_requests()) {
+ RTE_LOG(ERR, EAL, "Couldn't register malloc multiprocess actions\n");
+ rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+ return -1;
+ }
+
+ /* unlock mem hotplug here. it's safe for primary as no requests can
+ * even come before primary itself is fully initialized, and secondaries
+ * do not need to initialize the heap.
+ */
+ rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+
+ /* secondary process does not need to initialize anything */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ /* add all IOVA-contiguous areas to the heap */
+ return rte_memseg_contig_walk(malloc_add_seg, NULL);
+}
+
+static int
+destroy_seg(struct malloc_elem *elem, size_t len)
+{
+ struct malloc_heap *heap = elem->heap;
+ struct rte_memseg_list *msl;
+
+ msl = elem->msl;
+
+ /* notify all subscribers that a memory area is going to be removed */
+ eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE, elem, len);
+
+ /* this element can be removed */
+ malloc_elem_free_list_remove(elem);
+ malloc_elem_hide_region(elem, elem, len);
+
+ heap->total_size -= len;
+
+ memset(elem, 0, sizeof(*elem));
+
+ /* destroy the fbarray backing this memory */
+ if (rte_fbarray_destroy(&msl->memseg_arr) < 0)
+ return -1;
+
+ /* reset the memseg list */
+ memset(msl, 0, sizeof(*msl));
+
+ return 0;
+}
+
+int
+malloc_heap_add_external_memory(struct malloc_heap *heap, void *va_addr,
+ rte_iova_t iova_addrs[], unsigned int n_pages, size_t page_sz)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ char fbarray_name[RTE_FBARRAY_NAME_LEN];
+ struct rte_memseg_list *msl = NULL;
+ struct rte_fbarray *arr;
+ size_t seg_len = n_pages * page_sz;
+ unsigned int i;
+
+ /* first, find a free memseg list */
+ for (i = 0; i < RTE_MAX_MEMSEG_LISTS; i++) {
+ struct rte_memseg_list *tmp = &mcfg->memsegs[i];
+ if (tmp->base_va == NULL) {
+ msl = tmp;
+ break;
+ }
+ }
+ if (msl == NULL) {
+ RTE_LOG(ERR, EAL, "Couldn't find empty memseg list\n");
+ rte_errno = ENOSPC;
+ return -1;
+ }
+
+ snprintf(fbarray_name, sizeof(fbarray_name) - 1, "%s_%p",
+ heap->name, va_addr);
+
+ /* create the backing fbarray */
+ if (rte_fbarray_init(&msl->memseg_arr, fbarray_name, n_pages,
+ sizeof(struct rte_memseg)) < 0) {
+ RTE_LOG(ERR, EAL, "Couldn't create fbarray backing the memseg list\n");
+ return -1;
+ }
+ arr = &msl->memseg_arr;
+
+ /* fbarray created, fill it up */
+ for (i = 0; i < n_pages; i++) {
+ struct rte_memseg *ms;
+
+ rte_fbarray_set_used(arr, i);
+ ms = rte_fbarray_get(arr, i);
+ ms->addr = RTE_PTR_ADD(va_addr, i * page_sz);
+ ms->iova = iova_addrs == NULL ? RTE_BAD_IOVA : iova_addrs[i];
+ ms->hugepage_sz = page_sz;
+ ms->len = page_sz;
+ ms->nchannel = rte_memory_get_nchannel();
+ ms->nrank = rte_memory_get_nrank();
+ ms->socket_id = heap->socket_id;
+ }
+
+ /* set up the memseg list */
+ msl->base_va = va_addr;
+ msl->page_sz = page_sz;
+ msl->socket_id = heap->socket_id;
+ msl->len = seg_len;
+ msl->version = 0;
+ msl->external = 1;
+
+ /* erase contents of new memory */
+ memset(va_addr, 0, seg_len);
+
+ /* now, add newly minted memory to the malloc heap */
+ malloc_heap_add_memory(heap, msl, va_addr, seg_len);
+
+ heap->total_size += seg_len;
+
+ /* all done! */
+ RTE_LOG(DEBUG, EAL, "Added segment for heap %s starting at %p\n",
+ heap->name, va_addr);
+
+ /* notify all subscribers that a new memory area has been added */
+ eal_memalloc_mem_event_notify(RTE_MEM_EVENT_ALLOC,
+ va_addr, seg_len);
+
+ return 0;
+}
+
+int
+malloc_heap_remove_external_memory(struct malloc_heap *heap, void *va_addr,
+ size_t len)
+{
+ struct malloc_elem *elem = heap->first;
+
+ /* find element with specified va address */
+ while (elem != NULL && elem != va_addr) {
+ elem = elem->next;
+ /* stop if we've blown past our VA */
+ if (elem > (struct malloc_elem *)va_addr) {
+ rte_errno = ENOENT;
+ return -1;
+ }
+ }
+ /* check if element was found */
+ if (elem == NULL || elem->msl->len != len) {
+ rte_errno = ENOENT;
+ return -1;
+ }
+ /* if element's size is not equal to segment len, segment is busy */
+ if (elem->state == ELEM_BUSY || elem->size != len) {
+ rte_errno = EBUSY;
+ return -1;
+ }
+ return destroy_seg(elem, len);
+}
+
+int
+malloc_heap_create(struct malloc_heap *heap, const char *heap_name)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ uint32_t next_socket_id = mcfg->next_socket_id;
+
+ /* prevent overflow. did you really create 2 billion heaps??? */
+ if (next_socket_id > INT32_MAX) {
+ RTE_LOG(ERR, EAL, "Cannot assign new socket ID's\n");
+ rte_errno = ENOSPC;
+ return -1;
+ }
+
+ /* initialize empty heap */
+ heap->alloc_count = 0;
+ heap->first = NULL;
+ heap->last = NULL;
+ LIST_INIT(heap->free_head);
+ rte_spinlock_init(&heap->lock);
+ heap->total_size = 0;
+ heap->socket_id = next_socket_id;
+
+ /* we hold a global mem hotplug writelock, so it's safe to increment */
+ mcfg->next_socket_id++;
+
+ /* set up name */
+ strlcpy(heap->name, heap_name, RTE_HEAP_NAME_MAX_LEN);
+
+ return 0;
+}
+
+int
+malloc_heap_destroy(struct malloc_heap *heap)
+{
+ if (heap->alloc_count != 0) {
+ RTE_LOG(ERR, EAL, "Heap is still in use\n");
+ rte_errno = EBUSY;
+ return -1;
+ }
+ if (heap->first != NULL || heap->last != NULL) {
+ RTE_LOG(ERR, EAL, "Heap still contains memory segments\n");
+ rte_errno = EBUSY;
+ return -1;
+ }
+ if (heap->total_size != 0)
+ RTE_LOG(ERR, EAL, "Total size not zero, heap is likely corrupt\n");
+
+ /* after this, the lock will be dropped */
+ memset(heap, 0, sizeof(*heap));
+
+ return 0;
+}
+
+int
+malloc_socket_to_heap_id(unsigned int socket_id)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ int i;
+
+ for (i = 0; i < RTE_MAX_HEAPS; i++) {
+ struct malloc_heap *heap = &mcfg->malloc_heaps[i];
+
+ if (heap->socket_id == socket_id)
+ return i;
+ }
+ return -1;
+}
diff --git a/lib/librte_eal/windows/eal/malloc_mp.c b/lib/librte_eal/windows/eal/malloc_mp.c
new file mode 100644
index 000000000..15227e2ae
--- /dev/null
+++ b/lib/librte_eal/windows/eal/malloc_mp.c
@@ -0,0 +1,645 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+
+#include <rte_alarm.h>
+#include <rte_errno.h>
+#include <rte_string_fns.h>
+
+#include "eal_memalloc.h"
+
+#include "malloc_elem.h"
+#include "malloc_mp.h"
+
+#define MP_ACTION_SYNC "mp_malloc_sync"
+/**< request sent by primary process to notify of changes in memory map */
+#define MP_ACTION_ROLLBACK "mp_malloc_rollback"
+/**< request sent by primary process to notify of changes in memory map. this is
+ * essentially a regular sync request, but we cannot send sync requests while
+ * another one is in progress, and we might have to - therefore, we do this as
+ * a separate callback.
+ */
+#define MP_ACTION_REQUEST "mp_malloc_request"
+/**< request sent by secondary process to ask for allocation/deallocation */
+#define MP_ACTION_RESPONSE "mp_malloc_response"
+/**< response sent to secondary process to indicate result of request */
+
+/* forward declarations */
+static int
+handle_sync_response(const struct rte_mp_msg *request,
+ const struct rte_mp_reply *reply);
+static int
+handle_rollback_response(const struct rte_mp_msg *request,
+ const struct rte_mp_reply *reply);
+
+#define MP_TIMEOUT_S 5 /**< 5 seconds timeouts */
+
+/* when we're allocating, we need to store some state to ensure that we can
+ * roll back later
+ */
+struct primary_alloc_req_state {
+ struct malloc_heap *heap;
+ struct rte_memseg **ms;
+ int ms_len;
+ struct malloc_elem *elem;
+ void *map_addr;
+ size_t map_len;
+};
+
+enum req_state {
+ REQ_STATE_INACTIVE = 0,
+ REQ_STATE_ACTIVE,
+ REQ_STATE_COMPLETE
+};
+
+struct mp_request {
+ TAILQ_ENTRY(mp_request) next;
+ struct malloc_mp_req user_req; /**< contents of request */
+ CONDITION_VARIABLE cond; /**< variable we use to time out on this request */
+ enum req_state state; /**< indicate status of this request */
+ struct primary_alloc_req_state alloc_state;
+};
+
+/*
+ * We could've used just a single request, but it may be possible for
+ * secondaries to timeout earlier than the primary, and send a new request while
+ * primary is still expecting replies to the old one. Therefore, each new
+ * request will get assigned a new ID, which is how we will distinguish between
+ * expected and unexpected messages.
+ */
+TAILQ_HEAD(mp_request_list, mp_request);
+static struct {
+ struct mp_request_list list;
+ SRWLOCK lock;
+} mp_request_list = {
+ .list = TAILQ_HEAD_INITIALIZER(mp_request_list.list),
+ .lock = SRWLOCK_INIT
+};
+
+/**
+ * General workflow is the following:
+ *
+ * Allocation:
+ * S: send request to primary
+ * P: attempt to allocate memory
+ * if failed, sendmsg failure
+ * if success, send sync request
+ * S: if received msg of failure, quit
+ * if received sync request, synchronize memory map and reply with result
+ * P: if received sync request result
+ * if success, sendmsg success
+ * if failure, roll back allocation and send a rollback request
+ * S: if received msg of success, quit
+ * if received rollback request, synchronize memory map and reply with result
+ * P: if received sync request result
+ * sendmsg sync request result
+ * S: if received msg, quit
+ *
+ * Aside from timeouts, there are three points where we can quit:
+ * - if allocation failed straight away
+ * - if allocation and sync request succeeded
+ * - if allocation succeeded, sync request failed, allocation rolled back and
+ * rollback request received (irrespective of whether it succeeded or failed)
+ *
+ * Deallocation:
+ * S: send request to primary
+ * P: attempt to deallocate memory
+ * if failed, sendmsg failure
+ * if success, send sync request
+ * S: if received msg of failure, quit
+ * if received sync request, synchronize memory map and reply with result
+ * P: if received sync request result
+ * sendmsg sync request result
+ * S: if received msg, quit
+ *
+ * There is no "rollback" from deallocation, as it's safe to have some memory
+ * mapped in some processes - it's absent from the heap, so it won't get used.
+ */
+
+static struct mp_request *
+find_request_by_id(uint64_t id)
+{
+ struct mp_request *req;
+ TAILQ_FOREACH(req, &mp_request_list.list, next) {
+ if (req->user_req.id == id)
+ break;
+ }
+ return req;
+}
+
+/* this ID is, like, totally guaranteed to be absolutely unique. pinky swear. */
+static uint64_t
+get_unique_id(void)
+{
+ uint64_t id;
+ do {
+ id = rte_rand();
+ } while (find_request_by_id(id) != NULL);
+ return id;
+}
+
+/* secondary will respond to sync requests thusly */
+static int
+handle_sync(const struct rte_mp_msg *msg, const void *peer)
+{
+ /* TODO dpdk-1808 Not implemented in Windows*/
+ return 0;
+}
+
+static int
+handle_alloc_request(const struct malloc_mp_req *m,
+ struct mp_request *req)
+{
+ const struct malloc_req_alloc *ar = &m->alloc_req;
+ struct malloc_heap *heap;
+ struct malloc_elem *elem;
+ struct rte_memseg **ms;
+ size_t alloc_sz;
+ int n_segs;
+ void *map_addr;
+
+ alloc_sz = RTE_ALIGN_CEIL(ar->align + ar->elt_size +
+ MALLOC_ELEM_TRAILER_LEN, ar->page_sz);
+ n_segs = alloc_sz / ar->page_sz;
+
+ heap = ar->heap;
+
+ /* we can't know in advance how many pages we'll need, so we malloc */
+ ms = malloc(sizeof(*ms) * n_segs);
+
+ memset(ms, 0, sizeof(*ms) * n_segs);
+
+ if (ms == NULL) {
+ RTE_LOG(ERR, EAL, "Couldn't allocate memory for request state\n");
+ goto fail;
+ }
+
+ elem = alloc_pages_on_heap(heap, ar->page_sz, ar->elt_size, ar->socket,
+ ar->flags, ar->align, ar->bound, ar->contig, ms,
+ n_segs);
+
+ if (elem == NULL)
+ goto fail;
+
+ map_addr = ms[0]->addr;
+
+ /* we have succeeded in allocating memory, but we still need to sync
+ * with other processes. however, since DPDK IPC is single-threaded, we
+ * send an asynchronous request and exit this callback.
+ */
+
+ req->alloc_state.ms = ms;
+ req->alloc_state.ms_len = n_segs;
+ req->alloc_state.map_addr = map_addr;
+ req->alloc_state.map_len = alloc_sz;
+ req->alloc_state.elem = elem;
+ req->alloc_state.heap = heap;
+
+ return 0;
+fail:
+ free(ms);
+ return -1;
+}
+
+/* first stage of primary handling requests from secondary */
+static int
+handle_request(const struct rte_mp_msg *msg, const void *peer __rte_unused)
+{
+ const struct malloc_mp_req *m =
+ (const struct malloc_mp_req *)msg->param;
+ struct mp_request *entry;
+ int ret;
+
+ /* lock access to request */
+ AcquireSRWLockExclusive(&mp_request_list.lock);
+
+ /* make sure it's not a dupe */
+ entry = find_request_by_id(m->id);
+ if (entry != NULL) {
+ RTE_LOG(ERR, EAL, "Duplicate request id\n");
+ goto fail;
+ }
+
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL) {
+ RTE_LOG(ERR, EAL, "Unable to allocate memory for request\n");
+ goto fail;
+ }
+
+ /* erase all data */
+ memset(entry, 0, sizeof(*entry));
+
+ if (m->t == REQ_TYPE_ALLOC) {
+ ret = handle_alloc_request(m, entry);
+ } else if (m->t == REQ_TYPE_FREE) {
+ ret = malloc_heap_free_pages(m->free_req.addr,
+ m->free_req.len);
+ } else {
+ RTE_LOG(ERR, EAL, "Unexpected request from secondary\n");
+ goto fail;
+ }
+
+ if (ret != 0) {
+ struct rte_mp_msg resp_msg;
+ struct malloc_mp_req *resp =
+ (struct malloc_mp_req *)resp_msg.param;
+
+ /* send failure message straight away */
+ resp_msg.num_fds = 0;
+ resp_msg.len_param = sizeof(*resp);
+ strlcpy(resp_msg.name, MP_ACTION_RESPONSE,
+ sizeof(resp_msg.name));
+
+ resp->t = m->t;
+ resp->result = REQ_RESULT_FAIL;
+ resp->id = m->id;
+
+ /* TODO dpdk-1808 send msg across to the other process using rte_mp_sendmsg(&resp_msg) */
+ /* we did not modify the request */
+ free(entry);
+ } else {
+ struct rte_mp_msg sr_msg;
+ struct malloc_mp_req *sr =
+ (struct malloc_mp_req *)sr_msg.param;
+ struct timespec ts;
+
+ memset(&sr_msg, 0, sizeof(sr_msg));
+
+ /* we can do something, so send sync request asynchronously */
+ sr_msg.num_fds = 0;
+ sr_msg.len_param = sizeof(*sr);
+ strlcpy(sr_msg.name, MP_ACTION_SYNC, sizeof(sr_msg.name));
+
+ ts.tv_nsec = 0;
+ ts.tv_sec = MP_TIMEOUT_S;
+
+ /* sync requests carry no data */
+ sr->t = REQ_TYPE_SYNC;
+ sr->id = m->id;
+
+ /* TODO dpdk-1808 check if there may be stray timeout still waiting */
+
+ /* mark request as in progress */
+ memcpy(&entry->user_req, m, sizeof(*m));
+ entry->state = REQ_STATE_ACTIVE;
+
+ TAILQ_INSERT_TAIL(&mp_request_list.list, entry, next);
+ }
+ ReleaseSRWLockExclusive(&mp_request_list.lock);
+ return 0;
+fail:
+ ReleaseSRWLockExclusive(&mp_request_list.lock);
+ free(entry);
+ return -1;
+}
+
+/* callback for asynchronous sync requests for primary. this will either do a
+ * sendmsg with results, or trigger rollback request.
+ */
+static int
+handle_sync_response(const struct rte_mp_msg *request,
+ const struct rte_mp_reply *reply)
+{
+ enum malloc_req_result result;
+ struct mp_request *entry;
+ const struct malloc_mp_req *mpreq =
+ (const struct malloc_mp_req *)request->param;
+ int i;
+
+ /* lock the request */
+ AcquireSRWLockExclusive(&mp_request_list.lock);
+
+ entry = find_request_by_id(mpreq->id);
+ if (entry == NULL) {
+ RTE_LOG(ERR, EAL, "Wrong request ID\n");
+ goto fail;
+ }
+
+ result = REQ_RESULT_SUCCESS;
+
+ if (reply->nb_received != reply->nb_sent)
+ result = REQ_RESULT_FAIL;
+
+ for (i = 0; i < reply->nb_received; i++) {
+ struct malloc_mp_req *resp =
+ (struct malloc_mp_req *)reply->msgs[i].param;
+
+ if (resp->t != REQ_TYPE_SYNC) {
+ RTE_LOG(ERR, EAL, "Unexpected response to sync request\n");
+ result = REQ_RESULT_FAIL;
+ break;
+ }
+ if (resp->id != entry->user_req.id) {
+ RTE_LOG(ERR, EAL, "Response to wrong sync request\n");
+ result = REQ_RESULT_FAIL;
+ break;
+ }
+ if (resp->result == REQ_RESULT_FAIL) {
+ result = REQ_RESULT_FAIL;
+ break;
+ }
+ }
+
+ if (entry->user_req.t == REQ_TYPE_FREE) {
+ struct rte_mp_msg msg;
+ struct malloc_mp_req *resp = (struct malloc_mp_req *)msg.param;
+
+ memset(&msg, 0, sizeof(msg));
+
+ /* this is a free request, just sendmsg result */
+ resp->t = REQ_TYPE_FREE;
+ resp->result = result;
+ resp->id = entry->user_req.id;
+ msg.num_fds = 0;
+ msg.len_param = sizeof(*resp);
+ strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));
+
+ if (rte_mp_sendmsg(&msg))
+ RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");
+
+ TAILQ_REMOVE(&mp_request_list.list, entry, next);
+ free(entry);
+ } else if (entry->user_req.t == REQ_TYPE_ALLOC &&
+ result == REQ_RESULT_SUCCESS) {
+ struct malloc_heap *heap = entry->alloc_state.heap;
+ struct rte_mp_msg msg;
+ struct malloc_mp_req *resp =
+ (struct malloc_mp_req *)msg.param;
+
+ memset(&msg, 0, sizeof(msg));
+
+ heap->total_size += entry->alloc_state.map_len;
+
+ /* result is success, so just notify secondary about this */
+ resp->t = REQ_TYPE_ALLOC;
+ resp->result = result;
+ resp->id = entry->user_req.id;
+ msg.num_fds = 0;
+ msg.len_param = sizeof(*resp);
+ strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));
+
+ if (rte_mp_sendmsg(&msg))
+ RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");
+
+ TAILQ_REMOVE(&mp_request_list.list, entry, next);
+ free(entry->alloc_state.ms);
+ free(entry);
+ } else if (entry->user_req.t == REQ_TYPE_ALLOC &&
+ result == REQ_RESULT_FAIL) {
+ struct rte_mp_msg rb_msg;
+ struct malloc_mp_req *rb =
+ (struct malloc_mp_req *)rb_msg.param;
+ struct timespec ts;
+ struct primary_alloc_req_state *state =
+ &entry->alloc_state;
+ int ret;
+
+ memset(&rb_msg, 0, sizeof(rb_msg));
+
+ /* we've failed to sync, so do a rollback */
+ rollback_expand_heap(state->ms, state->ms_len, state->elem,
+ state->map_addr, state->map_len);
+
+ /* send rollback request */
+ rb_msg.num_fds = 0;
+ rb_msg.len_param = sizeof(*rb);
+ strlcpy(rb_msg.name, MP_ACTION_ROLLBACK, sizeof(rb_msg.name));
+
+ ts.tv_nsec = 0;
+ ts.tv_sec = MP_TIMEOUT_S;
+
+ /* sync requests carry no data */
+ rb->t = REQ_TYPE_SYNC;
+ rb->id = entry->user_req.id;
+
+ /* TODO dpdk-1808 check if there may be stray timeout still waiting */
+ } else {
+ RTE_LOG(ERR, EAL, " to sync request of unknown type\n");
+ goto fail;
+ }
+
+ ReleaseSRWLockExclusive(&mp_request_list.lock);
+ return 0;
+fail:
+ ReleaseSRWLockExclusive(&mp_request_list.lock);
+ return -1;
+}
+
+static int
+handle_rollback_response(const struct rte_mp_msg *request,
+ const struct rte_mp_reply *reply __rte_unused)
+{
+ struct rte_mp_msg msg;
+ struct malloc_mp_req *resp = (struct malloc_mp_req *)msg.param;
+ const struct malloc_mp_req *mpreq =
+ (const struct malloc_mp_req *)request->param;
+ struct mp_request *entry;
+
+ /* lock the request */
+ AcquireSRWLockExclusive(&mp_request_list.lock);
+
+ memset(&msg, 0, sizeof(0));
+
+ entry = find_request_by_id(mpreq->id);
+ if (entry == NULL) {
+ RTE_LOG(ERR, EAL, "Wrong request ID\n");
+ goto fail;
+ }
+
+ if (entry->user_req.t != REQ_TYPE_ALLOC) {
+ RTE_LOG(ERR, EAL, "Unexpected active request\n");
+ goto fail;
+ }
+
+ /* we don't care if rollback succeeded, request still failed */
+ resp->t = REQ_TYPE_ALLOC;
+ resp->result = REQ_RESULT_FAIL;
+ resp->id = mpreq->id;
+ msg.num_fds = 0;
+ msg.len_param = sizeof(*resp);
+ strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));
+
+ if (rte_mp_sendmsg(&msg))
+ RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");
+
+ /* clean up */
+ TAILQ_REMOVE(&mp_request_list.list, entry, next);
+ free(entry->alloc_state.ms);
+ free(entry);
+
+ ReleaseSRWLockExclusive(&mp_request_list.lock);
+ return 0;
+fail:
+ ReleaseSRWLockExclusive(&mp_request_list.lock);
+ return -1;
+}
+
+/* final stage of the request from secondary */
+static int
+handle_response(const struct rte_mp_msg *msg, const void *peer __rte_unused)
+{
+ const struct malloc_mp_req *m =
+ (const struct malloc_mp_req *)msg->param;
+ struct mp_request *entry;
+
+ AcquireSRWLockExclusive(&mp_request_list.lock);
+
+ entry = find_request_by_id(m->id);
+ if (entry != NULL) {
+ /* update request status */
+ entry->user_req.result = m->result;
+
+ entry->state = REQ_STATE_COMPLETE;
+
+ /* trigger thread wakeup */
+ WakeConditionVariable(&entry->cond);
+ }
+
+ ReleaseSRWLockExclusive(&mp_request_list.lock);
+
+ return 0;
+}
+
+/* synchronously request memory map sync, this is only called whenever primary
+ * process initiates the allocation.
+ */
+int
+request_sync(void)
+{
+ struct rte_mp_msg msg;
+ struct rte_mp_reply reply;
+ struct malloc_mp_req *req = (struct malloc_mp_req *)msg.param;
+ struct timespec ts;
+ int i, ret;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+
+ /* no need to create tailq entries as this is entirely synchronous */
+
+ msg.num_fds = 0;
+ msg.len_param = sizeof(*req);
+ strlcpy(msg.name, MP_ACTION_SYNC, sizeof(msg.name));
+
+ /* sync request carries no data */
+ req->t = REQ_TYPE_SYNC;
+ req->id = get_unique_id();
+
+ ts.tv_nsec = 0;
+ ts.tv_sec = MP_TIMEOUT_S;
+
+ /* TODO dpdk-1808 check if there may be stray timeout still waiting */
+
+ if (reply.nb_received != reply.nb_sent) {
+ RTE_LOG(ERR, EAL, "Not all secondaries have responded\n");
+ ret = -1;
+ goto out;
+ }
+
+ for (i = 0; i < reply.nb_received; i++) {
+ struct malloc_mp_req *resp =
+ (struct malloc_mp_req *)reply.msgs[i].param;
+ if (resp->t != REQ_TYPE_SYNC) {
+ RTE_LOG(ERR, EAL, "Unexpected response from secondary\n");
+ ret = -1;
+ goto out;
+ }
+ if (resp->id != req->id) {
+ RTE_LOG(ERR, EAL, "Wrong request ID\n");
+ ret = -1;
+ goto out;
+ }
+ if (resp->result != REQ_RESULT_SUCCESS) {
+ RTE_LOG(ERR, EAL, "Secondary process failed to synchronize\n");
+ ret = -1;
+ goto out;
+ }
+ }
+
+ ret = 0;
+out:
+ free(reply.msgs);
+ return ret;
+}
+
+/* this is a synchronous wrapper around a bunch of asynchronous requests to
+ * primary process. this will initiate a request and wait until responses come.
+ */
+int
+request_to_primary(struct malloc_mp_req *user_req)
+{
+ struct rte_mp_msg msg;
+ struct malloc_mp_req *msg_req = (struct malloc_mp_req *)msg.param;
+ struct mp_request *entry;
+
+ DWORD milliseconds;
+ int ret;
+
+ memset(&msg, 0, sizeof(msg));
+
+ AcquireSRWLockExclusive(&mp_request_list.lock);
+
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL) {
+ RTE_LOG(ERR, EAL, "Cannot allocate memory for request\n");
+ goto fail;
+ }
+
+ memset(entry, 0, sizeof(*entry));
+
+
+ milliseconds = MP_TIMEOUT_S * 1000000;
+ /* initialize the request */
+ InitializeConditionVariable(&entry->cond);
+
+ msg.num_fds = 0;
+ msg.len_param = sizeof(*msg_req);
+ strlcpy(msg.name, MP_ACTION_REQUEST, sizeof(msg.name));
+
+ /* (attempt to) get a unique id */
+ user_req->id = get_unique_id();
+
+ /* copy contents of user request into the message */
+ memcpy(msg_req, user_req, sizeof(*msg_req));
+
+ /* TODO dpdk-1808 send msg across to the other process using rte_mp_sendmsg(&resp_msg) */
+ /* copy contents of user request into active request */
+ memcpy(&entry->user_req, user_req, sizeof(*user_req));
+
+ /* mark request as in progress */
+ entry->state = REQ_STATE_ACTIVE;
+
+ TAILQ_INSERT_TAIL(&mp_request_list.list, entry, next);
+
+ /* finally, wait on timeout */
+ do {
+ ret = SleepConditionVariableSRW(&entry->cond,
+ &mp_request_list.lock, milliseconds,0);
+ } while (ret != 0 && ret != ETIMEDOUT);
+
+ if (entry->state != REQ_STATE_COMPLETE) {
+ RTE_LOG(ERR, EAL, "Request timed out\n");
+ ret = -1;
+ } else {
+ ret = 0;
+ user_req->result = entry->user_req.result;
+ }
+ TAILQ_REMOVE(&mp_request_list.list, entry, next);
+ free(entry);
+
+ ReleaseSRWLockExclusive(&mp_request_list.lock);
+ return ret;
+fail:
+ ReleaseSRWLockExclusive(&mp_request_list.lock);
+ free(entry);
+ return -1;
+}
+
+int
+register_mp_requests(void)
+{
+ /* TODO dpdk-1808 Not implemented in Windows*/
+ return 0;
+}
diff --git a/lib/librte_eal/windows/include_override/dirent.h b/lib/librte_eal/windows/include_override/dirent.h
new file mode 100644
index 000000000..47d17fd9a
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/dirent.h
@@ -0,0 +1,950 @@
+/*
+* Dirent interface for Microsoft Visual Studio
+* Version 1.21
+*
+* Copyright (C) 2006-2012 Toni Ronkko
+* This file is part of dirent. Dirent may be freely distributed
+* under the MIT license. For all details and documentation, see
+* https://github.com/tronkko/dirent
+*/
+#ifndef DIRENT_H
+#define DIRENT_H
+
+/*
+* Include windows.h without Windows Sockets 1.1 to prevent conflicts with
+* Windows Sockets 2.0.
+*/
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+/* Indicates that d_type field is available in dirent structure */
+#define _DIRENT_HAVE_D_TYPE
+
+/* Indicates that d_namlen field is available in dirent structure */
+#define _DIRENT_HAVE_D_NAMLEN
+
+/* Entries missing from MSVC 6.0 */
+#if !defined(FILE_ATTRIBUTE_DEVICE)
+# define FILE_ATTRIBUTE_DEVICE 0x40
+#endif
+
+/* File type and permission flags for stat(), general mask */
+#if !defined(S_IFMT)
+# define S_IFMT _S_IFMT
+#endif
+
+/* Directory bit */
+#if !defined(S_IFDIR)
+# define S_IFDIR _S_IFDIR
+#endif
+
+/* Character device bit */
+#if !defined(S_IFCHR)
+# define S_IFCHR _S_IFCHR
+#endif
+
+/* Pipe bit */
+#if !defined(S_IFFIFO)
+# define S_IFFIFO _S_IFFIFO
+#endif
+
+/* Regular file bit */
+#if !defined(S_IFREG)
+# define S_IFREG _S_IFREG
+#endif
+
+/* Read permission */
+#if !defined(S_IREAD)
+# define S_IREAD _S_IREAD
+#endif
+
+/* Write permission */
+#if !defined(S_IWRITE)
+# define S_IWRITE _S_IWRITE
+#endif
+
+/* Execute permission */
+#if !defined(S_IEXEC)
+# define S_IEXEC _S_IEXEC
+#endif
+
+/* Pipe */
+#if !defined(S_IFIFO)
+# define S_IFIFO _S_IFIFO
+#endif
+
+/* Block device */
+#if !defined(S_IFBLK)
+# define S_IFBLK 0
+#endif
+
+/* Link */
+#if !defined(S_IFLNK)
+# define S_IFLNK 0
+#endif
+
+/* Socket */
+#if !defined(S_IFSOCK)
+# define S_IFSOCK 0
+#endif
+
+/* Read user permission */
+#if !defined(S_IRUSR)
+# define S_IRUSR S_IREAD
+#endif
+
+/* Write user permission */
+#if !defined(S_IWUSR)
+# define S_IWUSR S_IWRITE
+#endif
+
+/* Execute user permission */
+#if !defined(S_IXUSR)
+# define S_IXUSR 0
+#endif
+
+/* Read group permission */
+#if !defined(S_IRGRP)
+# define S_IRGRP 0
+#endif
+
+/* Write group permission */
+#if !defined(S_IWGRP)
+# define S_IWGRP 0
+#endif
+
+/* Execute group permission */
+#if !defined(S_IXGRP)
+# define S_IXGRP 0
+#endif
+
+/* Read others permission */
+#if !defined(S_IROTH)
+# define S_IROTH 0
+#endif
+
+/* Write others permission */
+#if !defined(S_IWOTH)
+# define S_IWOTH 0
+#endif
+
+/* Execute others permission */
+#if !defined(S_IXOTH)
+# define S_IXOTH 0
+#endif
+
+/* Maximum length of file name */
+#if !defined(PATH_MAX)
+# define PATH_MAX MAX_PATH
+#endif
+#if !defined(FILENAME_MAX)
+# define FILENAME_MAX MAX_PATH
+#endif
+#if !defined(NAME_MAX)
+# define NAME_MAX FILENAME_MAX
+#endif
+
+/* File type flags for d_type */
+#define DT_UNKNOWN 0
+#define DT_REG S_IFREG
+#define DT_DIR S_IFDIR
+#define DT_FIFO S_IFIFO
+#define DT_SOCK S_IFSOCK
+#define DT_CHR S_IFCHR
+#define DT_BLK S_IFBLK
+#define DT_LNK S_IFLNK
+
+/* Macros for converting between st_mode and d_type */
+#define IFTODT(mode) ((mode) & S_IFMT)
+#define DTTOIF(type) (type)
+
+/*
+* File type macros. Note that block devices, sockets and links cannot be
+* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
+* only defined for compatibility. These macros should always return false
+* on Windows.
+*/
+#if !defined(S_ISFIFO)
+# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
+#endif
+#if !defined(S_ISDIR)
+# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+#if !defined(S_ISREG)
+# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+#endif
+#if !defined(S_ISLNK)
+# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
+#endif
+#if !defined(S_ISSOCK)
+# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+#endif
+#if !defined(S_ISCHR)
+# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
+#endif
+#if !defined(S_ISBLK)
+# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
+#endif
+
+/* Return the exact length of d_namlen without zero terminator */
+#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
+
+/* Return number of bytes needed to store d_namlen */
+#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ /* Wide-character version */
+ struct _wdirent {
+ /* Always zero */
+ long d_ino;
+
+ /* Structure size */
+ unsigned short d_reclen;
+
+ /* Length of name without \0 */
+ size_t d_namlen;
+
+ /* File type */
+ int d_type;
+
+ /* File name */
+ wchar_t d_name[PATH_MAX];
+ };
+ typedef struct _wdirent _wdirent;
+
+ struct _WDIR {
+ /* Current directory entry */
+ struct _wdirent ent;
+
+ /* Private file data */
+ WIN32_FIND_DATAW data;
+
+ /* True if data is valid */
+ int cached;
+
+ /* Win32 search handle */
+ HANDLE handle;
+
+ /* Initial directory name */
+ wchar_t *patt;
+ };
+ typedef struct _WDIR _WDIR;
+
+ static _WDIR *_wopendir(const wchar_t *dirname);
+ static struct _wdirent *_wreaddir(_WDIR *dirp);
+ static int _wclosedir(_WDIR *dirp);
+ static void _wrewinddir(_WDIR* dirp);
+
+
+ /* For compatibility with Symbian */
+#define wdirent _wdirent
+#define WDIR _WDIR
+#define wopendir _wopendir
+#define wreaddir _wreaddir
+#define wclosedir _wclosedir
+#define wrewinddir _wrewinddir
+
+
+ /* Multi-byte character versions */
+ struct dirent {
+ /* Always zero */
+ long d_ino;
+
+ /* Structure size */
+ unsigned short d_reclen;
+
+ /* Length of name without \0 */
+ size_t d_namlen;
+
+ /* File type */
+ int d_type;
+
+ /* File name */
+ char d_name[PATH_MAX];
+ };
+ typedef struct dirent dirent;
+
+ struct DIR {
+ struct dirent ent;
+ struct _WDIR *wdirp;
+ };
+ typedef struct DIR DIR;
+
+ static DIR *opendir(const char *dirname);
+ static struct dirent *readdir(DIR *dirp);
+ static int closedir(DIR *dirp);
+ static void rewinddir(DIR* dirp);
+
+
+ /* Internal utility functions */
+ static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp);
+ static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp);
+
+ static int dirent_mbstowcs_s(
+ size_t *pReturnValue,
+ wchar_t *wcstr,
+ size_t sizeInWords,
+ const char *mbstr,
+ size_t count);
+
+ static int dirent_wcstombs_s(
+ size_t *pReturnValue,
+ char *mbstr,
+ size_t sizeInBytes,
+ const wchar_t *wcstr,
+ size_t count);
+
+ static void dirent_set_errno(int error);
+
+ /*
+ * Open directory stream DIRNAME for read and return a pointer to the
+ * internal working area that is used to retrieve individual directory
+ * entries.
+ */
+ static _WDIR*
+ _wopendir(
+ const wchar_t *dirname)
+ {
+ _WDIR *dirp = NULL;
+ int error;
+
+ /* Must have directory name */
+ if (dirname == NULL || dirname[0] == '\0') {
+ dirent_set_errno(ENOENT);
+ return NULL;
+ }
+
+ /* Allocate new _WDIR structure */
+ dirp = (_WDIR*)malloc(sizeof(struct _WDIR));
+ if (dirp != NULL) {
+ DWORD n;
+
+ /* Reset _WDIR structure */
+ dirp->handle = INVALID_HANDLE_VALUE;
+ dirp->patt = NULL;
+ dirp->cached = 0;
+
+ /* Compute the length of full path plus zero terminator
+ *
+ * Note that on WinRT there's no way to convert relative paths
+ * into absolute paths, so just assume its an absolute path.
+ */
+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ n = wcslen(dirname);
+# else
+ n = GetFullPathNameW(dirname, 0, NULL, NULL);
+# endif
+
+ /* Allocate room for absolute directory name and search pattern */
+ dirp->patt = (wchar_t*)malloc(sizeof(wchar_t) * n + 16);
+ if (dirp->patt) {
+
+ /*
+ * Convert relative directory name to an absolute one. This
+ * allows rewinddir() to function correctly even when current
+ * working directory is changed between opendir() and rewinddir().
+ *
+ * Note that on WinRT there's no way to convert relative paths
+ * into absolute paths, so just assume its an absolute path.
+ */
+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ wcsncpy_s(dirp->patt, n + 1, dirname, n);
+# else
+ n = GetFullPathNameW(dirname, n, dirp->patt, NULL);
+# endif
+ if (n > 0) {
+ wchar_t *p;
+
+ /* Append search pattern \* to the directory name */
+ p = dirp->patt + n;
+ if (dirp->patt < p) {
+ switch (p[-1]) {
+ case '\\':
+ case '/':
+ case ':':
+ /* Directory ends in path separator, e.g. c:\temp\ */
+ /*NOP*/;
+ break;
+
+ default:
+ /* Directory name doesn't end in path separator */
+ *p++ = '\\';
+ }
+ }
+ *p++ = '*';
+ *p = '\0';
+
+ /* Open directory stream and retrieve the first entry */
+ if (dirent_first(dirp)) {
+ /* Directory stream opened successfully */
+ error = 0;
+ }
+ else {
+ /* Cannot retrieve first entry */
+ error = 1;
+ dirent_set_errno(ENOENT);
+ }
+
+ }
+ else {
+ /* Cannot retrieve full path name */
+ dirent_set_errno(ENOENT);
+ error = 1;
+ }
+
+ }
+ else {
+ /* Cannot allocate memory for search pattern */
+ error = 1;
+ }
+
+ }
+ else {
+ /* Cannot allocate _WDIR structure */
+ error = 1;
+ }
+
+ /* Clean up in case of error */
+ if (error && dirp) {
+ _wclosedir(dirp);
+ dirp = NULL;
+ }
+
+ return dirp;
+ }
+
+ /*
+ * Read next directory entry. The directory entry is returned in dirent
+ * structure in the d_name field. Individual directory entries returned by
+ * this function include regular files, sub-directories, pseudo-directories
+ * "." and ".." as well as volume labels, hidden files and system files.
+ */
+ static struct _wdirent*
+ _wreaddir(
+ _WDIR *dirp)
+ {
+ WIN32_FIND_DATAW *datap;
+ struct _wdirent *entp;
+
+ /* Read next directory entry */
+ datap = dirent_next(dirp);
+ if (datap) {
+ size_t n;
+ DWORD attr;
+
+ /* Pointer to directory entry to return */
+ entp = &dirp->ent;
+
+ /*
+ * Copy file name as wide-character string. If the file name is too
+ * long to fit in to the destination buffer, then truncate file name
+ * to PATH_MAX characters and zero-terminate the buffer.
+ */
+ n = 0;
+ while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
+ entp->d_name[n] = datap->cFileName[n];
+ n++;
+ }
+ dirp->ent.d_name[n] = 0;
+
+ /* Length of file name excluding zero terminator */
+ entp->d_namlen = n;
+
+ /* File type */
+ attr = datap->dwFileAttributes;
+ if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
+ entp->d_type = DT_CHR;
+ }
+ else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+ entp->d_type = DT_DIR;
+ }
+ else {
+ entp->d_type = DT_REG;
+ }
+
+ /* Reset dummy fields */
+ entp->d_ino = 0;
+ entp->d_reclen = sizeof(struct _wdirent);
+
+ }
+ else {
+
+ /* Last directory entry read */
+ entp = NULL;
+
+ }
+
+ return entp;
+ }
+
+ /*
+ * Close directory stream opened by opendir() function. This invalidates the
+ * DIR structure as well as any directory entry read previously by
+ * _wreaddir().
+ */
+ static int
+ _wclosedir(
+ _WDIR *dirp)
+ {
+ int ok;
+ if (dirp) {
+
+ /* Release search handle */
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
+ FindClose(dirp->handle);
+ dirp->handle = INVALID_HANDLE_VALUE;
+ }
+
+ /* Release search pattern */
+ if (dirp->patt) {
+ free(dirp->patt);
+ dirp->patt = NULL;
+ }
+
+ /* Release directory structure */
+ free(dirp);
+ ok = /*success*/0;
+
+ }
+ else {
+ /* Invalid directory stream */
+ dirent_set_errno(EBADF);
+ ok = /*failure*/-1;
+ }
+ return ok;
+ }
+
+ /*
+ * Rewind directory stream such that _wreaddir() returns the very first
+ * file name again.
+ */
+ static void
+ _wrewinddir(
+ _WDIR* dirp)
+ {
+ if (dirp) {
+ /* Release existing search handle */
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
+ FindClose(dirp->handle);
+ }
+
+ /* Open new search handle */
+ dirent_first(dirp);
+ }
+ }
+
+ /* Get first directory entry (internal) */
+ static WIN32_FIND_DATAW*
+ dirent_first(
+ _WDIR *dirp)
+ {
+ WIN32_FIND_DATAW *datap;
+
+ /* Open directory and retrieve the first entry */
+ dirp->handle = FindFirstFileExW(
+ dirp->patt, FindExInfoStandard, &dirp->data,
+ FindExSearchNameMatch, NULL, 0);
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
+
+ /* a directory entry is now waiting in memory */
+ datap = &dirp->data;
+ dirp->cached = 1;
+
+ }
+ else {
+
+ /* Failed to re-open directory: no directory entry in memory */
+ dirp->cached = 0;
+ datap = NULL;
+
+ }
+ return datap;
+ }
+
+ /* Get next directory entry (internal) */
+ static WIN32_FIND_DATAW*
+ dirent_next(
+ _WDIR *dirp)
+ {
+ WIN32_FIND_DATAW *p;
+
+ /* Get next directory entry */
+ if (dirp->cached != 0) {
+
+ /* A valid directory entry already in memory */
+ p = &dirp->data;
+ dirp->cached = 0;
+
+ }
+ else if (dirp->handle != INVALID_HANDLE_VALUE) {
+
+ /* Get the next directory entry from stream */
+ if (FindNextFileW(dirp->handle, &dirp->data) != FALSE) {
+ /* Got a file */
+ p = &dirp->data;
+ }
+ else {
+ /* The very last entry has been processed or an error occured */
+ FindClose(dirp->handle);
+ dirp->handle = INVALID_HANDLE_VALUE;
+ p = NULL;
+ }
+
+ }
+ else {
+
+ /* End of directory stream reached */
+ p = NULL;
+
+ }
+
+ return p;
+ }
+
+ /*
+ * Open directory stream using plain old C-string.
+ */
+ static DIR*
+ opendir(
+ const char *dirname)
+ {
+ struct DIR *dirp;
+ int error;
+
+ /* Must have directory name */
+ if (dirname == NULL || dirname[0] == '\0') {
+ dirent_set_errno(ENOENT);
+ return NULL;
+ }
+
+ /* Allocate memory for DIR structure */
+ dirp = (DIR*)malloc(sizeof(struct DIR));
+ if (dirp) {
+ wchar_t wname[PATH_MAX];
+ size_t n;
+
+ /* Convert directory name to wide-character string */
+ error = dirent_mbstowcs_s(&n, wname, PATH_MAX, dirname, PATH_MAX);
+ if (!error) {
+
+ /* Open directory stream using wide-character name */
+ dirp->wdirp = _wopendir(wname);
+ if (dirp->wdirp) {
+ /* Directory stream opened */
+ error = 0;
+ }
+ else {
+ /* Failed to open directory stream */
+ error = 1;
+ }
+
+ }
+ else {
+ /*
+ * Cannot convert file name to wide-character string. This
+ * occurs if the string contains invalid multi-byte sequences or
+ * the output buffer is too small to contain the resulting
+ * string.
+ */
+ error = 1;
+ }
+
+ }
+ else {
+ /* Cannot allocate DIR structure */
+ error = 1;
+ }
+
+ /* Clean up in case of error */
+ if (error && dirp) {
+ free(dirp);
+ dirp = NULL;
+ }
+
+ return dirp;
+ }
+
+ /*
+ * Read next directory entry.
+ *
+ * When working with text consoles, please note that file names returned by
+ * readdir() are represented in the default ANSI code page while any output to
+ * console is typically formatted on another code page. Thus, non-ASCII
+ * characters in file names will not usually display correctly on console. The
+ * problem can be fixed in two ways: (1) change the character set of console
+ * to 1252 using chcp utility and use Lucida Console font, or (2) use
+ * _cprintf function when writing to console. The _cprinf() will re-encode
+ * ANSI strings to the console code page so many non-ASCII characters will
+ * display correcly.
+ */
+ static struct dirent*
+ readdir(
+ DIR *dirp)
+ {
+ WIN32_FIND_DATAW *datap;
+ struct dirent *entp;
+
+ /* Read next directory entry */
+ datap = dirent_next(dirp->wdirp);
+ if (datap) {
+ size_t n;
+ int error;
+
+ /* Attempt to convert file name to multi-byte string */
+ error = dirent_wcstombs_s(
+ &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
+
+ /*
+ * If the file name cannot be represented by a multi-byte string,
+ * then attempt to use old 8+3 file name. This allows traditional
+ * Unix-code to access some file names despite of unicode
+ * characters, although file names may seem unfamiliar to the user.
+ *
+ * Be ware that the code below cannot come up with a short file
+ * name unless the file system provides one. At least
+ * VirtualBox shared folders fail to do this.
+ */
+ if (error && datap->cAlternateFileName[0] != '\0') {
+ error = dirent_wcstombs_s(
+ &n, dirp->ent.d_name, PATH_MAX,
+ datap->cAlternateFileName, PATH_MAX);
+ }
+
+ if (!error) {
+ DWORD attr;
+
+ /* Initialize directory entry for return */
+ entp = &dirp->ent;
+
+ /* Length of file name excluding zero terminator */
+ entp->d_namlen = n - 1;
+
+ /* File attributes */
+ attr = datap->dwFileAttributes;
+ if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
+ entp->d_type = DT_CHR;
+ }
+ else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+ entp->d_type = DT_DIR;
+ }
+ else {
+ entp->d_type = DT_REG;
+ }
+
+ /* Reset dummy fields */
+ entp->d_ino = 0;
+ entp->d_reclen = sizeof(struct dirent);
+
+ }
+ else {
+ /*
+ * Cannot convert file name to multi-byte string so construct
+ * an errornous directory entry and return that. Note that
+ * we cannot return NULL as that would stop the processing
+ * of directory entries completely.
+ */
+ entp = &dirp->ent;
+ entp->d_name[0] = '?';
+ entp->d_name[1] = '\0';
+ entp->d_namlen = 1;
+ entp->d_type = DT_UNKNOWN;
+ entp->d_ino = 0;
+ entp->d_reclen = 0;
+ }
+
+ }
+ else {
+ /* No more directory entries */
+ entp = NULL;
+ }
+
+ return entp;
+ }
+
+ /*
+ * Close directory stream.
+ */
+ static int
+ closedir(
+ DIR *dirp)
+ {
+ int ok;
+ if (dirp) {
+
+ /* Close wide-character directory stream */
+ ok = _wclosedir(dirp->wdirp);
+ dirp->wdirp = NULL;
+
+ /* Release multi-byte character version */
+ free(dirp);
+
+ }
+ else {
+
+ /* Invalid directory stream */
+ dirent_set_errno(EBADF);
+ ok = /*failure*/-1;
+
+ }
+ return ok;
+ }
+
+ /*
+ * Rewind directory stream to beginning.
+ */
+ static void
+ rewinddir(
+ DIR* dirp)
+ {
+ /* Rewind wide-character string directory stream */
+ _wrewinddir(dirp->wdirp);
+ }
+
+ /* Convert multi-byte string to wide character string */
+ static int
+ dirent_mbstowcs_s(
+ size_t *pReturnValue,
+ wchar_t *wcstr,
+ size_t sizeInWords,
+ const char *mbstr,
+ size_t count)
+ {
+ int error;
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+
+ /* Microsoft Visual Studio 2005 or later */
+ error = mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count);
+
+#else
+
+ /* Older Visual Studio or non-Microsoft compiler */
+ size_t n;
+
+ /* Convert to wide-character string (or count characters) */
+ n = mbstowcs(wcstr, mbstr, sizeInWords);
+ if (!wcstr || n < count) {
+
+ /* Zero-terminate output buffer */
+ if (wcstr && sizeInWords) {
+ if (n >= sizeInWords) {
+ n = sizeInWords - 1;
+ }
+ wcstr[n] = 0;
+ }
+
+ /* Length of resuting multi-byte string WITH zero terminator */
+ if (pReturnValue) {
+ *pReturnValue = n + 1;
+ }
+
+ /* Success */
+ error = 0;
+
+ }
+ else {
+
+ /* Could not convert string */
+ error = 1;
+
+ }
+
+#endif
+
+ return error;
+ }
+
+ /* Convert wide-character string to multi-byte string */
+ static int
+ dirent_wcstombs_s(
+ size_t *pReturnValue,
+ char *mbstr,
+ size_t sizeInBytes, /* max size of mbstr */
+ const wchar_t *wcstr,
+ size_t count)
+ {
+ int error;
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+
+ /* Microsoft Visual Studio 2005 or later */
+ error = wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count);
+
+#else
+
+ /* Older Visual Studio or non-Microsoft compiler */
+ size_t n;
+
+ /* Convert to multi-byte string (or count the number of bytes needed) */
+ n = wcstombs(mbstr, wcstr, sizeInBytes);
+ if (!mbstr || n < count) {
+
+ /* Zero-terminate output buffer */
+ if (mbstr && sizeInBytes) {
+ if (n >= sizeInBytes) {
+ n = sizeInBytes - 1;
+ }
+ mbstr[n] = '\0';
+ }
+
+ /* Length of resulting multi-bytes string WITH zero-terminator */
+ if (pReturnValue) {
+ *pReturnValue = n + 1;
+ }
+
+ /* Success */
+ error = 0;
+
+ }
+ else {
+
+ /* Cannot convert string */
+ error = 1;
+
+ }
+
+#endif
+
+ return error;
+ }
+
+ /* Set errno variable */
+ static void
+ dirent_set_errno(
+ int error)
+ {
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+
+ /* Microsoft Visual Studio 2005 and later */
+ _set_errno(error);
+
+#else
+
+ /* Non-Microsoft compiler or older Microsoft compiler */
+ errno = error;
+
+#endif
+ }
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*DIRENT_H*/
diff --git a/lib/librte_eal/windows/include_override/getopt.h b/lib/librte_eal/windows/include_override/getopt.h
new file mode 100644
index 000000000..19bc18f9a
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/getopt.h
@@ -0,0 +1,252 @@
+#ifndef __GETOPT_H__
+/**
+ * DISCLAIMER
+ * This file is a part of the w64 mingw-runtime package.
+ *
+ * The w64 mingw-runtime package and its code is distributed in the hope that it
+ * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
+ * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
+ * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+/*
+* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+*
+* Permission to use, copy, modify, and distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*
+* Sponsored in part by the Defense Advanced Research Projects
+* Agency (DARPA) and Air Force Research Laboratory, Air Force
+* Materiel Command, USAF, under agreement number F39502-99-1-0512.
+*/
+/*-
+* Copyright (c) 2000 The NetBSD Foundation, Inc.
+* All rights reserved.
+*
+* This code is derived from software contributed to The NetBSD Foundation
+* by Dieter Baron and Thomas Klausner.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma warning(disable:4996);
+
+#define __GETOPT_H__
+
+/* All the headers include this file. */
+#include <crtdefs.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
+
+#define PRINT_ERROR ((opterr) && (*options != ':'))
+
+#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
+#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
+
+/* return values */
+#define BADCH (int)'?'
+#define BADARG ((*options == ':') ? (int)':' : (int)'?')
+#define INORDER (int)1
+
+#ifndef __CYGWIN__
+#define __progname __argv[0]
+#else
+ extern char __declspec(dllimport) *__progname;
+#endif
+
+#ifdef __CYGWIN__
+ static char EMSG[] = "";
+#else
+#define EMSG ""
+#endif
+extern int optind; /* index of first non-option in argv */
+extern int optopt; /* single option character, as parsed */
+extern int opterr; /* flag to enable built-in diagnostics... */
+ /* (user may set to zero, to suppress) */
+
+extern char *optarg; /* pointer to argument of current option */
+
+extern int getopt(int nargc, char * const *nargv, const char *options);
+
+static int getopt_internal(int, char * const *, const char *,
+ const struct option *, int *, int);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static void
+_vwarnx(const char *fmt, va_list ap)
+{
+ (void)fprintf(stderr, "%s: ", __progname);
+ if (fmt != NULL)
+ (void)vfprintf(stderr, fmt, ap);
+ (void)fprintf(stderr, "\n");
+}
+
+static void
+warnx(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ _vwarnx(fmt, ap);
+ va_end(ap);
+}
+
+/*
+* Compute the greatest common divisor of a and b.
+*/
+static int
+gcd(int a, int b)
+{
+ int c;
+
+ c = a % b;
+ while (c != 0) {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+
+ return (b);
+}
+
+/*
+* Exchange the block from nonopt_start to nonopt_end with the block
+* from nonopt_end to opt_end (keeping the same order of arguments
+* in each block).
+*/
+static void
+permute_args(int panonopt_start, int panonopt_end, int opt_end, char * const *nargv)
+{
+ int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+ char *swap;
+
+ /*
+ * compute lengths of blocks and number and size of cycles
+ */
+ nnonopts = panonopt_end - panonopt_start;
+ nopts = opt_end - panonopt_end;
+ ncycle = gcd(nnonopts, nopts);
+ cyclelen = (opt_end - panonopt_start) / ncycle;
+
+ for (i = 0; i < ncycle; i++) {
+ cstart = panonopt_end + i;
+ pos = cstart;
+ for (j = 0; j < cyclelen; j++) {
+ if (pos >= panonopt_end)
+ pos -= nnonopts;
+ else
+ pos += nopts;
+ swap = nargv[pos];
+ /* LINTED const cast */
+ ((char **)nargv)[pos] = nargv[cstart];
+ /* LINTED const cast */
+ ((char **)nargv)[cstart] = swap;
+ }
+ }
+}
+
+
+#ifdef _BSD_SOURCE
+/*
+ * BSD adds the non-standard `optreset' feature, for reinitialisation
+ * of `getopt' parsing. We support this feature, for applications which
+ * proclaim their BSD heritage, before including this header; however,
+ * to maintain portability, developers are advised to avoid it.
+ */
+# define optreset __mingw_optreset
+extern int optreset;
+#endif
+#ifdef __cplusplus
+}
+#endif
+/*
+ * POSIX requires the `getopt' API to be specified in `unistd.h';
+ * thus, `unistd.h' includes this header. However, we do not want
+ * to expose the `getopt_long' or `getopt_long_only' APIs, when
+ * included in this manner. Thus, close the standard __GETOPT_H__
+ * declarations block, and open an additional __GETOPT_LONG_H__
+ * specific block, only when *not* __UNISTD_H_SOURCED__, in which
+ * to declare the extended API.
+ */
+#endif /* !defined(__GETOPT_H__) */
+
+#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
+#define __GETOPT_LONG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct option /* specification for a long form option... */
+{
+ const char *name; /* option name, without leading hyphens */
+ int has_arg; /* does it take an argument? */
+ int *flag; /* where to save its status, or NULL */
+ int val; /* its associated status value */
+};
+
+enum /* permitted values for its `has_arg' field... */
+{
+ no_argument = 0, /* option never takes an argument */
+ required_argument, /* option always requires an argument */
+ optional_argument /* option may take an argument */
+};
+
+extern int getopt_long(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx);
+extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx);
+/*
+ * Previous MinGW implementation had...
+ */
+#ifndef HAVE_DECL_GETOPT
+/*
+ * ...for the long form API only; keep this for compatibility.
+ */
+# define HAVE_DECL_GETOPT 1
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */
diff --git a/lib/librte_eal/windows/include_override/net/ethernet.h b/lib/librte_eal/windows/include_override/net/ethernet.h
new file mode 100644
index 000000000..ae7341ee8
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/net/ethernet.h
@@ -0,0 +1,405 @@
+/*
+ * Fundamental constants relating to ethernet.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef _NET_ETHERNET_H_
+#define _NET_ETHERNET_H_
+
+/*
+ * Some basic Ethernet constants.
+ */
+#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
+#define ETHER_TYPE_LEN 2 /* length of the Ethernet type field */
+#define ETHER_CRC_LEN 4 /* length of the Ethernet CRC */
+#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN)
+#define ETHER_MIN_LEN 64 /* minimum frame len, including CRC */
+#define ETHER_MAX_LEN 1518 /* maximum frame len, including CRC */
+#define ETHER_MAX_LEN_JUMBO 9018 /* max jumbo frame len, including CRC */
+
+#define ETHER_VLAN_ENCAP_LEN 4 /* len of 802.1Q VLAN encapsulation */
+/*
+ * Mbuf adjust factor to force 32-bit alignment of IP header.
+ * Drivers should do m_adj(m, ETHER_ALIGN) when setting up a
+ * receive so the upper layers get the IP header properly aligned
+ * past the 14-byte Ethernet header.
+ */
+#define ETHER_ALIGN 2 /* driver adjust for IP hdr alignment */
+
+/*
+ * Compute the maximum frame size based on ethertype (i.e. possible
+ * encapsulation) and whether or not an FCS is present.
+ */
+#define ETHER_MAX_FRAME(ifp, etype, hasfcs) \
+ ((ifp)->if_mtu + ETHER_HDR_LEN + \
+ ((hasfcs) ? ETHER_CRC_LEN : 0) + \
+ (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0))
+
+/*
+ * Ethernet-specific mbuf flags.
+ */
+#define M_HASFCS M_PROTO5 /* FCS included at end of frame */
+
+/*
+ * Ethernet CRC32 polynomials (big- and little-endian verions).
+ */
+#define ETHER_CRC_POLY_LE 0xedb88320
+#define ETHER_CRC_POLY_BE 0x04c11db6
+
+/*
+ * A macro to validate a length with
+ */
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+struct ether_header {
+ u_char ether_dhost[ETHER_ADDR_LEN];
+ u_char ether_shost[ETHER_ADDR_LEN];
+ u_short ether_type;
+} __packed;
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+struct ether_addr {
+ u_char octet[ETHER_ADDR_LEN];
+} __packed;
+
+#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
+
+/*
+ * NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields.
+ * However, there are some conflicts.
+ */
+
+#define ETHERTYPE_8023 0x0004 /* IEEE 802.3 packet */
+ /* 0x0101 .. 0x1FF Experimental */
+#define ETHERTYPE_PUP 0x0200 /* Xerox PUP protocol - see 0A00 */
+#define ETHERTYPE_PUPAT 0x0200 /* PUP Address Translation - see 0A01 */
+#define ETHERTYPE_SPRITE 0x0500 /* ??? */
+ /* 0x0400 Nixdorf */
+#define ETHERTYPE_NS 0x0600 /* XNS */
+#define ETHERTYPE_NSAT 0x0601 /* XNS Address Translation (3Mb only) */
+#define ETHERTYPE_DLOG1 0x0660 /* DLOG (?) */
+#define ETHERTYPE_DLOG2 0x0661 /* DLOG (?) */
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#define ETHERTYPE_X75 0x0801 /* X.75 Internet */
+#define ETHERTYPE_NBS 0x0802 /* NBS Internet */
+#define ETHERTYPE_ECMA 0x0803 /* ECMA Internet */
+#define ETHERTYPE_CHAOS 0x0804 /* CHAOSnet */
+#define ETHERTYPE_X25 0x0805 /* X.25 Level 3 */
+#define ETHERTYPE_ARP 0x0806 /* Address resolution protocol */
+#define ETHERTYPE_NSCOMPAT 0x0807 /* XNS Compatibility */
+#define ETHERTYPE_FRARP 0x0808 /* Frame Relay ARP (RFC1701) */
+ /* 0x081C Symbolics Private */
+ /* 0x0888 - 0x088A Xyplex */
+#define ETHERTYPE_UBDEBUG 0x0900 /* Ungermann-Bass network debugger */
+#define ETHERTYPE_IEEEPUP 0x0A00 /* Xerox IEEE802.3 PUP */
+#define ETHERTYPE_IEEEPUPAT 0x0A01 /* Xerox IEEE802.3 PUP Address Translation */
+#define ETHERTYPE_VINES 0x0BAD /* Banyan VINES */
+#define ETHERTYPE_VINESLOOP 0x0BAE /* Banyan VINES Loopback */
+#define ETHERTYPE_VINESECHO 0x0BAF /* Banyan VINES Echo */
+
+/* 0x1000 - 0x100F Berkeley Trailer */
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERTYPE_DCA 0x1234 /* DCA - Multicast */
+#define ETHERTYPE_VALID 0x1600 /* VALID system protocol */
+#define ETHERTYPE_DOGFIGHT 0x1989 /* Artificial Horizons ("Aviator" dogfight simulator [on Sun]) */
+#define ETHERTYPE_RCL 0x1995 /* Datapoint Corporation (RCL lan protocol) */
+
+ /* The following 3C0x types
+ are unregistered: */
+#define ETHERTYPE_NBPVCD 0x3C00 /* 3Com NBP virtual circuit datagram (like XNS SPP) not registered */
+#define ETHERTYPE_NBPSCD 0x3C01 /* 3Com NBP System control datagram not registered */
+#define ETHERTYPE_NBPCREQ 0x3C02 /* 3Com NBP Connect request (virtual cct) not registered */
+#define ETHERTYPE_NBPCRSP 0x3C03 /* 3Com NBP Connect response not registered */
+#define ETHERTYPE_NBPCC 0x3C04 /* 3Com NBP Connect complete not registered */
+#define ETHERTYPE_NBPCLREQ 0x3C05 /* 3Com NBP Close request (virtual cct) not registered */
+#define ETHERTYPE_NBPCLRSP 0x3C06 /* 3Com NBP Close response not registered */
+#define ETHERTYPE_NBPDG 0x3C07 /* 3Com NBP Datagram (like XNS IDP) not registered */
+#define ETHERTYPE_NBPDGB 0x3C08 /* 3Com NBP Datagram broadcast not registered */
+#define ETHERTYPE_NBPCLAIM 0x3C09 /* 3Com NBP Claim NetBIOS name not registered */
+#define ETHERTYPE_NBPDLTE 0x3C0A /* 3Com NBP Delete NetBIOS name not registered */
+#define ETHERTYPE_NBPRAS 0x3C0B /* 3Com NBP Remote adaptor status request not registered */
+#define ETHERTYPE_NBPRAR 0x3C0C /* 3Com NBP Remote adaptor response not registered */
+#define ETHERTYPE_NBPRST 0x3C0D /* 3Com NBP Reset not registered */
+
+#define ETHERTYPE_PCS 0x4242 /* PCS Basic Block Protocol */
+#define ETHERTYPE_IMLBLDIAG 0x424C /* Information Modes Little Big LAN diagnostic */
+#define ETHERTYPE_DIDDLE 0x4321 /* THD - Diddle */
+#define ETHERTYPE_IMLBL 0x4C42 /* Information Modes Little Big LAN */
+#define ETHERTYPE_SIMNET 0x5208 /* BBN Simnet Private */
+#define ETHERTYPE_DECEXPER 0x6000 /* DEC Unassigned, experimental */
+#define ETHERTYPE_MOPDL 0x6001 /* DEC MOP dump/load */
+#define ETHERTYPE_MOPRC 0x6002 /* DEC MOP remote console */
+#define ETHERTYPE_DECnet 0x6003 /* DEC DECNET Phase IV route */
+#define ETHERTYPE_DN ETHERTYPE_DECnet /* libpcap, tcpdump */
+#define ETHERTYPE_LAT 0x6004 /* DEC LAT */
+#define ETHERTYPE_DECDIAG 0x6005 /* DEC diagnostic protocol (at interface initialization?) */
+#define ETHERTYPE_DECCUST 0x6006 /* DEC customer protocol */
+#define ETHERTYPE_SCA 0x6007 /* DEC LAVC, SCA */
+#define ETHERTYPE_AMBER 0x6008 /* DEC AMBER */
+#define ETHERTYPE_DECMUMPS 0x6009 /* DEC MUMPS */
+ /* 0x6010 - 0x6014 3Com Corporation */
+#define ETHERTYPE_TRANSETHER 0x6558 /* Trans Ether Bridging (RFC1701)*/
+#define ETHERTYPE_RAWFR 0x6559 /* Raw Frame Relay (RFC1701) */
+#define ETHERTYPE_UBDL 0x7000 /* Ungermann-Bass download */
+#define ETHERTYPE_UBNIU 0x7001 /* Ungermann-Bass NIUs */
+#define ETHERTYPE_UBDIAGLOOP 0x7002 /* Ungermann-Bass diagnostic/loopback */
+#define ETHERTYPE_UBNMC 0x7003 /* Ungermann-Bass ??? (NMC to/from UB Bridge) */
+#define ETHERTYPE_UBBST 0x7005 /* Ungermann-Bass Bridge Spanning Tree */
+#define ETHERTYPE_OS9 0x7007 /* OS/9 Microware */
+#define ETHERTYPE_OS9NET 0x7009 /* OS/9 Net? */
+ /* 0x7020 - 0x7029 LRT (England) (now Sintrom) */
+#define ETHERTYPE_RACAL 0x7030 /* Racal-Interlan */
+#define ETHERTYPE_PRIMENTS 0x7031 /* Prime NTS (Network Terminal Service) */
+#define ETHERTYPE_CABLETRON 0x7034 /* Cabletron */
+#define ETHERTYPE_CRONUSVLN 0x8003 /* Cronus VLN */
+#define ETHERTYPE_CRONUS 0x8004 /* Cronus Direct */
+#define ETHERTYPE_HP 0x8005 /* HP Probe */
+#define ETHERTYPE_NESTAR 0x8006 /* Nestar */
+#define ETHERTYPE_ATTSTANFORD 0x8008 /* AT&T/Stanford (local use) */
+#define ETHERTYPE_EXCELAN 0x8010 /* Excelan */
+#define ETHERTYPE_SG_DIAG 0x8013 /* SGI diagnostic type */
+#define ETHERTYPE_SG_NETGAMES 0x8014 /* SGI network games */
+#define ETHERTYPE_SG_RESV 0x8015 /* SGI reserved type */
+#define ETHERTYPE_SG_BOUNCE 0x8016 /* SGI bounce server */
+#define ETHERTYPE_APOLLODOMAIN 0x8019 /* Apollo DOMAIN */
+#define ETHERTYPE_TYMSHARE 0x802E /* Tymeshare */
+#define ETHERTYPE_TIGAN 0x802F /* Tigan, Inc. */
+#define ETHERTYPE_REVARP 0x8035 /* Reverse addr resolution protocol */
+#define ETHERTYPE_AEONIC 0x8036 /* Aeonic Systems */
+#define ETHERTYPE_IPXNEW 0x8037 /* IPX (Novell Netware?) */
+#define ETHERTYPE_LANBRIDGE 0x8038 /* DEC LANBridge */
+#define ETHERTYPE_DSMD 0x8039 /* DEC DSM/DDP */
+#define ETHERTYPE_ARGONAUT 0x803A /* DEC Argonaut Console */
+#define ETHERTYPE_VAXELN 0x803B /* DEC VAXELN */
+#define ETHERTYPE_DECDNS 0x803C /* DEC DNS Naming Service */
+#define ETHERTYPE_ENCRYPT 0x803D /* DEC Ethernet Encryption */
+#define ETHERTYPE_DECDTS 0x803E /* DEC Distributed Time Service */
+#define ETHERTYPE_DECLTM 0x803F /* DEC LAN Traffic Monitor */
+#define ETHERTYPE_DECNETBIOS 0x8040 /* DEC PATHWORKS DECnet NETBIOS Emulation */
+#define ETHERTYPE_DECLAST 0x8041 /* DEC Local Area System Transport */
+ /* 0x8042 DEC Unassigned */
+#define ETHERTYPE_PLANNING 0x8044 /* Planning Research Corp. */
+ /* 0x8046 - 0x8047 AT&T */
+#define ETHERTYPE_DECAM 0x8048 /* DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) */
+#define ETHERTYPE_EXPERDATA 0x8049 /* ExperData */
+#define ETHERTYPE_VEXP 0x805B /* Stanford V Kernel exp. */
+#define ETHERTYPE_VPROD 0x805C /* Stanford V Kernel prod. */
+#define ETHERTYPE_ES 0x805D /* Evans & Sutherland */
+#define ETHERTYPE_LITTLE 0x8060 /* Little Machines */
+#define ETHERTYPE_COUNTERPOINT 0x8062 /* Counterpoint Computers */
+ /* 0x8065 - 0x8066 Univ. of Mass @ Amherst */
+#define ETHERTYPE_VEECO 0x8067 /* Veeco Integrated Auto. */
+#define ETHERTYPE_GENDYN 0x8068 /* General Dynamics */
+#define ETHERTYPE_ATT 0x8069 /* AT&T */
+#define ETHERTYPE_AUTOPHON 0x806A /* Autophon */
+#define ETHERTYPE_COMDESIGN 0x806C /* ComDesign */
+#define ETHERTYPE_COMPUGRAPHIC 0x806D /* Compugraphic Corporation */
+ /* 0x806E - 0x8077 Landmark Graphics Corp. */
+#define ETHERTYPE_MATRA 0x807A /* Matra */
+#define ETHERTYPE_DDE 0x807B /* Dansk Data Elektronik */
+#define ETHERTYPE_MERIT 0x807C /* Merit Internodal (or Univ of Michigan?) */
+ /* 0x807D - 0x807F Vitalink Communications */
+#define ETHERTYPE_VLTLMAN 0x8080 /* Vitalink TransLAN III Management */
+ /* 0x8081 - 0x8083 Counterpoint Computers */
+ /* 0x8088 - 0x808A Xyplex */
+#define ETHERTYPE_ATALK 0x809B /* AppleTalk */
+#define ETHERTYPE_AT ETHERTYPE_ATALK /* old NetBSD */
+#define ETHERTYPE_APPLETALK ETHERTYPE_ATALK /* HP-UX */
+ /* 0x809C - 0x809E Datability */
+#define ETHERTYPE_SPIDER 0x809F /* Spider Systems Ltd. */
+ /* 0x80A3 Nixdorf */
+ /* 0x80A4 - 0x80B3 Siemens Gammasonics Inc. */
+ /* 0x80C0 - 0x80C3 DCA (Digital Comm. Assoc.) Data Exchange Cluster */
+ /* 0x80C4 - 0x80C5 Banyan Systems */
+#define ETHERTYPE_PACER 0x80C6 /* Pacer Software */
+#define ETHERTYPE_APPLITEK 0x80C7 /* Applitek Corporation */
+ /* 0x80C8 - 0x80CC Intergraph Corporation */
+ /* 0x80CD - 0x80CE Harris Corporation */
+ /* 0x80CF - 0x80D2 Taylor Instrument */
+ /* 0x80D3 - 0x80D4 Rosemount Corporation */
+#define ETHERTYPE_SNA 0x80D5 /* IBM SNA Services over Ethernet */
+#define ETHERTYPE_VARIAN 0x80DD /* Varian Associates */
+ /* 0x80DE - 0x80DF TRFS (Integrated Solutions Transparent Remote File System) */
+ /* 0x80E0 - 0x80E3 Allen-Bradley */
+ /* 0x80E4 - 0x80F0 Datability */
+#define ETHERTYPE_RETIX 0x80F2 /* Retix */
+#define ETHERTYPE_AARP 0x80F3 /* AppleTalk AARP */
+ /* 0x80F4 - 0x80F5 Kinetics */
+#define ETHERTYPE_APOLLO 0x80F7 /* Apollo Computer */
+#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging (XXX conflicts) */
+ /* 0x80FF - 0x8101 Wellfleet Communications (XXX conflicts) */
+#define ETHERTYPE_BOFL 0x8102 /* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */
+#define ETHERTYPE_WELLFLEET 0x8103 /* Wellfleet Communications */
+ /* 0x8107 - 0x8109 Symbolics Private */
+#define ETHERTYPE_TALARIS 0x812B /* Talaris */
+#define ETHERTYPE_WATERLOO 0x8130 /* Waterloo Microsystems Inc. (XXX which?) */
+#define ETHERTYPE_HAYES 0x8130 /* Hayes Microcomputers (XXX which?) */
+#define ETHERTYPE_VGLAB 0x8131 /* VG Laboratory Systems */
+ /* 0x8132 - 0x8137 Bridge Communications */
+#define ETHERTYPE_IPX 0x8137 /* Novell (old) NetWare IPX (ECONFIG E option) */
+#define ETHERTYPE_NOVELL 0x8138 /* Novell, Inc. */
+ /* 0x8139 - 0x813D KTI */
+#define ETHERTYPE_MUMPS 0x813F /* M/MUMPS data sharing */
+#define ETHERTYPE_AMOEBA 0x8145 /* Vrije Universiteit (NL) Amoeba 4 RPC (obsolete) */
+#define ETHERTYPE_FLIP 0x8146 /* Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) */
+#define ETHERTYPE_VURESERVED 0x8147 /* Vrije Universiteit (NL) [reserved] */
+#define ETHERTYPE_LOGICRAFT 0x8148 /* Logicraft */
+#define ETHERTYPE_NCD 0x8149 /* Network Computing Devices */
+#define ETHERTYPE_ALPHA 0x814A /* Alpha Micro */
+#define ETHERTYPE_SNMP 0x814C /* SNMP over Ethernet (see RFC1089) */
+ /* 0x814D - 0x814E BIIN */
+#define ETHERTYPE_TEC 0x814F /* Technically Elite Concepts */
+#define ETHERTYPE_RATIONAL 0x8150 /* Rational Corp */
+ /* 0x8151 - 0x8153 Qualcomm */
+ /* 0x815C - 0x815E Computer Protocol Pty Ltd */
+ /* 0x8164 - 0x8166 Charles River Data Systems */
+#define ETHERTYPE_XTP 0x817D /* Protocol Engines XTP */
+#define ETHERTYPE_SGITW 0x817E /* SGI/Time Warner prop. */
+#define ETHERTYPE_HIPPI_FP 0x8180 /* HIPPI-FP encapsulation */
+#define ETHERTYPE_STP 0x8181 /* Scheduled Transfer STP, HIPPI-ST */
+ /* 0x8182 - 0x8183 Reserved for HIPPI-6400 */
+ /* 0x8184 - 0x818C SGI prop. */
+#define ETHERTYPE_MOTOROLA 0x818D /* Motorola */
+#define ETHERTYPE_NETBEUI 0x8191 /* PowerLAN NetBIOS/NetBEUI (PC) */
+ /* 0x819A - 0x81A3 RAD Network Devices */
+ /* 0x81B7 - 0x81B9 Xyplex */
+ /* 0x81CC - 0x81D5 Apricot Computers */
+ /* 0x81D6 - 0x81DD Artisoft Lantastic */
+ /* 0x81E6 - 0x81EF Polygon */
+ /* 0x81F0 - 0x81F2 Comsat Labs */
+ /* 0x81F3 - 0x81F5 SAIC */
+ /* 0x81F6 - 0x81F8 VG Analytical */
+ /* 0x8203 - 0x8205 QNX Software Systems Ltd. */
+ /* 0x8221 - 0x8222 Ascom Banking Systems */
+ /* 0x823E - 0x8240 Advanced Encryption Systems */
+ /* 0x8263 - 0x826A Charles River Data Systems */
+ /* 0x827F - 0x8282 Athena Programming */
+ /* 0x829A - 0x829B Inst Ind Info Tech */
+ /* 0x829C - 0x82AB Taurus Controls */
+ /* 0x82AC - 0x8693 Walker Richer & Quinn */
+#define ETHERTYPE_ACCTON 0x8390 /* Accton Technologies (unregistered) */
+#define ETHERTYPE_TALARISMC 0x852B /* Talaris multicast */
+#define ETHERTYPE_KALPANA 0x8582 /* Kalpana */
+ /* 0x8694 - 0x869D Idea Courier */
+ /* 0x869E - 0x86A1 Computer Network Tech */
+ /* 0x86A3 - 0x86AC Gateway Communications */
+#define ETHERTYPE_SECTRA 0x86DB /* SECTRA */
+#define ETHERTYPE_IPV6 0x86DD /* IP protocol version 6 */
+#define ETHERTYPE_DELTACON 0x86DE /* Delta Controls */
+#define ETHERTYPE_ATOMIC 0x86DF /* ATOMIC */
+ /* 0x86E0 - 0x86EF Landis & Gyr Powers */
+ /* 0x8700 - 0x8710 Motorola */
+#define ETHERTYPE_RDP 0x8739 /* Control Technology Inc. RDP Without IP */
+#define ETHERTYPE_MICP 0x873A /* Control Technology Inc. Mcast Industrial Ctrl Proto. */
+ /* 0x873B - 0x873C Control Technology Inc. Proprietary */
+#define ETHERTYPE_TCPCOMP 0x876B /* TCP/IP Compression (RFC1701) */
+#define ETHERTYPE_IPAS 0x876C /* IP Autonomous Systems (RFC1701) */
+#define ETHERTYPE_SECUREDATA 0x876D /* Secure Data (RFC1701) */
+#define ETHERTYPE_FLOWCONTROL 0x8808 /* 802.3x flow control packet */
+#define ETHERTYPE_SLOW 0x8809 /* 802.3ad link aggregation (LACP) */
+#define ETHERTYPE_PPP 0x880B /* PPP (obsolete by PPPoE) */
+#define ETHERTYPE_HITACHI 0x8820 /* Hitachi Cable (Optoelectronic Systems Laboratory) */
+#define ETHERTYPE_MPLS 0x8847 /* MPLS Unicast */
+#define ETHERTYPE_MPLS_MCAST 0x8848 /* MPLS Multicast */
+#define ETHERTYPE_AXIS 0x8856 /* Axis Communications AB proprietary bootstrap/config */
+#define ETHERTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
+#define ETHERTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
+#define ETHERTYPE_LANPROBE 0x8888 /* HP LanProbe test? */
+#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
+#define ETHERTYPE_LOOPBACK 0x9000 /* Loopback: used to test interfaces */
+#define ETHERTYPE_LBACK ETHERTYPE_LOOPBACK /* DEC MOP loopback */
+#define ETHERTYPE_XNSSM 0x9001 /* 3Com (Formerly Bridge Communications), XNS Systems Management */
+#define ETHERTYPE_TCPSM 0x9002 /* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */
+#define ETHERTYPE_BCLOOP 0x9003 /* 3Com (Formerly Bridge Communications), loopback detection */
+#define ETHERTYPE_DEBNI 0xAAAA /* DECNET? Used by VAX 6220 DEBNI */
+#define ETHERTYPE_SONIX 0xFAF5 /* Sonix Arpeggio */
+#define ETHERTYPE_VITAL 0xFF00 /* BBN VITAL-LanBridge cache wakeups */
+ /* 0xFF00 - 0xFFOF ISC Bunker Ramo */
+
+#define ETHERTYPE_MAX 0xFFFF /* Maximum valid ethernet type, reserved */
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERMTU (ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+#define ETHERMIN (ETHER_MIN_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+#define ETHERMTU_JUMBO (ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN)
+/*
+ * The ETHER_BPF_MTAP macro should be used by drivers which support hardware
+ * offload for VLAN tag processing. It will check the mbuf to see if it has
+ * M_VLANTAG set, and if it does, will pass the packet along to
+ * ether_vlan_mtap. This function will re-insert VLAN tags for the duration
+ * of the tap, so they show up properly for network analyzers.
+ */
+#define ETHER_BPF_MTAP(_ifp, _m) do { \
+ if (bpf_peers_present((_ifp)->if_bpf)) { \
+ M_ASSERTVALID(_m); \
+ if (((_m)->m_flags & M_VLANTAG) != 0) \
+ ether_vlan_mtap((_ifp)->if_bpf, (_m), NULL, 0); \
+ else \
+ bpf_mtap((_ifp)->if_bpf, (_m)); \
+ } \
+} while (0)
+
+#ifdef _KERNEL
+
+struct ifnet;
+struct mbuf;
+struct route;
+struct sockaddr;
+struct bpf_if;
+
+extern uint32_t ether_crc32_le(const uint8_t *, size_t);
+extern uint32_t ether_crc32_be(const uint8_t *, size_t);
+extern void ether_demux(struct ifnet *, struct mbuf *);
+extern void ether_ifattach(struct ifnet *, const u_int8_t *);
+extern void ether_ifdetach(struct ifnet *);
+extern int ether_ioctl(struct ifnet *, u_long, caddr_t);
+extern int ether_output(struct ifnet *,
+ struct mbuf *, struct sockaddr *, struct route *);
+extern int ether_output_frame(struct ifnet *, struct mbuf *);
+extern char *ether_sprintf(const u_int8_t *);
+void ether_vlan_mtap(struct bpf_if *, struct mbuf *,
+ void *, u_int);
+struct mbuf *ether_vlanencap(struct mbuf *, uint16_t);
+
+#else /* _KERNEL */
+
+#include <sys/cdefs.h>
+
+/*
+ * Ethernet address conversion/parsing routines.
+ */
+__BEGIN_DECLS
+struct ether_addr *ether_aton(const char *);
+struct ether_addr *ether_aton_r(const char *, struct ether_addr *);
+int ether_hostton(const char *, struct ether_addr *);
+int ether_line(const char *, struct ether_addr *, char *);
+char *ether_ntoa(const struct ether_addr *);
+char *ether_ntoa_r(const struct ether_addr *, char *);
+int ether_ntohost(char *, const struct ether_addr *);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_NET_ETHERNET_H_ */
diff --git a/lib/librte_eal/windows/include_override/netinet/in.h b/lib/librte_eal/windows/include_override/netinet/in.h
new file mode 100644
index 000000000..5d4f411a3
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/netinet/in.h
@@ -0,0 +1,48 @@
+#ifndef _IN_H_
+#define _IN_H_
+
+/*
+ * IPv6 address
+ */
+struct in6_addr {
+ union {
+ uint8_t __u6_addr8[16];
+ uint16_t __u6_addr16[8];
+ uint32_t __u6_addr32[4];
+ } __u6_addr; /* 128-bit IP6 address */
+};
+
+#define INET6_ADDRSTRLEN 46
+
+#ifndef _IN_ADDR_T_DECLARED
+typedef uint32_t in_addr_t;
+#define _IN_ADDR_T_DECLARED
+#endif
+
+// #define _STRUCT_IN_ADDR_DECLARED
+/* Internet address (a structure for historical reasons). */
+#ifndef _STRUCT_IN_ADDR_DECLARED
+struct in_addr {
+ in_addr_t s_addr;
+};
+#define _STRUCT_IN_ADDR_DECLARED
+#endif
+
+#define AF_INET 0
+
+#define IPPROTO_IP 0
+#define IPPROTO_HOPOPTS 0
+#define IPPROTO_IPV4 4 /* IPv4 encapsulation */
+#define IPPROTO_IPIP IPPROTO_IPV4 /* for compatibility */
+#define IPPROTO_TCP 6
+#define IPPROTO_UDP 17
+#define IPPROTO_IPV6 41 /* IP6 header */
+#define IPPROTO_ROUTING 43 /* IP6 routing header */
+#define IPPROTO_FRAGMENT 44 /* IP6 fragmentation header */
+#define IPPROTO_GRE 47 /* General Routing Encap. */
+#define IPPROTO_ESP 50 /* IP6 Encap Sec. Payload */
+#define IPPROTO_AH 51 /* IP6 Auth Header */
+#define IPPROTO_DSTOPTS 60 /* IP6 destination option */
+
+
+#endif
diff --git a/lib/librte_eal/windows/include_override/netinet/tcp.h b/lib/librte_eal/windows/include_override/netinet/tcp.h
new file mode 100644
index 000000000..250c4c354
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/netinet/tcp.h
@@ -0,0 +1,4 @@
+#ifndef NETINET_TCP_H
+#define NETINET_TCP_H
+
+#endif
diff --git a/lib/librte_eal/windows/include_override/pthread.h b/lib/librte_eal/windows/include_override/pthread.h
new file mode 100644
index 000000000..1505842e8
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/pthread.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _PTHREAD_H_
+#define _PTHREAD_H_
+
+#define PTHREAD_BARRIER_SERIAL_THREAD TRUE
+
+typedef void* pthread_t;
+typedef void pthread_attr_t;
+typedef SYNCHRONIZATION_BARRIER pthread_barrier_t;
+typedef HANDLE pthread_mutex_t;
+
+#define pthread_barrier_init(barrier,attr,count) InitializeSynchronizationBarrier(barrier,count,-1)
+#define pthread_barrier_wait(barrier) EnterSynchronizationBarrier(barrier,SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
+#define pthread_barrier_destroy(barrier) DeleteSynchronizationBarrier(barrier)
+#define pthread_cancel(thread) TerminateThread(thread,0)
+#define pthread_mutex_lock(mutex) WaitForSingleObject(mutex,INFINITE)
+#define pthread_mutex_unlock(mutex) ReleaseMutex(mutex)
+#define pthread_cond_signal(condition_variable) WakeConditionVariable(condition_variable)
+
+
+// pthread function overrides
+#define pthread_self() ((pthread_t)GetCurrentThreadId())
+#define pthread_setaffinity_np(thread,size,cpuset) WinSetThreadAffinityMask(thread, cpuset)
+#define pthread_getaffinity_np(thread,size,cpuset) WinGetThreadAffinityMask(thread, cpuset)
+#define pthread_create(threadID, threadattr, threadfunc, args) WinCreateThreadOverride(threadID, threadattr, threadfunc, args)
+
+typedef int pid_t;
+pid_t fork(void);
+
+static inline int WinSetThreadAffinityMask(void* threadID, unsigned long *cpuset)
+{
+ DWORD dwPrevAffinityMask = SetThreadAffinityMask(threadID, *cpuset);
+ return 0;
+}
+
+static inline int WinGetThreadAffinityMask(void* threadID, unsigned long *cpuset)
+{
+ /* Workaround for the lack of a GetThreadAffinityMask() API in Windows */
+ DWORD dwPrevAffinityMask = SetThreadAffinityMask(threadID, 0x1); /* obtain previous mask by setting dummy mask */
+ SetThreadAffinityMask(threadID, dwPrevAffinityMask); /* set it back! */
+ *cpuset = dwPrevAffinityMask;
+ return 0;
+}
+
+static inline int WinCreateThreadOverride(void* threadID, const void* threadattr, void* threadfunc, void* args)
+{
+ HANDLE hThread;
+ hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, args, 0, (LPDWORD)threadID);
+ if (hThread)
+ {
+ SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
+ SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
+ }
+ return ((hThread != NULL) ? 0 : E_FAIL);
+}
+
+static inline int pthread_join(void* thread, void **value_ptr)
+{
+ return 0;
+}
+
+#endif /* _PTHREAD_H_ */
diff --git a/lib/librte_eal/windows/include_override/rand48.h b/lib/librte_eal/windows/include_override/rand48.h
new file mode 100644
index 000000000..4adabb794
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/rand48.h
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#ifndef _RAND48_H_
+#define _RAND48_H_
+
+#include <math.h>
+#include <stdlib.h>
+
+void _dorand48(unsigned short[3]);
+void srand48(long seed);
+long lrand48(void);
+
+#define RAND48_SEED_0 (0x330e)
+#define RAND48_SEED_1 (0xabcd)
+#define RAND48_SEED_2 (0x1234)
+#define RAND48_MULT_0 (0xe66d)
+#define RAND48_MULT_1 (0xdeec)
+#define RAND48_MULT_2 (0x0005)
+#define RAND48_ADD (0x000b)
+
+#endif /* _RAND48_H_ */
diff --git a/lib/librte_eal/windows/include_override/sched.h b/lib/librte_eal/windows/include_override/sched.h
new file mode 100644
index 000000000..1a2df795c
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sched.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#ifndef _SCHED_H_
+#define _SCHED_H_
+
+/* Re-defined for Windows */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sched_yield(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SCHED_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/_iovec.h b/lib/librte_eal/windows/include_override/sys/_iovec.h
new file mode 100644
index 000000000..bd7207332
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/_iovec.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)uio.h 8.5 (Berkeley) 2/22/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__IOVEC_H_
+#define _SYS__IOVEC_H_
+
+#include <sys/_types.h>
+
+#ifndef _SIZE_T_DECLARED
+typedef __size_t size_t;
+#define _SIZE_T_DECLARED
+#endif
+
+struct iovec {
+ void *iov_base; /* Base address. */
+ size_t iov_len; /* Length. */
+};
+
+#endif /* !_SYS__IOVEC_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/_sockaddr_storage.h b/lib/librte_eal/windows/include_override/sys/_sockaddr_storage.h
new file mode 100644
index 000000000..5c0048b56
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/_sockaddr_storage.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)socket.h 8.4 (Berkeley) 2/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__SOCKADDR_STORAGE_H_
+#define _SYS__SOCKADDR_STORAGE_H_
+
+/*
+ * RFC 2553: protocol-independent placeholder for socket addresses
+ */
+#define _SS_MAXSIZE 128U
+#define _SS_ALIGNSIZE (sizeof(__int64_t))
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) - \
+ sizeof(sa_family_t))
+#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) - \
+ sizeof(sa_family_t) - _SS_PAD1SIZE - _SS_ALIGNSIZE)
+
+struct sockaddr_storage {
+ unsigned char ss_len; /* address length */
+ sa_family_t ss_family; /* address family */
+ char __ss_pad1[_SS_PAD1SIZE];
+ __int64_t __ss_align; /* force desired struct alignment */
+ char __ss_pad2[_SS_PAD2SIZE];
+};
+
+#endif /* !_SYS__SOCKADDR_STORAGE_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/_termios.h b/lib/librte_eal/windows/include_override/sys/_termios.h
new file mode 100644
index 000000000..ae07158a9
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/_termios.h
@@ -0,0 +1,222 @@
+/*-
+ * Copyright (c) 1988, 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)termios.h 8.3 (Berkeley) 3/28/94
+ * $FreeBSD: release/9.1.0/sys/sys/_termios.h 199898 2009-11-28 23:50:48Z ed $
+ */
+
+#ifndef _SYS__TERMIOS_H_
+#define _SYS__TERMIOS_H_
+
+/*
+ * Special Control Characters
+ *
+ * Index into c_cc[] character array.
+ *
+ * Name Subscript Enabled by
+ */
+#define VEOF 0 /* ICANON */
+#define VEOL 1 /* ICANON */
+#ifndef _POSIX_SOURCE
+#define VEOL2 2 /* ICANON together with IEXTEN */
+#endif
+#define VERASE 3 /* ICANON */
+#ifndef _POSIX_SOURCE
+#define VWERASE 4 /* ICANON together with IEXTEN */
+#endif
+#define VKILL 5 /* ICANON */
+#ifndef _POSIX_SOURCE
+#define VREPRINT 6 /* ICANON together with IEXTEN */
+#define VERASE2 7 /* ICANON */
+#endif
+/* 7 ex-spare 1 */
+#define VINTR 8 /* ISIG */
+#define VQUIT 9 /* ISIG */
+#define VSUSP 10 /* ISIG */
+#ifndef _POSIX_SOURCE
+#define VDSUSP 11 /* ISIG together with IEXTEN */
+#endif
+#define VSTART 12 /* IXON, IXOFF */
+#define VSTOP 13 /* IXON, IXOFF */
+#ifndef _POSIX_SOURCE
+#define VLNEXT 14 /* IEXTEN */
+#define VDISCARD 15 /* IEXTEN */
+#endif
+#define VMIN 16 /* !ICANON */
+#define VTIME 17 /* !ICANON */
+#ifndef _POSIX_SOURCE
+#define VSTATUS 18 /* ICANON together with IEXTEN */
+/* 19 spare 2 */
+#endif
+#define NCCS 20
+
+#define _POSIX_VDISABLE 0xff
+
+/*
+ * Input flags - software input processing
+ */
+#define IGNBRK 0x00000001 /* ignore BREAK condition */
+#define BRKINT 0x00000002 /* map BREAK to SIGINTR */
+#define IGNPAR 0x00000004 /* ignore (discard) parity errors */
+#define PARMRK 0x00000008 /* mark parity and framing errors */
+#define INPCK 0x00000010 /* enable checking of parity errors */
+#define ISTRIP 0x00000020 /* strip 8th bit off chars */
+#define INLCR 0x00000040 /* map NL into CR */
+#define IGNCR 0x00000080 /* ignore CR */
+#define ICRNL 0x00000100 /* map CR to NL (ala CRMOD) */
+#define IXON 0x00000200 /* enable output flow control */
+#define IXOFF 0x00000400 /* enable input flow control */
+#ifndef _POSIX_SOURCE
+#define IXANY 0x00000800 /* any char will restart after stop */
+#define IMAXBEL 0x00002000 /* ring bell on input queue full */
+#endif /*_POSIX_SOURCE */
+
+/*
+ * Output flags - software output processing
+ */
+#define OPOST 0x00000001 /* enable following output processing */
+#ifndef _POSIX_SOURCE
+#define ONLCR 0x00000002 /* map NL to CR-NL (ala CRMOD) */
+#define TABDLY 0x00000004 /* tab delay mask */
+#define TAB0 0x00000000 /* no tab delay and expansion */
+#define TAB3 0x00000004 /* expand tabs to spaces */
+#define ONOEOT 0x00000008 /* discard EOT's (^D) on output) */
+#define OCRNL 0x00000010 /* map CR to NL on output */
+#define ONOCR 0x00000020 /* no CR output at column 0 */
+#define ONLRET 0x00000040 /* NL performs CR function */
+#endif /*_POSIX_SOURCE */
+
+/*
+ * Control flags - hardware control of terminal
+ */
+#ifndef _POSIX_SOURCE
+#define CIGNORE 0x00000001 /* ignore control flags */
+#endif
+#define CSIZE 0x00000300 /* character size mask */
+#define CS5 0x00000000 /* 5 bits (pseudo) */
+#define CS6 0x00000100 /* 6 bits */
+#define CS7 0x00000200 /* 7 bits */
+#define CS8 0x00000300 /* 8 bits */
+#define CSTOPB 0x00000400 /* send 2 stop bits */
+#define CREAD 0x00000800 /* enable receiver */
+#define PARENB 0x00001000 /* parity enable */
+#define PARODD 0x00002000 /* odd parity, else even */
+#define HUPCL 0x00004000 /* hang up on last close */
+#define CLOCAL 0x00008000 /* ignore modem status lines */
+#ifndef _POSIX_SOURCE
+#define CCTS_OFLOW 0x00010000 /* CTS flow control of output */
+#define CRTSCTS (CCTS_OFLOW | CRTS_IFLOW)
+#define CRTS_IFLOW 0x00020000 /* RTS flow control of input */
+#define CDTR_IFLOW 0x00040000 /* DTR flow control of input */
+#define CDSR_OFLOW 0x00080000 /* DSR flow control of output */
+#define CCAR_OFLOW 0x00100000 /* DCD flow control of output */
+#endif
+
+
+/*
+ * "Local" flags - dumping ground for other state
+ *
+ * Warning: some flags in this structure begin with
+ * the letter "I" and look like they belong in the
+ * input flag.
+ */
+
+#ifndef _POSIX_SOURCE
+#define ECHOKE 0x00000001 /* visual erase for line kill */
+#endif /*_POSIX_SOURCE */
+#define ECHOE 0x00000002 /* visually erase chars */
+#define ECHOK 0x00000004 /* echo NL after line kill */
+#define ECHO 0x00000008 /* enable echoing */
+#define ECHONL 0x00000010 /* echo NL even if ECHO is off */
+#ifndef _POSIX_SOURCE
+#define ECHOPRT 0x00000020 /* visual erase mode for hardcopy */
+#define ECHOCTL 0x00000040 /* echo control chars as ^(Char) */
+#endif /*_POSIX_SOURCE */
+#define ISIG 0x00000080 /* enable signals INTR, QUIT, [D]SUSP */
+#define ICANON 0x00000100 /* canonicalize input lines */
+#ifndef _POSIX_SOURCE
+#define ALTWERASE 0x00000200 /* use alternate WERASE algorithm */
+#endif /*_POSIX_SOURCE */
+#define IEXTEN 0x00000400 /* enable DISCARD and LNEXT */
+#define EXTPROC 0x00000800 /* external processing */
+#define TOSTOP 0x00400000 /* stop background jobs from output */
+#ifndef _POSIX_SOURCE
+#define FLUSHO 0x00800000 /* output being flushed (state) */
+#define NOKERNINFO 0x02000000 /* no kernel output from VSTATUS */
+#define PENDIN 0x20000000 /* XXX retype pending input (state) */
+#endif /*_POSIX_SOURCE */
+#define NOFLSH 0x80000000 /* don't flush after interrupt */
+
+/*
+ * Standard speeds
+ */
+#define B0 0
+#define B50 50
+#define B75 75
+#define B110 110
+#define B134 134
+#define B150 150
+#define B200 200
+#define B300 300
+#define B600 600
+#define B1200 1200
+#define B1800 1800
+#define B2400 2400
+#define B4800 4800
+#define B9600 9600
+#define B19200 19200
+#define B38400 38400
+#ifndef _POSIX_SOURCE
+#define B7200 7200
+#define B14400 14400
+#define B28800 28800
+#define B57600 57600
+#define B76800 76800
+#define B115200 115200
+#define B230400 230400
+#define B460800 460800
+#define B921600 921600
+#define EXTA 19200
+#define EXTB 38400
+#endif /* !_POSIX_SOURCE */
+
+typedef unsigned int tcflag_t;
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+
+struct termios {
+ tcflag_t c_iflag; /* input flags */
+ tcflag_t c_oflag; /* output flags */
+ tcflag_t c_cflag; /* control flags */
+ tcflag_t c_lflag; /* local flags */
+ cc_t c_cc[NCCS]; /* control chars */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+#endif /* !_SYS__TERMIOS_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/_types.h b/lib/librte_eal/windows/include_override/sys/_types.h
new file mode 100644
index 000000000..27ecaf4f0
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/_types.h
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__TYPES_H_
+#define _SYS__TYPES_H_
+
+#include <sys/cdefs.h>
+#include <machine/_types.h>
+
+/*
+ * Standard type definitions.
+ */
+typedef __uint32_t __blksize_t; /* file block size */
+typedef __int64_t __blkcnt_t; /* file block count */
+typedef __int32_t __clockid_t; /* clock_gettime()... */
+typedef __uint64_t __cap_rights_t; /* capability rights */
+typedef __uint32_t __fflags_t; /* file flags */
+typedef __uint64_t __fsblkcnt_t;
+typedef __uint64_t __fsfilcnt_t;
+typedef __uint32_t __gid_t;
+typedef __int64_t __id_t; /* can hold a gid_t, pid_t, or uid_t */
+typedef __uint32_t __ino_t; /* inode number */
+typedef long __key_t; /* IPC key (for Sys V IPC) */
+typedef __int32_t __lwpid_t; /* Thread ID (a.k.a. LWP) */
+typedef __uint16_t __mode_t; /* permissions */
+typedef int __accmode_t; /* access permissions */
+typedef int __nl_item;
+typedef __uint16_t __nlink_t; /* link count */
+typedef __int64_t __off_t; /* file offset */
+typedef __int32_t __pid_t; /* process [group] */
+typedef __int64_t __rlim_t; /* resource limit - intentionally */
+ /* signed, because of legacy code */
+ /* that uses -1 for RLIM_INFINITY */
+typedef __uint8_t __sa_family_t;
+typedef __uint32_t __socklen_t;
+typedef long __suseconds_t; /* microseconds (signed) */
+typedef struct __timer *__timer_t; /* timer_gettime()... */
+typedef struct __mq *__mqd_t; /* mq_open()... */
+typedef __uint32_t __uid_t;
+typedef unsigned int __useconds_t; /* microseconds (unsigned) */
+typedef int __cpuwhich_t; /* which parameter for cpuset. */
+typedef int __cpulevel_t; /* level parameter for cpuset. */
+typedef int __cpusetid_t; /* cpuset identifier. */
+
+/*
+ * Unusual type definitions.
+ */
+/*
+ * rune_t is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''. Two things are happening here. It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
+ * it looks like 10646 will be a 31 bit standard. This means that if your
+ * ints cannot hold 32 bits, you will be in trouble. The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use __ct_rune_t instead of int.
+ *
+ * NOTE: rune_t is not covered by ANSI nor other standards, and should not
+ * be instantiated outside of lib/libc/locale. Use wchar_t. wint_t and
+ * rune_t must be the same type. Also, wint_t should be able to hold all
+ * members of the largest character set plus one extra value (WEOF), and
+ * must be at least 16 bits.
+ */
+typedef int __ct_rune_t; /* arg type for ctype funcs */
+typedef __ct_rune_t __rune_t; /* rune_t (see above) */
+typedef __ct_rune_t __wint_t; /* wint_t (see above) */
+
+typedef __uint32_t __dev_t; /* device number */
+
+typedef __uint32_t __fixpt_t; /* fixed point number */
+
+/*
+ * mbstate_t is an opaque object to keep conversion state during multibyte
+ * stream conversions.
+ */
+typedef union {
+ char __mbstate8[128];
+ __int64_t _mbstateL; /* for alignment */
+} __mbstate_t;
+
+#endif /* !_SYS__TYPES_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/cdefs.h b/lib/librte_eal/windows/include_override/sys/cdefs.h
new file mode 100644
index 000000000..b4d2009c5
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/cdefs.h
@@ -0,0 +1,3 @@
+#ifndef _SYS_CDEFS_H_
+#define _SYS_CDEFS_H_
+#endif
diff --git a/lib/librte_eal/windows/include_override/sys/mman.h b/lib/librte_eal/windows/include_override/sys/mman.h
new file mode 100644
index 000000000..7a0ff4258
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/mman.h
@@ -0,0 +1,63 @@
+/*
+* sys/mman.h
+* mman-win32
+*/
+
+#ifndef _SYS_MMAN_H_
+#define _SYS_MMAN_H_
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+/* All the headers include this file. */
+#ifndef _MSC_VER
+#include <_mingw.h>
+#endif
+
+/* Determine offset type */
+#include <stdint.h>
+#if defined(_WIN64)
+typedef int64_t OffsetType;
+#else
+typedef uint32_t OffsetType;
+#endif
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PROT_NONE 0
+#define PROT_READ 1
+#define PROT_WRITE 2
+#define PROT_EXEC 4
+
+#define MAP_FILE 0
+#define MAP_SHARED 1
+#define MAP_PRIVATE 2
+#define MAP_TYPE 0xf
+#define MAP_FIXED 0x10
+#define MAP_ANONYMOUS 0x20
+#define MAP_ANON MAP_ANONYMOUS
+
+#define MAP_FAILED ((void *)-1)
+
+ /* Flags for msync. */
+#define MS_ASYNC 1
+#define MS_SYNC 2
+#define MS_INVALIDATE 4
+
+ void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off);
+ int munmap(void *addr, size_t len);
+ int _mprotect(void *addr, size_t len, int prot);
+ int msync(void *addr, size_t len, int flags);
+ int mlock(const void *addr, size_t len);
+ int munlock(const void *addr, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MMAN_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/netbsd/queue.h b/lib/librte_eal/windows/include_override/sys/netbsd/queue.h
new file mode 100644
index 000000000..99d01a55b
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/netbsd/queue.h
@@ -0,0 +1,846 @@
+/* $NetBSD: queue.h,v 1.68 2014/11/19 08:10:01 uebayasi Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues, and circular queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The
+ * elements are singly linked for minimum space and pointer manipulation
+ * overhead at the expense of O(n) removal for arbitrary elements. New
+ * elements can be added to the list after an existing element or at the
+ * head of the list. Elements being removed from the head of the list
+ * should use the explicit macro for this purpose for optimum
+ * efficiency. A singly-linked list may only be traversed in the forward
+ * direction. Singly-linked lists are ideal for applications with large
+ * datasets and few or no removals or for implementing a LIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * Include the definition of NULL only on NetBSD because sys/null.h
+ * is not available elsewhere. This conditional makes the header
+ * portable and it can simply be dropped verbatim into any system.
+ * The caveat is that on other systems some other header
+ * must provide NULL before the macros can be used.
+ */
+#ifdef __NetBSD__
+#include <sys/null.h>
+#endif
+
+#if defined(QUEUEDEBUG)
+# if defined(_KERNEL)
+# define QUEUEDEBUG_ABORT(...) panic(__VA_ARGS__)
+# else
+# include <err.h>
+# define QUEUEDEBUG_ABORT(...) err(1, __VA_ARGS__)
+# endif
+#endif
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List access methods.
+ */
+#define SLIST_FIRST(head) ((head)->slh_first)
+#define SLIST_END(head) NULL
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#define SLIST_FOREACH(var, head, field) \
+ for((var) = (head)->slh_first; \
+ (var) != SLIST_END(head); \
+ (var) = (var)->field.sle_next)
+
+#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = SLIST_FIRST((head)); \
+ (var) != SLIST_END(head) && \
+ ((tvar) = SLIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_INIT(head) do { \
+ (head)->slh_first = SLIST_END(head); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE_AFTER(slistelm, field) do { \
+ (slistelm)->field.sle_next = \
+ SLIST_NEXT(SLIST_NEXT((slistelm), field), field); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ if ((head)->slh_first == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = (head)->slh_first; \
+ while(curelm->field.sle_next != (elm)) \
+ curelm = curelm->field.sle_next; \
+ curelm->field.sle_next = \
+ curelm->field.sle_next->field.sle_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List access methods.
+ */
+#define LIST_FIRST(head) ((head)->lh_first)
+#define LIST_END(head) NULL
+#define LIST_EMPTY(head) ((head)->lh_first == LIST_END(head))
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#define LIST_FOREACH(var, head, field) \
+ for ((var) = ((head)->lh_first); \
+ (var) != LIST_END(head); \
+ (var) = ((var)->field.le_next))
+
+#define LIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = LIST_FIRST((head)); \
+ (var) != LIST_END(head) && \
+ ((tvar) = LIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define LIST_MOVE(head1, head2) do { \
+ LIST_INIT((head2)); \
+ if (!LIST_EMPTY((head1))) { \
+ (head2)->lh_first = (head1)->lh_first; \
+ LIST_INIT((head1)); \
+ } \
+} while (/*CONSTCOND*/0)
+
+/*
+ * List functions.
+ */
+#if defined(QUEUEDEBUG)
+#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) \
+ if ((head)->lh_first && \
+ (head)->lh_first->field.le_prev != &(head)->lh_first) \
+ QUEUEDEBUG_ABORT("LIST_INSERT_HEAD %p %s:%d", (head), \
+ __FILE__, __LINE__);
+#define QUEUEDEBUG_LIST_OP(elm, field) \
+ if ((elm)->field.le_next && \
+ (elm)->field.le_next->field.le_prev != \
+ &(elm)->field.le_next) \
+ QUEUEDEBUG_ABORT("LIST_* forw %p %s:%d", (elm), \
+ __FILE__, __LINE__); \
+ if (*(elm)->field.le_prev != (elm)) \
+ QUEUEDEBUG_ABORT("LIST_* back %p %s:%d", (elm), \
+ __FILE__, __LINE__);
+#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) \
+ (elm)->field.le_next = (void *)1L; \
+ (elm)->field.le_prev = (void *)1L;
+#else
+#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
+#define QUEUEDEBUG_LIST_OP(elm, field)
+#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
+#endif
+
+#define LIST_INIT(head) do { \
+ (head)->lh_first = LIST_END(head); \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ QUEUEDEBUG_LIST_OP((listelm), field) \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != \
+ LIST_END(head)) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ QUEUEDEBUG_LIST_OP((listelm), field) \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field) \
+ if (((elm)->field.le_next = (head)->lh_first) != LIST_END(head))\
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_REMOVE(elm, field) do { \
+ QUEUEDEBUG_LIST_OP((elm), field) \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+ QUEUEDEBUG_LIST_POSTREMOVE((elm), field) \
+} while (/*CONSTCOND*/0)
+
+#define LIST_REPLACE(elm, elm2, field) do { \
+ if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
+ (elm2)->field.le_next->field.le_prev = \
+ &(elm2)->field.le_next; \
+ (elm2)->field.le_prev = (elm)->field.le_prev; \
+ *(elm2)->field.le_prev = (elm2); \
+ QUEUEDEBUG_LIST_POSTREMOVE((elm), field) \
+} while (/*CONSTCOND*/0)
+
+/*
+ * Simple queue definitions.
+ */
+#define SIMPLEQ_HEAD(name, type) \
+struct name { \
+ struct type *sqh_first; /* first element */ \
+ struct type **sqh_last; /* addr of last next element */ \
+}
+
+#define SIMPLEQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).sqh_first }
+
+#define SIMPLEQ_ENTRY(type) \
+struct { \
+ struct type *sqe_next; /* next element */ \
+}
+
+/*
+ * Simple queue access methods.
+ */
+#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
+#define SIMPLEQ_END(head) NULL
+#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == SIMPLEQ_END(head))
+#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
+
+#define SIMPLEQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->sqh_first); \
+ (var) != SIMPLEQ_END(head); \
+ (var) = ((var)->field.sqe_next))
+
+#define SIMPLEQ_FOREACH_SAFE(var, head, field, next) \
+ for ((var) = ((head)->sqh_first); \
+ (var) != SIMPLEQ_END(head) && \
+ ((next = ((var)->field.sqe_next)), 1); \
+ (var) = (next))
+
+/*
+ * Simple queue functions.
+ */
+#define SIMPLEQ_INIT(head) do { \
+ (head)->sqh_first = NULL; \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (head)->sqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.sqe_next = NULL; \
+ *(head)->sqh_last = (elm); \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (listelm)->field.sqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
+ if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
+ == NULL) \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->sqh_first == (elm)) { \
+ SIMPLEQ_REMOVE_HEAD((head), field); \
+ } else { \
+ struct type *curelm = (head)->sqh_first; \
+ while (curelm->field.sqe_next != (elm)) \
+ curelm = curelm->field.sqe_next; \
+ if ((curelm->field.sqe_next = \
+ curelm->field.sqe_next->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(curelm)->field.sqe_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_CONCAT(head1, head2) do { \
+ if (!SIMPLEQ_EMPTY((head2))) { \
+ *(head1)->sqh_last = (head2)->sqh_first; \
+ (head1)->sqh_last = (head2)->sqh_last; \
+ SIMPLEQ_INIT((head2)); \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_LAST(head, type, field) \
+ (SIMPLEQ_EMPTY((head)) ? \
+ NULL : \
+ ((struct type *)(void *) \
+ ((char *)((head)->sqh_last) - offsetof(struct type, field))))
+
+/*
+ * Tail queue definitions.
+ */
+#define _TAILQ_HEAD(name, type, qual) \
+struct name { \
+ qual type *tqh_first; /* first element */ \
+ qual type *qual *tqh_last; /* addr of last next element */ \
+}
+#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { TAILQ_END(head), &(head).tqh_first }
+
+#define _TAILQ_ENTRY(type, qual) \
+struct { \
+ qual type *tqe_next; /* next element */ \
+ qual type *qual *tqe_prev; /* address of previous next element */\
+}
+#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
+
+/*
+ * Tail queue access methods.
+ */
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#define TAILQ_END(head) (NULL)
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+#define TAILQ_EMPTY(head) (TAILQ_FIRST(head) == TAILQ_END(head))
+
+
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->tqh_first); \
+ (var) != TAILQ_END(head); \
+ (var) = ((var)->field.tqe_next))
+
+#define TAILQ_FOREACH_SAFE(var, head, field, next) \
+ for ((var) = ((head)->tqh_first); \
+ (var) != TAILQ_END(head) && \
+ ((next) = TAILQ_NEXT(var, field), 1); (var) = (next))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));\
+ (var) != TAILQ_END(head); \
+ (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var) != TAILQ_END(head) && \
+ ((prev) = TAILQ_PREV((var), headname, field), 1); (var) = (prev))
+
+/*
+ * Tail queue functions.
+ */
+#if defined(QUEUEDEBUG)
+#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field) \
+ if ((head)->tqh_first && \
+ (head)->tqh_first->field.tqe_prev != &(head)->tqh_first) \
+ QUEUEDEBUG_ABORT("TAILQ_INSERT_HEAD %p %s:%d", (head), \
+ __FILE__, __LINE__);
+#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field) \
+ if (*(head)->tqh_last != NULL) \
+ QUEUEDEBUG_ABORT("TAILQ_INSERT_TAIL %p %s:%d", (head), \
+ __FILE__, __LINE__);
+#define QUEUEDEBUG_TAILQ_OP(elm, field) \
+ if ((elm)->field.tqe_next && \
+ (elm)->field.tqe_next->field.tqe_prev != \
+ &(elm)->field.tqe_next) \
+ QUEUEDEBUG_ABORT("TAILQ_* forw %p %s:%d", (elm), \
+ __FILE__, __LINE__); \
+ if (*(elm)->field.tqe_prev != (elm)) \
+ QUEUEDEBUG_ABORT("TAILQ_* back %p %s:%d", (elm), \
+ __FILE__, __LINE__);
+#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field) \
+ if ((elm)->field.tqe_next == NULL && \
+ (head)->tqh_last != &(elm)->field.tqe_next) \
+ QUEUEDEBUG_ABORT("TAILQ_PREREMOVE head %p elm %p %s:%d",\
+ (head), (elm), __FILE__, __LINE__);
+#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field) \
+ (elm)->field.tqe_next = (void *)1L; \
+ (elm)->field.tqe_prev = (void *)1L;
+#else
+#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
+#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
+#define QUEUEDEBUG_TAILQ_OP(elm, field)
+#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
+#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
+#endif
+
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = TAILQ_END(head); \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field) \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != TAILQ_END(head))\
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field) \
+ (elm)->field.tqe_next = TAILQ_END(head); \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ QUEUEDEBUG_TAILQ_OP((listelm), field) \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != \
+ TAILQ_END(head)) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ QUEUEDEBUG_TAILQ_OP((listelm), field) \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field) \
+ QUEUEDEBUG_TAILQ_OP((elm), field) \
+ if (((elm)->field.tqe_next) != TAILQ_END(head)) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+ QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field); \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_REPLACE(head, elm, elm2, field) do { \
+ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != \
+ TAILQ_END(head)) \
+ (elm2)->field.tqe_next->field.tqe_prev = \
+ &(elm2)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm2)->field.tqe_next; \
+ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
+ *(elm2)->field.tqe_prev = (elm2); \
+ QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field); \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_CONCAT(head1, head2, field) do { \
+ if (!TAILQ_EMPTY(head2)) { \
+ *(head1)->tqh_last = (head2)->tqh_first; \
+ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ TAILQ_INIT((head2)); \
+ } \
+} while (/*CONSTCOND*/0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define STAILQ_HEAD(name, type) \
+struct name { \
+ struct type *stqh_first; /* first element */ \
+ struct type **stqh_last; /* addr of last next element */ \
+}
+
+#define STAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).stqh_first }
+
+#define STAILQ_ENTRY(type) \
+struct { \
+ struct type *stqe_next; /* next element */ \
+}
+
+/*
+ * Singly-linked Tail queue access methods.
+ */
+#define STAILQ_FIRST(head) ((head)->stqh_first)
+#define STAILQ_END(head) NULL
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+#define STAILQ_EMPTY(head) (STAILQ_FIRST(head) == STAILQ_END(head))
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define STAILQ_INIT(head) do { \
+ (head)->stqh_first = NULL; \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (head)->stqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.stqe_next = NULL; \
+ *(head)->stqh_last = (elm); \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (listelm)->field.stqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->stqh_first == (elm)) { \
+ STAILQ_REMOVE_HEAD((head), field); \
+ } else { \
+ struct type *curelm = (head)->stqh_first; \
+ while (curelm->field.stqe_next != (elm)) \
+ curelm = curelm->field.stqe_next; \
+ if ((curelm->field.stqe_next = \
+ curelm->field.stqe_next->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(curelm)->field.stqe_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->stqh_first); \
+ (var); \
+ (var) = ((var)->field.stqe_next))
+
+#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = STAILQ_FIRST((head)); \
+ (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define STAILQ_CONCAT(head1, head2) do { \
+ if (!STAILQ_EMPTY((head2))) { \
+ *(head1)->stqh_last = (head2)->stqh_first; \
+ (head1)->stqh_last = (head2)->stqh_last; \
+ STAILQ_INIT((head2)); \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_LAST(head, type, field) \
+ (STAILQ_EMPTY((head)) ? \
+ NULL : \
+ ((struct type *)(void *) \
+ ((char *)((head)->stqh_last) - offsetof(struct type, field))))
+
+
+#ifndef _KERNEL
+/*
+ * Circular queue definitions. Do not use. We still keep the macros
+ * for compatibility but because of pointer aliasing issues their use
+ * is discouraged!
+ */
+
+/*
+ * __launder_type(): We use this ugly hack to work around the the compiler
+ * noticing that two types may not alias each other and elide tests in code.
+ * We hit this in the CIRCLEQ macros when comparing 'struct name *' and
+ * 'struct type *' (see CIRCLEQ_HEAD()). Modern compilers (such as GCC
+ * 4.8) declare these comparisons as always false, causing the code to
+ * not run as designed.
+ *
+ * This hack is only to be used for comparisons and thus can be fully const.
+ * Do not use for assignment.
+ *
+ * If we ever choose to change the ABI of the CIRCLEQ macros, we could fix
+ * this by changing the head/tail sentinal values, but see the note above
+ * this one.
+ */
+static __inline const void * __launder_type(const void *);
+static __inline const void *
+__launder_type(const void *__x)
+{
+ __asm __volatile("" : "+r" (__x));
+ return __x;
+}
+
+#if defined(QUEUEDEBUG)
+#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \
+ if ((head)->cqh_first != CIRCLEQ_ENDC(head) && \
+ (head)->cqh_first->field.cqe_prev != CIRCLEQ_ENDC(head)) \
+ QUEUEDEBUG_ABORT("CIRCLEQ head forw %p %s:%d", (head), \
+ __FILE__, __LINE__); \
+ if ((head)->cqh_last != CIRCLEQ_ENDC(head) && \
+ (head)->cqh_last->field.cqe_next != CIRCLEQ_ENDC(head)) \
+ QUEUEDEBUG_ABORT("CIRCLEQ head back %p %s:%d", (head), \
+ __FILE__, __LINE__);
+#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \
+ if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) { \
+ if ((head)->cqh_last != (elm)) \
+ QUEUEDEBUG_ABORT("CIRCLEQ elm last %p %s:%d", \
+ (elm), __FILE__, __LINE__); \
+ } else { \
+ if ((elm)->field.cqe_next->field.cqe_prev != (elm)) \
+ QUEUEDEBUG_ABORT("CIRCLEQ elm forw %p %s:%d", \
+ (elm), __FILE__, __LINE__); \
+ } \
+ if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) { \
+ if ((head)->cqh_first != (elm)) \
+ QUEUEDEBUG_ABORT("CIRCLEQ elm first %p %s:%d", \
+ (elm), __FILE__, __LINE__); \
+ } else { \
+ if ((elm)->field.cqe_prev->field.cqe_next != (elm)) \
+ QUEUEDEBUG_ABORT("CIRCLEQ elm prev %p %s:%d", \
+ (elm), __FILE__, __LINE__); \
+ }
+#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field) \
+ (elm)->field.cqe_next = (void *)1L; \
+ (elm)->field.cqe_prev = (void *)1L;
+#else
+#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)
+#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)
+#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)
+#endif
+
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_HEAD_INITIALIZER(head) \
+ { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = CIRCLEQ_END(head); \
+ (head)->cqh_last = CIRCLEQ_END(head); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == CIRCLEQ_ENDC(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == CIRCLEQ_ENDC(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = CIRCLEQ_END(head); \
+ if ((head)->cqh_last == CIRCLEQ_ENDC(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ (elm)->field.cqe_next = CIRCLEQ_END(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == CIRCLEQ_ENDC(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_REMOVE(head, elm, field) do { \
+ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \
+ QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field) \
+ if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+ QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field) \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->cqh_first); \
+ (var) != CIRCLEQ_ENDC(head); \
+ (var) = ((var)->field.cqe_next))
+
+#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
+ for ((var) = ((head)->cqh_last); \
+ (var) != CIRCLEQ_ENDC(head); \
+ (var) = ((var)->field.cqe_prev))
+
+/*
+ * Circular queue access methods.
+ */
+#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
+#define CIRCLEQ_LAST(head) ((head)->cqh_last)
+/* For comparisons */
+#define CIRCLEQ_ENDC(head) (__launder_type(head))
+/* For assignments */
+#define CIRCLEQ_END(head) ((void *)(head))
+#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
+#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
+#define CIRCLEQ_EMPTY(head) \
+ (CIRCLEQ_FIRST(head) == CIRCLEQ_ENDC(head))
+
+#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
+ (((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) \
+ ? ((head)->cqh_first) \
+ : (elm->field.cqe_next))
+#define CIRCLEQ_LOOP_PREV(head, elm, field) \
+ (((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) \
+ ? ((head)->cqh_last) \
+ : (elm->field.cqe_prev))
+#endif /* !_KERNEL */
+
+#endif /* !_SYS_QUEUE_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/queue.h b/lib/librte_eal/windows/include_override/sys/queue.h
new file mode 100644
index 000000000..485e86f9e
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/queue.h
@@ -0,0 +1,11 @@
+#pragma once
+
+/*
+ * $NetBSD: queue.h,v 1.68 2014/11/19 08:10:01 uebayasi Exp $
+ *
+ * Need to define _KERNEL to avoid the __launder_type()_ function
+ *
+ */
+#define _KERNEL
+#include "netbsd\queue.h"
+#undef _KERNEL
diff --git a/lib/librte_eal/windows/include_override/syslog.h b/lib/librte_eal/windows/include_override/syslog.h
new file mode 100644
index 000000000..890491b24
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/syslog.h
@@ -0,0 +1,217 @@
+/*
+* Copyright (c) 1982, 1986, 1988, 1993
+* The Regents of the University of California. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* 4. Neither the name of the University nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+*
+* @(#)syslog.h 8.1 (Berkeley) 6/2/93
+*/
+
+#ifndef _SYS_SYSLOG_H
+#define _SYS_SYSLOG_H 1
+
+#include <stdarg.h>
+
+/*
+* priorities/facilities are encoded into a single 32-bit quantity, where the
+* bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
+* (0-big number). Both the priorities and the facilities map roughly
+* one-to-one to strings in the syslogd(8) source code. This mapping is
+* included in this file.
+*
+* priorities (these are ordered)
+*/
+#define LOG_EMERG 0 /* system is unusable */
+#define LOG_ALERT 1 /* action must be taken immediately */
+#define LOG_CRIT 2 /* critical conditions */
+#define LOG_ERR 3 /* error conditions */
+#define LOG_WARNING 4 /* warning conditions */
+#define LOG_NOTICE 5 /* normal but significant condition */
+#define LOG_INFO 6 /* informational */
+#define LOG_DEBUG 7 /* debug-level messages */
+
+#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */
+/* extract priority */
+#define LOG_PRI(p) ((p) & LOG_PRIMASK)
+#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
+
+#ifdef SYSLOG_NAMES
+#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */
+/* mark "facility" */
+#define INTERNAL_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0)
+typedef struct _code {
+ char *c_name;
+ int c_val;
+} CODE;
+
+CODE prioritynames[] =
+{
+ { "alert", LOG_ALERT },
+ { "crit", LOG_CRIT },
+ { "debug", LOG_DEBUG },
+ { "emerg", LOG_EMERG },
+ { "err", LOG_ERR },
+ { "error", LOG_ERR }, /* DEPRECATED */
+ { "info", LOG_INFO },
+ { "none", INTERNAL_NOPRI }, /* INTERNAL */
+ { "notice", LOG_NOTICE },
+ { "panic", LOG_EMERG }, /* DEPRECATED */
+ { "warn", LOG_WARNING }, /* DEPRECATED */
+ { "warning", LOG_WARNING },
+ { NULL, -1 }
+};
+#endif
+
+/* facility codes */
+#define LOG_KERN (0<<3) /* kernel messages */
+#define LOG_USER (1<<3) /* random user-level messages */
+#define LOG_MAIL (2<<3) /* mail system */
+#define LOG_DAEMON (3<<3) /* system daemons */
+#define LOG_AUTH (4<<3) /* security/authorization messages */
+#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
+#define LOG_LPR (6<<3) /* line printer subsystem */
+#define LOG_NEWS (7<<3) /* network news subsystem */
+#define LOG_UUCP (8<<3) /* UUCP subsystem */
+#define LOG_CRON (9<<3) /* clock daemon */
+#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */
+#define LOG_FTP (11<<3) /* ftp daemon */
+
+/* other codes through 15 reserved for system use */
+#define LOG_LOCAL0 (16<<3) /* reserved for local use */
+#define LOG_LOCAL1 (17<<3) /* reserved for local use */
+#define LOG_LOCAL2 (18<<3) /* reserved for local use */
+#define LOG_LOCAL3 (19<<3) /* reserved for local use */
+#define LOG_LOCAL4 (20<<3) /* reserved for local use */
+#define LOG_LOCAL5 (21<<3) /* reserved for local use */
+#define LOG_LOCAL6 (22<<3) /* reserved for local use */
+#define LOG_LOCAL7 (23<<3) /* reserved for local use */
+
+#define LOG_NFACILITIES 24 /* current number of facilities */
+#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
+/* facility of pri */
+#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
+
+#ifdef SYSLOG_NAMES
+CODE facilitynames[] =
+{
+ { "auth", LOG_AUTH },
+ { "authpriv", LOG_AUTHPRIV },
+ { "cron", LOG_CRON },
+ { "daemon", LOG_DAEMON },
+ { "ftp", LOG_FTP },
+ { "kern", LOG_KERN },
+ { "lpr", LOG_LPR },
+ { "mail", LOG_MAIL },
+ { "mark", INTERNAL_MARK }, /* INTERNAL */
+ { "news", LOG_NEWS },
+ { "security", LOG_AUTH }, /* DEPRECATED */
+ { "syslog", LOG_SYSLOG },
+ { "user", LOG_USER },
+ { "uucp", LOG_UUCP },
+ { "local0", LOG_LOCAL0 },
+ { "local1", LOG_LOCAL1 },
+ { "local2", LOG_LOCAL2 },
+ { "local3", LOG_LOCAL3 },
+ { "local4", LOG_LOCAL4 },
+ { "local5", LOG_LOCAL5 },
+ { "local6", LOG_LOCAL6 },
+ { "local7", LOG_LOCAL7 },
+ { NULL, -1 }
+};
+#endif
+
+/*
+* arguments to setlogmask.
+*/
+#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
+#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
+
+/*
+* Option flags for openlog.
+*
+* LOG_ODELAY no longer does anything.
+* LOG_NDELAY is the inverse of what it used to be.
+*/
+#define LOG_PID 0x01 /* log the pid with each message */
+#define LOG_CONS 0x02 /* log on the console if errors in sending */
+#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */
+#define LOG_NDELAY 0x08 /* don't delay open */
+#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */
+#define LOG_PERROR 0x20 /* log to stderr as well */
+
+#define SYSLOG_PORT 514
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Close desriptor used to write to system logger. */
+ extern void closelog(void);
+
+ /* Open connection to system logger. */
+ extern void openlog(char *__ident, int __option, int __facility);
+
+ /* Set the log mask level. */
+ extern int setlogmask(int __mask);
+
+ /* Generate a log message using FMT string and option arguments. */
+ extern void syslog(int __pri, char *__fmt, ...);
+
+ /* Generate a log message using FMT and using arguments pointed to by AP. */
+ extern void vsyslog(int __pri, char *__fmt, va_list __ap);
+
+#ifdef _WIN32
+ /* Windows specific.
+
+ init_syslog() *must* be called before calling any of the above
+ functions. exit_syslog() will be scheduled using atexit().
+ However, it is not an error and encouraged to call
+ exit_syslog() before the application exits.
+
+ During operation, the application is free to call exit_syslog()
+ followed by init_syslog() to re-initialize the library. i.e. if
+ a different syslog host is to be used.
+
+ */
+
+ /* Initializes the syslog library and sets the syslog host. The
+ hostname parameter is of the form "<hostname>[:<port>]". The
+ <port> may be a numeric port or it may be a name of a service.
+ If the <port> is specified using a service name, it will be
+ looked up using getservbyname().
+
+ On failure, the hostname and port will be set to "localhost"
+ and SYSLOG_PORT respectively.
+ */
+ extern void init_syslog(const char * hostname);
+
+ extern void exit_syslog(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* syslog.h */
diff --git a/lib/librte_eal/windows/include_override/termios.h b/lib/librte_eal/windows/include_override/termios.h
new file mode 100644
index 000000000..ece9cc5c9
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/termios.h
@@ -0,0 +1 @@
+#include <sys/_termios.h>
diff --git a/lib/librte_eal/windows/include_override/unistd.h b/lib/librte_eal/windows/include_override/unistd.h
new file mode 100644
index 000000000..e78a696ab
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/unistd.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+/* This header file is required to build other rte* libraries and applications */
+
+//#include <io.h>
+#include <getopt.h> /* getopt at: https://gist.github.com/bikerm16/1b75e2dd20d839dcea58 */
+
+/* Types used by Unix-y systems */
+typedef __int8 int8_t;
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+#define srandom srand
+#define random rand
+#define _SC_PAGESIZE
+#define sysconf getpagesize
+/* function prototypes */
+int getpagesize(void);
+
+#endif /* unistd.h */
diff --git a/lib/librte_eal/windows/include_override/x86intrin.h b/lib/librte_eal/windows/include_override/x86intrin.h
new file mode 100644
index 000000000..336aa0baa
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/x86intrin.h
@@ -0,0 +1 @@
+#include <intrin.h>
\ No newline at end of file
diff --git a/lib/librte_eal/windows/rte_override/exec-env/rte_interrupts.h b/lib/librte_eal/windows/rte_override/exec-env/rte_interrupts.h
new file mode 100644
index 000000000..e731442aa
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/exec-env/rte_interrupts.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include "..\..\..\linuxapp\eal\include\exec-env\rte_interrupts.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_acl.h b/lib/librte_eal/windows/rte_override/rte_acl.h
new file mode 100644
index 000000000..f35b12c4f
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_acl.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "..\..\..\librte_acl\rte_acl.h"
+
+#undef RTE_ACL_MASKLEN_TO_BITMASK
+#define RTE_ACL_MASKLEN_TO_BITMASK(v, s) \
+((v) == 0 ? (v) : ((uint64_t)-1 << ((s) * CHAR_BIT - (v))))
diff --git a/lib/librte_eal/windows/rte_override/rte_atomic.h b/lib/librte_eal/windows/rte_override/rte_atomic.h
new file mode 100644
index 000000000..936710726
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_atomic.h
@@ -0,0 +1,744 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _RTE_ATOMIC_H_
+#define _RTE_ATOMIC_H_
+
+#include <emmintrin.h>
+
+/* Do not include any of the core rte_atomic.h includes. They cause compilation problems on Windows */
+/* Instead, duplicate some of the required definitions here - this is sub-optimal, but... */
+
+#define rte_mb() _mm_mfence()
+#define rte_wmb() _mm_sfence()
+#define rte_rmb() _mm_lfence()
+
+#define rte_smp_mb() rte_mb()
+#define rte_smp_rmb() _ReadBarrier()
+#define rte_smp_wmb() _WriteBarrier()
+
+
+#define rte_io_mb() rte_mb()
+#define rte_io_wmb() _ReadBarrier()
+#define rte_io_rmb() _WriteBarrier()
+
+/**
+* Compiler barrier.
+*
+* Guarantees that operation reordering does not occur at compile time
+* for operations directly before and after the barrier.
+*/
+#define rte_compiler_barrier() do { \
+ asm volatile ("" : : : "memory"); \
+} while(0)
+
+
+/* Inline Windows implementation of atomic operations */
+
+/*------------------------- 16 bit atomic operations -------------------------*/
+
+/**
+* Atomic compare and set.
+*
+* (atomic) equivalent to:
+* if (*dst == exp)
+* *dst = src (all 16-bit words)
+*
+* @param dst
+* The destination location into which the value will be written.
+* @param exp
+* The expected value.
+* @param src
+* The new value.
+* @return
+* Non-zero on success; 0 on failure.
+*/
+static inline int
+rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src)
+{
+ return (_InterlockedCompareExchange16((SHORT *)dst, src, exp) != src);
+}
+
+/**
+* The atomic counter structure.
+*/
+typedef struct {
+ volatile int16_t cnt; /**< An internal counter value. */
+} rte_atomic16_t;
+
+/**
+* Static initializer for an atomic counter.
+*/
+#define RTE_ATOMIC16_INIT(val) { (val) }
+
+/**
+* Initialize an atomic counter.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic16_init(rte_atomic16_t *v)
+{
+ v->cnt = 0;
+}
+
+/**
+* Atomically read a 16-bit value from a counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* The value of the counter.
+*/
+static inline int16_t
+rte_atomic16_read(const rte_atomic16_t *v)
+{
+ return v->cnt;
+}
+
+/**
+* Atomically set a counter to a 16-bit value.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param new_value
+* The new value for the counter.
+*/
+static inline void
+rte_atomic16_set(rte_atomic16_t *v, int16_t new_value)
+{
+ _InterlockedExchange16(&v->cnt, new_value);
+}
+
+/**
+* Atomically add a 16-bit value to an atomic counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param inc
+* The value to be added to the counter.
+*/
+static inline void
+rte_atomic16_add(rte_atomic16_t *v, int16_t inc)
+{
+ _InterlockedExchangeAdd16(&v->cnt, inc);
+}
+
+/**
+* Atomically subtract a 16-bit value from an atomic counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param dec
+* The value to be subtracted from the counter.
+*/
+static inline void
+rte_atomic16_sub(rte_atomic16_t *v, int16_t dec)
+{
+ _InterlockedExchangeAdd16(&v->cnt, (-dec));
+}
+
+/**
+* Atomically increment a counter by one.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic16_inc(rte_atomic16_t *v)
+{
+ rte_atomic16_add(v, 1);
+}
+
+/**
+* Atomically decrement a counter by one.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic16_dec(rte_atomic16_t *v)
+{
+ rte_atomic16_sub(v, 1);
+}
+
+/**
+* Atomically add a 16-bit value to a counter and return the result.
+*
+* Atomically adds the 16-bits value (inc) to the atomic counter (v) and
+* returns the value of v after addition.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param inc
+* The value to be added to the counter.
+* @return
+* The value of v after the addition.
+*/
+static inline int16_t
+rte_atomic16_add_return(rte_atomic16_t *v, int16_t inc)
+{
+ _InterlockedExchangeAdd16(&v->cnt, inc);
+ return v->cnt;
+}
+
+/**
+* Atomically subtract a 16-bit value from a counter and return
+* the result.
+*
+* Atomically subtracts the 16-bit value (inc) from the atomic counter
+* (v) and returns the value of v after the subtraction.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param dec
+* The value to be subtracted from the counter.
+* @return
+* The value of v after the subtraction.
+*/
+static inline int16_t
+rte_atomic16_sub_return(rte_atomic16_t *v, int16_t dec)
+{
+ _InterlockedExchangeAdd16(&v->cnt, (-dec));
+ return v->cnt;
+}
+
+/**
+* Atomically increment a 16-bit counter by one and test.
+*
+* Atomically increments the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* True if the result after the increment operation is 0; false otherwise.
+*/
+static inline int rte_atomic16_inc_and_test(rte_atomic16_t *v)
+{
+ return ((rte_atomic16_add_return(v, 1) == 0));
+}
+
+/**
+* Atomically decrement a 16-bit counter by one and test.
+*
+* Atomically decrements the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* True if the result after the decrement operation is 0; false otherwise.
+*/
+static inline int rte_atomic16_dec_and_test(rte_atomic16_t *v)
+{
+ return ((rte_atomic16_sub_return(v, 1) == 0));
+}
+
+/**
+* Atomically test and set a 16-bit atomic counter.
+*
+* If the counter value is already set, return 0 (failed). Otherwise, set
+* the counter value to 1 and return 1 (success).
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* 0 if failed; else 1, success.
+*/
+static inline int rte_atomic16_test_and_set(rte_atomic16_t *v)
+{
+ return rte_atomic16_cmpset((volatile uint16_t *)&v->cnt, 0, 1);
+}
+
+/**
+* Atomically set a 16-bit counter to 0.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void rte_atomic16_clear(rte_atomic16_t *v)
+{
+ rte_atomic16_set(v, 0);
+}
+
+/*------------------------- 32 bit atomic operations -------------------------*/
+
+/**
+* Atomic compare and set.
+*
+* (atomic) equivalent to:
+* if (*dst == exp)
+* *dst = src (all 32-bit words)
+*
+* @param dst
+* The destination location into which the value will be written.
+* @param exp
+* The expected value.
+* @param src
+* The new value.
+* @return
+* Non-zero on success; 0 on failure.
+*/
+static inline int
+rte_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src)
+{
+ return (_InterlockedCompareExchange(dst, src, exp) != src);
+}
+
+/**
+* The atomic counter structure.
+*/
+typedef struct {
+ volatile int32_t cnt; /**< An internal counter value. */
+} rte_atomic32_t;
+
+/**
+* Static initializer for an atomic counter.
+*/
+#define RTE_ATOMIC32_INIT(val) { (val) }
+
+/**
+* Initialize an atomic counter.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic32_init(rte_atomic32_t *v)
+{
+ v->cnt = 0;
+}
+
+/**
+* Atomically read a 32-bit value from a counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* The value of the counter.
+*/
+static inline int32_t
+rte_atomic32_read(const rte_atomic32_t *v)
+{
+ return v->cnt;
+}
+
+/**
+* Atomically set a counter to a 32-bit value.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param new_value
+* The new value for the counter.
+*/
+static inline void
+rte_atomic32_set(rte_atomic32_t *v, int32_t new_value)
+{
+ _InterlockedExchange((LONG volatile *)&v->cnt, new_value);
+}
+
+/**
+* Atomically add a 32-bit value to an atomic counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param inc
+* The value to be added to the counter.
+*/
+static inline void
+rte_atomic32_add(rte_atomic32_t *v, int32_t inc)
+{
+ _InterlockedExchangeAdd((LONG volatile *)&v->cnt, inc);
+}
+
+/**
+* Atomically subtract a 32-bit value from an atomic counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param dec
+* The value to be subtracted from the counter.
+*/
+static inline void
+rte_atomic32_sub(rte_atomic32_t *v, int32_t dec)
+{
+ _InterlockedExchangeAdd((LONG volatile *)&v->cnt, (-dec));
+}
+
+/**
+* Atomically increment a counter by one.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic32_inc(rte_atomic32_t *v)
+{
+ rte_atomic32_add(v, 1);
+}
+
+/**
+* Atomically decrement a counter by one.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic32_dec(rte_atomic32_t *v)
+{
+ rte_atomic32_sub(v, 1);
+}
+
+/**
+* Atomically add a 32-bit value to a counter and return the result.
+*
+* Atomically adds the 32-bits value (inc) to the atomic counter (v) and
+* returns the value of v after addition.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param inc
+* The value to be added to the counter.
+* @return
+* The value of v after the addition.
+*/
+static inline int32_t
+rte_atomic32_add_return(rte_atomic32_t *v, int32_t inc)
+{
+ _InterlockedExchangeAdd((LONG volatile *)&v->cnt, inc);
+ return v->cnt;
+}
+
+/**
+* Atomically subtract a 32-bit value from a counter and return
+* the result.
+*
+* Atomically subtracts the 32-bit value (inc) from the atomic counter
+* (v) and returns the value of v after the subtraction.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param dec
+* The value to be subtracted from the counter.
+* @return
+* The value of v after the subtraction.
+*/
+static inline int32_t
+rte_atomic32_sub_return(rte_atomic32_t *v, int32_t dec)
+{
+ _InterlockedExchangeAdd((LONG volatile *)&v->cnt, (-dec));
+ return v->cnt;
+}
+
+/**
+* Atomically increment a 32-bit counter by one and test.
+*
+* Atomically increments the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* True if the result after the increment operation is 0; false otherwise.
+*/
+static inline int rte_atomic32_inc_and_test(rte_atomic32_t *v)
+{
+ return ((rte_atomic32_add_return(v, 1) == 0));
+}
+
+/**
+* Atomically decrement a 32-bit counter by one and test.
+*
+* Atomically decrements the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* True if the result after the decrement operation is 0; false otherwise.
+*/
+static inline int rte_atomic32_dec_and_test(rte_atomic32_t *v)
+{
+ return ((rte_atomic32_sub_return(v, 1) == 0));
+}
+
+/**
+* Atomically test and set a 32-bit atomic counter.
+*
+* If the counter value is already set, return 0 (failed). Otherwise, set
+* the counter value to 1 and return 1 (success).
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* 0 if failed; else 1, success.
+*/
+static inline int rte_atomic32_test_and_set(rte_atomic32_t *v)
+{
+ return rte_atomic32_cmpset((volatile uint32_t *)&v->cnt, 0, 1);
+}
+
+/**
+* Atomically set a 32-bit counter to 0.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void rte_atomic32_clear(rte_atomic32_t *v)
+{
+ rte_atomic32_set(v, 0);
+}
+
+/*------------------------- 64 bit atomic operations -------------------------*/
+
+/**
+* An atomic compare and set function used by the mutex functions.
+* (atomic) equivalent to:
+* if (*dst == exp)
+* *dst = src (all 64-bit words)
+*
+* @param dst
+* The destination into which the value will be written.
+* @param exp
+* The expected value.
+* @param src
+* The new value.
+* @return
+* Non-zero on success; 0 on failure.
+*/
+static inline int
+rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src)
+{
+ return (_InterlockedCompareExchange64((volatile LONG64 *)dst, src, exp) != src);
+}
+
+/**
+* Atomic exchange.
+*
+* (atomic)equivalent to :
+*ret = *dst
+* *dst = val;
+*return ret;
+*
+* @param dst
+* The destination location into which the value will be written.
+* @param val
+* The new value.
+* @return
+* The original value at that location
+**/
+static inline uint64_t
+rte_atomic64_exchange(volatile uint64_t *dst, uint64_t val){
+ return _InterlockedExchange64((volatile LONG64 *)dst, val);
+}
+
+/**
+* The atomic counter structure.
+*/
+typedef struct {
+ volatile int64_t cnt; /**< Internal counter value. */
+} rte_atomic64_t;
+
+/**
+* Static initializer for an atomic counter.
+*/
+#define RTE_ATOMIC64_INIT(val) { (val) }
+
+/**
+* Initialize the atomic counter.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic64_init(rte_atomic64_t *v)
+{
+ v->cnt = 0;
+}
+
+/**
+* Atomically read a 64-bit counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* The value of the counter.
+*/
+static inline int64_t
+rte_atomic64_read(rte_atomic64_t *v)
+{
+ return v->cnt;
+}
+
+/**
+* Atomically set a 64-bit counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param new_value
+* The new value of the counter.
+*/
+static inline void
+rte_atomic64_set(rte_atomic64_t *v, int64_t new_value)
+{
+ _InterlockedExchange64(&v->cnt, new_value);
+}
+
+/**
+* Atomically add a 64-bit value to a counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param inc
+* The value to be added to the counter.
+*/
+static inline void
+rte_atomic64_add(rte_atomic64_t *v, int64_t inc)
+{
+ _InterlockedExchangeAdd64(&v->cnt, inc);
+}
+
+/**
+* Atomically subtract a 64-bit value from a counter.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param dec
+* The value to be subtracted from the counter.
+*/
+static inline void
+rte_atomic64_sub(rte_atomic64_t *v, int64_t dec)
+{
+ _InterlockedExchangeAdd64(&v->cnt, (-dec));
+}
+
+/**
+* Atomically increment a 64-bit counter by one and test.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic64_inc(rte_atomic64_t *v)
+{
+ _InterlockedIncrement64(&v->cnt);
+}
+
+/**
+* Atomically decrement a 64-bit counter by one and test.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic64_dec(rte_atomic64_t *v)
+{
+ _InterlockedDecrement64(&v->cnt);
+}
+
+/**
+* Add a 64-bit value to an atomic counter and return the result.
+*
+* Atomically adds the 64-bit value (inc) to the atomic counter (v) and
+* returns the value of v after the addition.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param inc
+* The value to be added to the counter.
+* @return
+* The value of v after the addition.
+*/
+static inline int64_t
+rte_atomic64_add_return(rte_atomic64_t *v, int64_t inc)
+{
+ _InterlockedExchangeAdd64(&v->cnt, inc);
+ return v->cnt;
+}
+
+/**
+* Subtract a 64-bit value from an atomic counter and return the result.
+*
+* Atomically subtracts the 64-bit value (dec) from the atomic counter (v)
+* and returns the value of v after the subtraction.
+*
+* @param v
+* A pointer to the atomic counter.
+* @param dec
+* The value to be subtracted from the counter.
+* @return
+* The value of v after the subtraction.
+*/
+static inline int64_t
+rte_atomic64_sub_return(rte_atomic64_t *v, int64_t dec)
+{
+ _InterlockedExchangeAdd64(&v->cnt, (-dec));
+ return v->cnt;
+}
+
+/**
+* Atomically increment a 64-bit counter by one and test.
+*
+* Atomically increments the atomic counter (v) by one and returns
+* true if the result is 0, or false in all other cases.
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* True if the result after the addition is 0; false otherwise.
+*/
+static inline int rte_atomic64_inc_and_test(rte_atomic64_t *v)
+{
+ return ((rte_atomic64_add_return(v, 1) == 0));
+}
+
+/**
+* Atomically decrement a 64-bit counter by one and test.
+*
+* Atomically decrements the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* True if the result after subtraction is 0; false otherwise.
+*/
+static inline int rte_atomic64_dec_and_test(rte_atomic64_t *v)
+{
+ return ((rte_atomic64_sub_return(v, 1) == 0));
+}
+
+/**
+* Atomically test and set a 64-bit atomic counter.
+*
+* If the counter value is already set, return 0 (failed). Otherwise, set
+* the counter value to 1 and return 1 (success).
+*
+* @param v
+* A pointer to the atomic counter.
+* @return
+* 0 if failed; else 1, success.
+*/
+static inline int rte_atomic64_test_and_set(rte_atomic64_t *v)
+{
+ return rte_atomic64_cmpset((volatile uint64_t *)&v->cnt, 0, 1);
+}
+
+/**
+* Atomically set a 64-bit counter to 0.
+*
+* @param v
+* A pointer to the atomic counter.
+*/
+static inline void rte_atomic64_clear(rte_atomic64_t *v)
+{
+ rte_atomic64_set(v, 0);
+}
+
+#endif /* _RTE_ATOMIC_H_ */
+
+/* */
+/* */
diff --git a/lib/librte_eal/windows/rte_override/rte_bus_pci.h b/lib/librte_eal/windows/rte_override/rte_bus_pci.h
new file mode 100644
index 000000000..d7950e218
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_bus_pci.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+/* include the original file, so that we can re-define certain macros */
+#include "..\..\..\..\drivers\bus\pci\rte_bus_pci.h"
+
+/* Need to re-define RTE_PMD_REGISTER_PCI for Windows */
+#ifdef RTE_PMD_REGISTER_PCI(nm, pci_drv)
+#undef RTE_PMD_REGISTER_PCI(nm, pci_drv)
+#endif
+
+/*
+* Definition for registering PMDs
+* (This is a workaround for Windows in lieu of a constructor-like function)
+*/
+#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
+void pciinitfn_##nm(void); \
+void pciinitfn_##nm(void) \
+{\
+ (pci_drv).driver.name = RTE_STR(nm);\
+ rte_pci_register(&pci_drv); \
+}
diff --git a/lib/librte_eal/windows/rte_override/rte_byteorder.h b/lib/librte_eal/windows/rte_override/rte_byteorder.h
new file mode 100644
index 000000000..b87a42756
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_byteorder.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+#pragma once
+
+#ifndef RTE_BYTE_ORDER
+#define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN
+#endif
+
+#include "..\..\common\include\arch\x86\rte_byteorder.h"
\ No newline at end of file
diff --git a/lib/librte_eal/windows/rte_override/rte_common.h b/lib/librte_eal/windows/rte_override/rte_common.h
new file mode 100644
index 000000000..564fe6f82
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_common.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+/* If rte_common.h has already been included, then we will have issues */
+#ifdef _RTE_COMMON_H_
+#error
+#endif
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (disable : 42)
+#endif
+
+#include <rte_wincompat.h>
+
+#include "../common/include/rte_common.h"
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (enable : 42)
+#endif
+
+#ifdef container_of
+/* undefine the existing definition, so that we can use the Windows-compliant version */
+#undef container_of
+#endif
+
+#define container_of(ptr, type, member) CONTAINING_RECORD(ptr, type, member)
+
+
+/* Override RTE_MIN() / RTE_MAX() as defined, since the one in rte_common uses typeof....TODO: Diagnose this later */
+#undef RTE_MIN
+#define RTE_MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+#undef RTE_MAX
+#define RTE_MAX(a, b) max(a, b)
+
+/* Redefine these macros with appropriate typecasting */
+#undef RTE_ALIGN_FLOOR
+#define RTE_ALIGN_FLOOR(val, align) ((uintptr_t)(val) & (~((uintptr_t)((align) - 1))))
+
+#undef RTE_ALIGN_CEIL
+#define RTE_ALIGN_CEIL(val, align) RTE_ALIGN_FLOOR((val + ((uintptr_t)(align) - 1)), align)
+
+#undef RTE_ALIGN
+#define RTE_ALIGN(val, align) RTE_ALIGN_CEIL(val, align)
+
+#undef RTE_PTR_ALIGN_FLOOR
+#define RTE_PTR_ALIGN_FLOOR(ptr, align) (void *)(RTE_ALIGN_FLOOR((uintptr_t)ptr, align))
+
+#undef RTE_PTR_ALIGN_CEIL
+#define RTE_PTR_ALIGN_CEIL(ptr, align) (void *)RTE_PTR_ALIGN_FLOOR((uintptr_t)RTE_PTR_ADD(ptr, (align) - 1), align)
+
+#undef RTE_LEN2MASK
+#define RTE_LEN2MASK(ln, tp) ((uint64_t)-1 >> (sizeof(uint64_t) * CHAR_BIT - (ln)))
diff --git a/lib/librte_eal/windows/rte_override/rte_common.h.sav b/lib/librte_eal/windows/rte_override/rte_common.h.sav
new file mode 100644
index 000000000..6f067aa3f
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_common.h.sav
@@ -0,0 +1,372 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _RTE_COMMON_H_
+#define _RTE_COMMON_H_
+
+/**
+ * @file
+ *
+ * Generic, commonly-used macro and inline function definitions
+ * for DPDK.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+
+#ifndef typeof
+#define typeof __typeof__
+#endif
+
+#ifndef asm
+#define asm __asm__
+#endif
+
+#ifdef RTE_ARCH_STRICT_ALIGN
+typedef uint64_t unaligned_uint64_t __attribute__ ((aligned(1)));
+typedef uint32_t unaligned_uint32_t __attribute__ ((aligned(1)));
+typedef uint16_t unaligned_uint16_t __attribute__ ((aligned(1)));
+#else
+typedef uint64_t unaligned_uint64_t;
+typedef uint32_t unaligned_uint32_t;
+typedef uint16_t unaligned_uint16_t;
+#endif
+
+/**
+ * Force alignment
+ */
+#define __rte_aligned(a) __attribute__((__aligned__(a)))
+
+/**
+ * Force a structure to be packed
+ */
+#define __rte_packed __attribute__((__packed__))
+
+/******* Macro to mark functions and fields scheduled for removal *****/
+#define __rte_deprecated __attribute__((__deprecated__))
+
+/*********** Macros to eliminate unused variable warnings ********/
+
+/**
+ * short definition to mark a function parameter unused
+ */
+#define __rte_unused __attribute__((__unused__))
+
+/**
+ * definition to mark a variable or function parameter as used so
+ * as to avoid a compiler warning
+ */
+#define RTE_SET_USED(x) (void)(x)
+
+/*********** Macros for pointer arithmetic ********/
+
+/**
+ * add a byte-value offset from a pointer
+ */
+#define RTE_PTR_ADD(ptr, x) ((void*)((uintptr_t)(ptr) + (x)))
+
+/**
+ * subtract a byte-value offset from a pointer
+ */
+#define RTE_PTR_SUB(ptr, x) ((void*)((uintptr_t)ptr - (x)))
+
+/**
+ * get the difference between two pointer values, i.e. how far apart
+ * in bytes are the locations they point two. It is assumed that
+ * ptr1 is greater than ptr2.
+ */
+#define RTE_PTR_DIFF(ptr1, ptr2) ((uintptr_t)(ptr1) - (uintptr_t)(ptr2))
+
+/*********** Macros/static functions for doing alignment ********/
+
+
+/**
+ * Macro to align a pointer to a given power-of-two. The resultant
+ * pointer will be a pointer of the same type as the first parameter, and
+ * point to an address no higher than the first parameter. Second parameter
+ * must be a power-of-two value.
+ */
+#define RTE_PTR_ALIGN_FLOOR(ptr, align) \
+ ((typeof(ptr))RTE_ALIGN_FLOOR((uintptr_t)ptr, align))
+
+/**
+ * Macro to align a value to a given power-of-two. The resultant value
+ * will be of the same type as the first parameter, and will be no
+ * bigger than the first parameter. Second parameter must be a
+ * power-of-two value.
+ */
+#define RTE_ALIGN_FLOOR(val, align) \
+ (typeof(val))((val) & (~((typeof(val))((align) - 1))))
+
+/**
+ * Macro to align a pointer to a given power-of-two. The resultant
+ * pointer will be a pointer of the same type as the first parameter, and
+ * point to an address no lower than the first parameter. Second parameter
+ * must be a power-of-two value.
+ */
+#define RTE_PTR_ALIGN_CEIL(ptr, align) \
+ RTE_PTR_ALIGN_FLOOR((typeof(ptr))RTE_PTR_ADD(ptr, (align) - 1), align)
+
+/**
+ * Macro to align a value to a given power-of-two. The resultant value
+ * will be of the same type as the first parameter, and will be no lower
+ * than the first parameter. Second parameter must be a power-of-two
+ * value.
+ */
+#define RTE_ALIGN_CEIL(val, align) \
+ RTE_ALIGN_FLOOR(((val) + ((typeof(val)) (align) - 1)), align)
+
+/**
+ * Macro to align a pointer to a given power-of-two. The resultant
+ * pointer will be a pointer of the same type as the first parameter, and
+ * point to an address no lower than the first parameter. Second parameter
+ * must be a power-of-two value.
+ * This function is the same as RTE_PTR_ALIGN_CEIL
+ */
+#define RTE_PTR_ALIGN(ptr, align) RTE_PTR_ALIGN_CEIL(ptr, align)
+
+/**
+ * Macro to align a value to a given power-of-two. The resultant
+ * value will be of the same type as the first parameter, and
+ * will be no lower than the first parameter. Second parameter
+ * must be a power-of-two value.
+ * This function is the same as RTE_ALIGN_CEIL
+ */
+#define RTE_ALIGN(val, align) RTE_ALIGN_CEIL(val, align)
+
+/**
+ * Checks if a pointer is aligned to a given power-of-two value
+ *
+ * @param ptr
+ * The pointer whose alignment is to be checked
+ * @param align
+ * The power-of-two value to which the ptr should be aligned
+ *
+ * @return
+ * True(1) where the pointer is correctly aligned, false(0) otherwise
+ */
+static inline int
+rte_is_aligned(void *ptr, unsigned align)
+{
+ return (((uintptr_t)ptr % align) == 0);
+}
+
+/*********** Macros for compile type checks ********/
+
+/**
+ * Triggers an error at compilation time if the condition is true.
+ */
+#ifndef __OPTIMIZE__
+#define RTE_BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+#else
+extern int RTE_BUILD_BUG_ON_detected_error;
+#define RTE_BUILD_BUG_ON(condition) do { \
+ ((void)sizeof(char[1 - 2*!!(condition)])); \
+ if (condition) \
+ RTE_BUILD_BUG_ON_detected_error = 1; \
+} while(0)
+#endif
+
+/*********** Macros to work with powers of 2 ********/
+
+/**
+ * Returns true if n is a power of 2
+ * @param n
+ * Number to check
+ * @return 1 if true, 0 otherwise
+ */
+static inline int
+rte_is_power_of_2(uint32_t n)
+{
+ return n && !(n & (n - 1));
+}
+
+/**
+ * Aligns input parameter to the next power of 2
+ *
+ * @param x
+ * The integer value to algin
+ *
+ * @return
+ * Input parameter aligned to the next power of 2
+ */
+static inline uint32_t
+rte_align32pow2(uint32_t x)
+{
+ x--;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+
+ return x + 1;
+}
+
+/**
+ * Aligns 64b input parameter to the next power of 2
+ *
+ * @param v
+ * The 64b value to align
+ *
+ * @return
+ * Input parameter aligned to the next power of 2
+ */
+static inline uint64_t
+rte_align64pow2(uint64_t v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v |= v >> 32;
+
+ return v + 1;
+}
+
+/*********** Macros for calculating min and max **********/
+
+/**
+ * Macro to return the minimum of two numbers
+ */
+#define RTE_MIN(a, b) ({ \
+ typeof (a) _a = (a); \
+ typeof (b) _b = (b); \
+ _a < _b ? _a : _b; \
+ })
+
+/**
+ * Macro to return the maximum of two numbers
+ */
+#define RTE_MAX(a, b) ({ \
+ typeof (a) _a = (a); \
+ typeof (b) _b = (b); \
+ _a > _b ? _a : _b; \
+ })
+
+/*********** Other general functions / macros ********/
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+/**
+ * PAUSE instruction for tight loops (avoid busy waiting)
+ */
+static inline void
+rte_pause (void)
+{
+ _mm_pause();
+}
+#else
+static inline void
+rte_pause(void) {}
+#endif
+
+/**
+ * Searches the input parameter for the least significant set bit
+ * (starting from zero).
+ * If a least significant 1 bit is found, its bit index is returned.
+ * If the content of the input parameter is zero, then the content of the return
+ * value is undefined.
+ * @param v
+ * input parameter, should not be zero.
+ * @return
+ * least significant set bit in the input parameter.
+ */
+static inline uint32_t
+rte_bsf32(uint32_t v)
+{
+ return __builtin_ctz(v);
+}
+
+#ifndef offsetof
+/** Return the offset of a field in a structure. */
+#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+#endif
+
+#define _RTE_STR(x) #x
+/** Take a macro value and get a string version of it */
+#define RTE_STR(x) _RTE_STR(x)
+
+/** Mask value of type "tp" for the first "ln" bit set. */
+#define RTE_LEN2MASK(ln, tp) \
+ ((tp)((uint64_t)-1 >> (sizeof(uint64_t) * CHAR_BIT - (ln))))
+
+/** Number of elements in the array. */
+#define RTE_DIM(a) (sizeof (a) / sizeof ((a)[0]))
+
+/**
+ * Converts a numeric string to the equivalent uint64_t value.
+ * As well as straight number conversion, also recognises the suffixes
+ * k, m and g for kilobytes, megabytes and gigabytes respectively.
+ *
+ * If a negative number is passed in i.e. a string with the first non-black
+ * character being "-", zero is returned. Zero is also returned in the case of
+ * an error with the strtoull call in the function.
+ *
+ * @param str
+ * String containing number to convert.
+ * @return
+ * Number.
+ */
+static inline uint64_t
+rte_str_to_size(const char *str)
+{
+ char *endptr;
+ unsigned long long size;
+
+ while (isspace((int)*str))
+ str++;
+ if (*str == '-')
+ return 0;
+
+ errno = 0;
+ size = strtoull(str, &endptr, 0);
+ if (errno)
+ return 0;
+
+ if (*endptr == ' ')
+ endptr++; /* allow 1 space gap */
+
+ switch (*endptr){
+ case 'G': case 'g': size *= 1024; /* fall-through */
+ case 'M': case 'm': size *= 1024; /* fall-through */
+ case 'K': case 'k': size *= 1024; /* fall-through */
+ default:
+ break;
+ }
+ return size;
+}
+
+/**
+ * Function to terminate the application immediately, printing an error
+ * message and returning the exit_code back to the shell.
+ *
+ * This function never returns
+ *
+ * @param exit_code
+ * The exit code to be returned by the application
+ * @param format
+ * The format string to be used for printing the message. This can include
+ * printf format characters which will be expanded using any further parameters
+ * to the function.
+ */
+void
+rte_exit(int exit_code, const char *format, ...)
+ __attribute__((noreturn))
+ __attribute__((format(printf, 2, 3)));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_config.h b/lib/librte_eal/windows/rte_override/rte_config.h
new file mode 100644
index 000000000..d26f689b1
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_config.h
@@ -0,0 +1,328 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#define RTE_EXEC_ENV "windowsapp"
+#define RTE_EXEC_ENV_WINDOWSAPP 1
+#define RTE_MACHINE "native"
+#define RTE_ARCH "x86_64"
+#define RTE_ARCH_X86_64 1
+#define RTE_TOOLCHAIN "icc"
+#define RTE_TOOLCHAIN_ICC 1
+#undef RTE_LIBC
+#undef RTE_LIBC_NEWLIB_SRC
+#undef RTE_LIBC_NEWLIB_BIN
+#undef RTE_LIBC_NETINCS
+#undef RTE_LIBGLOSS
+
+#define RTE_MAX_HEAPS 32
+#define RTE_MAX_MEMSEG_LISTS 128
+#define RTE_MAX_MEMSEG_PER_LIST 8192
+#define RTE_LIBRTE_EAL 1
+#define RTE_MAX_LCORE 128
+#define RTE_MAX_NUMA_NODES 8
+#define RTE_MAX_MEMSEG 256
+#define RTE_MAX_MEMZONE 2560
+#define RTE_MAX_TAILQ 32
+#define RTE_LOG_LEVEL RTE_LOG_DEBUG
+#define RTE_LOG_DP_LEVEL RTE_LOG_DEBUG
+#define RTE_LOG_HISTORY 256
+#undef RTE_LIBEAL_USE_HPET
+#undef RTE_EAL_ALLOW_INV_SOCKET_ID
+#undef RTE_EAL_ALWAYS_PANIC_ON_ERROR
+#undef RTE_EAL_UNBIND_PORTS
+#define RTE_LIBRTE_EAL_LINUXAPP 1
+#undef RTE_LIBRTE_EAL_BAREMETAL
+#define RTE_ENABLE_AVX 1
+#undef RTE_ENABLE_AVX512
+#undef RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT
+#define RTE_LIBRTE_PCI 1
+#define RTE_LIBRTE_KVARGS 1
+#define RTE_LIBRTE_ETHDEV 1
+#undef RTE_LIBRTE_ETHDEV_DEBUG
+#define RTE_MAX_ETHPORTS 32
+#define RTE_MAX_QUEUES_PER_PORT 1024
+#undef RTE_LIBRTE_IEEE1588
+#define RTE_ETHDEV_QUEUE_STAT_CNTRS 16
+#define RTE_ETHDEV_RXTX_CALLBACKS 1
+#undef RTE_ETHDEV_PROFILE_ITT_WASTED_RX_ITERATIONS
+#undef RTE_ETHDEV_TX_PREPARE_NOOP
+#define RTE_LIBRTE_PCI_BUS 1
+#undef RTE_LIBRTE_ENA_PMD
+#undef RTE_LIBRTE_ENA_DEBUG_RX
+#undef RTE_LIBRTE_ENA_DEBUG_TX
+#undef RTE_LIBRTE_ENA_DEBUG_TX_FREE
+#undef RTE_LIBRTE_ENA_DEBUG_DRIVER
+#undef RTE_LIBRTE_ENA_COM_DEBUG
+#define RTE_LIBRTE_EM_PMD 1
+#define RTE_LIBRTE_IGB_PMD 1
+#undef RTE_LIBRTE_E1000_DEBUG_INIT
+#undef RTE_LIBRTE_E1000_DEBUG_RX
+#undef RTE_LIBRTE_E1000_DEBUG_TX
+#undef RTE_LIBRTE_E1000_DEBUG_TX_FREE
+#undef RTE_LIBRTE_E1000_DEBUG_DRIVER
+#undef RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC
+#define RTE_LIBRTE_IXGBE_PMD 1
+#undef RTE_LIBRTE_IXGBE_DEBUG_INIT
+#undef RTE_LIBRTE_IXGBE_DEBUG_RX
+#undef RTE_LIBRTE_IXGBE_DEBUG_TX
+#undef RTE_LIBRTE_IXGBE_DEBUG_TX_FREE
+#undef RTE_LIBRTE_IXGBE_DEBUG_DRIVER
+#undef RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC
+#define RTE_IXGBE_INC_VECTOR 1
+#undef RTE_LIBRTE_IXGBE_BYPASS
+#define RTE_LIBRTE_I40E_PMD 1
+#undef RTE_LIBRTE_I40E_DEBUG_RX
+#undef RTE_LIBRTE_I40E_DEBUG_TX
+#undef RTE_LIBRTE_I40E_DEBUG_TX_FREE
+#define RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC 1
+#define RTE_LIBRTE_I40E_INC_VECTOR 1
+#undef RTE_LIBRTE_I40E_16BYTE_RX_DESC
+#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF 64
+#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF 4
+#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM 4
+#define RTE_LIBRTE_I40E_ITR_INTERVAL -1
+#undef RTE_LIBRTE_FM10K_PMD
+#undef RTE_LIBRTE_FM10K_DEBUG_INIT
+#undef RTE_LIBRTE_FM10K_DEBUG_RX
+#undef RTE_LIBRTE_FM10K_DEBUG_TX
+#undef RTE_LIBRTE_FM10K_DEBUG_TX_FREE
+#undef RTE_LIBRTE_FM10K_DEBUG_DRIVER
+#define RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE 1
+#define RTE_LIBRTE_FM10K_INC_VECTOR 1
+#undef RTE_LIBRTE_MLX4_PMD
+#undef RTE_LIBRTE_MLX4_DEBUG
+#undef RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS
+#define RTE_LIBRTE_MLX4_TX_MP_CACHE 8
+#undef RTE_LIBRTE_MLX5_PMD
+#undef RTE_LIBRTE_MLX5_DEBUG
+#define RTE_LIBRTE_MLX5_TX_MP_CACHE 8
+#undef RTE_LIBRTE_BNX2X_PMD
+#undef RTE_LIBRTE_BNX2X_DEBUG
+#undef RTE_LIBRTE_BNX2X_DEBUG_INIT
+#undef RTE_LIBRTE_BNX2X_DEBUG_RX
+#undef RTE_LIBRTE_BNX2X_DEBUG_TX
+#undef RTE_LIBRTE_BNX2X_MF_SUPPORT
+#undef RTE_LIBRTE_BNX2X_DEBUG_PERIODIC
+#undef RTE_LIBRTE_CXGBE_PMD
+#undef RTE_LIBRTE_CXGBE_DEBUG
+#undef RTE_LIBRTE_CXGBE_DEBUG_REG
+#undef RTE_LIBRTE_CXGBE_DEBUG_MBOX
+#undef RTE_LIBRTE_CXGBE_DEBUG_TX
+#undef RTE_LIBRTE_CXGBE_DEBUG_RX
+#undef RTE_LIBRTE_CXGBE_TPUT
+#undef RTE_LIBRTE_ENIC_PMD
+#undef RTE_LIBRTE_ENIC_DEBUG
+#undef RTE_LIBRTE_ENIC_DEBUG_FLOW
+#undef RTE_LIBRTE_NFP_PMD
+#undef RTE_LIBRTE_NFP_DEBUG
+#undef RTE_LIBRTE_MRVL_PMD
+#undef RTE_LIBRTE_BNXT_PMD
+#undef RTE_LIBRTE_SFC_EFX_PMD
+#undef RTE_LIBRTE_SFC_EFX_DEBUG
+#define RTE_LIBRTE_PMD_SOFTNIC 1
+#undef RTE_LIBRTE_PMD_SZEDATA2
+#define RTE_LIBRTE_PMD_SZEDATA2_AS 0
+#undef RTE_LIBRTE_THUNDERX_NICVF_PMD
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_INIT
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_RX
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_TX
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX
+#undef RTE_LIBRTE_LIO_PMD
+#undef RTE_LIBRTE_LIO_DEBUG_DRIVER
+#undef RTE_LIBRTE_LIO_DEBUG_INIT
+#undef RTE_LIBRTE_LIO_DEBUG_RX
+#undef RTE_LIBRTE_LIO_DEBUG_TX
+#undef RTE_LIBRTE_LIO_DEBUG_MBOX
+#undef RTE_LIBRTE_LIO_DEBUG_REGS
+#undef RTE_LIBRTE_DPAA_BUS
+#undef RTE_LIBRTE_DPAA_MEMPOOL
+#undef RTE_LIBRTE_DPAA_PMD
+#undef RTE_LIBRTE_OCTEONTX_PMD
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_INIT
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_RX
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_TX
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_DRIVER
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_MBOX
+#undef RTE_LIBRTE_FSLMC_BUS
+#undef RTE_LIBRTE_DPAA2_MEMPOOL
+#undef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
+#undef RTE_LIBRTE_DPAA2_PMD
+#undef RTE_LIBRTE_DPAA2_DEBUG_INIT
+#undef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
+#undef RTE_LIBRTE_DPAA2_DEBUG_RX
+#undef RTE_LIBRTE_DPAA2_DEBUG_TX
+#undef RTE_LIBRTE_DPAA2_DEBUG_TX_FREE
+#undef RTE_LIBRTE_VIRTIO_PMD
+#undef RTE_LIBRTE_VIRTIO_DEBUG_INIT
+#undef RTE_LIBRTE_VIRTIO_DEBUG_RX
+#undef RTE_LIBRTE_VIRTIO_DEBUG_TX
+#undef RTE_LIBRTE_VIRTIO_DEBUG_DRIVER
+#undef RTE_LIBRTE_VIRTIO_DEBUG_DUMP
+#undef RTE_VIRTIO_USER
+#undef RTE_LIBRTE_VMXNET3_PMD
+#undef RTE_LIBRTE_VMXNET3_DEBUG_INIT
+#undef RTE_LIBRTE_VMXNET3_DEBUG_RX
+#undef RTE_LIBRTE_VMXNET3_DEBUG_TX
+#undef RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE
+#undef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
+#define RTE_LIBRTE_PMD_RING 1
+#define RTE_PMD_RING_MAX_RX_RINGS 16
+#define RTE_PMD_RING_MAX_TX_RINGS 16
+#define RTE_LIBRTE_PMD_PCAP 1
+#undef RTE_LIBRTE_PMD_BOND
+#undef RTE_LIBRTE_BOND_DEBUG_ALB
+#undef RTE_LIBRTE_BOND_DEBUG_ALB_L1
+#undef RTE_LIBRTE_QEDE_PMD
+#undef RTE_LIBRTE_QEDE_DEBUG_INIT
+#undef RTE_LIBRTE_QEDE_DEBUG_INFO
+#undef RTE_LIBRTE_QEDE_DEBUG_DRIVER
+#undef RTE_LIBRTE_QEDE_DEBUG_TX
+#undef RTE_LIBRTE_QEDE_DEBUG_RX
+#define RTE_LIBRTE_QEDE_FW ""
+#undef RTE_LIBRTE_PMD_AF_PACKET
+#undef RTE_LIBRTE_ARK_PMD
+#undef RTE_LIBRTE_ARK_PAD_TX
+#undef RTE_LIBRTE_ARK_DEBUG_RX
+#undef RTE_LIBRTE_ARK_DEBUG_TX
+#undef RTE_LIBRTE_ARK_DEBUG_STATS
+#undef RTE_LIBRTE_ARK_DEBUG_TRACE
+#undef RTE_LIBRTE_AVP_PMD
+#undef RTE_LIBRTE_AVP_DEBUG_RX
+#undef RTE_LIBRTE_AVP_DEBUG_TX
+#undef RTE_LIBRTE_AVP_DEBUG_DRIVER
+#undef RTE_LIBRTE_AVP_DEBUG_BUFFERS
+#undef RTE_LIBRTE_PMD_TAP
+#undef RTE_LIBRTE_PMD_NULL
+#undef RTE_LIBRTE_PMD_FAILSAFE
+#define RTE_PMD_PACKET_PREFETCH 1
+#define RTE_LIBRTE_CRYPTODEV 1
+#undef RTE_LIBRTE_CRYPTODEV_DEBUG
+#define RTE_CRYPTO_MAX_DEVS 64
+#define RTE_CRYPTODEV_NAME_LEN 64
+#undef RTE_LIBRTE_PMD_ARMV8_CRYPTO
+#undef RTE_LIBRTE_PMD_ARMV8_CRYPTO_DEBUG
+#undef RTE_LIBRTE_PMD_DPAA2_SEC
+#undef RTE_LIBRTE_DPAA2_SEC_DEBUG_INIT
+#undef RTE_LIBRTE_DPAA2_SEC_DEBUG_DRIVER
+#undef RTE_LIBRTE_DPAA2_SEC_DEBUG_RX
+#undef RTE_LIBRTE_PMD_DPAA_SEC
+#undef RTE_LIBRTE_DPAA_SEC_DEBUG_INIT
+#undef RTE_LIBRTE_DPAA_SEC_DEBUG_DRIVER
+#undef RTE_LIBRTE_DPAA_SEC_DEBUG_RX
+#undef RTE_LIBRTE_PMD_QAT
+#undef RTE_LIBRTE_PMD_QAT_DEBUG_INIT
+#undef RTE_LIBRTE_PMD_QAT_DEBUG_TX
+#undef RTE_LIBRTE_PMD_QAT_DEBUG_RX
+#undef RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER
+#define RTE_QAT_PMD_MAX_NB_SESSIONS 2048
+#undef RTE_LIBRTE_PMD_AESNI_MB
+#undef RTE_LIBRTE_PMD_AESNI_MB_DEBUG
+#undef RTE_LIBRTE_PMD_OPENSSL
+#undef RTE_LIBRTE_PMD_OPENSSL_DEBUG
+#undef RTE_LIBRTE_PMD_AESNI_GCM
+#undef RTE_LIBRTE_PMD_AESNI_GCM_DEBUG
+#undef RTE_LIBRTE_PMD_SNOW3G
+#undef RTE_LIBRTE_PMD_SNOW3G_DEBUG
+#undef RTE_LIBRTE_PMD_KASUMI
+#undef RTE_LIBRTE_PMD_KASUMI_DEBUG
+#undef RTE_LIBRTE_PMD_ZUC
+#undef RTE_LIBRTE_PMD_ZUC_DEBUG
+#undef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER
+#undef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER_DEBUG
+#undef RTE_LIBRTE_PMD_NULL_CRYPTO
+#undef RTE_LIBRTE_PMD_MRVL_CRYPTO
+#undef RTE_LIBRTE_PMD_MRVL_CRYPTO_DEBUG
+#define RTE_LIBRTE_SECURITY 1
+#define RTE_LIBRTE_EVENTDEV 1
+#undef RTE_LIBRTE_EVENTDEV_DEBUG
+#define RTE_EVENT_MAX_DEVS 16
+#define RTE_EVENT_MAX_QUEUES_PER_DEV 64
+#define RTE_LIBRTE_PMD_SKELETON_EVENTDEV 1
+#undef RTE_LIBRTE_PMD_SKELETON_EVENTDEV_DEBUG
+#define RTE_LIBRTE_PMD_SW_EVENTDEV 1
+#undef RTE_LIBRTE_PMD_SW_EVENTDEV_DEBUG
+#undef RTE_LIBRTE_PMD_OCTEONTX_SSOVF
+#undef RTE_LIBRTE_PMD_OCTEONTX_SSOVF_DEBUG
+#define RTE_LIBRTE_RING 1
+#undef RTE_LIBRTE_RING_DEBUG
+#define RTE_LIBRTE_MEMPOOL 1
+#define RTE_MEMPOOL_CACHE_MAX_SIZE 512
+#undef RTE_LIBRTE_MEMPOOL_DEBUG
+#define RTE_DRIVER_MEMPOOL_RING 1
+#define RTE_DRIVER_MEMPOOL_STACK 1
+#undef RTE_LIBRTE_OCTEONTX_MEMPOOL
+#undef RTE_LIBRTE_OCTEONTX_MEMPOOL_DEBUG
+#define RTE_LIBRTE_MBUF 1
+#undef RTE_LIBRTE_MBUF_DEBUG
+#define RTE_MBUF_DEFAULT_MEMPOOL_OPS "ring_mp_mc"
+#undef RTE_MBUF_SCATTER_GATHER 1
+#undef RTE_MBUF_REFCNT_ATOMIC 1
+#define RTE_PKTMBUF_HEADROOM 128
+#define RTE_LIBRTE_TIMER 1
+#undef RTE_LIBRTE_TIMER_DEBUG
+#define RTE_LIBRTE_CFGFILE 1
+#define RTE_LIBRTE_CMDLINE 1
+#undef RTE_LIBRTE_CMDLINE_DEBUG
+#define RTE_LIBRTE_HASH 1
+#undef RTE_LIBRTE_HASH_DEBUG
+#undef RTE_LIBRTE_EFD
+#undef RTE_LIBRTE_MEMBER
+#define RTE_LIBRTE_JOBSTATS 1
+#define RTE_LIBRTE_METRICS 1
+#define RTE_LIBRTE_BITRATE 1
+#define RTE_LIBRTE_LATENCY_STATS 1
+#define RTE_LIBRTE_LPM 1
+#undef RTE_LIBRTE_LPM_DEBUG
+#define RTE_LIBRTE_ACL 1
+#undef RTE_LIBRTE_ACL_DEBUG
+#undef RTE_LIBRTE_POWER
+#undef RTE_LIBRTE_POWER_DEBUG
+#define RTE_MAX_LCORE_FREQS 64
+#define RTE_LIBRTE_NET 1
+#define RTE_LIBRTE_IP_FRAG 1
+#undef CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG
+#define RTE_LIBRTE_IP_FRAG_MAX_FRAG 4
+#undef RTE_LIBRTE_IP_FRAG_TBL_STAT
+#define RTE_LIBRTE_GRO 1
+#define RTE_LIBRTE_GSO 1
+#define RTE_LIBRTE_METER 1
+#define RTE_LIBRTE_FLOW_CLASSIFY 1
+#define RTE_LIBRTE_SCHED 1
+#undef CONFIG_RTE_SCHED_DEBUG
+#undef CONFIG_RTE_SCHED_RED
+#undef RTE_SCHED_COLLECT_STATS
+#undef RTE_SCHED_SUBPORT_TC_OV
+#define RTE_SCHED_PORT_N_GRINDERS 8
+#undef RTE_SCHED_VECTOR
+#define RTE_LIBRTE_DISTRIBUTOR 1
+#define RTE_LIBRTE_REORDER 1
+#define RTE_LIBRTE_PORT 1
+#undef RTE_PORT_STATS_COLLECT
+#undef RTE_PORT_PCAP
+#define RTE_LIBRTE_TABLE 1
+#undef RTE_TABLE_STATS_COLLECT
+#define RTE_LIBRTE_PIPELINE 1
+#undef RTE_PIPELINE_STATS_COLLECT
+#undef RTE_LIBRTE_KNI
+#undef RTE_LIBRTE_PMD_KNI
+#undef RTE_KNI_KMOD
+#undef RTE_KNI_KMOD_ETHTOOL
+#undef RTE_KNI_PREEMPT_DEFAULT
+#undef RTE_LIBRTE_PDUMP
+#undef RTE_LIBRTE_VHOST
+#undef RTE_LIBRTE_VHOST_NUMA
+#undef RTE_LIBRTE_VHOST_DEBUG
+#undef RTE_LIBRTE_PMD_VHOST
+#define RTE_APP_TEST 1
+#undef RTE_APP_TEST_RESOURCE_TAR
+#define RTE_APP_CHKINCS 1
+#define RTE_TEST_PMD 1
+#undef RTE_TEST_PMD_RECORD_CORE_CYCLES
+#undef RTE_TEST_PMD_RECORD_BURST_STATS
+#define RTE_APP_CRYPTO_PERF 1
+#define RTE_APP_EVENTDEV 1
+#define RTE_EAL_PMD_PATH ""
+#define RTE_CACHE_LINE_SIZE 64
+#define RTE_CACHE_LINE_MIN_SIZE 64
diff --git a/lib/librte_eal/windows/rte_override/rte_cpuflags.h b/lib/librte_eal/windows/rte_override/rte_cpuflags.h
new file mode 100644
index 000000000..23accc85b
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_cpuflags.h
@@ -0,0 +1,3 @@
+#define RTE_COMPILE_TIME_CPUFLAGS RTE_CPUFLAG_SSE4_1
+
+#include "..\common\include\arch\x86\rte_cpuflags.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_cycles.h b/lib/librte_eal/windows/rte_override/rte_cycles.h
new file mode 100644
index 000000000..98e4cc426
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_cycles.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#include "..\..\common\include\generic\rte_cycles.h"
+
+static inline uint64_t
+rte_rdtsc(void)
+{
+ return (uint64_t) __rdtsc();
+}
+
+static inline uint64_t
+rte_rdtsc_precise(void)
+{
+ rte_mb();
+ return rte_rdtsc();
+}
+
+static inline uint64_t
+rte_get_tsc_cycles(void)
+{
+ return rte_rdtsc();
+}
diff --git a/lib/librte_eal/windows/rte_override/rte_debug.h b/lib/librte_eal/windows/rte_override/rte_debug.h
new file mode 100644
index 000000000..3469ff3d7
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_debug.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+/* If rte_common.h has already been included, then we will have issues */
+#ifdef _RTE_DEBUG_H_
+#error
+#endif
+
+#include <stdio.h>
+#include "../common/include/rte_debug.h"
+
+#undef rte_panic
+#define rte_panic(fmt, ...) { printf (fmt, ##__VA_ARGS__); while(1); }
+
+#undef RTE_VERIFY
+#define RTE_VERIFY(exp) do { \
+ if (!(exp)) \
+ rte_panic("line %d\tassert \"" #exp "\" failed\n", __LINE__); \
+} while (0)
diff --git a/lib/librte_eal/windows/rte_override/rte_io.h b/lib/librte_eal/windows/rte_override/rte_io.h
new file mode 100644
index 000000000..d111c4239
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_io.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#pragma once
+
+#include "..\..\common\include\generic\rte_io.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_lcore.h b/lib/librte_eal/windows/rte_override/rte_lcore.h
new file mode 100644
index 000000000..d2a2788c8
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_lcore.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _RTE_WIN_LCORE_H_
+#define _RTE_WIN_LCORE_H_
+
+/* DPDK 1.8 */
+typedef unsigned long rte_cpuset_t;
+
+/* Include the original rte_lcore.h from common */
+#include "../../common/include/rte_lcore.h"
+
+
+#endif
\ No newline at end of file
diff --git a/lib/librte_eal/windows/rte_override/rte_log.h.sav b/lib/librte_eal/windows/rte_override/rte_log.h.sav
new file mode 100644
index 000000000..e892a69ac
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_log.h.sav
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "..\..\common\include\rte_log.h"
+
+#undef RTE_LOG
+#define RTE_LOG(l, t, ...) printf (##__VA_ARGS__)
diff --git a/lib/librte_eal/windows/rte_override/rte_memcpy.h b/lib/librte_eal/windows/rte_override/rte_memcpy.h
new file mode 100644
index 000000000..6132df294
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_memcpy.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define rte_memcpy(dest, src, n) memcpy(dest, src,n)
diff --git a/lib/librte_eal/windows/rte_override/rte_memory.h b/lib/librte_eal/windows/rte_override/rte_memory.h
new file mode 100644
index 000000000..0df9dd822
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_memory.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+/* If rte_common.h has already been included, then we will have issues */
+#ifdef _RTE_MEMORY_H_
+#error
+#endif
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (disable : 66) /* warning #66: enumeration value is out of "int" range */
+#endif
+
+#include "../common/include/rte_memory.h"
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (enable : 66)
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_pause.h b/lib/librte_eal/windows/rte_override/rte_pause.h
new file mode 100644
index 000000000..a8fa3bf51
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_pause.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#include "..\..\common\include\generic\rte_pause.h"
+#if defined(RTE_ARCH_X86)
+#include "..\..\common\include\arch\x86\rte_pause.h"
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_pci.h b/lib/librte_eal/windows/rte_override/rte_pci.h
new file mode 100644
index 000000000..fbf62b861
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_pci.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#include "..\..\..\librte_pci\rte_pci.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_per_lcore.h b/lib/librte_eal/windows/rte_override/rte_per_lcore.h
new file mode 100644
index 000000000..3dd629e68
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_per_lcore.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#include "..\..\common\include\rte_per_lcore.h"
+
+/* Undefine the stuff that is problematic for windows and redefine */
+#undef RTE_DEFINE_PER_LCORE
+#undef RTE_DECLARE_PER_LCORE
+
+
+/**
+ * @file
+ * Per-lcore variables in RTE on windows environment
+ */
+
+/**
+ * Macro to define a per lcore variable "name" of type "type", don't
+ * use keywords like "static" or "volatile" in type, just prefix the
+ * whole macro.
+ */
+#define RTE_DEFINE_PER_LCORE(type, name) __declspec(thread) type per_lcore_##name
+
+/**
+ * Macro to declare an extern per lcore variable "name" of type "type"
+ */
+#define RTE_DECLARE_PER_LCORE(type, name) __declspec(thread) extern type per_lcore_##name
diff --git a/lib/librte_eal/windows/rte_override/rte_prefetch.h b/lib/librte_eal/windows/rte_override/rte_prefetch.h
new file mode 100644
index 000000000..c5a750715
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_prefetch.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (disable : 2330)
+#endif
+
+static inline void rte_prefetch0(const volatile void *p)
+{
+ _mm_prefetch(p, _MM_HINT_T0);
+}
+
+static inline void rte_prefetch1(const volatile void *p)
+{
+ _mm_prefetch(p, _MM_HINT_T1);
+}
+
+static inline void rte_prefetch2(const volatile void *p)
+{
+ _mm_prefetch(p, _MM_HINT_T2);
+}
+
+static inline void rte_prefetch_non_temporal(const volatile void *p)
+{
+ _mm_prefetch(p, _MM_HINT_NTA);
+}
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (enable : 2330)
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_rtm.h b/lib/librte_eal/windows/rte_override/rte_rtm.h
new file mode 100644
index 000000000..0313ca0b1
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_rtm.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#pragma once
+
+#include "..\..\common\include\arch\x86\rte_rtm.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_rwlock.h b/lib/librte_eal/windows/rte_override/rte_rwlock.h
new file mode 100644
index 000000000..1ea667d0c
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_rwlock.h
@@ -0,0 +1,40 @@
+
+
+#ifndef _RTE_RWLOCK_WIN_H_
+#define _RTE_RWLOCK_WIN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_rwlock.h"
+
+static inline void
+rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)
+{
+ rte_rwlock_read_lock(rwl);
+}
+
+static inline void
+rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)
+{
+ rte_rwlock_read_unlock(rwl);
+}
+
+static inline void
+rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)
+{
+ rte_rwlock_write_lock(rwl);
+}
+
+static inline void
+rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)
+{
+ rte_rwlock_write_unlock(rwl);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RWLOCK_WIN_H_ */
\ No newline at end of file
diff --git a/lib/librte_eal/windows/rte_override/rte_spinlock.h b/lib/librte_eal/windows/rte_override/rte_spinlock.h
new file mode 100644
index 000000000..475a406e7
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_spinlock.h
@@ -0,0 +1,271 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#ifndef _RTE_SPINLOCK_H_
+#define _RTE_SPINLOCK_H_
+
+#include <rte_eal.h>
+#include <rte_pause.h>
+
+/**
+* The rte_spinlock_t type.
+*/
+typedef struct {
+ volatile long locked; /**< lock status 0 = unlocked, 1 = locked */
+} rte_spinlock_t;
+
+/**
+* A static spinlock initializer.
+*/
+#define RTE_SPINLOCK_INITIALIZER { 0 }
+
+/**
+* Initialize the spinlock to an unlocked state.
+*
+* @param sl
+* A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_init(rte_spinlock_t *sl)
+{
+ sl->locked = 0;
+}
+
+/**
+* Take the spinlock.
+*
+* @param sl
+* A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_lock(rte_spinlock_t *sl)
+{
+ while (_InterlockedExchange(&sl->locked, 1))
+ while (sl->locked)
+ rte_pause();
+}
+
+/**
+* Release the spinlock.
+*
+* @param sl
+* A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_unlock(rte_spinlock_t *sl)
+{
+ _InterlockedExchange(&sl->locked, 0);
+}
+
+/**
+* Try to take the lock.
+*
+* @param sl
+* A pointer to the spinlock.
+* @return
+* 1 if the lock is successfully taken; 0 otherwise.
+*/
+static inline int
+rte_spinlock_trylock(rte_spinlock_t *sl)
+{
+ return _InterlockedExchange(&sl->locked, 1) == 0;
+}
+
+/**
+* Test if the lock is taken.
+*
+* @param sl
+* A pointer to the spinlock.
+* @return
+* 1 if the lock is currently taken; 0 otherwise.
+*/
+static inline int rte_spinlock_is_locked(rte_spinlock_t *sl)
+{
+ return sl->locked;
+}
+
+/**
+* Test if hardware transactional memory (lock elision) is supported
+*
+* @return
+* 1 if the hardware transactional memory is supported; 0 otherwise.
+*/
+static inline int rte_tm_supported(void)
+{
+ return 0;
+}
+
+/**
+* Try to execute critical section in a hardware memory transaction,
+* if it fails or not available take the spinlock.
+*
+* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
+* transaction always aborts the transaction since the CPU is not able to
+* roll-back should the transaction fail. Therefore, hardware transactional
+* locks are not advised to be used around rte_eth_rx_burst() and
+* rte_eth_tx_burst() calls.
+*
+* @param sl
+* A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_lock_tm(rte_spinlock_t *sl);
+
+/**
+* Commit hardware memory transaction or release the spinlock if
+* the spinlock is used as a fall-back
+*
+* @param sl
+* A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_unlock_tm(rte_spinlock_t *sl);
+
+/**
+* Try to execute critical section in a hardware memory transaction,
+* if it fails or not available try to take the lock.
+*
+* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
+* transaction always aborts the transaction since the CPU is not able to
+* roll-back should the transaction fail. Therefore, hardware transactional
+* locks are not advised to be used around rte_eth_rx_burst() and
+* rte_eth_tx_burst() calls.
+*
+* @param sl
+* A pointer to the spinlock.
+* @return
+* 1 if the hardware memory transaction is successfully started
+* or lock is successfully taken; 0 otherwise.
+*/
+static inline int
+rte_spinlock_trylock_tm(rte_spinlock_t *sl);
+
+/**
+* The rte_spinlock_recursive_t type.
+*/
+typedef struct {
+ rte_spinlock_t sl; /**< the actual spinlock */
+ volatile int user; /**< core id using lock, -1 for unused */
+ volatile int count; /**< count of time this lock has been called */
+} rte_spinlock_recursive_t;
+
+/**
+* A static recursive spinlock initializer.
+*/
+#define RTE_SPINLOCK_RECURSIVE_INITIALIZER {RTE_SPINLOCK_INITIALIZER, -1, 0}
+
+/**
+* Initialize the recursive spinlock to an unlocked state.
+*
+* @param slr
+* A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_init(rte_spinlock_recursive_t *slr)
+{
+ rte_spinlock_init(&slr->sl);
+ slr->user = -1;
+ slr->count = 0;
+}
+
+/**
+* Take the recursive spinlock.
+*
+* @param slr
+* A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
+{
+ int id = rte_gettid();
+
+ if (slr->user != id) {
+ rte_spinlock_lock(&slr->sl);
+ slr->user = id;
+ }
+ slr->count++;
+}
+/**
+* Release the recursive spinlock.
+*
+* @param slr
+* A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
+{
+ if (--(slr->count) == 0) {
+ slr->user = -1;
+ rte_spinlock_unlock(&slr->sl);
+ }
+
+}
+
+/**
+* Try to take the recursive lock.
+*
+* @param slr
+* A pointer to the recursive spinlock.
+* @return
+* 1 if the lock is successfully taken; 0 otherwise.
+*/
+static inline int rte_spinlock_recursive_trylock(rte_spinlock_recursive_t *slr)
+{
+ int id = rte_gettid();
+
+ if (slr->user != id) {
+ if (rte_spinlock_trylock(&slr->sl) == 0)
+ return 0;
+ slr->user = id;
+ }
+ slr->count++;
+ return 1;
+}
+
+
+/**
+* Try to execute critical section in a hardware memory transaction,
+* if it fails or not available take the recursive spinlocks
+*
+* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
+* transaction always aborts the transaction since the CPU is not able to
+* roll-back should the transaction fail. Therefore, hardware transactional
+* locks are not advised to be used around rte_eth_rx_burst() and
+* rte_eth_tx_burst() calls.
+*
+* @param slr
+* A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_lock_tm(
+ rte_spinlock_recursive_t *slr);
+
+/**
+* Commit hardware memory transaction or release the recursive spinlock
+* if the recursive spinlock is used as a fall-back
+*
+* @param slr
+* A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_unlock_tm(
+ rte_spinlock_recursive_t *slr);
+
+/**
+* Try to execute critical section in a hardware memory transaction,
+* if it fails or not available try to take the recursive lock
+*
+* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
+* transaction always aborts the transaction since the CPU is not able to
+* roll-back should the transaction fail. Therefore, hardware transactional
+* locks are not advised to be used around rte_eth_rx_burst() and
+* rte_eth_tx_burst() calls.
+*
+* @param slr
+* A pointer to the recursive spinlock.
+* @return
+* 1 if the hardware memory transaction is successfully started
+* or lock is successfully taken; 0 otherwise.
+*/
+static inline int rte_spinlock_recursive_trylock_tm(
+ rte_spinlock_recursive_t *slr);
+
+#endif /* _RTE_SPINLOCK_H_ */
diff --git a/lib/librte_eal/windows/rte_override/rte_vect.h b/lib/librte_eal/windows/rte_override/rte_vect.h
new file mode 100644
index 000000000..f2530147d
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_vect.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define __ICC 1600
+
+#include "..\..\common\include\arch\x86\rte_vect.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_wincompat.h b/lib/librte_eal/windows/rte_override/rte_wincompat.h
new file mode 100644
index 000000000..2dff9f279
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_wincompat.h
@@ -0,0 +1,347 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#ifndef _RTE_WINCOMPAT_H_
+#define _RTE_WINCOMPAT_H_
+
+#if !defined _M_IX86 && !defined _M_X64
+#error Unsupported architecture
+#endif
+
+#include <stdint.h>
+
+/* Required for definition of read(), write() */
+#include <io.h>
+#include <intrin.h>
+
+/* limits.h replacement */
+#include <stdlib.h>
+#ifndef PATH_MAX
+#define PATH_MAX _MAX_PATH
+#endif
+
+
+#ifndef EDQUOT
+#define EDQUOT 0xFE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Quick generic implemetation of popcount - all architectures */
+static __forceinline int __popcount(unsigned int x)
+{
+ static const unsigned int m1 = 0x55555555;
+ static const unsigned int m2 = 0x33333333;
+ static const unsigned int m4 = 0x0f0f0f0f;
+ static const unsigned int h01 = 0x01010101;
+
+ x -= (x >> 1) & m1;
+ x = (x & m2) + ((x >> 2) & m2);
+ x = (x + (x >> 4)) & m4;
+ return (x * h01) >> 24;
+}
+
+static __forceinline int __builtin_popcountl(unsigned long x)
+{
+ return __popcount((unsigned int)x);
+}
+
+static __forceinline int __builtin_popcountll(unsigned long long x)
+{
+ static const unsigned long long m1 = 0x5555555555555555LL;
+ static const unsigned long long m2 = 0x3333333333333333LL;
+ static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0fLL;
+ static const unsigned long long h01 = 0x0101010101010101LL;
+
+ x -= (x >> 1) & m1;
+ x = (x & m2) + ((x >> 2) & m2);
+ x = (x + (x >> 4)) & m4;
+ return (x * h01) >> 56;
+}
+
+static __forceinline int __builtin_popcount(unsigned int x)
+{
+ return __popcount(x);
+}
+
+// __builtin_ctz - count of trailing zeroes
+// _BitScanForward returns the bit number of first bit that is 1 starting from the LSB to MSB
+static __forceinline int __builtin_ctz(unsigned int x)
+{
+ unsigned long index = 0;
+
+ if (_BitScanForward(&index, x))
+ return index;
+
+ return 32;
+}
+
+// __builtin_ctzl - count of trailing zeroes for long
+static __forceinline int __builtin_ctzl(unsigned long x)
+{
+ return __builtin_ctz((unsigned int) x);
+}
+
+// __builtin_ctzll - count of trailing zeroes for long long (64 bits)
+static __forceinline int __builtin_ctzll(unsigned long long x)
+{
+ unsigned long index = 0;
+
+ if (_BitScanForward64(&index, x))
+ return (int) index;
+
+ return 64;
+}
+
+
+// __builtin_clz - count of leading zeroes
+// _BitScanReverse returns the bit number of first bit that is 1 starting from the MSB to LSB
+static __forceinline int __builtin_clz(unsigned int x)
+{
+ unsigned long index = 0;
+
+ if (_BitScanReverse(&index, x))
+ return ((sizeof(x) * CHAR_BIT) -1 - index);
+
+ return 32;
+}
+
+// __builtin_clzl - count of leading zeroes for long
+static __forceinline int __builtin_clzl(unsigned long x)
+{
+ return __builtin_clz((unsigned int) x);
+}
+
+// __builtin_clzll - count of leading zeroes for long long (64 bits)
+static __forceinline int __builtin_clzll(unsigned long long x)
+{
+ unsigned long index = 0;
+
+ if (_BitScanReverse64(&index, x))
+ return ((sizeof(x) * CHAR_BIT) - 1 - index);
+
+ return 64;
+}
+
+static __forceinline uint32_t __builtin_bswap32(uint32_t val)
+{
+ return (uint32_t)_byteswap_ulong((unsigned long)val);
+}
+
+static __forceinline uint64_t __builtin_bswap64(uint64_t val)
+{
+ return (uint64_t) _byteswap_uint64((unsigned long long)val);
+}
+
+typedef int useconds_t;
+static void usleep(useconds_t us)
+{
+ LARGE_INTEGER cntr, start, current;
+ useconds_t curr_time;
+
+ QueryPerformanceFrequency(&cntr);
+ QueryPerformanceCounter(&start);
+
+ do {
+ QueryPerformanceCounter(¤t);
+
+ // Compute current time.
+ curr_time = ((current.QuadPart - start.QuadPart) / (float)cntr.QuadPart * 1000 * 1000);
+ } while (curr_time < us);
+
+}
+
+static inline int getuid (void)
+{
+ return 0;
+}
+
+#include <string.h>
+static inline char* strtok_r(char *str, const char *delim, char **nextp)
+{
+ char *ret;
+
+ if (str == NULL)
+ str = *nextp;
+
+ str += strspn(str, delim);
+ if (*str == '\0')
+ return NULL;
+
+ ret = str;
+ str += strcspn(str, delim);
+
+ if (*str)
+ *str++ = '\0';
+
+ *nextp = str;
+ return ret;
+}
+
+#define index(a, b) strchr(a, b)
+#define rindex(a, b) strrchr(a, b)
+
+#define pipe(i) _pipe(i, 8192, _O_BINARY)
+
+#define siglongjmp(a, err) /* NO-OP */
+
+#define strncasecmp(s1,s2,count) _strnicmp(s1,s2,count)
+
+// Replacement with safe string functions
+#define strcpy(dest,src) strcpy_s(dest,sizeof(dest),src)
+#define strncpy(dest,src,count) strncpy_s(dest,sizeof(dest),src,count)
+#define strlcpy(dest,src,count) strncpy_s(dest,sizeof(dest),src,count)
+#define strerror(errnum) WinSafeStrError(errnum)
+#define strsep(str,sep) WinStrSep(str,sep)
+#define strdup(str) _strdup(str)
+#define strcat(dest,src) strcat_s(dest,sizeof(dest),src)
+#define sscanf(source,pattern, ...) sscanf_s(source,pattern, __VA_ARGS__)
+
+
+static inline char* WinSafeStrError(int errnum)
+{
+ static char buffer[256];
+
+ ZeroMemory(buffer, sizeof(buffer));
+ strerror_s(buffer, sizeof(buffer), errnum);
+ return buffer;
+}
+
+static inline char* WinStrSep(char** ppString, char* pSeparator)
+{
+ char *pStrStart = NULL;
+
+ if ((ppString != NULL) && (*ppString != NULL) && (**ppString != '\0')) {
+ pStrStart = *ppString;
+ char *pStr = pStrStart + strcspn(pStrStart, pSeparator);
+
+ if (pStr == NULL)
+ *ppString = NULL;
+ else {
+ *pStr = '\0';
+ *ppString = pStr + 1;
+ }
+ }
+
+ return pStrStart;
+}
+
+#define sleep(secs) Sleep((secs)*1000) // Windows Sleep() requires milliseconds
+#define ftruncate(fd,len) _chsize_s(fd,len)
+
+// CPU set function overrides
+#define CPU_ZERO(cpuset) {*cpuset = 0;}
+#define CPU_SET(cpucore, cpuset) { *cpuset |= (1 << cpucore); }
+#define CPU_ISSET(cpucore, cpuset) ((*cpuset & (1 << cpucore)) ? 1 : 0)
+
+/* Winsock IP protocol Numbers (not available on Windows) */
+#define IPPROTO_NONE 59 /* No next header for IPv6 */
+#define IPPROTO_SCTP 132 /* Stream Control Transmission Protocol */
+
+/* signal definitions - defined in signal.h */
+#define SIGUSR1 30
+#define SIGUSR2 31
+
+/* Definitions for access() */
+#define F_OK 0 /* Check for existence */
+#define W_OK 2 /* Write permission */
+#define R_OK 4 /* Read permission */
+#define X_OK 8 /* DO NOT USE */
+
+#ifndef AF_INET6
+#define AF_INET6 28
+#endif
+
+/* stdlib extensions that aren't defined in windows */
+int setenv(const char *name, const char *value, int overwrite);
+
+// Returns a handle to an mutex object that is created only once
+static inline HANDLE OpenMutexHandleAsync(INIT_ONCE *g_InitOnce)
+{
+ PVOID lpContext;
+ BOOL fStatus;
+ BOOL fPending;
+ HANDLE hMutex;
+
+ // Begin one-time initialization
+ fStatus = InitOnceBeginInitialize(g_InitOnce, // Pointer to one-time initialization structure
+ INIT_ONCE_ASYNC, // Asynchronous one-time initialization
+ &fPending, // Receives initialization status
+ &lpContext); // Receives pointer to data in g_InitOnce
+
+ // InitOnceBeginInitialize function failed.
+ if (!fStatus)
+ {
+ return (INVALID_HANDLE_VALUE);
+ }
+
+ // Initialization has already completed and lpContext contains mutex object.
+ if (!fPending)
+ {
+ return (HANDLE)lpContext;
+ }
+
+ // Create Mutex object for one-time initialization.
+ hMutex = CreateMutex(NULL, // Default security descriptor
+ FALSE, // Manual-reset mutex object
+ NULL); // Object is unnamed
+
+ // mutex object creation failed.
+ if (NULL == hMutex)
+ {
+ return (INVALID_HANDLE_VALUE);
+ }
+
+ // Complete one-time initialization.
+ fStatus = InitOnceComplete(g_InitOnce, // Pointer to one-time initialization structure
+ INIT_ONCE_ASYNC, // Asynchronous initialization
+ (PVOID)hMutex); // Pointer to mutex object to be stored in g_InitOnce
+
+ // InitOnceComplete function succeeded. Return mutex object.
+ if (fStatus)
+ {
+ return hMutex;
+ }
+
+ // Initialization has already completed. Free the local mutex.
+ CloseHandle(hMutex);
+
+
+ // Retrieve the final context data.
+ fStatus = InitOnceBeginInitialize(g_InitOnce, // Pointer to one-time initialization structure
+ INIT_ONCE_CHECK_ONLY, // Check whether initialization is complete
+ &fPending, // Receives initialization status
+ &lpContext); // Receives pointer to mutex object in g_InitOnce
+
+ // Initialization is complete. Return mutex.
+ if (fStatus && !fPending)
+ {
+ return (HANDLE)lpContext;
+ }
+ else
+ {
+ return INVALID_HANDLE_VALUE;
+ }
+}
+
+/*
+ * Used to statically create and lock a mutex
+*/
+static inline HANDLE WinCreateAndLockStaticMutex(HANDLE mutex, INIT_ONCE *g_InitOnce) {
+ mutex = OpenMutexHandleAsync(g_InitOnce);
+ WaitForSingleObject(mutex, INFINITE);
+ return mutex;
+}
+
+//#include <rte_gcc_builtins.h>
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_windows.h b/lib/librte_eal/windows/rte_override/rte_windows.h
new file mode 100644
index 000000000..8e7f5299a
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_windows.h
@@ -0,0 +1,497 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#pragma once
+
+#ifndef _RTE_WINDOWS_H_
+#define _RTE_WINDOWS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _MSC_VER
+#error
+#endif
+
+#ifndef _WINDOWS
+#define _WINDOWS
+#endif
+
+// If we define WIN32_LEAN_AND_MEAN, winsock isn't included by default. We can then include it in specific header files as we need later.
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+
+// This isn't a complete replacement for typeof in GCC. For example, it doesn't work in cases where you have typeof(x) _val = 0. However,
+// it does allow us to remove some of the windows specific changes that need to be put into a lot of files to allow compilation.
+#define typeof(x) _Generic((x), \
+ void * : void *, \
+ char : char, \
+ unsigned char : unsigned char \
+ char * : char *, \
+ unsigned char * : unsigned char *, \
+ short : short, \
+ unsigned short : unsigned short, \
+ short * : short *, \
+ unsigned short * : unsigned short *, \
+ int : int, \
+ int * : int *, \
+ unsigned int : unsigned int \
+ unsigned int * : unsigned int *, \
+ long : long, \
+ long * : long *, \
+ unsigned long : unsigned long, \
+ unsigned long * : unsigned long *, \
+ long long : long long, \
+ unsigned long long : unsigned long long, \
+ unsigned long long * : unsigned long long *, \
+ default : void \
+)
+
+/*
+* Globally driven over-rides.
+*/
+#define __attribute__(x)
+
+#define __func__ __FUNCTION__
+
+#define NORETURN __declspec(noreturn)
+#define ATTR_UNUSED
+#define __AVX__ 1
+
+#define E_RTE_NO_TAILQ (-1)
+
+/* Include this header here, so that we can re-define EAL_REGISTER_TAILQ */
+#include <rte_tailq.h>
+#ifdef EAL_REGISTER_TAILQ(t)
+#undef EAL_REGISTER_TAILQ(t)
+#endif
+
+/*
+* Definition for registering TAILQs
+* (This is a workaround for Windows in lieu of a constructor-like function)
+*/
+#define EAL_REGISTER_TAILQ(t) \
+void init_##t(void); \
+void init_##t(void) \
+{ \
+ if (rte_eal_tailq_register(&t) < 0) \
+ rte_panic("Cannot initialize tailq: %s\n", t.name); \
+}
+
+/* Include this header here, so that we can re-define RTE_REGISTER_BUS */
+#include <rte_bus.h>
+#ifdef RTE_REGISTER_BUS(nm, bus)
+#undef RTE_REGISTER_BUS(nm, bus)
+#endif
+
+/*
+* Definition for registering a bus
+* (This is a workaround for Windows in lieu of a constructor-like function)
+*/
+#define RTE_REGISTER_BUS(nm, bus) \
+void businitfn_ ##nm(void) \
+{\
+ (bus).name = RTE_STR(nm);\
+ rte_bus_register(&bus); \
+}
+
+
+/*
+* Global warnings control. Disable this to see warnings in the
+* include/rte_override files
+*/
+#define DPDKWIN_NO_WARNINGS
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (disable : 94) /* warning #94: the size of an array must be greater than zero */
+#pragma warning (disable : 169) /* warning #169: expected a declaration */
+#endif
+
+
+/*
+* These definitions are to force a specific version of the defined function.
+* For Windows, we'll always stick with the latest defined version.
+*/
+#define rte_lpm_create rte_lpm_create_v1604
+#define rte_lpm_add rte_lpm_add_v1604
+#define rte_lpm6_add rte_lpm6_add_v1705
+#define rte_lpm6_lookup rte_lpm6_lookup_v1705
+#define rte_lpm6_lookup_bulk_func rte_lpm6_lookup_bulk_func_v1705
+#define rte_lpm6_is_rule_present rte_lpm6_is_rule_present_v1705
+#define rte_lpm_find_existing rte_lpm_find_existing_v1604
+
+#define rte_distributor_request_pkt rte_distributor_request_pkt_v1705
+#define rte_distributor_poll_pkt rte_distributor_poll_pkt_v1705
+#define rte_distributor_get_pkt rte_distributor_get_pkt_v1705
+#define rte_distributor_return_pkt rte_distributor_return_pkt_v1705
+#define rte_distributor_returned_pkts rte_distributor_returned_pkts_v1705
+#define rte_distributor_clear_returns rte_distributor_clear_returns_v1705
+#define rte_distributor_process rte_distributor_process_v1705
+#define rte_distributor_flush rte_distributor_flush_v1705
+#define rte_distributor_create rte_distributor_create_v1705
+
+/*
+* Definitions and overrides for ethernet.h
+*/
+#define u_char uint8_t
+#define u_short uint16_t
+
+#define __packed
+
+#define __BEGIN_DECLS
+#define __END_DECLS
+
+/*
+* sys/_cdefs.h
+*/
+#define __extension__
+
+/*
+* sys/_iovec.h
+*/
+#define ssize_t size_t
+#define SSIZE_T_DECLARED
+#define _SSIZE_T_DECLARED
+#define _SIZE_T_DECLARED
+
+/*
+* Linux to BSD termios differences
+*/
+#define TCSANOW 0
+
+/* Support X86 architecture */
+#define RTE_ARCH_X86
+
+/*
+* We can safely remove __attribute__((__packed__)). We will replace it with all structures
+* being packed
+*/
+#pragma pack(1)
+
+#include <rte_wincompat.h>
+
+/* Include rte_common.h first to get this out of the way controlled */
+#include "./rte_common.h"
+
+
+#include <sys/types.h>
+/* rte_pci.h must be included before we define typeof() to be nothing */
+//#include "./rte_pci.h"
+
+
+#define __attribute__(x)
+
+#define RTE_FORCE_INTRINSICS
+
+#include "rte_config.h"
+
+#define RTE_CACHE_ALIGN __declspec(align(RTE_CACHE_LINE_SIZE))
+#define RTE_CACHE_MIN_ALIGN __declspec(align(RTE_CACHE_LINE_MIN_SIZE))
+
+/* The windows port does not currently support dymamic loading of libraries, so fail these calls */
+#define dlopen(lib, flag) (0)
+#define dlerror() ("Not supported!")
+
+/* Include time.h for struct timespec */
+#include <time.h>
+#ifndef _TIMESPEC_DEFINED
+#define _TIMESPEC_DEFINED
+#endif
+
+typedef jmp_buf sigjmp_buf;
+#define sigsetjmp(env, savemask) _setjmp((env))
+
+/* function prototypes for those used exclusively by Windows */
+void eal_create_cpu_map();
+
+#define uint uint32_t
+
+#define RTE_APP_TEST_RESOURCE_TAR 1
+
+#if 0
+/* rte_config.h defines all the libraries that we have to include. For all the libraries that are enabled,
+generate a comment that will include it */
+#ifdef _RTE_WIN_DPDK_APP
+
+#ifdef RTE_LIBRTE_EAL
+#pragma comment (lib, "librte_eal.lib")
+#endif
+#ifdef RTE_LIBRTE_PCI
+#pragma comment (lib, "librte_pci.lib")
+#endif
+#ifdef RTE_LIBRTE_ETHDEV
+#pragma comment (lib, "librte_ethdev.lib")
+#endif
+#ifdef RTE_LIBRTE_KVARGS
+#pragma comment (lib, "librte_kvargs.lib")
+#endif
+#ifdef RTE_LIBRTE_IEEE1588
+#pragma comment (lib, "librte_ieee1588.lib")
+#endif
+#ifdef RTE_LIBRTE_PCI_BUS
+#pragma comment (lib, "librte_bus_pci.lib")
+#endif
+#ifdef RTE_LIBRTE_EM_PMD || RTE_LIBRTE_IGB_PMD
+#pragma comment (lib, "librte_pmd_e1000.lib")
+#endif
+#ifdef RTE_LIBRTE_IXGBE_PMD
+#pragma comment (lib, "librte_pmd_ixgbe.lib")
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+#pragma comment (lib, "librte_pmd_i40e.lib")
+#endif
+#ifdef RTE_LIBRTE_FM10K_PMD
+#pragma comment (lib, "librte_pmd_fm10k.lib")
+#endif
+#ifdef RTE_LIBRTE_MLX4_PMD
+#pragma comment (lib, "librte_pmd_mlx4.lib")
+#endif
+#ifdef RTE_LIBRTE_MLX5_PMD
+#pragma comment (lib, "librte_pmd_mlx5.lib")
+#endif
+#ifdef RTE_LIBRTE_BNX2X_PMD
+#pragma comment (lib, "librte_pmd_bnx2x.lib")
+#endif
+#ifdef RTE_LIBRTE_CXGBE_PMD
+#pragma comment (lib, "librte_pmd_cxgbe.lib")
+#endif
+#ifdef RTE_LIBRTE_ENIC_PMD
+#pragma comment (lib, "librte_pmd_enic.lib")
+#endif
+#ifdef RTE_LIBRTE_NFP_PMD
+#pragma comment (lib, "librte_pmd_nfp.lib")
+#endif
+#ifdef RTE_LIBRTE_SFC_EFX_PMD
+#pragma comment (lib, "librte_pmd_sfc_efx.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SOFTNIC
+//#pragma comment (lib, "librte_pmd_softnic.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SZEDATA2
+#pragma comment (lib, "librte_pmd_szedata2.lib")
+#endif
+#ifdef RTE_LIBRTE_THUNDERX_NICVF_PMD
+#pragma comment (lib, "librte_pmd_thunderx_nicvf.lib")
+#endif
+#ifdef RTE_LIBRTE_LIO_PMD
+#pragma comment (lib, "librte_pmd_lio.lib")
+#endif
+#ifdef RTE_LIBRTE_DPAA_BUS
+#pragma comment (lib, "librte_dpaa_bus.lib")
+#endif
+#ifdef RTE_LIBRTE_DPAA_PMD
+#pragma comment (lib, "librte_pmd_dpaa.lib")
+#endif
+#ifdef RTE_LIBRTE_OCTEONTX_PMD
+#pragma comment (lib, "librte_pmd_octeontx.lib")
+#endif
+#ifdef RTE_LIBRTE_FSLMC_BUS
+#pragma comment (lib, "librte_fslmc_bus.lib")
+#endif
+#ifdef RTE_LIBRTE_DPAA2_PMD
+#pragma comment (lib, "librte_pmd_dpaa2.lib")
+#endif
+#ifdef RTE_LIBRTE_VIRTIO_PMD
+#pragma comment (lib, "librte_pmd_virtio.lib")
+#endif
+#ifdef RTE_VIRTIO_USER
+#pragma comment (lib, "librte_virtio_user.lib")
+#endif
+#ifdef RTE_LIBRTE_VMXNET3_PMD
+#pragma comment (lib, "librte_pmd_vmxnet3.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_RING
+//#pragma comment (lib, "librte_pmd_ring.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_BOND
+#pragma comment (lib, "librte_pmd_bond.lib")
+#endif
+#ifdef RTE_LIBRTE_QEDE_PMD
+#pragma comment (lib, "librte_pmd_qede.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_AF_PACKET
+#pragma comment (lib, "librte_pmd_af_packet.lib")
+#endif
+#ifdef RTE_LIBRTE_ARK_PMD
+#pragma comment (lib, "librte_pmd_ark.lib")
+#endif
+#ifdef RTE_LIBRTE_AVP_PMD
+#pragma comment (lib, "librte_pmd_avp.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_TAP
+#pragma comment (lib, "librte_pmd_tap.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_NULL
+#pragma comment (lib, "librte_pmd_null.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_FAILSAFE
+#pragma comment (lib, "librte_pmd_failsafe.lib")
+#endif
+#ifdef RTE_LIBRTE_CRYPTODEV
+#pragma comment (lib, "librte_cryptodev.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_ARMV8_CRYPTO
+#pragma comment (lib, "librte_pmd_armv8_crypto.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_DPAA2_SEC
+#pragma comment (lib, "librte_pmd_dpaa2_sec.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_QAT
+#pragma comment (lib, "librte_pmd_qat.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_AESNI_MB
+#pragma comment (lib, "librte_pmd_aesni_mb.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_OPENSSL
+#pragma comment (lib, "librte_pmd_openssl.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_AESNI_GCM
+#pragma comment (lib, "librte_pmd_aesni_gcm.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SNOW3G
+#pragma comment (lib, "librte_pmd_snow3g.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_KASUMI
+#pragma comment (lib, "librte_pmd_kasumi.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_ZUC
+#pragma comment (lib, "librte_pmd_zuc.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER
+#pragma comment (lib, "librte_pmd_crypto_scheduler.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_NULL_CRYPTO
+#pragma comment (lib, "librte_pmd_null_crypto.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_MRVL_CRYPTO
+#pragma comment (lib, "librte_pmd_mrvl_crypto.lib")
+#endif
+#ifdef RTE_LIBRTE_SECURITY
+#pragma comment (lib, "librte_security.lib")
+#endif
+#ifdef RTE_LIBRTE_EVENTDEV
+#pragma comment (lib, "librte_eventdev.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SKELETON_EVENTDEV
+//#pragma comment (lib, "librte_pmd_skeleton_eventdev.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SW_EVENTDEV
+//#pragma comment (lib, "librte_pmd_sw_eventdev.lib")
+#endif
+#ifdef RTE_LIBRTE_RING
+#pragma comment (lib, "librte_ring.lib")
+#endif
+#ifdef RTE_LIBRTE_MEMPOOL
+#pragma comment (lib, "librte_mempool.lib")
+#pragma comment (lib, "librte_mempool_ring.lib")
+#endif
+#ifdef RTE_LIBRTE_MBUF
+#pragma comment (lib, "librte_mbuf.lib")
+#endif
+#ifdef RTE_LIBRTE_TIMER
+#pragma comment (lib, "librte_timer.lib")
+#endif
+#ifdef RTE_LIBRTE_CFGFILE
+#pragma comment (lib, "librte_cfgfile.lib")
+#endif
+#ifdef RTE_LIBRTE_CMDLINE
+#pragma comment (lib, "librte_cmdline.lib")
+#endif
+#ifdef RTE_LIBRTE_HASH
+#pragma comment (lib, "librte_hash.lib")
+#endif
+#ifdef RTE_LIBRTE_EFD
+#pragma comment (lib, "librte_efd.lib")
+#endif
+#ifdef RTE_LIBRTE_EFD
+#pragma comment (lib, "librte_efd.lib")
+#endif
+#ifdef RTE_LIBRTE_MEMBER
+#pragma comment (lib, "librte_member.lib")
+#endif
+#ifdef RTE_LIBRTE_JOBSTATS
+//#pragma comment (lib, "librte_jobstats.lib")
+#endif
+#ifdef RTE_LIBRTE_METRICS
+#pragma comment (lib, "librte_metrics.lib")
+#endif
+#ifdef RTE_LIBRTE_BITRATE
+#pragma comment (lib, "librte_bitratestats.lib")
+#endif
+#ifdef RTE_LIBRTE_LATENCY_STATS
+#pragma comment (lib, "librte_latencystats.lib")
+#endif
+#ifdef RTE_LIBRTE_LPM
+#pragma comment (lib, "librte_lpm.lib")
+#endif
+#ifdef RTE_LIBRTE_ACL
+#pragma comment (lib, "librte_acl.lib")
+#endif
+#ifdef RTE_LIBRTE_POWER
+#pragma comment (lib, "librte_power.lib")
+#endif
+#ifdef RTE_LIBRTE_NET
+#pragma comment (lib, "librte_net.lib")
+#endif
+#ifdef RTE_LIBRTE_IP_FRAG
+#pragma comment (lib, "librte_ipfrag.lib")
+#endif
+#ifdef RTE_LIBRTE_GRO
+#pragma comment (lib, "librte_gro.lib")
+#endif
+#ifdef RTE_LIBRTE_GSO
+#pragma comment (lib, "librte_gso.lib")
+#endif
+#ifdef RTE_LIBRTE_METER
+#pragma comment (lib, "librte_meter.lib")
+#endif
+#ifdef RTE_LIBRTE_FLOW_CLASSIFY
+#pragma comment (lib, "librte_flowclassify.lib")
+#endif
+#ifdef RTE_LIBRTE_SCHED
+#pragma comment (lib, "librte_sched.lib")
+#endif
+#ifdef RTE_LIBRTE_DISTRIBUTOR
+#pragma comment (lib, "librte_distributor.lib")
+#endif
+#ifdef RTE_LIBRTE_REORDER
+#pragma comment (lib, "librte_reorder.lib")
+#endif
+#ifdef RTE_LIBRTE_PORT
+#pragma comment (lib, "librte_port.lib")
+#endif
+#ifdef RTE_LIBRTE_TABLE
+#pragma comment (lib, "librte_table.lib")
+#endif
+#ifdef RTE_LIBRTE_PIPELINE
+#pragma comment (lib, "librte_pipeline.lib")
+#endif
+#ifdef RTE_LIBRTE_KNI
+#pragma comment (lib, "librte_kni.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_KNI
+#pragma comment (lib, "librte_pmd_kni.lib")
+#endif
+#ifdef RTE_LIBRTE_PDUMP
+#pragma comment (lib, "librte_pdump.lib")
+#endif
+#ifdef RTE_LIBRTE_VHOST
+#pragma comment (lib, "librte_vhost.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_VHOST
+#pragma comment (lib, "librte_pmd_vhost.lib")
+#endif
+
+
+#endif /* _RTE_WIN_DPDK_APP */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_WINDOWS_H_ */
diff --git a/mk/exec-env/windows/DpdkRteLib.props b/mk/exec-env/windows/DpdkRteLib.props
new file mode 100644
index 000000000..076253937
--- /dev/null
+++ b/mk/exec-env/windows/DpdkRteLib.props
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros">
+ <RTE_SDK>$(SolutionDir)..\..\..</RTE_SDK>
+ </PropertyGroup>
+ <PropertyGroup>
+ <OutDir>$(RTE_SDK)\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutDir>
+ <IntDir>$(RTE_SDK)\mk\exec-env\windows\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Globals">
+ <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <PrecompiledHeaderFile />
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <PrecompiledHeaderOutputFile />
+ <AdditionalIncludeDirectories>$(RTE_SDK)\lib\librte_eal\windows\include_override;$(RTE_SDK)\lib\librte_eal\windows\rte_override;$(RTE_SDK)\lib\librte_eal\common;$(RTE_SDK)\lib\librte_eal\common\include;$(RTE_SDK)\lib\librte_acl;$(RTE_SDK)\lib\librte_cmdline;$(RTE_SDK)\lib\librte_distributor;$(RTE_SDK)\lib\librte_ethdev;$(RTE_SDK)\lib\librte_hash;$(RTE_SDK)\lib\librte_ip_frag;$(RTE_SDK)\lib\librte_kvargs;$(RTE_SDK)\lib\librte_lpm;$(RTE_SDK)\lib\librte_malloc;$(RTE_SDK)\lib\librte_mempool;$(RTE_SDK)\lib\librte_mbuf;$(RTE_SDK)\lib\librte_meter;$(RTE_SDK)\lib\librte_net;$(RTE_SDK)\lib\librte_pipeline;$(RTE_SDK)\lib\librte_port;$(RTE_SDK)\lib\librte_reorder;$(RTE_SDK)\lib\librte_ring;$(RTE_SDK)\lib\librte_sched;$(RTE_SDK)\lib\librte_table;$(RTE_SDK)\lib\librte_timer;$(RTE_SDK)\lib\librte_vhost;$(RTE_SDK)\lib\librte_compat;$(RTE_SDK)\drivers\bus\pci;$(RTE_SDK)\lib\librte_security;$(RTE_SDK)\lib\librte_bitratestats;$(RTE_SDK)\lib\librte_metrics;$(RTE_SDK)\lib\librte_efd;$(RTE_SDK)\lib\librte_cryptodev;$(RTE_SDK)\lib\librte_flow_classify</AdditionalIncludeDirectories>
+ <ForcedIncludeFiles>$(RTE_SDK)\lib\librte_eal\windows\rte_override\rte_windows.h</ForcedIncludeFiles>
+ <CLanguageStandard>gnu11</CLanguageStandard>
+ <PrecompiledHeaderCompileAs>
+ </PrecompiledHeaderCompileAs>
+ <PrecompiledHeaderOutputFileDirectory />
+ <CompileAs>Default</CompileAs>
+ <C99Support>
+ </C99Support>
+ <StructMemberAlignment>1Byte</StructMemberAlignment>
+ <AdditionalOptions>/Qstd=c11 %(AdditionalOptions)</AdditionalOptions>
+ <WarningLevel>Level3</WarningLevel>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <BuildMacro Include="RTE_SDK">
+ <Value>$(RTE_SDK)</Value>
+ </BuildMacro>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/dpdk.sln b/mk/exec-env/windows/dpdk.sln
new file mode 100644
index 000000000..8cbaa9e93
--- /dev/null
+++ b/mk/exec-env/windows/dpdk.sln
@@ -0,0 +1,43 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2010
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librte_eal", "librte_eal\librte_eal.vcxproj", "{7380DC42-DE9A-4BA3-B153-FC0156DA20B7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {F74A831C-CD22-4D19-BE6F-A318D0376EFA} = {F74A831C-CD22-4D19-BE6F-A318D0376EFA}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librte_kvargs", "librte_kvargs\librte_kvargs.vcxproj", "{F74A831C-CD22-4D19-BE6F-A318D0376EFA}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "helloworld", "helloworld\helloworld.vcxproj", "{40B2A34F-A9EC-4420-8BD1-652883AA39E5}"
+ ProjectSection(ProjectDependencies) = postProject
+ {7380DC42-DE9A-4BA3-B153-FC0156DA20B7} = {7380DC42-DE9A-4BA3-B153-FC0156DA20B7}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7380DC42-DE9A-4BA3-B153-FC0156DA20B7}.Debug|x64.ActiveCfg = Debug|x64
+ {7380DC42-DE9A-4BA3-B153-FC0156DA20B7}.Debug|x64.Build.0 = Debug|x64
+ {7380DC42-DE9A-4BA3-B153-FC0156DA20B7}.Release|x64.ActiveCfg = Release|x64
+ {7380DC42-DE9A-4BA3-B153-FC0156DA20B7}.Release|x64.Build.0 = Release|x64
+ {F74A831C-CD22-4D19-BE6F-A318D0376EFA}.Debug|x64.ActiveCfg = Debug|x64
+ {F74A831C-CD22-4D19-BE6F-A318D0376EFA}.Debug|x64.Build.0 = Debug|x64
+ {F74A831C-CD22-4D19-BE6F-A318D0376EFA}.Release|x64.ActiveCfg = Release|x64
+ {F74A831C-CD22-4D19-BE6F-A318D0376EFA}.Release|x64.Build.0 = Release|x64
+ {40B2A34F-A9EC-4420-8BD1-652883AA39E5}.Debug|x64.ActiveCfg = Debug|x64
+ {40B2A34F-A9EC-4420-8BD1-652883AA39E5}.Debug|x64.Build.0 = Debug|x64
+ {40B2A34F-A9EC-4420-8BD1-652883AA39E5}.Release|x64.ActiveCfg = Release|x64
+ {40B2A34F-A9EC-4420-8BD1-652883AA39E5}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {6CB597CF-1AD9-4A06-9C23-26B0EAEA3E63}
+ EndGlobalSection
+EndGlobal
diff --git a/mk/exec-env/windows/helloworld/helloworld.vcxproj b/mk/exec-env/windows/helloworld/helloworld.vcxproj
new file mode 100644
index 000000000..108d4b05b
--- /dev/null
+++ b/mk/exec-env/windows/helloworld/helloworld.vcxproj
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\examples\helloworld\main.c" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{40B2A34F-A9EC-4420-8BD1-652883AA39E5}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>helloworld</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\DpdkRteLib.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\DpdkRteLib.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <PrecompiledHeaderFile>
+ </PrecompiledHeaderFile>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>setupapi.lib;dbghelp.lib;$(RTE_SDK)\$(Platform)\$(Configuration)\librte_eal\librte_eal.lib;$(RTE_SDK)\$(Platform)\$(Configuration)\librte_kvargs\librte_kvargs.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <PrecompiledHeaderFile>
+ </PrecompiledHeaderFile>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>setupapi.lib;dbghelp.lib;$(RTE_SDK)\$(Platform)\$(Configuration)\librte_eal\librte_eal.lib;$(RTE_SDK)\$(Platform)\$(Configuration)\librte_kvargs\librte_kvargs.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/helloworld/helloworld.vcxproj.filters b/mk/exec-env/windows/helloworld/helloworld.vcxproj.filters
new file mode 100644
index 000000000..cf332900f
--- /dev/null
+++ b/mk/exec-env/windows/helloworld/helloworld.vcxproj.filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\examples\helloworld\main.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/helloworld/helloworld.vcxproj.user b/mk/exec-env/windows/helloworld/helloworld.vcxproj.user
new file mode 100644
index 000000000..be2507870
--- /dev/null
+++ b/mk/exec-env/windows/helloworld/helloworld.vcxproj.user
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_eal/librte_eal.vcxproj b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj
new file mode 100644
index 000000000..5b456d351
--- /dev/null
+++ b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{7380DC42-DE9A-4BA3-B153-FC0156DA20B7}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>librte_eal</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="..\DpdkRteLib.props" />
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="..\DpdkRteLib.props" />
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(RTE_SDK)\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutDir>
+ <IntDir>$(RTE_SDK)\mk\exec-env\windows\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(RTE_SDK)\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutDir>
+ <IntDir>$(RTE_SDK)\mk\exec-env\windows\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>C:\winddk\MSVS2015_SDK_WDK_Windows10_14393\Program Files\Microsoft Visual Studio 14.0\VC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <UndefinePreprocessorDefinitions>__ICL</UndefinePreprocessorDefinitions>
+ <StructMemberAlignment>1Byte</StructMemberAlignment>
+ <CCppSupport>C99Support</CCppSupport>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>C:\winddk\MSVS2015_SDK_WDK_Windows10_14393\Program Files\Microsoft Visual Studio 14.0\VC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <StructMemberAlignment>1Byte</StructMemberAlignment>
+ <CCppSupport>C99Support</CCppSupport>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_bus.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_class.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_cpuflags.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_dev.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_devargs.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_errno.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_hexdump.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_hypervisor.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_launch.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_lcore.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memalloc.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memory.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memzone.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_options.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_string_fns.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_tailqs.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_thread.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_timer.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\malloc_elem.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_keepalive.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_malloc.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_reciprocal.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_alarm.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_debug.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_fbarray.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_hugepage_info.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_interrupts.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_lcore.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_log.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_memalloc.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_memory.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_thread.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_timer.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\fork.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\getopt.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\lrand48.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\mman.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\setenv.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\srand48.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\termios.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\unistd.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\_rand48.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\malloc_heap.c" />
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\malloc_mp.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_internal_cfg.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_memalloc.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_options.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_private.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_thread.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\generic\rte_cycles.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\generic\rte_rwlock.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_bus.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_common.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_debug.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_dev.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_eal.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_eal_memconfig.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_interrupts.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_launch.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_lcore.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_log.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_malloc_heap.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_memory.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_memzone.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_pci.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_pci_dev_feature_defs.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_per_lcore.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_random.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_string_fns.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_tailq.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_version.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_elem.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_heap.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_mp.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\eal\eal_filesystem.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\eal\eal_pci_private.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\include_override\rand48.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\include_override\unistd.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_atomic.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_common.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_cycles.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_debug.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_lcore.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_memory.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_pci.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_per_lcore.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_spinlock.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_wincompat.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_windows.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.filters b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.filters
new file mode 100644
index 000000000..589392cf5
--- /dev/null
+++ b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.filters
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Header Files\windows override">
+ <UniqueIdentifier>{ba45c4dc-83b8-4fb0-9cec-e2b175fa8db4}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\windows override">
+ <UniqueIdentifier>{4ab5055a-d124-48a7-8801-14bc9f281934}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_cpuflags.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_dev.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_devargs.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_errno.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_hexdump.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_launch.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_lcore.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memory.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memzone.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_options.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_string_fns.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_tailqs.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_thread.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_timer.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\malloc_elem.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_malloc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\_rand48.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\getopt.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\lrand48.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\mman.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\srand48.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\unistd.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_debug.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_log.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_alarm.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_interrupts.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_timer.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_lcore.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_thread.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_memory.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_hugepage_info.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_bus.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\fork.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\setenv.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\termios.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_hypervisor.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_keepalive.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_reciprocal.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_class.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_fbarray.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memalloc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_memalloc.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\malloc_mp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\malloc_heap.c">
+ <Filter>Source Files\windows override</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_private.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_thread.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_internal_cfg.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_heap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_options.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_eal.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_pci_dev_feature_defs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_string_fns.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_pci.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_lcore.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_memory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_per_lcore.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_launch.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_interrupts.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\include_override\rand48.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_pci.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_per_lcore.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_lcore.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_memory.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_common.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_common.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_cycles.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\generic\rte_cycles.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\eal\eal_filesystem.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_windows.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\include_override\unistd.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_eal_memconfig.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_log.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_random.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_spinlock.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\generic\rte_rwlock.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_malloc_heap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_memzone.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_debug.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_debug.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_atomic.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_wincompat.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\windows\eal\eal_pci_private.h">
+ <Filter>Header Files\windows override</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_dev.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_bus.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_tailq.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_memalloc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_mp.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_elem.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.user b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.user
new file mode 100644
index 000000000..abe8dd896
--- /dev/null
+++ b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.user
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj
new file mode 100644
index 000000000..afd216f2d
--- /dev/null
+++ b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\lib\librte_kvargs\rte_kvargs.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_log.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_string_fns.h" />
+ <ClInclude Include="..\..\..\..\lib\librte_kvargs\rte_kvargs.h" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{F74A831C-CD22-4D19-BE6F-A318D0376EFA}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>librte_kvargs</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\DpdkRteLib.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\DpdkRteLib.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <StructMemberAlignment>1Byte</StructMemberAlignment>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <StructMemberAlignment>1Byte</StructMemberAlignment>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.filters b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.filters
new file mode 100644
index 000000000..ce48d6391
--- /dev/null
+++ b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.filters
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\lib\librte_kvargs\rte_kvargs.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\lib\librte_kvargs\rte_kvargs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_log.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_string_fns.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.user b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.user
new file mode 100644
index 000000000..be2507870
--- /dev/null
+++ b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.user
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup />
+</Project>
\ No newline at end of file
--
2.18.0.windows.1
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH] ethdev: support double precision RED queue weight
@ 2018-11-29 6:12 3% ` Stephen Hemminger
2018-12-10 5:43 0% ` Rao, Nikhil
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2018-11-29 6:12 UTC (permalink / raw)
To: Nikhil Rao; +Cc: cristian.dumitrescu, jasvinder.singh, dev
On Thu, 29 Nov 2018 11:24:42 +0530
Nikhil Rao <nikhil.rao@intel.com> wrote:
> RED queue weight is currently specified as a negated log of 2.
>
> Add support for RED queue weight to be specified in double precision
> and TM capability flags for double precision and negated log2
> RED queue weight support.
>
> Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
Since this is an ABI break anyway, why not just commit to the new
format?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] mbuf: implement generic format for sched field
@ 2018-11-29 10:42 3% ` Singh, Jasvinder
2018-12-04 17:39 0% ` Dumitrescu, Cristian
0 siblings, 1 reply; 200+ results
From: Singh, Jasvinder @ 2018-11-29 10:42 UTC (permalink / raw)
To: Dumitrescu, Cristian, dev; +Cc: Pattan, Reshma
<snip>
>
> > diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> > index 3dbc6695e..98428bd21 100644
> > --- a/lib/librte_mbuf/rte_mbuf.h
> > +++ b/lib/librte_mbuf/rte_mbuf.h
> > @@ -575,12 +575,10 @@ struct rte_mbuf {
> > */
> > } fdir; /**< Filter identifier if FDIR enabled */
> > struct {
> > - uint32_t lo;
> > - uint32_t hi;
> > - /**< The event eth Tx adapter uses this field
> > - * to store Tx queue id.
> > - * @see
> > rte_event_eth_tx_adapter_txq_set()
> > - */
> > + uint32_t queue_id; /**< Queue ID. */
> > + uint8_t traffic_class; /**< Traffic class ID. */
>
> We should add comment here that traffic class 0 is the highest priority traffic
> class.
Will add the suggested comment.
>
> > + uint8_t color; /**< Color. */
>
> We should create a new file rte_color.h in a common place
> (librte_eal/common/include) to consolidate the color definition, which is
> currently replicated in too many places, such as: rte_meter.h, rte_mtr.h,
> rte_tm.h.
>
> We should include the rte_color.h file here (and in the above header files)
>
> We should also document the link between this field and the color enum type
> (@see ...).
Replacing the existing color definition with the above suggested one in rte_meter.h (librte_meter)
would be ABI break. We can do it separately through different patch.
>
> > + uint16_t reserved; /**< Reserved. */
> > } sched; /**< Hierarchical scheduler */
> > /**< User defined tags. See
> > rte_distributor_process() */
> > uint32_t usr;
>
> We should also add trivial inline functions to read/write these mbuf fields as
> part of this header file. We want to discourage people from accessing these
> fields directly.
>
> Besides the functions to read/write each field individually, we should also
> have a function to read all the sched fields in one operation, as well as another
> one to write all the sched fields in one operation.
Will create inline functions for reading and writing each field separately and jointly.
>
> > diff --git a/lib/librte_pipeline/rte_table_action.c
> > b/lib/librte_pipeline/rte_table_action.c
> > index 7c7c8dd82..99f2d779b 100644
> > --- a/lib/librte_pipeline/rte_table_action.c
> > +++ b/lib/librte_pipeline/rte_table_action.c
> > @@ -108,12 +108,12 @@ mtr_cfg_check(struct rte_table_action_mtr_config
> > *mtr)
> > }
> >
> > #define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
> > - ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
> > - ((((uint64_t)(tc)) & 0x3) << 2) | \
> > - ((((uint64_t)(color)) & 0x3) << 4)))
> > + ((uint64_t)((((uint64_t)(queue)) & 0xffffffff) | \
> > + ((((uint64_t)(tc)) & 0xff) << 32) | \
> > + ((((uint64_t)(color)) & 0xff) << 40)))
> >
> > #define MBUF_SCHED_COLOR(sched, color) \
> > - (((sched) & (~0x30LLU)) | ((color) << 4))
> > + ((uint64_t)((sched) & (~0xff000000LLU)) | (((uint64_t)(color)) <<
> > +40))
> >
>
> Given the read/write mbuf->sched field functions, the above two macros are
> no longer needed.
Will remove this.
> > struct mtr_trtcm_data {
> > struct rte_meter_trtcm trtcm;
> > @@ -176,7 +176,7 @@ mtr_data_size(struct rte_table_action_mtr_config
> > *mtr)
> > struct dscp_table_entry_data {
> > enum rte_meter_color color;
> > uint16_t tc;
> > - uint16_t queue_tc_color;
> > + uint32_t queue;
> > };
> >
> > struct dscp_table_data {
> > @@ -368,7 +368,6 @@ tm_cfg_check(struct rte_table_action_tm_config
> > *tm)
> > }
> >
> > struct tm_data {
> > - uint16_t queue_tc_color;
> > uint16_t subport;
> > uint32_t pipe;
> > } __attribute__((__packed__));
> > @@ -397,26 +396,40 @@ tm_apply(struct tm_data *data,
> > return status;
> >
> > /* Apply */
> > - data->queue_tc_color = 0;
> > data->subport = (uint16_t) p->subport_id;
> > data->pipe = p->pipe_id;
> >
> > return 0;
> > }
> >
> > +static uint32_t
> > +tm_sched_qindex(struct tm_data *data,
> > + struct dscp_table_entry_data *dscp,
> > + struct rte_table_action_tm_config *cfg) {
> > +
> > + uint32_t result;
> > +
> > + result = data->subport * cfg->n_pipes_per_subport + data->pipe;
>
> Since n_subports_per_pipe and n_pipes_per_subport are enforced to be
> power of 2, we should replace multiplication/division with shift left/right. We
> probably need to store log2 correspondents in the action context.
Thanks. Will store log2 component in action context and use them in run time for shift operations.
> > + result = result * RTE_TABLE_ACTION_TC_MAX + dscp->tc;
> > + result = result * RTE_TABLE_ACTION_TC_QUEUE_MAX + dscp-
> > >queue;
> > +
> > + return result;
> > +}
> > +
> > static __rte_always_inline void
> > pkt_work_tm(struct rte_mbuf *mbuf,
> > struct tm_data *data,
> > struct dscp_table_data *dscp_table,
> > - uint32_t dscp)
> > + uint32_t dscp,
> > + struct rte_table_action_tm_config *cfg)
> > {
> > struct dscp_table_entry_data *dscp_entry = &dscp_table-
> > >entry[dscp];
> > - struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
> > - struct tm_data sched;
> > + uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
> > + uint32_t queue = tm_sched_qindex(data, dscp_entry, cfg);
> >
> > - sched = *data;
> > - sched.queue_tc_color = dscp_entry->queue_tc_color;
> > - *sched_ptr = sched;
> > + *sched_ptr = MBUF_SCHED_QUEUE_TC_COLOR(queue,
> > + dscp_entry->tc,
> > + dscp_entry->color);
> > }
> >
> > /**
> > @@ -2580,17 +2593,13 @@ rte_table_action_dscp_table_update(struct
> > rte_table_action *action,
> > &action->dscp_table.entry[i];
> > struct rte_table_action_dscp_table_entry *entry =
> > &table->entry[i];
> > - uint16_t queue_tc_color =
> > - MBUF_SCHED_QUEUE_TC_COLOR(entry-
> > >tc_queue_id,
> > - entry->tc_id,
> > - entry->color);
> >
> > if ((dscp_mask & (1LLU << i)) == 0)
> > continue;
> >
> > data->color = entry->color;
> > data->tc = entry->tc_id;
> > - data->queue_tc_color = queue_tc_color;
> > + data->queue = entry->tc_queue_id;
> > }
> >
> > return 0;
> > @@ -2882,7 +2891,8 @@ pkt_work(struct rte_mbuf *mbuf,
> > pkt_work_tm(mbuf,
> > data,
> > &action->dscp_table,
> > - dscp);
> > + dscp,
> > + &cfg->tm);
> > }
> >
> > if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) { @@
> > -3108,22 +3118,26 @@ pkt4_work(struct rte_mbuf **mbufs,
> > pkt_work_tm(mbuf0,
> > data0,
> > &action->dscp_table,
> > - dscp0);
> > + dscp0,
> > + &cfg->tm);
> >
> > pkt_work_tm(mbuf1,
> > data1,
> > &action->dscp_table,
> > - dscp1);
> > + dscp1,
> > + &cfg->tm);
> >
> > pkt_work_tm(mbuf2,
> > data2,
> > &action->dscp_table,
> > - dscp2);
> > + dscp2,
> > + &cfg->tm);
> >
> > pkt_work_tm(mbuf3,
> > data3,
> > &action->dscp_table,
> > - dscp3);
> > + dscp3,
> > + &cfg->tm);
> > }
> >
> > if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) { diff
> > --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile index
> > 46c53ed71..644fd9d15 100644
> > --- a/lib/librte_sched/Makefile
> > +++ b/lib/librte_sched/Makefile
> > @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer
> >
> > EXPORT_MAP := rte_sched_version.map
> >
> > -LIBABIVER := 1
> > +LIBABIVER := 2
> >
> > #
> > # all source are stored in SRCS-y
> > diff --git a/lib/librte_sched/rte_sched.c
> > b/lib/librte_sched/rte_sched.c index 587d5e602..7bf4d6400 100644
> > --- a/lib/librte_sched/rte_sched.c
> > +++ b/lib/librte_sched/rte_sched.c
> > @@ -128,22 +128,6 @@ enum grinder_state {
> > e_GRINDER_READ_MBUF
> > };
> >
> > -/*
> > - * Path through the scheduler hierarchy used by the scheduler enqueue
> > - * operation to identify the destination queue for the current
> > - * packet. Stored in the field pkt.hash.sched of struct rte_mbuf of
> > - * each packet, typically written by the classification stage and
> > read
> > - * by scheduler enqueue.
> > - */
> > -struct rte_sched_port_hierarchy {
> > - uint16_t queue:2; /**< Queue ID (0 .. 3) */
> > - uint16_t traffic_class:2; /**< Traffic class ID (0 .. 3)*/
> > - uint32_t color:2; /**< Color */
> > - uint16_t unused:10;
> > - uint16_t subport; /**< Subport ID */
> > - uint32_t pipe; /**< Pipe ID */
> > -};
> > -
> > struct rte_sched_grinder {
> > /* Pipe cache */
> > uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
> > @@ -241,16 +225,12 @@ enum rte_sched_port_array {
> > e_RTE_SCHED_PORT_ARRAY_TOTAL,
> > };
> >
> > -#ifdef RTE_SCHED_COLLECT_STATS
> > -
> > static inline uint32_t
> > rte_sched_port_queues_per_subport(struct rte_sched_port *port) {
> > return RTE_SCHED_QUEUES_PER_PIPE * port-
> > >n_pipes_per_subport;
> > }
> >
> > -#endif
> > -
> > static inline uint32_t
> > rte_sched_port_queues_per_port(struct rte_sched_port *port) { @@
> > -1006,44 +986,50 @@ rte_sched_port_pipe_profile_add(struct
> > rte_sched_port *port,
> > return 0;
> > }
> >
> > +static inline uint32_t
> > +rte_sched_port_qindex(struct rte_sched_port *port,
> > + uint32_t subport,
> > + uint32_t pipe,
> > + uint32_t traffic_class,
> > + uint32_t queue)
> > +{
> > + uint32_t result;
> > +
> > + result = subport * port->n_pipes_per_subport + pipe;
>
> Since n_subports_per_pipe and n_pipes_per_subport are enforced to be
> power of 2, we should replace multiplication/division with shift left/right.
Will replace with shift operation using log2 of n_subports_per_pipe and n_pipes_per_subport.
> > + result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE +
> > traffic_class;
> > + result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
> > +
> > + return result;
> > +}
> > +
> > void
> > -rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> > +rte_sched_port_pkt_write(struct rte_sched_port *port,
> > + struct rte_mbuf *pkt,
> > uint32_t subport, uint32_t pipe, uint32_t traffic_class,
> > uint32_t queue, enum rte_meter_color color) {
> > - struct rte_sched_port_hierarchy *sched
> > - = (struct rte_sched_port_hierarchy *) &pkt->hash.sched;
> > -
> > - RTE_BUILD_BUG_ON(sizeof(*sched) > sizeof(pkt->hash.sched));
> > -
> > - sched->color = (uint32_t) color;
> > - sched->subport = subport;
> > - sched->pipe = pipe;
> > - sched->traffic_class = traffic_class;
> > - sched->queue = queue;
> > + pkt->hash.sched.traffic_class = traffic_class;
> > + pkt->hash.sched.queue_id = rte_sched_port_qindex(port, subport,
> > pipe,
> > + traffic_class, queue);
> > + pkt->hash.sched.color = (uint8_t) color;
> > }
> >
> > void
> > -rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
> > +rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
> > + const struct rte_mbuf *pkt,
> > uint32_t *subport, uint32_t *pipe,
> > uint32_t *traffic_class, uint32_t *queue) {
> > - const struct rte_sched_port_hierarchy *sched
> > - = (const struct rte_sched_port_hierarchy *) &pkt-
> > >hash.sched;
> > -
> > - *subport = sched->subport;
> > - *pipe = sched->pipe;
> > - *traffic_class = sched->traffic_class;
> > - *queue = sched->queue;
> > + *subport = pkt->hash.sched.queue_id /
> > rte_sched_port_queues_per_subport(port);
> > + *pipe = pkt->hash.sched.queue_id /
> > RTE_SCHED_QUEUES_PER_PIPE;
>
> Since n_subports_per_pipe and n_pipes_per_subport are enforced to be
> power of 2, we should replace multiplication/division with shift left/right.
Will do that.
> > + *traffic_class = pkt->hash.sched.traffic_class;
> > + *queue = pkt->hash.sched.queue_id %
> > RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS;
>
> Since RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS is enforced to be a power of
> 2, please replace modulo with bitwise AND of
> (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1).
>
> > }
Will do that.
> > enum rte_meter_color
> > rte_sched_port_pkt_read_color(const struct rte_mbuf *pkt) {
> > - const struct rte_sched_port_hierarchy *sched
> > - = (const struct rte_sched_port_hierarchy *) &pkt-
> > >hash.sched;
> > -
> > - return (enum rte_meter_color) sched->color;
> > + return (enum rte_meter_color) pkt->hash.sched.color;
> > }
>
> Should use the mbuf->sched.color read function to be added in rte_mbuf.h.
Yes. Will change this.
> > int
> > @@ -1100,18 +1086,6 @@ rte_sched_queue_read_stats(struct
> > rte_sched_port *port,
> > return 0;
> > }
> >
> > -static inline uint32_t
> > -rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport,
> > uint32_t pipe, uint32_t traffic_class, uint32_t queue) -{
> > - uint32_t result;
> > -
> > - result = subport * port->n_pipes_per_subport + pipe;
> > - result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE +
> > traffic_class;
> > - result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
> > -
> > - return result;
> > -
>
> Since n_subports_per_pipe and n_pipes_per_subport are enforced to be
> power of 2, we should replace multiplication/division with shift left/right.
Will change this as well.
> }
> > -
> > #ifdef RTE_SCHED_DEBUG
> >
> > static inline int
> > @@ -1272,11 +1246,8 @@ rte_sched_port_enqueue_qptrs_prefetch0(struct
> > rte_sched_port *port,
> > #ifdef RTE_SCHED_COLLECT_STATS
> > struct rte_sched_queue_extra *qe;
> > #endif
> > - uint32_t subport, pipe, traffic_class, queue, qindex;
> > -
> > - rte_sched_port_pkt_read_tree_path(pkt, &subport, &pipe,
> > &traffic_class, &queue);
> > + uint32_t qindex = pkt->hash.sched.queue_id;
>
> Let's use the read function for this mbuf field.
Yes.
> >
> > - qindex = rte_sched_port_qindex(port, subport, pipe, traffic_class,
> > queue);
> > q = port->queue + qindex;
> > rte_prefetch0(q);
> > #ifdef RTE_SCHED_COLLECT_STATS
> > diff --git a/lib/librte_sched/rte_sched.h
> > b/lib/librte_sched/rte_sched.h index 84fa896de..4d9f869eb 100644
> > --- a/lib/librte_sched/rte_sched.h
> > +++ b/lib/librte_sched/rte_sched.h
> > @@ -355,6 +355,8 @@ rte_sched_queue_read_stats(struct rte_sched_port
> > *port,
> > * Scheduler hierarchy path write to packet descriptor. Typically
> > * called by the packet classification stage.
> > *
> > + * @param port
> > + * Handle to port scheduler instance
> > * @param pkt
> > * Packet descriptor handle
> > * @param subport
> > @@ -369,7 +371,8 @@ rte_sched_queue_read_stats(struct rte_sched_port
> > *port,
> > * Packet color set
> > */
> > void
> > -rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> > +rte_sched_port_pkt_write(struct rte_sched_port *port,
> > + struct rte_mbuf *pkt,
> > uint32_t subport, uint32_t pipe, uint32_t traffic_class,
> > uint32_t queue, enum rte_meter_color color);
> >
> > @@ -379,6 +382,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> > * enqueue operation. The subport, pipe, traffic class and queue
> > * parameters need to be pre-allocated by the caller.
> > *
> > + * @param port
> > + * Handle to port scheduler instance
> > * @param pkt
> > * Packet descriptor handle
> > * @param subport
> > @@ -392,7 +397,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> > *
> > */
> > void
> > -rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
> > +rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
> > + const struct rte_mbuf *pkt,
> > uint32_t *subport, uint32_t *pipe,
> > uint32_t *traffic_class, uint32_t *queue);
> >
>
> <snip>
>
> Regards,
> Cristian
We will work on the suggested changes and send another version. Thank you, Cristian.
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [RFC PATCH] kvargs: add match count inside processing
@ 2018-11-30 0:39 2% Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-11-30 0:39 UTC (permalink / raw)
To: olivier.matz, ferruh.yigit; +Cc: dev
After processing a kvlist in rte_kvargs_process(),
it may be needed to loop again over kvlist, in order to know
whether the key is matched or not, as done with rte_kvargs_count().
In order to simplify implementation of kvargs checks,
a new pointer parameter is added to get the match count from
the function rte_kvargs_process().
This count could have been returned as a positive value of the function,
but it would change also the meaning of "return 0".
It looks simpler to keep return code as 0 or negative,
and add a dedicated output parameter for counting purpose.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
This RFC is not complete: the calls to rte_kvargs_process()
in the drivers must be updated with the new parameter,
and simplified if rte_kvargs_count() is used.
---
app/pdump/main.c | 20 ++++-----
doc/guides/rel_notes/deprecation.rst | 3 --
doc/guides/rel_notes/release_19_02.rst | 5 ++-
drivers/baseband/null/bbdev_null.c | 6 ++-
.../baseband/turbo_sw/bbdev_turbo_software.c | 6 ++-
drivers/bus/ifpga/ifpga_bus.c | 44 +++++++++----------
drivers/bus/pci/pci_params.c | 1 +
drivers/bus/vdev/vdev_params.c | 2 +-
lib/librte_compressdev/rte_compressdev_pmd.c | 4 +-
lib/librte_cryptodev/rte_cryptodev_pmd.c | 6 +--
lib/librte_ethdev/rte_class_eth.c | 20 +++------
lib/librte_kvargs/Makefile | 2 +-
lib/librte_kvargs/meson.build | 2 +-
lib/librte_kvargs/rte_kvargs.c | 18 ++++++--
lib/librte_kvargs/rte_kvargs.h | 14 +++---
test/test/test_kvargs.c | 31 +++++++++++--
16 files changed, 107 insertions(+), 77 deletions(-)
diff --git a/app/pdump/main.c b/app/pdump/main.c
index 9e86bf623..255ff61fe 100644
--- a/app/pdump/main.c
+++ b/app/pdump/main.c
@@ -262,14 +262,14 @@ parse_pdump(const char *optarg)
} else if (cnt1 == 1) {
v.min = 0;
v.max = RTE_MAX_ETHPORTS-1;
- ret = rte_kvargs_process(kvlist, PDUMP_PORT_ARG,
+ ret = rte_kvargs_process(kvlist, PDUMP_PORT_ARG, NULL,
&parse_uint_value, &v);
if (ret < 0)
goto free_kvlist;
pt->port = (uint16_t) v.val;
pt->dump_by_type = PORT_ID;
} else if (cnt2 == 1) {
- ret = rte_kvargs_process(kvlist, PDUMP_PCI_ARG,
+ ret = rte_kvargs_process(kvlist, PDUMP_PCI_ARG, NULL,
&parse_device_id, pt);
if (ret < 0)
goto free_kvlist;
@@ -282,7 +282,7 @@ parse_pdump(const char *optarg)
ret = -1;
goto free_kvlist;
}
- ret = rte_kvargs_process(kvlist, PDUMP_QUEUE_ARG, &parse_queue, pt);
+ ret = rte_kvargs_process(kvlist, PDUMP_QUEUE_ARG, NULL, &parse_queue, pt);
if (ret < 0)
goto free_kvlist;
@@ -295,11 +295,11 @@ parse_pdump(const char *optarg)
ret = -1;
goto free_kvlist;
} else if (cnt1 == 1 && cnt2 == 1) {
- ret = rte_kvargs_process(kvlist, PDUMP_RX_DEV_ARG,
+ ret = rte_kvargs_process(kvlist, PDUMP_RX_DEV_ARG, NULL,
&parse_rxtxdev, pt);
if (ret < 0)
goto free_kvlist;
- ret = rte_kvargs_process(kvlist, PDUMP_TX_DEV_ARG,
+ ret = rte_kvargs_process(kvlist, PDUMP_TX_DEV_ARG, NULL,
&parse_rxtxdev, pt);
if (ret < 0)
goto free_kvlist;
@@ -308,13 +308,13 @@ parse_pdump(const char *optarg)
pt->single_pdump_dev = true;
pt->dir = RTE_PDUMP_FLAG_RXTX;
} else if (cnt1 == 1) {
- ret = rte_kvargs_process(kvlist, PDUMP_RX_DEV_ARG,
+ ret = rte_kvargs_process(kvlist, PDUMP_RX_DEV_ARG, NULL,
&parse_rxtxdev, pt);
if (ret < 0)
goto free_kvlist;
pt->dir = RTE_PDUMP_FLAG_RX;
} else if (cnt2 == 1) {
- ret = rte_kvargs_process(kvlist, PDUMP_TX_DEV_ARG,
+ ret = rte_kvargs_process(kvlist, PDUMP_TX_DEV_ARG, NULL,
&parse_rxtxdev, pt);
if (ret < 0)
goto free_kvlist;
@@ -327,7 +327,7 @@ parse_pdump(const char *optarg)
if (cnt1 == 1) {
v.min = 2;
v.max = RTE_RING_SZ_MASK-1;
- ret = rte_kvargs_process(kvlist, PDUMP_RING_SIZE_ARG,
+ ret = rte_kvargs_process(kvlist, PDUMP_RING_SIZE_ARG, NULL,
&parse_uint_value, &v);
if (ret < 0)
goto free_kvlist;
@@ -340,7 +340,7 @@ parse_pdump(const char *optarg)
if (cnt1 == 1) {
v.min = 1;
v.max = UINT16_MAX;
- ret = rte_kvargs_process(kvlist, PDUMP_MSIZE_ARG,
+ ret = rte_kvargs_process(kvlist, PDUMP_MSIZE_ARG, NULL,
&parse_uint_value, &v);
if (ret < 0)
goto free_kvlist;
@@ -353,7 +353,7 @@ parse_pdump(const char *optarg)
if (cnt1 == 1) {
v.min = 1025;
v.max = UINT16_MAX;
- ret = rte_kvargs_process(kvlist, PDUMP_NUM_MBUFS_ARG,
+ ret = rte_kvargs_process(kvlist, PDUMP_NUM_MBUFS_ARG, NULL,
&parse_uint_value, &v);
if (ret < 0)
goto free_kvlist;
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b48486d36..4ff96c5ec 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -17,9 +17,6 @@ Deprecation Notices
Long Term Stable (LTS) version which is 3.16, but compatibility for
recent distribution kernels will be kept.
-* kvargs: The function ``rte_kvargs_process`` will get a new parameter
- for returning key match count. It will ease handling of no-match case.
-
* eal: function ``rte_bsf64`` in ``rte_bitmap.h`` has been renamed to
``rte_bsf64_safe`` and moved to ``rte_common.h``. A new ``rte_bsf64`` function
will be added in the next release in ``rte_common.h`` that follows convention
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index a94fa86a7..c5dfff5f8 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -83,6 +83,9 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+kvargs: A parameter is added to ``rte_kvargs_process()`` in order to get
+the match count in one pass (without calling ``rte_kvargs_count()``).
+
ABI Changes
-----------
@@ -143,7 +146,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_ip_frag.so.1
librte_jobstats.so.1
librte_kni.so.2
- librte_kvargs.so.1
+ + librte_kvargs.so.2
librte_latencystats.so.1
librte_lpm.so.2
librte_mbuf.so.4
diff --git a/drivers/baseband/null/bbdev_null.c b/drivers/baseband/null/bbdev_null.c
index 2f2515101..eeae9962d 100644
--- a/drivers/baseband/null/bbdev_null.c
+++ b/drivers/baseband/null/bbdev_null.c
@@ -228,12 +228,14 @@ parse_bbdev_null_params(struct bbdev_null_params *params,
if (kvlist == NULL)
return -EFAULT;
- ret = rte_kvargs_process(kvlist, bbdev_null_valid_params[0],
+ ret = rte_kvargs_process(kvlist,
+ bbdev_null_valid_params[0], NULL,
&parse_u16_arg, ¶ms->queues_num);
if (ret < 0)
goto exit;
- ret = rte_kvargs_process(kvlist, bbdev_null_valid_params[1],
+ ret = rte_kvargs_process(kvlist,
+ bbdev_null_valid_params[1], NULL,
&parse_u16_arg, ¶ms->socket_id);
if (ret < 0)
goto exit;
diff --git a/drivers/baseband/turbo_sw/bbdev_turbo_software.c b/drivers/baseband/turbo_sw/bbdev_turbo_software.c
index 8ceb2769f..9cc01d164 100644
--- a/drivers/baseband/turbo_sw/bbdev_turbo_software.c
+++ b/drivers/baseband/turbo_sw/bbdev_turbo_software.c
@@ -1179,12 +1179,14 @@ parse_turbo_sw_params(struct turbo_sw_params *params, const char *input_args)
if (kvlist == NULL)
return -EFAULT;
- ret = rte_kvargs_process(kvlist, turbo_sw_valid_params[0],
+ ret = rte_kvargs_process(kvlist,
+ turbo_sw_valid_params[0], NULL,
&parse_u16_arg, ¶ms->queues_num);
if (ret < 0)
goto exit;
- ret = rte_kvargs_process(kvlist, turbo_sw_valid_params[1],
+ ret = rte_kvargs_process(kvlist,
+ turbo_sw_valid_params[1], NULL,
&parse_u16_arg, ¶ms->socket_id);
if (ret < 0)
goto exit;
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 5f23ed8b4..05ff9771f 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -94,6 +94,7 @@ ifpga_scan_one(struct rte_rawdev *rawdev,
struct rte_kvargs *kvlist = NULL;
struct rte_afu_device *afu_dev = NULL;
struct rte_afu_pr_conf afu_pr_conf;
+ unsigned int key_count;
int ret = 0;
char *path = NULL;
@@ -105,27 +106,24 @@ ifpga_scan_one(struct rte_rawdev *rawdev,
goto end;
}
- if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) {
- if (rte_kvargs_process(kvlist, IFPGA_ARG_PORT,
- &rte_ifpga_get_integer32_arg, &afu_pr_conf.afu_id.port) < 0) {
- IFPGA_BUS_ERR("error to parse %s",
- IFPGA_ARG_PORT);
- goto end;
- }
- } else {
+ if (rte_kvargs_process(kvlist, IFPGA_ARG_PORT, &key_count,
+ &rte_ifpga_get_integer32_arg,
+ &afu_pr_conf.afu_id.port) < 0) {
+ IFPGA_BUS_ERR("error to parse %s", IFPGA_ARG_PORT);
+ goto end;
+ }
+ if (key_count == 0) {
IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus",
IFPGA_ARG_PORT);
goto end;
}
- if (rte_kvargs_count(kvlist, IFPGA_AFU_BTS) == 1) {
- if (rte_kvargs_process(kvlist, IFPGA_AFU_BTS,
- &rte_ifpga_get_string_arg, &path) < 0) {
- IFPGA_BUS_ERR("Failed to parse %s",
- IFPGA_AFU_BTS);
- goto end;
- }
- } else {
+ if (rte_kvargs_process(kvlist, IFPGA_AFU_BTS, &key_count,
+ &rte_ifpga_get_string_arg, &path) < 0) {
+ IFPGA_BUS_ERR("Failed to parse %s", IFPGA_AFU_BTS);
+ goto end;
+ }
+ if (key_count == 0) {
IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus",
IFPGA_AFU_BTS);
goto end;
@@ -195,6 +193,7 @@ ifpga_scan(void)
struct rte_devargs *devargs;
struct rte_kvargs *kvlist = NULL;
struct rte_rawdev *rawdev = NULL;
+ unsigned int key_count;
char *name = NULL;
char name1[RTE_RAWDEV_NAME_MAX_LEN];
struct rte_afu_device *afu_dev = NULL;
@@ -210,14 +209,11 @@ ifpga_scan(void)
goto end;
}
- if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
- if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
- &rte_ifpga_get_string_arg, &name) < 0) {
- IFPGA_BUS_ERR("error to parse %s",
- IFPGA_ARG_NAME);
- goto end;
- }
- } else {
+ if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME, &key_count,
+ &rte_ifpga_get_string_arg, &name) < 0) {
+ IFPGA_BUS_ERR("error to parse %s", IFPGA_ARG_NAME);
+ goto end;
+ if (key_count == 0) {
IFPGA_BUS_ERR("arg %s is mandatory for ifpga bus",
IFPGA_ARG_NAME);
goto end;
diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c
index 3192e9c96..215ffef70 100644
--- a/drivers/bus/pci/pci_params.c
+++ b/drivers/bus/pci/pci_params.c
@@ -48,6 +48,7 @@ pci_dev_match(const struct rte_device *dev,
pdev = RTE_DEV_TO_PCI_CONST(dev);
/* if any field does not match. */
if (rte_kvargs_process(kvlist, pci_params_keys[RTE_PCI_PARAM_ADDR],
+ NULL,
&pci_addr_kv_cmp,
(void *)(intptr_t)&pdev->addr))
return 1;
diff --git a/drivers/bus/vdev/vdev_params.c b/drivers/bus/vdev/vdev_params.c
index 6f74704d1..9c00ed44f 100644
--- a/drivers/bus/vdev/vdev_params.c
+++ b/drivers/bus/vdev/vdev_params.c
@@ -35,7 +35,7 @@ vdev_dev_match(const struct rte_device *dev,
if (name == NULL)
return -1;
ret = rte_kvargs_process(kvlist,
- vdev_params_keys[RTE_VDEV_PARAM_NAME],
+ vdev_params_keys[RTE_VDEV_PARAM_NAME], NULL,
rte_kvargs_strcmp, name);
free(name);
if (ret != 0)
diff --git a/lib/librte_compressdev/rte_compressdev_pmd.c b/lib/librte_compressdev/rte_compressdev_pmd.c
index 95beb26ab..43e79fcbc 100644
--- a/lib/librte_compressdev/rte_compressdev_pmd.c
+++ b/lib/librte_compressdev/rte_compressdev_pmd.c
@@ -64,14 +64,14 @@ rte_compressdev_pmd_parse_input_args(
return -EINVAL;
ret = rte_kvargs_process(kvlist,
- RTE_COMPRESSDEV_PMD_SOCKET_ID_ARG,
+ RTE_COMPRESSDEV_PMD_SOCKET_ID_ARG, NULL,
&rte_compressdev_pmd_parse_uint_arg,
¶ms->socket_id);
if (ret < 0)
goto free_kvlist;
ret = rte_kvargs_process(kvlist,
- RTE_COMPRESSDEV_PMD_NAME_ARG,
+ RTE_COMPRESSDEV_PMD_NAME_ARG, NULL,
&rte_compressdev_pmd_parse_name_arg,
params);
if (ret < 0)
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index f03bdbd5e..04b064346 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -59,21 +59,21 @@ rte_cryptodev_pmd_parse_input_args(
return -EINVAL;
ret = rte_kvargs_process(kvlist,
- RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG,
+ RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG, NULL,
&rte_cryptodev_pmd_parse_uint_arg,
¶ms->max_nb_queue_pairs);
if (ret < 0)
goto free_kvlist;
ret = rte_kvargs_process(kvlist,
- RTE_CRYPTODEV_PMD_SOCKET_ID_ARG,
+ RTE_CRYPTODEV_PMD_SOCKET_ID_ARG, NULL,
&rte_cryptodev_pmd_parse_uint_arg,
¶ms->socket_id);
if (ret < 0)
goto free_kvlist;
ret = rte_kvargs_process(kvlist,
- RTE_CRYPTODEV_PMD_NAME_ARG,
+ RTE_CRYPTODEV_PMD_NAME_ARG, NULL,
&rte_cryptodev_pmd_parse_name_arg,
params);
if (ret < 0)
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index cb99c92ec..bf6a5f2cf 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -106,7 +106,7 @@ eth_dev_match(const struct rte_eth_dev *edev,
int ret;
const struct eth_dev_match_arg *arg = _arg;
const struct rte_kvargs *kvlist = arg->kvlist;
- unsigned int pair;
+ unsigned int match_count;
if (edev->state == RTE_ETH_DEV_UNUSED)
return -1;
@@ -114,27 +114,19 @@ eth_dev_match(const struct rte_eth_dev *edev,
return -1;
ret = rte_kvargs_process(kvlist,
- eth_params_keys[RTE_ETH_PARAM_MAC],
+ eth_params_keys[RTE_ETH_PARAM_MAC], NULL,
eth_mac_cmp, edev->data);
if (ret != 0)
return -1;
ret = rte_kvargs_process(kvlist,
- eth_params_keys[RTE_ETH_PARAM_REPRESENTOR],
+ eth_params_keys[RTE_ETH_PARAM_REPRESENTOR], &match_count,
eth_representor_cmp, edev->data);
if (ret != 0)
return -1;
- /* search for representor key */
- for (pair = 0; pair < kvlist->count; pair++) {
- ret = strcmp(kvlist->pairs[pair].key,
- eth_params_keys[RTE_ETH_PARAM_REPRESENTOR]);
- if (ret == 0)
- break; /* there is a representor key */
- }
- /* if no representor key, default is to not match representor ports */
- if (ret != 0)
- if ((edev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0)
- return -1; /* do not match any representor */
+ if (match_count == 0 /* if no representor key */ &&
+ (edev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0)
+ return -1; /* do not match any representor */
return 0;
}
diff --git a/lib/librte_kvargs/Makefile b/lib/librte_kvargs/Makefile
index 875939547..11f013739 100644
--- a/lib/librte_kvargs/Makefile
+++ b/lib/librte_kvargs/Makefile
@@ -11,7 +11,7 @@ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
EXPORT_MAP := rte_kvargs_version.map
-LIBABIVER := 1
+LIBABIVER := 2
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) := rte_kvargs.c
diff --git a/lib/librte_kvargs/meson.build b/lib/librte_kvargs/meson.build
index acd3e5432..a00d198ed 100644
--- a/lib/librte_kvargs/meson.build
+++ b/lib/librte_kvargs/meson.build
@@ -4,7 +4,7 @@
includes = [global_inc]
includes += include_directories('../librte_eal/common/include')
-version = 1
+version = 2
sources = files('rte_kvargs.c')
headers = files('rte_kvargs.h')
diff --git a/lib/librte_kvargs/rte_kvargs.c b/lib/librte_kvargs/rte_kvargs.c
index f7030c63b..02c7ec1a8 100644
--- a/lib/librte_kvargs/rte_kvargs.c
+++ b/lib/librte_kvargs/rte_kvargs.c
@@ -128,20 +128,30 @@ rte_kvargs_count(const struct rte_kvargs *kvlist, const char *key_match)
int
rte_kvargs_process(const struct rte_kvargs *kvlist,
const char *key_match,
- arg_handler_t handler,
- void *opaque_arg)
+ unsigned int *match_count,
+ arg_handler_t match_handler,
+ void *opaque)
{
+ int ret;
const struct rte_kvargs_pair *pair;
unsigned i;
+ if (match_count != NULL)
+ *match_count = 0;
+
if (kvlist == NULL)
return 0;
for (i = 0; i < kvlist->count; i++) {
pair = &kvlist->pairs[i];
if (key_match == NULL || strcmp(pair->key, key_match) == 0) {
- if ((*handler)(pair->key, pair->value, opaque_arg) < 0)
- return -1;
+ if (match_count != NULL)
+ (*match_count)++;
+ if (match_handler == NULL)
+ continue;
+ ret = (*match_handler)(pair->key, pair->value, opaque);
+ if (ret < 0)
+ return ret;
}
}
return 0;
diff --git a/lib/librte_kvargs/rte_kvargs.h b/lib/librte_kvargs/rte_kvargs.h
index 1946195de..e9f47ae65 100644
--- a/lib/librte_kvargs/rte_kvargs.h
+++ b/lib/librte_kvargs/rte_kvargs.h
@@ -118,17 +118,18 @@ void rte_kvargs_free(struct rte_kvargs *kvlist);
* Call a handler function for each key/value matching the key
*
* For each key/value association that matches the given key, calls the
- * handler function with the for a given arg_name passing the value on the
- * dictionary for that key and a given extra argument.
+ * handler function and count the matches.
*
* @param kvlist
* The rte_kvargs structure. No error if NULL.
* @param key_match
* The key on which the handler should be called, or NULL to process handler
* on all associations
- * @param handler
- * The function to call for each matching key
- * @param opaque_arg
+ * @param match_count
+ * The number of times the key matches in kvlist (can be NULL).
+ * @param match_handler
+ * The function to call for each matching key (can be NULL).
+ * @param opaque
* A pointer passed unchanged to the handler
*
* @return
@@ -136,7 +137,8 @@ void rte_kvargs_free(struct rte_kvargs *kvlist);
* - Negative on error
*/
int rte_kvargs_process(const struct rte_kvargs *kvlist,
- const char *key_match, arg_handler_t handler, void *opaque_arg);
+ const char *key_match, unsigned int *match_count,
+ arg_handler_t match_handler, void *opaque);
/**
* Count the number of associations matching the given key
diff --git a/test/test/test_kvargs.c b/test/test/test_kvargs.c
index a42056f36..648f40e8e 100644
--- a/test/test/test_kvargs.c
+++ b/test/test/test_kvargs.c
@@ -42,6 +42,7 @@ static int test_valid_kvargs(void)
const char *args;
const char *valid_keys_list[] = { "foo", "check", NULL };
const char **valid_keys;
+ unsigned int match_count;
/* empty args is valid */
args = "";
@@ -63,11 +64,19 @@ static int test_valid_kvargs(void)
}
/* call check_handler() for all entries with key="check" */
count = 0;
- if (rte_kvargs_process(kvlist, "check", check_handler, NULL) < 0) {
+ if (rte_kvargs_process(kvlist, "check", &match_count,
+ check_handler, NULL) < 0) {
printf("rte_kvargs_process() error\n");
rte_kvargs_free(kvlist);
goto fail;
}
+ if (match_count != 2) {
+ printf("invalid match_count value %d"
+ " after rte_kvargs_process(check)\n",
+ count);
+ rte_kvargs_free(kvlist);
+ goto fail;
+ }
if (count != 2) {
printf("invalid count value %d after rte_kvargs_process(check)\n",
count);
@@ -76,11 +85,19 @@ static int test_valid_kvargs(void)
}
count = 0;
/* call check_handler() for all entries with key="unexistant_key" */
- if (rte_kvargs_process(kvlist, "unexistant_key", check_handler, NULL) < 0) {
+ if (rte_kvargs_process(kvlist, "unexistant_key", &match_count,
+ check_handler, NULL) < 0) {
printf("rte_kvargs_process() error\n");
rte_kvargs_free(kvlist);
goto fail;
}
+ if (match_count != 0) {
+ printf("invalid match_count value %d"
+ " after rte_kvargs_process(unexistant_key)\n",
+ count);
+ rte_kvargs_free(kvlist);
+ goto fail;
+ }
if (count != 0) {
printf("invalid count value %d after rte_kvargs_process(unexistant_key)\n",
count);
@@ -123,11 +140,19 @@ static int test_valid_kvargs(void)
}
/* call check_handler() on all entries with key="check", it
* should fail as the value is not recognized by the handler */
- if (rte_kvargs_process(kvlist, "check", check_handler, NULL) == 0) {
+ if (rte_kvargs_process(kvlist, "check", &match_count,
+ check_handler, NULL) == 0) {
printf("rte_kvargs_process() is success bu should not\n");
rte_kvargs_free(kvlist);
goto fail;
}
+ if (match_count != 3) {
+ printf("invalid match_count value %d"
+ " after rte_kvargs_process(check)\n",
+ count);
+ rte_kvargs_free(kvlist);
+ goto fail;
+ }
count = rte_kvargs_count(kvlist, "check");
if (count != 3) {
printf("invalid count value %d after rte_kvargs_count(check)\n",
--
2.19.0
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v2 0/9] ipsec: new library for IPsec data-path processing
@ 2018-11-30 16:45 2% ` Konstantin Ananyev
0 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2018-11-30 16:45 UTC (permalink / raw)
To: dev; +Cc: Konstantin Ananyev
This patch series depends on the patch:
http://patches.dpdk.org/patch/48044/
to be applied first.
v1 -> v2
- Changes to get into account l2_len for outbound transport packets
(Qi comments)
- Several bug fixes
- Some code restructured
- Update MAINTAINERS file
RFCv2 -> v1
- Changes per Jerin comments
- Implement transport mode
- Several bug fixes
- UT largely reworked and extended
This patch introduces a new library within DPDK: librte_ipsec.
The aim is to provide DPDK native high performance library for IPsec
data-path processing.
The library is supposed to utilize existing DPDK crypto-dev and
security API to provide application with transparent IPsec processing
API.
The library is concentrated on data-path protocols processing (ESP and
AH),
IKE protocol(s) implementation is out of scope for that library.
Current patch introduces SA-level API.
SA (low) level API
==================
API described below operates on SA level.
It provides functionality that allows user for given SA to process
inbound and outbound IPsec packets.
To be more specific:
- for inbound ESP/AH packets perform decryption, authentication,
integrity checking, remove ESP/AH related headers
- for outbound packets perform payload encryption, attach ICV,
update/add IP headers, add ESP/AH headers/trailers,
setup related mbuf felids (ol_flags, tx_offloads, etc.).
- initialize/un-initialize given SA based on user provided parameters.
The following functionality:
- match inbound/outbound packets to particular SA
- manage crypto/security devices
- provide SAD/SPD related functionality
- determine what crypto/security device has to be used
for given packet(s)
is out of scope for SA-level API.
SA-level API is based on top of crypto-dev/security API and relies on
them
to perform actual cipher and integrity checking.
To have an ability to easily map crypto/security sessions into related
IPSec SA opaque userdata field was added into
rte_cryptodev_sym_session and rte_security_session structures.
That implies ABI change for both librte_crytpodev and librte_security.
Due to the nature of crypto-dev API (enqueue/deque model) we use
asynchronous API for IPsec packets destined to be processed
by crypto-device.
Expected API call sequence would be:
/* enqueue for processing by crypto-device */
rte_ipsec_pkt_crypto_prepare(...);
rte_cryptodev_enqueue_burst(...);
/* dequeue from crypto-device and do final processing (if any) */
rte_cryptodev_dequeue_burst(...);
rte_ipsec_pkt_crypto_group(...); /* optional */
rte_ipsec_pkt_process(...);
Though for packets destined for inline processing no extra overhead
is required and synchronous API call: rte_ipsec_pkt_process()
is sufficient for that case.
Current implementation supports all four currently defined rte_security
types.
Though to accommodate future custom implementations function pointers
model is used for both for *crypto_prepare* and *process*
impelementations.
TODO list
---------
- update docs
Konstantin Ananyev (9):
cryptodev: add opaque userdata pointer into crypto sym session
security: add opaque userdata pointer into security session
net: add ESP trailer structure definition
lib: introduce ipsec library
ipsec: add SA data-path API
ipsec: implement SA data-path API
ipsec: rework SA replay window/SQN for MT environment
ipsec: helper functions to group completed crypto-ops
test/ipsec: introduce functional test
MAINTAINERS | 5 +
config/common_base | 5 +
lib/Makefile | 2 +
lib/librte_cryptodev/rte_cryptodev.h | 2 +
lib/librte_ipsec/Makefile | 27 +
lib/librte_ipsec/crypto.h | 123 ++
lib/librte_ipsec/iph.h | 84 +
lib/librte_ipsec/ipsec_sqn.h | 343 ++++
lib/librte_ipsec/meson.build | 10 +
lib/librte_ipsec/pad.h | 45 +
lib/librte_ipsec/rte_ipsec.h | 156 ++
lib/librte_ipsec/rte_ipsec_group.h | 151 ++
lib/librte_ipsec/rte_ipsec_sa.h | 166 ++
lib/librte_ipsec/rte_ipsec_version.map | 15 +
lib/librte_ipsec/sa.c | 1381 +++++++++++++++
lib/librte_ipsec/sa.h | 98 ++
lib/librte_ipsec/ses.c | 45 +
lib/librte_net/rte_esp.h | 10 +-
lib/librte_security/rte_security.h | 2 +
lib/meson.build | 2 +
mk/rte.app.mk | 2 +
test/test/Makefile | 3 +
test/test/meson.build | 3 +
test/test/test_ipsec.c | 2209 ++++++++++++++++++++++++
24 files changed, 4888 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_ipsec/Makefile
create mode 100644 lib/librte_ipsec/crypto.h
create mode 100644 lib/librte_ipsec/iph.h
create mode 100644 lib/librte_ipsec/ipsec_sqn.h
create mode 100644 lib/librte_ipsec/meson.build
create mode 100644 lib/librte_ipsec/pad.h
create mode 100644 lib/librte_ipsec/rte_ipsec.h
create mode 100644 lib/librte_ipsec/rte_ipsec_group.h
create mode 100644 lib/librte_ipsec/rte_ipsec_sa.h
create mode 100644 lib/librte_ipsec/rte_ipsec_version.map
create mode 100644 lib/librte_ipsec/sa.c
create mode 100644 lib/librte_ipsec/sa.h
create mode 100644 lib/librte_ipsec/ses.c
create mode 100644 test/test/test_ipsec.c
--
2.17.1
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH v2 1/2] version: 19.02-rc0
2018-11-28 14:52 9% ` [dpdk-dev] [PATCH v2 1/2] " Thomas Monjalon
2018-11-28 14:52 18% ` [dpdk-dev] [PATCH v2 2/2] doc: improve release notes template Thomas Monjalon
@ 2018-11-30 17:01 0% ` Ferruh Yigit
1 sibling, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-11-30 17:01 UTC (permalink / raw)
To: Thomas Monjalon, dev; +Cc: john.mcnamara, marko.kovacevic
On 11/28/2018 2:52 PM, Thomas Monjalon wrote:
> Start version numbering for a new release cycle,
> and introduce a template file for release notes.
>
> The release notes comments are updated to mandate
> a scope label for API and ABI changes.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> Acked-by: John McNamara <john.mcnamara@intel.com>
Series applied, thanks.
(meson.build typo (missing ',' at the end) fixed while applying)
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] pdump: remove deprecated APIs
@ 2018-12-03 2:58 6% ` Tiwei Bie
2018-12-13 17:15 0% ` Pattan, Reshma
0 siblings, 1 reply; 200+ results
From: Tiwei Bie @ 2018-12-03 2:58 UTC (permalink / raw)
To: dev; +Cc: reshma.pattan, john.mcnamara, marko.kovacevic
We already changed to use generic IPC in pdump since below commit:
commit 660098d61f57 ("pdump: use generic multi-process channel")
The `rte_pdump_set_socket_dir()`, the `path` parameter of
`rte_pdump_init()` and the `enum rte_pdump_socktype` have been
deprecated since then. This commit removes these deprecated
APIs and also bumps the pdump ABI.
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
changes:
- update release notes;
- minor updates in pdump_lib.rst;
app/test-pmd/testpmd.c | 2 +-
doc/guides/prog_guide/pdump_lib.rst | 18 ++++--------------
doc/guides/rel_notes/deprecation.rst | 7 -------
doc/guides/rel_notes/release_19_02.rst | 6 +++++-
lib/librte_pdump/Makefile | 2 +-
lib/librte_pdump/meson.build | 2 +-
lib/librte_pdump/rte_pdump.c | 9 +--------
lib/librte_pdump/rte_pdump.h | 34 +---------------------------------
lib/librte_pdump/rte_pdump_version.map | 1 -
9 files changed, 14 insertions(+), 67 deletions(-)
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 4c75587d0..a10bc40bb 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -3104,7 +3104,7 @@ main(int argc, char** argv)
#ifdef RTE_LIBRTE_PDUMP
/* initialize packet capture framework */
- rte_pdump_init(NULL);
+ rte_pdump_init();
#endif
count = 0;
diff --git a/doc/guides/prog_guide/pdump_lib.rst b/doc/guides/prog_guide/pdump_lib.rst
index ed3c15e58..2a0f1f397 100644
--- a/doc/guides/prog_guide/pdump_lib.rst
+++ b/doc/guides/prog_guide/pdump_lib.rst
@@ -34,10 +34,6 @@ or disable the packet capture, and to uninitialize it:
* ``rte_pdump_uninit()``:
This API uninitializes the packet capture framework.
-* ``rte_pdump_set_socket_dir()``:
- This API sets the server and client socket paths.
- Note: This API is not thread-safe.
-
Operation
---------
@@ -60,8 +56,8 @@ enabling or disabling the packet capture.
Implementation Details
----------------------
-The library API ``rte_pdump_init()``, initializes the packet capture framework by creating the pthread and the server
-socket. The server socket in the pthread context will be listening to the client requests to enable or disable the
+The library API ``rte_pdump_init()``, initializes the packet capture framework by creating the pdump server by calling
+``rte_mp_action_register()`` function. The server will listen to the client requests to enable or disable the
packet capture.
The library APIs ``rte_pdump_enable()`` and ``rte_pdump_enable_by_deviceid()`` enables the packet capture.
@@ -79,14 +75,8 @@ capture by removing the Ethernet RX and TX callbacks for the given port or devic
also sends the response back to the client about the status of the request that was processed. After the response is
received from the server, the client socket is closed.
-The library API ``rte_pdump_uninit()``, uninitializes the packet capture framework by closing the pthread and the
-server socket.
-
-The library API ``rte_pdump_set_socket_dir()``, sets the given path as either server socket path
-or client socket path based on the ``type`` argument of the API.
-If the given path is ``NULL``, default path will be selected, i.e. either ``/var/run/.dpdk`` for root user or ``~/.dpdk``
-for non root user. Clients also need to call this API to set their server socket path if the server socket
-path is different from default path.
+The library API ``rte_pdump_uninit()``, uninitializes the packet capture framework by calling ``rte_mp_action_unregister()``
+function.
Use Case: Packet Capturing
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b48486d36..ac7fb29a7 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -98,10 +98,3 @@ Deprecation Notices
- The size and layout of ``rte_cryptodev_qp_conf`` and syntax of
``rte_cryptodev_queue_pair_setup`` will change to to allow to use
two different mempools for crypto and device private sessions.
-
-* pdump: As we changed to use generic IPC, some changes in APIs and structure
- are expected in subsequent release.
-
- - ``rte_pdump_set_socket_dir`` will be removed;
- - The parameter, ``path``, of ``rte_pdump_init`` will be removed;
- - The enum ``rte_pdump_socktype`` will be removed.
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index a94fa86a7..4710fb7b8 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -83,6 +83,10 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* pdump: The ``rte_pdump_set_socket_dir()``, the parameter ``path`` of
+ ``rte_pdump_init()`` and enum ``rte_pdump_socktype`` were deprecated
+ since 18.05 and are removed in this release.
+
ABI Changes
-----------
@@ -153,7 +157,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_metrics.so.1
librte_net.so.1
librte_pci.so.1
- librte_pdump.so.2
+ + librte_pdump.so.3
librte_pipeline.so.3
librte_pmd_bnxt.so.2
librte_pmd_bond.so.2
diff --git a/lib/librte_pdump/Makefile b/lib/librte_pdump/Makefile
index b241151dc..89593689a 100644
--- a/lib/librte_pdump/Makefile
+++ b/lib/librte_pdump/Makefile
@@ -12,7 +12,7 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev
EXPORT_MAP := rte_pdump_version.map
-LIBABIVER := 2
+LIBABIVER := 3
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_PDUMP) := rte_pdump.c
diff --git a/lib/librte_pdump/meson.build b/lib/librte_pdump/meson.build
index be80904b9..b4b4f26c5 100644
--- a/lib/librte_pdump/meson.build
+++ b/lib/librte_pdump/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 2
+version = 3
sources = files('rte_pdump.c')
headers = files('rte_pdump.h')
allow_experimental_apis = true
diff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c
index 6c3a88581..4f38ac58b 100644
--- a/lib/librte_pdump/rte_pdump.c
+++ b/lib/librte_pdump/rte_pdump.c
@@ -406,7 +406,7 @@ pdump_server(const struct rte_mp_msg *mp_msg, const void *peer)
}
int
-rte_pdump_init(const char *path __rte_unused)
+rte_pdump_init(void)
{
return rte_mp_action_register(PDUMP_MP, pdump_server);
}
@@ -616,10 +616,3 @@ rte_pdump_disable_by_deviceid(char *device_id, uint16_t queue,
return ret;
}
-
-int
-rte_pdump_set_socket_dir(const char *path __rte_unused,
- enum rte_pdump_socktype type __rte_unused)
-{
- return 0;
-}
diff --git a/lib/librte_pdump/rte_pdump.h b/lib/librte_pdump/rte_pdump.h
index 673a2b070..6b00fc17a 100644
--- a/lib/librte_pdump/rte_pdump.h
+++ b/lib/librte_pdump/rte_pdump.h
@@ -29,25 +29,16 @@ enum {
RTE_PDUMP_FLAG_RXTX = (RTE_PDUMP_FLAG_RX|RTE_PDUMP_FLAG_TX)
};
-enum rte_pdump_socktype {
- RTE_PDUMP_SOCKET_SERVER = 1,
- RTE_PDUMP_SOCKET_CLIENT = 2
-};
-
/**
* Initialize packet capturing handling
*
* Register the IPC action for communication with target (primary) process.
*
- * @param path
- * This parameter is going to be deprecated; it was used for specifying the
- * directory path for server socket.
- *
* @return
* 0 on success, -1 on error
*/
int
-rte_pdump_init(const char *path);
+rte_pdump_init(void);
/**
* Un initialize packet capturing handling
@@ -162,29 +153,6 @@ int
rte_pdump_disable_by_deviceid(char *device_id, uint16_t queue,
uint32_t flags);
-/**
- * @deprecated
- * Allows applications to set server and client socket paths.
- * If specified path is null default path will be selected, i.e.
- *"/var/run/" for root user and "$HOME" for non root user.
- * Clients also need to call this API to set their server path if the
- * server path is different from default path.
- * This API is not thread-safe.
- *
- * @param path
- * directory path for server or client socket.
- * @param type
- * specifies RTE_PDUMP_SOCKET_SERVER if socket path is for server.
- * (or)
- * specifies RTE_PDUMP_SOCKET_CLIENT if socket path is for client.
- *
- * @return
- * 0 on success, -EINVAL on error
- *
- */
-__rte_deprecated int
-rte_pdump_set_socket_dir(const char *path, enum rte_pdump_socktype type);
-
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_pdump/rte_pdump_version.map b/lib/librte_pdump/rte_pdump_version.map
index edec99a41..3e744f301 100644
--- a/lib/librte_pdump/rte_pdump_version.map
+++ b/lib/librte_pdump/rte_pdump_version.map
@@ -6,7 +6,6 @@ DPDK_16.07 {
rte_pdump_enable;
rte_pdump_enable_by_deviceid;
rte_pdump_init;
- rte_pdump_set_socket_dir;
rte_pdump_uninit;
local: *;
--
2.14.5
^ permalink raw reply [relevance 6%]
* [dpdk-dev] [PATCH 18.11] malloc: fix deadlock when using malloc stats
@ 2018-12-04 12:22 4% Anatoly Burakov
2018-12-21 12:09 0% ` Thomas Monjalon
2018-12-21 12:26 4% ` [dpdk-dev] [PATCH 19.02 v2] " Anatoly Burakov
0 siblings, 2 replies; 200+ results
From: Anatoly Burakov @ 2018-12-04 12:22 UTC (permalink / raw)
To: dev; +Cc: thomas, stable
Currently, malloc statistics and external heap creation code
use memory hotplug lock as a way to synchronize accesses to
heaps (as in, locking the hotplug lock to prevent list of heaps
from changing under our feet). At the same time, malloc
statistics code will also lock the heap because it needs to
access heap data and does not want any other thread to allocate
anything from that heap.
In such scheme, it is possible to enter a deadlock with the
following sequence of events:
thread 1 thread 2
rte_malloc()
rte_malloc_dump_stats()
take heap lock
take hotplug lock
failed to allocate,
attempt to take
hotplug lock
attempt to take heap lock
Neither thread will be able to continue, as both of them are
waiting for the other one to drop the lock. Adding an
additional lock will require an ABI change, so instead of
that, make malloc statistics calls thread-unsafe with
respect to creating/destroying heaps.
Fixes: 72cf92b31855 ("malloc: index heaps using heap ID rather than NUMA node")
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
IMO this is the best we can do for 18.11 without breaking ABI.
For 19.02, we can introduce a new global heap lock (something
i should've done in the first place...), so this patch is
not applicable to 19.02. For 19.02, we can fix this properly
by introducing another lock and breaking the EAL ABI.
Not sure where to put docs update, feedback welcome.
lib/librte_eal/common/include/rte_malloc.h | 9 +++++++++
lib/librte_eal/common/rte_malloc.c | 19 +++----------------
2 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/lib/librte_eal/common/include/rte_malloc.h b/lib/librte_eal/common/include/rte_malloc.h
index 7249e6aae..cde6232f9 100644
--- a/lib/librte_eal/common/include/rte_malloc.h
+++ b/lib/librte_eal/common/include/rte_malloc.h
@@ -251,6 +251,9 @@ rte_malloc_validate(const void *ptr, size_t *size);
/**
* Get heap statistics for the specified heap.
*
+ * @note This function is not thread-safe with respect to
+ * ``rte_malloc_heap_create()``/``rte_malloc_heap_destroy()`` functions.
+ *
* @param socket
* An unsigned integer specifying the socket to get heap statistics for
* @param socket_stats
@@ -461,6 +464,9 @@ rte_malloc_heap_socket_is_external(int socket_id);
* Dump for the specified type to a file. If the type argument is
* NULL, all memory types will be dumped.
*
+ * @note This function is not thread-safe with respect to
+ * ``rte_malloc_heap_create()``/``rte_malloc_heap_destroy()`` functions.
+ *
* @param f
* A pointer to a file for output
* @param type
@@ -473,6 +479,9 @@ rte_malloc_dump_stats(FILE *f, const char *type);
/**
* Dump contents of all malloc heaps to a file.
*
+ * @note This function is not thread-safe with respect to
+ * ``rte_malloc_heap_create()``/``rte_malloc_heap_destroy()`` functions.
+ *
* @param f
* A pointer to a file for output
*/
diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c
index 0da5ad5e8..bc2b74d19 100644
--- a/lib/librte_eal/common/rte_malloc.c
+++ b/lib/librte_eal/common/rte_malloc.c
@@ -156,20 +156,14 @@ rte_malloc_get_socket_stats(int socket,
struct rte_malloc_socket_stats *socket_stats)
{
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
- int heap_idx, ret = -1;
-
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
+ int heap_idx;
heap_idx = malloc_socket_to_heap_id(socket);
if (heap_idx < 0)
- goto unlock;
+ return -1;
- ret = malloc_heap_get_stats(&mcfg->malloc_heaps[heap_idx],
+ return malloc_heap_get_stats(&mcfg->malloc_heaps[heap_idx],
socket_stats);
-unlock:
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
-
- return ret;
}
/*
@@ -181,14 +175,10 @@ rte_malloc_dump_heaps(FILE *f)
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
unsigned int idx;
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
-
for (idx = 0; idx < RTE_MAX_HEAPS; idx++) {
fprintf(f, "Heap id: %u\n", idx);
malloc_heap_dump(&mcfg->malloc_heaps[idx], f);
}
-
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
}
int
@@ -262,8 +252,6 @@ rte_malloc_dump_stats(FILE *f, __rte_unused const char *type)
unsigned int heap_id;
struct rte_malloc_socket_stats sock_stats;
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
-
/* Iterate through all initialised heaps */
for (heap_id = 0; heap_id < RTE_MAX_HEAPS; heap_id++) {
struct malloc_heap *heap = &mcfg->malloc_heaps[heap_id];
@@ -280,7 +268,6 @@ rte_malloc_dump_stats(FILE *f, __rte_unused const char *type)
fprintf(f, "\tAlloc_count:%u,\n",sock_stats.alloc_count);
fprintf(f, "\tFree_count:%u,\n", sock_stats.free_count);
}
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
return;
}
--
2.17.1
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] Marking symbols as experimental in the headers only
@ 2018-12-04 15:14 4% ` Neil Horman
2018-12-04 20:48 0% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2018-12-04 15:14 UTC (permalink / raw)
To: David Marchand; +Cc: dev, Timothy Redaelli, ferruh.yigit, adrien.mazarguil
On Tue, Dec 04, 2018 at 09:21:43AM +0100, David Marchand wrote:
> On Mon, Dec 3, 2018 at 5:48 PM Neil Horman <nhorman@tuxdriver.com> wrote:
>
> > On Mon, Dec 03, 2018 at 02:01:02PM +0100, David Marchand wrote:
> > > Hello Neil,
> > >
> > > Looking at
> > >
> > http://doc.dpdk.org/guides/contributing/versioning.html#experimental-apis,
> > > is there a real need to mark both the definition and the declaration of a
> > > symbol with the __rte_experimental marker ?
> > >
> > When I initially wrote the feature I marked both the function prototype
> > and its
> > definition with the macro to be consistent, as I like to make both
> > declaration
> > and definition look visually simmilar, just to ease readability, but I'm
> > not
> > bound to doing it that way per-se
> >
> > As to weather or not you can only mark the declaration as experimental,
> > I'm not
> > 100% sure. I think thats an artifact of the compiler. That is to say, the
> > macro expands to a compiler attribute that is applied at compile time, and
> > checked at link time, and I'm not sure what clang or gcc will do if there
> > is a
> > discrepancy between the attributes listed in the declaration and the
> > definition.
> >
> > I would say, give it a try, and if you can demonstrate that adding the
> > attribute
> > only to the declaration results in a link-time warning when external code
> > attempts to call an experimental function, I would have no problem
> > handling it
> > that way.
> >
>
> Did not experiment yet, putting this in my todolist.
> Just, I can see that lib/librte_pipeline/ at least only marks the
> declarations.
>
I just tried it. If I turn off ALLOW_EXPERIMENTAL_APIS, the ip_pipeline example
breaks with warnings about deprecated functions:
/home/nhorman/git/dpdk/examples/ip_pipeline/action.c:60:4: error: ‘rte_table_hash_crc_key8’ is deprecated: Symbol is not yet part of stable ABI [-Werror=deprecated-declarations]
params->lb.f_hash = rte_table_hash_crc_key8;
^~~~~~
In file included from /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:10:
/home/nhorman/git/dpdk/x86_64-native-linuxapp-gcc/include/rte_table_hash_func.h:56:1: note: declared here
rte_table_hash_crc_key8(void *key, void *mask, __rte_unused uint32_t key_size,
^~~~~~~~~~~~~~~~~~~~~~~
/home/nhorman/git/dpdk/examples/ip_pipeline/action.c:64:4: error: ‘rte_table_hash_crc_key16’ is deprecated: Symbol is not yet part of stable ABI [-Werror=deprecated-declarations]
params->lb.f_hash = rte_table_hash_crc_key16;
^~~~~~
...
That is sufficient for me to conclude that __rte_experimental only needs to be
set on the declaration, not the definiton as well.
If you would like to make this adjustment, I'm fine with it, though be aware,
you will likely need to make some adjustments to the check-experimental-syms
script to account for this
Neil
>
> --
> David Marchand
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [RFC] malloc: fix deadlock when using malloc stats
@ 2018-12-04 15:57 2% Anatoly Burakov
0 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-12-04 15:57 UTC (permalink / raw)
To: dev; +Cc: thomas, ferruh.yigit
Currently, malloc statistics and external heap creation code
use memory hotplug lock as a way to synchronize accesses to
heaps (as in, locking the hotplug lock to prevent list of heaps
from changing under our feet). At the same time, malloc
statistics code will also lock the heap because it needs to
access heap data and does not want any other thread to allocate
anything from that heap.
In such scheme, it is possible to enter a deadlock with the
following sequence of events:
thread 1 thread 2
rte_malloc()
rte_malloc_dump_stats()
take heap lock
take hotplug lock
attempt to take
hotplug lock
attempt to take heap lock
Neither thread will be able to continue, as both of them are
waiting for the other one to drop the lock. This can be
fixed by adding an additional lock protecting the heap list.
In addition, to prevent further issues, we must clearly
define what each lock is for, and how to use them. As is
explained in the code comments, there are now three locks:
- Heap list lock
- This lock guards the changes to heap list. We need it
because when we allocate, we might attempt to allocate
from more than one heap, and we also have functions that
can create or destroy heaps. We need heap list to be
consistent for the duration of allocation attempt.
- Heap lock
- This lock protects data inside a specific heap.
- Memseg list lock
- Also known as memory hotplug lock. This lock protects
access to our internal page tables - only one thread
at a time is allowed to make changes to the page
table (be it from dynamic allocation or from creating
additional page tables for external heaps).
For any given operation, not all of these locks may be
necessary, but when they are taken out, they are to be
taken out in the exact order specified above - heap list
lock first, then heap lock, then memseg list lock.
Fixes: 72cf92b31855 ("malloc: index heaps using heap ID rather than NUMA node")
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
This breaks EAL ABI, hence submitting as RFC as it may not be
possible to include this in 19.02.
.../common/include/rte_eal_memconfig.h | 33 +++++++++++-
lib/librte_eal/common/malloc_heap.c | 38 +++++++++----
lib/librte_eal/common/rte_malloc.c | 54 +++++++++++--------
3 files changed, 92 insertions(+), 33 deletions(-)
diff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h
index 84aabe36c..da3310da2 100644
--- a/lib/librte_eal/common/include/rte_eal_memconfig.h
+++ b/lib/librte_eal/common/include/rte_eal_memconfig.h
@@ -41,7 +41,35 @@ struct rte_memseg_list {
/**
* the structure for the memory configuration for the RTE.
* Used by the rte_config structure. It is separated out, as for multi-process
- * support, the memory details should be shared across instances
+ * support, the memory details should be shared across instances.
+ *
+ * For the memory subsystem, there are three locks that will be in use
+ * throughout the memory code: heap list lock, heap lock, and memseg list lock
+ * (aka memory hotplug lock).
+ *
+ * Each of these locks may not always be necessary, but any time they are used,
+ * they must *always* be taken out in the above specified order. The purpose of
+ * each lock is as follows:
+ *
+ * Heap list lock protects changes to list of malloc heaps and prevents changes
+ * in number and/or contents of ``malloc_heaps`` array of structures. For
+ * example, if we're allocating memory, we need to know to which heap a given
+ * socket ID belongs to, and we might need this information multiple times (in
+ * case of SOCKET_ID_ANY), so the heap list must stay as is untill we finish our
+ * allocation. By convention, this lock also protects the ``next_socket_id``
+ * value, and so must also be taken out any time this value is accessed (even if
+ * no changes to heap list are to be expected).
+ *
+ * Individual heap lock is part of ``malloc_heap`` structure, and protects
+ * contents of each individual heap. That is, multiple above described
+ * allocations may take place concurrently, but only one of them can happen from
+ * a given heap.
+ *
+ * Memseg list lock (aka memory hotplug lock) protects the internal page table
+ * stored in the ``memsegs`` array of structures. Any time internal page tables
+ * are to be accessed (such as allocating more memory from the system,
+ * registering a new external heap, or even simply reading the memory map), this
+ * lock must be taken out to manage concurrent accesses to page tables.
*/
struct rte_mem_config {
volatile uint32_t magic; /**< Magic number - Sanity check. */
@@ -72,6 +100,9 @@ struct rte_mem_config {
struct rte_tailq_head tailq_head[RTE_MAX_TAILQ]; /**< Tailqs for objects */
+ rte_rwlock_t heap_list_lock;
+ /**< indicates whether list of heaps is locked */
+
/* Heaps of Malloc */
struct malloc_heap malloc_heaps[RTE_MAX_HEAPS];
diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c
index c6a6d4f6b..0d2fc4025 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -690,6 +690,7 @@ void *
malloc_heap_alloc(const char *type, size_t size, int socket_arg,
unsigned int flags, size_t align, size_t bound, bool contig)
{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
int socket, heap_id, i;
void *ret;
@@ -705,16 +706,21 @@ malloc_heap_alloc(const char *type, size_t size, int socket_arg,
else
socket = socket_arg;
+ /* do not allow any alterations to heaps while we're allocating */
+ rte_rwlock_read_lock(&mcfg->heap_list_lock);
+
/* turn socket ID into heap ID */
heap_id = malloc_socket_to_heap_id(socket);
/* if heap id is negative, socket ID was invalid */
- if (heap_id < 0)
- return NULL;
+ if (heap_id < 0) {
+ ret = NULL;
+ goto unlock;
+ }
ret = malloc_heap_alloc_on_heap_id(type, size, heap_id, flags, align,
bound, contig);
if (ret != NULL || socket_arg != SOCKET_ID_ANY)
- return ret;
+ goto unlock;
/* try other heaps. we are only iterating through native DPDK sockets,
* so external heaps won't be included.
@@ -725,9 +731,12 @@ malloc_heap_alloc(const char *type, size_t size, int socket_arg,
ret = malloc_heap_alloc_on_heap_id(type, size, i, flags, align,
bound, contig);
if (ret != NULL)
- return ret;
+ goto unlock;
}
- return NULL;
+unlock:
+ rte_rwlock_read_unlock(&mcfg->heap_list_lock);
+
+ return ret;
}
static void *
@@ -753,6 +762,7 @@ void *
malloc_heap_alloc_biggest(const char *type, int socket_arg, unsigned int flags,
size_t align, bool contig)
{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
int socket, i, cur_socket, heap_id;
void *ret;
@@ -768,16 +778,21 @@ malloc_heap_alloc_biggest(const char *type, int socket_arg, unsigned int flags,
else
socket = socket_arg;
+ /* do not allow any alterations to heaps while we're allocating */
+ rte_rwlock_read_lock(&mcfg->heap_list_lock);
+
/* turn socket ID into heap ID */
heap_id = malloc_socket_to_heap_id(socket);
/* if heap id is negative, socket ID was invalid */
- if (heap_id < 0)
- return NULL;
+ if (heap_id < 0) {
+ ret = NULL;
+ goto unlock;
+ }
ret = heap_alloc_biggest_on_heap_id(type, heap_id, flags, align,
contig);
if (ret != NULL || socket_arg != SOCKET_ID_ANY)
- return ret;
+ goto unlock;
/* try other heaps */
for (i = 0; i < (int) rte_socket_count(); i++) {
@@ -787,9 +802,12 @@ malloc_heap_alloc_biggest(const char *type, int socket_arg, unsigned int flags,
ret = heap_alloc_biggest_on_heap_id(type, i, flags, align,
contig);
if (ret != NULL)
- return ret;
+ goto unlock;
}
- return NULL;
+unlock:
+ rte_rwlock_read_unlock(&mcfg->heap_list_lock);
+
+ return ret;
}
/* this function is exposed in malloc_mp.h */
diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c
index 0da5ad5e8..8010341b6 100644
--- a/lib/librte_eal/common/rte_malloc.c
+++ b/lib/librte_eal/common/rte_malloc.c
@@ -158,7 +158,7 @@ rte_malloc_get_socket_stats(int socket,
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
int heap_idx, ret = -1;
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_lock(&mcfg->heap_list_lock);
heap_idx = malloc_socket_to_heap_id(socket);
if (heap_idx < 0)
@@ -167,7 +167,7 @@ rte_malloc_get_socket_stats(int socket,
ret = malloc_heap_get_stats(&mcfg->malloc_heaps[heap_idx],
socket_stats);
unlock:
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_unlock(&mcfg->heap_list_lock);
return ret;
}
@@ -181,14 +181,14 @@ rte_malloc_dump_heaps(FILE *f)
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
unsigned int idx;
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_lock(&mcfg->heap_list_lock);
for (idx = 0; idx < RTE_MAX_HEAPS; idx++) {
fprintf(f, "Heap id: %u\n", idx);
malloc_heap_dump(&mcfg->malloc_heaps[idx], f);
}
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_unlock(&mcfg->heap_list_lock);
}
int
@@ -206,7 +206,7 @@ rte_malloc_heap_get_socket(const char *name)
rte_errno = EINVAL;
return -1;
}
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_lock(&mcfg->heap_list_lock);
for (idx = 0; idx < RTE_MAX_HEAPS; idx++) {
struct malloc_heap *tmp = &mcfg->malloc_heaps[idx];
@@ -222,7 +222,7 @@ rte_malloc_heap_get_socket(const char *name)
rte_errno = ENOENT;
ret = -1;
}
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_unlock(&mcfg->heap_list_lock);
return ret;
}
@@ -237,7 +237,7 @@ rte_malloc_heap_socket_is_external(int socket_id)
if (socket_id == SOCKET_ID_ANY)
return 0;
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_lock(&mcfg->heap_list_lock);
for (idx = 0; idx < RTE_MAX_HEAPS; idx++) {
struct malloc_heap *tmp = &mcfg->malloc_heaps[idx];
@@ -247,7 +247,7 @@ rte_malloc_heap_socket_is_external(int socket_id)
break;
}
}
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_unlock(&mcfg->heap_list_lock);
return ret;
}
@@ -262,7 +262,7 @@ rte_malloc_dump_stats(FILE *f, __rte_unused const char *type)
unsigned int heap_id;
struct rte_malloc_socket_stats sock_stats;
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_lock(&mcfg->heap_list_lock);
/* Iterate through all initialised heaps */
for (heap_id = 0; heap_id < RTE_MAX_HEAPS; heap_id++) {
@@ -280,7 +280,7 @@ rte_malloc_dump_stats(FILE *f, __rte_unused const char *type)
fprintf(f, "\tAlloc_count:%u,\n",sock_stats.alloc_count);
fprintf(f, "\tFree_count:%u,\n", sock_stats.free_count);
}
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_unlock(&mcfg->heap_list_lock);
return;
}
@@ -351,7 +351,7 @@ rte_malloc_heap_memory_add(const char *heap_name, void *va_addr, size_t len,
rte_errno = EINVAL;
return -1;
}
- rte_rwlock_write_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_write_lock(&mcfg->heap_list_lock);
/* find our heap */
heap = find_named_heap(heap_name);
@@ -373,13 +373,18 @@ rte_malloc_heap_memory_add(const char *heap_name, void *va_addr, size_t len,
goto unlock;
}
+ /* see rte_eal_memconfig.h for details on locking */
rte_spinlock_lock(&heap->lock);
+ rte_rwlock_write_lock(&mcfg->memory_hotplug_lock);
+
ret = malloc_heap_add_external_memory(heap, va_addr, iova_addrs, n,
page_sz);
+
+ rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);
rte_spinlock_unlock(&heap->lock);
unlock:
- rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_write_unlock(&mcfg->heap_list_lock);
return ret;
}
@@ -398,7 +403,7 @@ rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len)
rte_errno = EINVAL;
return -1;
}
- rte_rwlock_write_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_write_lock(&mcfg->heap_list_lock);
/* find our heap */
heap = find_named_heap(heap_name);
if (heap == NULL) {
@@ -413,12 +418,17 @@ rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len)
goto unlock;
}
+ /* see rte_eal_memconfig.h for details on locking */
rte_spinlock_lock(&heap->lock);
+ rte_rwlock_write_lock(&mcfg->memory_hotplug_lock);
+
ret = malloc_heap_remove_external_memory(heap, va_addr, len);
+
+ rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);
rte_spinlock_unlock(&heap->lock);
unlock:
- rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_write_unlock(&mcfg->heap_list_lock);
return ret;
}
@@ -489,7 +499,7 @@ sync_memory(const char *heap_name, void *va_addr, size_t len, bool attach)
rte_errno = EINVAL;
return -1;
}
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_lock(&mcfg->heap_list_lock);
/* find our heap */
heap = find_named_heap(heap_name);
@@ -511,8 +521,8 @@ sync_memory(const char *heap_name, void *va_addr, size_t len, bool attach)
wa.result = -ENOENT; /* fail unless explicitly told to succeed */
wa.attach = attach;
- /* we're already holding a read lock */
- rte_memseg_list_walk_thread_unsafe(sync_mem_walk, &wa);
+ /* we don't need the per-heap lock here */
+ rte_memseg_list_walk(sync_mem_walk, &wa);
if (wa.result < 0) {
rte_errno = -wa.result;
@@ -525,7 +535,7 @@ sync_memory(const char *heap_name, void *va_addr, size_t len, bool attach)
ret = 0;
}
unlock:
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_read_unlock(&mcfg->heap_list_lock);
return ret;
}
@@ -558,7 +568,7 @@ rte_malloc_heap_create(const char *heap_name)
/* check if there is space in the heap list, or if heap with this name
* already exists.
*/
- rte_rwlock_write_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_write_lock(&mcfg->heap_list_lock);
for (i = 0; i < RTE_MAX_HEAPS; i++) {
struct malloc_heap *tmp = &mcfg->malloc_heaps[i];
@@ -587,7 +597,7 @@ rte_malloc_heap_create(const char *heap_name)
/* we're sure that we can create a new heap, so do it */
ret = malloc_heap_create(heap, heap_name);
unlock:
- rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_write_unlock(&mcfg->heap_list_lock);
return ret;
}
@@ -606,7 +616,7 @@ rte_malloc_heap_destroy(const char *heap_name)
rte_errno = EINVAL;
return -1;
}
- rte_rwlock_write_lock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_write_lock(&mcfg->heap_list_lock);
/* start from non-socket heaps */
heap = find_named_heap(heap_name);
@@ -630,7 +640,7 @@ rte_malloc_heap_destroy(const char *heap_name)
if (ret < 0)
rte_spinlock_unlock(&heap->lock);
unlock:
- rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);
+ rte_rwlock_write_unlock(&mcfg->heap_list_lock);
return ret;
}
--
2.17.1
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH] mbuf: implement generic format for sched field
2018-11-29 10:42 3% ` Singh, Jasvinder
@ 2018-12-04 17:39 0% ` Dumitrescu, Cristian
2018-12-05 12:22 0% ` Singh, Jasvinder
0 siblings, 1 reply; 200+ results
From: Dumitrescu, Cristian @ 2018-12-04 17:39 UTC (permalink / raw)
To: Singh, Jasvinder, dev; +Cc: Pattan, Reshma
> >
> > > + uint8_t color; /**< Color. */
> >
> > We should create a new file rte_color.h in a common place
> > (librte_eal/common/include) to consolidate the color definition, which is
> > currently replicated in too many places, such as: rte_meter.h, rte_mtr.h,
> > rte_tm.h.
> >
> > We should include the rte_color.h file here (and in the above header files)
> >
> > We should also document the link between this field and the color enum
> type
> > (@see ...).
>
> Replacing the existing color definition with the above suggested one in
> rte_meter.h (librte_meter)
> would be ABI break. We can do it separately through different patch.
>
> >
We can avoid any such issues in a two step process:
1. Create aliases to the new color in rte_meter.h, rte_mtr.h and rte_tm.h at this point.
2. Announce deprecation of the existing color enums in favor of the new unified color enum at this point and remove during next release.
Example:
//file "rte_meter.h"
#include <rte_color.h>
#define rte_meter_color rte_color
#define RTE_METER_GREEN RTE_COLOR_GREEN
#define RTE_METER_YELLOW RTE_COLOR_YELLOW
#define RTE_METER_RED RTE_COLOR_RED
Makes sense?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] Marking symbols as experimental in the headers only
2018-12-04 15:14 4% ` Neil Horman
@ 2018-12-04 20:48 0% ` David Marchand
2018-12-04 21:34 0% ` Richardson, Bruce
2018-12-05 12:21 0% ` Neil Horman
0 siblings, 2 replies; 200+ results
From: David Marchand @ 2018-12-04 20:48 UTC (permalink / raw)
To: nhorman, ferruh.yigit; +Cc: dev, Timothy Redaelli, adrien.mazarguil
On Tue, Dec 4, 2018 at 4:16 PM Neil Horman <nhorman@tuxdriver.com> wrote:
> On Tue, Dec 04, 2018 at 09:21:43AM +0100, David Marchand wrote:
> > On Mon, Dec 3, 2018 at 5:48 PM Neil Horman <nhorman@tuxdriver.com>
> wrote:
> > > On Mon, Dec 03, 2018 at 02:01:02PM +0100, David Marchand wrote:
> > > I would say, give it a try, and if you can demonstrate that adding the
> > > attribute
> > > only to the declaration results in a link-time warning when external
> code
> > > attempts to call an experimental function, I would have no problem
> > > handling it
> > > that way.
> > >
> >
> > Did not experiment yet, putting this in my todolist.
> > Just, I can see that lib/librte_pipeline/ at least only marks the
> > declarations.
> >
> I just tried it. If I turn off ALLOW_EXPERIMENTAL_APIS, the ip_pipeline
> example
> breaks with warnings about deprecated functions:
>
> /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:60:4: error:
> ‘rte_table_hash_crc_key8’ is deprecated: Symbol is not yet part of stable
> ABI [-Werror=deprecated-declarations]
> params->lb.f_hash = rte_table_hash_crc_key8;
> ^~~~~~
> In file included from
> /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:10:
> /home/nhorman/git/dpdk/x86_64-native-linuxapp-gcc/include/rte_table_hash_func.h:56:1:
> note: declared here
> rte_table_hash_crc_key8(void *key, void *mask, __rte_unused uint32_t
> key_size,
> ^~~~~~~~~~~~~~~~~~~~~~~
> /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:64:4: error:
> ‘rte_table_hash_crc_key16’ is deprecated: Symbol is not yet part of stable
> ABI [-Werror=deprecated-declarations]
> params->lb.f_hash = rte_table_hash_crc_key16;
> ^~~~~~
> ...
>
> That is sufficient for me to conclude that __rte_experimental only needs
> to be
> set on the declaration, not the definiton as well.
>
Thanks for the test.
I tried with clang and this works fine as well.
Ferruh, could you do a little test with icc?
> If you would like to make this adjustment, I'm fine with it, though be
> aware,
> you will likely need to make some adjustments to the
> check-experimental-syms
> script to account for this
>
I find it much easier to track and, while doing the patch, I have found
another issue in the bbdev library header (another patch coming).
Under the impression that this can go undetected for quite some while...
If no one complains, yes, I am for this adjustment.
I am not sure I see what you mean on check-experimental-syms.sh.
I would only do a s/definition/declaration/ in the error message.
Do you have something else in mind ?
Btw, looking at the documentation, I can find no mention about meson and a
quick grep on check-experimental-syms.sh only catches mk/internal/
rte.compile-pre.mk.
Is there a trick ? or is meson simply not __rte_experimental aware ?
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] Marking symbols as experimental in the headers only
2018-12-04 20:48 0% ` David Marchand
@ 2018-12-04 21:34 0% ` Richardson, Bruce
2018-12-05 12:21 0% ` Neil Horman
1 sibling, 0 replies; 200+ results
From: Richardson, Bruce @ 2018-12-04 21:34 UTC (permalink / raw)
To: David Marchand, nhorman, Yigit, Ferruh
Cc: dev, Timothy Redaelli, adrien.mazarguil
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of David Marchand
> Sent: Tuesday, December 4, 2018 12:48 PM
> To: nhorman@tuxdriver.com; Yigit, Ferruh <ferruh.yigit@intel.com>
> Cc: dev@dpdk.org; Timothy Redaelli <tredaelli@redhat.com>;
> adrien.mazarguil@6wind.com
> Subject: Re: [dpdk-dev] Marking symbols as experimental in the headers
> only
>
> On Tue, Dec 4, 2018 at 4:16 PM Neil Horman <nhorman@tuxdriver.com> wrote:
>
> > On Tue, Dec 04, 2018 at 09:21:43AM +0100, David Marchand wrote:
> > > On Mon, Dec 3, 2018 at 5:48 PM Neil Horman <nhorman@tuxdriver.com>
> > wrote:
> > > > On Mon, Dec 03, 2018 at 02:01:02PM +0100, David Marchand wrote:
> > > > I would say, give it a try, and if you can demonstrate that adding
> > > > the attribute only to the declaration results in a link-time
> > > > warning when external
> > code
> > > > attempts to call an experimental function, I would have no problem
> > > > handling it that way.
> > > >
> > >
> > > Did not experiment yet, putting this in my todolist.
> > > Just, I can see that lib/librte_pipeline/ at least only marks the
> > > declarations.
> > >
> > I just tried it. If I turn off ALLOW_EXPERIMENTAL_APIS, the
> > ip_pipeline example breaks with warnings about deprecated functions:
> >
> > /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:60:4: error:
> > ‘rte_table_hash_crc_key8’ is deprecated: Symbol is not yet part of
> > stable ABI [-Werror=deprecated-declarations]
> > params->lb.f_hash = rte_table_hash_crc_key8;
> > ^~~~~~
> > In file included from
> > /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:10:
> > /home/nhorman/git/dpdk/x86_64-native-linuxapp-
> gcc/include/rte_table_hash_func.h:56:1:
> > note: declared here
> > rte_table_hash_crc_key8(void *key, void *mask, __rte_unused uint32_t
> > key_size, ^~~~~~~~~~~~~~~~~~~~~~~
> > /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:64:4: error:
> > ‘rte_table_hash_crc_key16’ is deprecated: Symbol is not yet part of
> > stable ABI [-Werror=deprecated-declarations]
> > params->lb.f_hash = rte_table_hash_crc_key16;
> > ^~~~~~
> > ...
> >
> > That is sufficient for me to conclude that __rte_experimental only
> > needs to be set on the declaration, not the definiton as well.
> >
>
> Thanks for the test.
> I tried with clang and this works fine as well.
> Ferruh, could you do a little test with icc?
>
>
> > If you would like to make this adjustment, I'm fine with it, though be
> > aware,
> > you will likely need to make some adjustments to the
> > check-experimental-syms
> > script to account for this
> >
>
> I find it much easier to track and, while doing the patch, I have found
> another issue in the bbdev library header (another patch coming).
> Under the impression that this can go undetected for quite some while...
> If no one complains, yes, I am for this adjustment.
>
>
> I am not sure I see what you mean on check-experimental-syms.sh.
> I would only do a s/definition/declaration/ in the error message.
> Do you have something else in mind ?
>
>
> Btw, looking at the documentation, I can find no mention about meson and a
> quick grep on check-experimental-syms.sh only catches mk/internal/
> rte.compile-pre.mk.
> Is there a trick ? or is meson simply not __rte_experimental aware ?
>
Good point, I suspect it isn't. I never thought to investigate how to integrate that tracking into meson builds.
/Bruce
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] Marking symbols as experimental in the headers only
2018-12-04 20:48 0% ` David Marchand
2018-12-04 21:34 0% ` Richardson, Bruce
@ 2018-12-05 12:21 0% ` Neil Horman
1 sibling, 0 replies; 200+ results
From: Neil Horman @ 2018-12-05 12:21 UTC (permalink / raw)
To: David Marchand; +Cc: ferruh.yigit, dev, Timothy Redaelli, adrien.mazarguil
On Tue, Dec 04, 2018 at 09:48:22PM +0100, David Marchand wrote:
> On Tue, Dec 4, 2018 at 4:16 PM Neil Horman <nhorman@tuxdriver.com> wrote:
>
> > On Tue, Dec 04, 2018 at 09:21:43AM +0100, David Marchand wrote:
> > > On Mon, Dec 3, 2018 at 5:48 PM Neil Horman <nhorman@tuxdriver.com>
> > wrote:
> > > > On Mon, Dec 03, 2018 at 02:01:02PM +0100, David Marchand wrote:
> > > > I would say, give it a try, and if you can demonstrate that adding the
> > > > attribute
> > > > only to the declaration results in a link-time warning when external
> > code
> > > > attempts to call an experimental function, I would have no problem
> > > > handling it
> > > > that way.
> > > >
> > >
> > > Did not experiment yet, putting this in my todolist.
> > > Just, I can see that lib/librte_pipeline/ at least only marks the
> > > declarations.
> > >
> > I just tried it. If I turn off ALLOW_EXPERIMENTAL_APIS, the ip_pipeline
> > example
> > breaks with warnings about deprecated functions:
> >
> > /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:60:4: error:
> > ‘rte_table_hash_crc_key8’ is deprecated: Symbol is not yet part of stable
> > ABI [-Werror=deprecated-declarations]
> > params->lb.f_hash = rte_table_hash_crc_key8;
> > ^~~~~~
> > In file included from
> > /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:10:
> > /home/nhorman/git/dpdk/x86_64-native-linuxapp-gcc/include/rte_table_hash_func.h:56:1:
> > note: declared here
> > rte_table_hash_crc_key8(void *key, void *mask, __rte_unused uint32_t
> > key_size,
> > ^~~~~~~~~~~~~~~~~~~~~~~
> > /home/nhorman/git/dpdk/examples/ip_pipeline/action.c:64:4: error:
> > ‘rte_table_hash_crc_key16’ is deprecated: Symbol is not yet part of stable
> > ABI [-Werror=deprecated-declarations]
> > params->lb.f_hash = rte_table_hash_crc_key16;
> > ^~~~~~
> > ...
> >
> > That is sufficient for me to conclude that __rte_experimental only needs
> > to be
> > set on the declaration, not the definiton as well.
> >
>
> Thanks for the test.
> I tried with clang and this works fine as well.
> Ferruh, could you do a little test with icc?
>
>
> > If you would like to make this adjustment, I'm fine with it, though be
> > aware,
> > you will likely need to make some adjustments to the
> > check-experimental-syms
> > script to account for this
> >
>
> I find it much easier to track and, while doing the patch, I have found
> another issue in the bbdev library header (another patch coming).
> Under the impression that this can go undetected for quite some while...
> If no one complains, yes, I am for this adjustment.
>
>
> I am not sure I see what you mean on check-experimental-syms.sh.
> I would only do a s/definition/declaration/ in the error message.
> Do you have something else in mind ?
>
>
> Btw, looking at the documentation, I can find no mention about meson and a
> quick grep on check-experimental-syms.sh only catches mk/internal/
> rte.compile-pre.mk.
> Is there a trick ? or is meson simply not __rte_experimental aware ?
>
All I was saying was that if you wanted to document the policy change, you might
need to check that script as its a reflection of that policy, and I couldn't
recall if it was grepping through .c and .h files (which might imply it needs to
change to reflect this policy). I just looked however, and its checking object
files, so you should be ok.
Neil
>
> --
> David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] mbuf: implement generic format for sched field
2018-12-04 17:39 0% ` Dumitrescu, Cristian
@ 2018-12-05 12:22 0% ` Singh, Jasvinder
0 siblings, 0 replies; 200+ results
From: Singh, Jasvinder @ 2018-12-05 12:22 UTC (permalink / raw)
To: Dumitrescu, Cristian, dev; +Cc: Pattan, Reshma
> -----Original Message-----
> From: Dumitrescu, Cristian
> Sent: Tuesday, December 4, 2018 5:39 PM
> To: Singh, Jasvinder <jasvinder.singh@intel.com>; dev@dpdk.org
> Cc: Pattan, Reshma <reshma.pattan@intel.com>
> Subject: RE: [PATCH] mbuf: implement generic format for sched field
>
> > >
> > > > + uint8_t color; /**< Color. */
> > >
> > > We should create a new file rte_color.h in a common place
> > > (librte_eal/common/include) to consolidate the color definition,
> > > which is currently replicated in too many places, such as:
> > > rte_meter.h, rte_mtr.h, rte_tm.h.
> > >
> > > We should include the rte_color.h file here (and in the above header
> > > files)
> > >
> > > We should also document the link between this field and the color
> > > enum
> > type
> > > (@see ...).
> >
> > Replacing the existing color definition with the above suggested one
> > in rte_meter.h (librte_meter) would be ABI break. We can do it
> > separately through different patch.
> >
> > >
>
> We can avoid any such issues in a two step process:
> 1. Create aliases to the new color in rte_meter.h, rte_mtr.h and rte_tm.h at
> this point.
> 2. Announce deprecation of the existing color enums in favor of the new
> unified color enum at this point and remove during next release.
>
> Example:
> //file "rte_meter.h"
> #include <rte_color.h>
>
> #define rte_meter_color rte_color
> #define RTE_METER_GREEN RTE_COLOR_GREEN
> #define RTE_METER_YELLOW RTE_COLOR_YELLOW #define RTE_METER_RED
> RTE_COLOR_RED
>
> Makes sense?
Looks ok. We will do this clean-up work in a separate patch instead of mixing with mbuf patch. Thanks.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3 0/9] ipsec: new library for IPsec data-path processing
@ 2018-12-06 15:38 2% ` Konstantin Ananyev
0 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2018-12-06 15:38 UTC (permalink / raw)
To: dev; +Cc: Konstantin Ananyev
This patch series depends on the patch:
http://patches.dpdk.org/patch/48044/
to be applied first.
v2 -> v3
- Several fixes for IPv6 support
- Extra checks for input parameters in public APi functions
v1 -> v2
- Changes to get into account l2_len for outbound transport packets
(Qi comments)
- Several bug fixes
- Some code restructured
- Update MAINTAINERS file
RFCv2 -> v1
- Changes per Jerin comments
- Implement transport mode
- Several bug fixes
- UT largely reworked and extended
This patch introduces a new library within DPDK: librte_ipsec.
The aim is to provide DPDK native high performance library for IPsec
data-path processing.
The library is supposed to utilize existing DPDK crypto-dev and
security API to provide application with transparent IPsec
processing API.
The library is concentrated on data-path protocols processing
(ESP and AH), IKE protocol(s) implementation is out of scope
for that library.
Current patch introduces SA-level API.
SA (low) level API
==================
API described below operates on SA level.
It provides functionality that allows user for given SA to process
inbound and outbound IPsec packets.
To be more specific:
- for inbound ESP/AH packets perform decryption, authentication,
integrity checking, remove ESP/AH related headers
- for outbound packets perform payload encryption, attach ICV,
update/add IP headers, add ESP/AH headers/trailers,
setup related mbuf felids (ol_flags, tx_offloads, etc.).
- initialize/un-initialize given SA based on user provided parameters.
The following functionality:
- match inbound/outbound packets to particular SA
- manage crypto/security devices
- provide SAD/SPD related functionality
- determine what crypto/security device has to be used
for given packet(s)
is out of scope for SA-level API.
SA-level API is based on top of crypto-dev/security API and relies on
them
to perform actual cipher and integrity checking.
To have an ability to easily map crypto/security sessions into related
IPSec SA opaque userdata field was added into
rte_cryptodev_sym_session and rte_security_session structures.
That implies ABI change for both librte_crytpodev and librte_security.
Due to the nature of crypto-dev API (enqueue/deque model) we use
asynchronous API for IPsec packets destined to be processed
by crypto-device.
Expected API call sequence would be:
/* enqueue for processing by crypto-device */
rte_ipsec_pkt_crypto_prepare(...);
rte_cryptodev_enqueue_burst(...);
/* dequeue from crypto-device and do final processing (if any) */
rte_cryptodev_dequeue_burst(...);
rte_ipsec_pkt_crypto_group(...); /* optional */
rte_ipsec_pkt_process(...);
Though for packets destined for inline processing no extra overhead
is required and synchronous API call: rte_ipsec_pkt_process()
is sufficient for that case.
Current implementation supports all four currently defined
rte_security types.
Though to accommodate future custom implementations function pointers
model is used for both for *crypto_prepare* and *process*
impelementations.
TODO list
---------
- update docs
Konstantin Ananyev (9):
cryptodev: add opaque userdata pointer into crypto sym session
security: add opaque userdata pointer into security session
net: add ESP trailer structure definition
lib: introduce ipsec library
ipsec: add SA data-path API
ipsec: implement SA data-path API
ipsec: rework SA replay window/SQN for MT environment
ipsec: helper functions to group completed crypto-ops
test/ipsec: introduce functional test
MAINTAINERS | 5 +
config/common_base | 5 +
lib/Makefile | 2 +
lib/librte_cryptodev/rte_cryptodev.h | 2 +
lib/librte_ipsec/Makefile | 27 +
lib/librte_ipsec/crypto.h | 123 ++
lib/librte_ipsec/iph.h | 84 +
lib/librte_ipsec/ipsec_sqn.h | 343 ++++
lib/librte_ipsec/meson.build | 10 +
lib/librte_ipsec/pad.h | 45 +
lib/librte_ipsec/rte_ipsec.h | 156 ++
lib/librte_ipsec/rte_ipsec_group.h | 151 ++
lib/librte_ipsec/rte_ipsec_sa.h | 166 ++
lib/librte_ipsec/rte_ipsec_version.map | 15 +
lib/librte_ipsec/sa.c | 1401 +++++++++++++++
lib/librte_ipsec/sa.h | 98 ++
lib/librte_ipsec/ses.c | 45 +
lib/librte_net/rte_esp.h | 10 +-
lib/librte_security/rte_security.h | 2 +
lib/meson.build | 2 +
mk/rte.app.mk | 2 +
test/test/Makefile | 3 +
test/test/meson.build | 3 +
test/test/test_ipsec.c | 2209 ++++++++++++++++++++++++
24 files changed, 4908 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_ipsec/Makefile
create mode 100644 lib/librte_ipsec/crypto.h
create mode 100644 lib/librte_ipsec/iph.h
create mode 100644 lib/librte_ipsec/ipsec_sqn.h
create mode 100644 lib/librte_ipsec/meson.build
create mode 100644 lib/librte_ipsec/pad.h
create mode 100644 lib/librte_ipsec/rte_ipsec.h
create mode 100644 lib/librte_ipsec/rte_ipsec_group.h
create mode 100644 lib/librte_ipsec/rte_ipsec_sa.h
create mode 100644 lib/librte_ipsec/rte_ipsec_version.map
create mode 100644 lib/librte_ipsec/sa.c
create mode 100644 lib/librte_ipsec/sa.h
create mode 100644 lib/librte_ipsec/ses.c
create mode 100644 test/test/test_ipsec.c
--
2.17.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v2 1/3] mbuf: implement generic format for sched field
@ 2018-12-07 14:31 5% ` Reshma Pattan
2018-12-11 19:02 0% ` Dumitrescu, Cristian
1 sibling, 2 replies; 200+ results
From: Reshma Pattan @ 2018-12-07 14:31 UTC (permalink / raw)
To: dev, cristian.dumitrescu, jerin.jacob, jasvinder.singh; +Cc: Reshma Pattan
This patch implements the changes proposed in the deprecation
notes [1][2].
librte_mbuf changes:
The mbuf::hash::sched field is updated to support generic
definition in line with the ethdev TM and MTR APIs. The new generic
format contains: queue ID, traffic class, color.
Added public APIs to set and get these new fields to and from mbuf.
librte_sched changes:
In addtion, following API functions of the sched library have
been modified with an additional parameter of type struct
rte_sched_port to accommodate the changes made to mbuf sched field.
(i) rte_sched_port_pkt_write()
(ii) rte_sched_port_pkt_read_tree_path()
librte_pipeline, qos_sched UT, qos_sched app are updated
to make use of new changes.
Also mbuf::hash::txadpater have been added for eventdev txq,
rte_event_eth_tx_adapter_txq_set and rte_event_eth_tx_adapter_txq_get()
are updated to use uses mbuf::hash::txadpater.txq.
doc:
Release notes updated.
Removed deprecation notice for mbuf::hash::sched and sched API.
[1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
[2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 10 --
doc/guides/rel_notes/release_19_02.rst | 15 ++-
examples/qos_sched/app_thread.c | 7 +-
examples/qos_sched/main.c | 1 +
.../rte_event_eth_tx_adapter.h | 14 +--
lib/librte_mbuf/Makefile | 2 +-
lib/librte_mbuf/rte_mbuf.h | 112 +++++++++++++++++-
lib/librte_pipeline/rte_table_action.c | 75 +++++++-----
lib/librte_sched/Makefile | 2 +-
lib/librte_sched/rte_sched.c | 97 +++++++--------
lib/librte_sched/rte_sched.h | 10 +-
test/test/test_sched.c | 9 +-
12 files changed, 234 insertions(+), 120 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b48486d36..60e081a54 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,16 +49,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* mbuf: The opaque ``mbuf->hash.sched`` field will be updated to support generic
- definition in line with the ethdev TM and MTR APIs. Currently, this field
- is defined in librte_sched in a non-generic way. The new generic format
- will contain: queue ID, traffic class, color. Field size will not change.
-
-* sched: Some API functions will change prototype due to the above
- deprecation note for mbuf->hash.sched, e.g. ``rte_sched_port_pkt_write()``
- and ``rte_sched_port_pkt_read()`` will likely have an additional parameter
- of type ``struct rte_sched_port``.
-
* mbuf: the macro ``RTE_MBUF_INDIRECT()`` will be removed in v18.08 or later and
replaced with ``RTE_MBUF_CLONED()`` which is already added in v18.05. As
``EXT_ATTACHED_MBUF`` is newly introduced in v18.05, ``RTE_MBUF_INDIRECT()``
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index a94fa86a7..24ba00d04 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -83,6 +83,11 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* The below functions of the sched library have been modified with an
+ additional parameter of type ``struct rte_sched_port`` to accommodate
+ the changes made to mbuf::hash::sched field.
+ (i) rte_sched_port_pkt_write()
+ (ii) rte_sched_port_pkt_read_tree_path()
ABI Changes
-----------
@@ -99,6 +104,12 @@ ABI Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* The mbuf::hash::sched field is updated to support generic
+ definition in line with the ethdev TM and MTR APIs. The new generic
+ format contains: ``queue ID, traffic class, color``.
+
+* The mbuf:hash:txadapter is now added for eventdev txq. The txadapter
+ format now contains ``reserved1, reserved2 and txq``.
Shared Library Versions
-----------------------
@@ -146,7 +157,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_kvargs.so.1
librte_latencystats.so.1
librte_lpm.so.2
- librte_mbuf.so.4
+ + librte_mbuf.so.5
librte_member.so.1
librte_mempool.so.5
librte_meter.so.2
@@ -168,7 +179,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_rawdev.so.1
librte_reorder.so.1
librte_ring.so.2
- librte_sched.so.1
+ + librte_sched.so.2
librte_security.so.1
librte_table.so.3
librte_timer.so.1
diff --git a/examples/qos_sched/app_thread.c b/examples/qos_sched/app_thread.c
index a59274236..bec4deee3 100644
--- a/examples/qos_sched/app_thread.c
+++ b/examples/qos_sched/app_thread.c
@@ -73,8 +73,11 @@ app_rx_thread(struct thread_conf **confs)
for(i = 0; i < nb_rx; i++) {
get_pkt_sched(rx_mbufs[i],
&subport, &pipe, &traffic_class, &queue, &color);
- rte_sched_port_pkt_write(rx_mbufs[i], subport, pipe,
- traffic_class, queue, (enum rte_meter_color) color);
+ rte_sched_port_pkt_write(conf->sched_port,
+ rx_mbufs[i],
+ subport, pipe,
+ traffic_class, queue,
+ (enum rte_meter_color) color);
}
if (unlikely(rte_ring_sp_enqueue_bulk(conf->rx_ring,
diff --git a/examples/qos_sched/main.c b/examples/qos_sched/main.c
index e7c97bd64..c0ed16b68 100644
--- a/examples/qos_sched/main.c
+++ b/examples/qos_sched/main.c
@@ -55,6 +55,7 @@ app_main_loop(__attribute__((unused))void *dummy)
flow->rx_thread.rx_port = flow->rx_port;
flow->rx_thread.rx_ring = flow->rx_ring;
flow->rx_thread.rx_queue = flow->rx_queue;
+ flow->rx_thread.sched_port = flow->sched_port;
rx_confs[rx_idx++] = &flow->rx_thread;
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index 81456d4a9..b406660ab 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -63,11 +63,11 @@
* function can be used to retrieve the adapter's service function ID.
*
* The ethernet port and transmit queue index to transmit the mbuf on are
- * specified using the mbuf port and the higher 16 bits of
- * struct rte_mbuf::hash::sched:hi. The application should use the
- * rte_event_eth_tx_adapter_txq_set() and rte_event_eth_tx_adapter_txq_get()
- * functions to access the transmit queue index since it is expected that the
- * transmit queue will be eventually defined within struct rte_mbuf and using
+ * specified using the mbuf port struct rte_mbuf::hash::txadapter:txq.
+ * The application should use the rte_event_eth_tx_adapter_txq_set()
+ * and rte_event_eth_tx_adapter_txq_get() functions to access the transmit
+ * queue index since it is expected that the transmit queue will be
+ * eventually defined within struct rte_mbuf and using
* these macros will help with minimizing application impact due to
* a change in how the transmit queue index is specified.
*/
@@ -300,7 +300,7 @@ rte_event_eth_tx_adapter_queue_del(uint8_t id,
static __rte_always_inline void __rte_experimental
rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
+ uint16_t *p = (uint16_t *)&pkt->hash.txadapter.txq;
p[1] = queue;
}
@@ -320,7 +320,7 @@ rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
static __rte_always_inline uint16_t __rte_experimental
rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
+ uint16_t *p = (uint16_t *)&pkt->hash.txadapter.txq;
return p[1];
}
diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
index e2b98a254..8c4c7d790 100644
--- a/lib/librte_mbuf/Makefile
+++ b/lib/librte_mbuf/Makefile
@@ -11,7 +11,7 @@ LDLIBS += -lrte_eal -lrte_mempool
EXPORT_MAP := rte_mbuf_version.map
-LIBABIVER := 4
+LIBABIVER := 5
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 3dbc6695e..accd98d9b 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -575,13 +575,23 @@ struct rte_mbuf {
*/
} fdir; /**< Filter identifier if FDIR enabled */
struct {
- uint32_t lo;
- uint32_t hi;
+ uint32_t queue_id; /**< Queue ID. */
+ uint8_t traffic_class;
+ /**< Traffic class ID. Traffic class 0 is high
+ * priority traffic class.
+ */
+ uint8_t color; /**< Color. */
+ uint16_t reserved; /**< Reserved. */
+ } sched; /**< Hierarchical scheduler */
+ struct {
+ uint32_t reserved1;
+ uint16_t reserved2;
+ uint16_t txq;
/**< The event eth Tx adapter uses this field
* to store Tx queue id.
* @see rte_event_eth_tx_adapter_txq_set()
*/
- } sched; /**< Hierarchical scheduler */
+ } txadapter; /**< Eventdev ethdev Tx adapter */
/**< User defined tags. See rte_distributor_process() */
uint32_t usr;
} hash; /**< hash information */
@@ -2289,6 +2299,102 @@ rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
*/
void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
+/**
+ * Reads the value of an mbuf's sched queue_id field.
+ */
+static inline uint32_t
+rte_mbuf_sched_queue_read(const struct rte_mbuf *m)
+{
+ return m->hash.sched.queue_id;
+}
+
+/**
+ * Reads the value of an mbuf's sched traffic_class field.
+ */
+static inline uint8_t
+rte_mbuf_sched_traffic_class_read(const struct rte_mbuf *m)
+{
+ return m->hash.sched.traffic_class;
+}
+
+/**
+ * Reads the value of an mbuf's sched color field.
+ */
+static inline uint8_t
+rte_mbuf_sched_color_read(const struct rte_mbuf *m)
+{
+ return m->hash.sched.color;
+}
+
+/**
+ * Sets an mbuf's sched queue_id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t qid)
+{
+ m->hash.sched.queue_id = qid;
+}
+
+/**
+ * Sets an mbuf's sched traffic_class id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t tc)
+{
+ m->hash.sched.traffic_class = tc;
+}
+
+/**
+ * Sets an mbuf's sched color id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_color_set(struct rte_mbuf *m, uint8_t color)
+{
+ m->hash.sched.color = color;
+}
+
+/**
+ * Reads the values of an mbuf's sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to read
+ * @param qid
+ * Returns the queue id
+ * @param tc
+ * Returns the traffic class id
+ * @param color
+ * Returns the colour id
+ */
+static inline void
+rte_mbuf_sched_read(const struct rte_mbuf *m, uint32_t *qid,
+ uint8_t *tc,
+ uint8_t *color)
+{
+ *qid = m->hash.sched.queue_id;
+ *tc = m->hash.sched.traffic_class;
+ *color = m->hash.sched.color;
+}
+
+/**
+ * Sets the mbuf's sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to set
+ * @param qid
+ * Queue id value to be set
+ * @param tc
+ * Traffic class id value to be set
+ * @param color
+ * Color id to be set
+ */
+static inline void
+rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t qid,
+ uint8_t tc,
+ uint8_t color)
+{
+ m->hash.sched.queue_id = qid;
+ m->hash.sched.traffic_class = tc;
+ m->hash.sched.color = color;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 7c7c8dd82..f9768b9cc 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -107,14 +107,6 @@ mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
return 0;
}
-#define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
- ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
- ((((uint64_t)(tc)) & 0x3) << 2) | \
- ((((uint64_t)(color)) & 0x3) << 4)))
-
-#define MBUF_SCHED_COLOR(sched, color) \
- (((sched) & (~0x30LLU)) | ((color) << 4))
-
struct mtr_trtcm_data {
struct rte_meter_trtcm trtcm;
uint64_t stats[e_RTE_METER_COLORS];
@@ -176,7 +168,7 @@ mtr_data_size(struct rte_table_action_mtr_config *mtr)
struct dscp_table_entry_data {
enum rte_meter_color color;
uint16_t tc;
- uint16_t queue_tc_color;
+ uint32_t queue;
};
struct dscp_table_data {
@@ -319,8 +311,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
uint32_t dscp,
uint16_t total_length)
{
- uint64_t drop_mask, sched;
- uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
+ uint64_t drop_mask;
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
enum rte_meter_color color_in, color_meter, color_policer;
uint32_t tc, mp_id;
@@ -329,7 +320,6 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
color_in = dscp_entry->color;
data += tc;
mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
- sched = *sched_ptr;
/* Meter */
color_meter = rte_meter_trtcm_color_aware_check(
@@ -346,7 +336,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
color_policer =
MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- *sched_ptr = MBUF_SCHED_COLOR(sched, color_policer);
+ rte_mbuf_sched_color_set(mbuf, color_policer);
return drop_mask;
}
@@ -368,11 +358,16 @@ tm_cfg_check(struct rte_table_action_tm_config *tm)
}
struct tm_data {
- uint16_t queue_tc_color;
uint16_t subport;
uint32_t pipe;
} __attribute__((__packed__));
+/* log2 representation of tm configuration */
+struct tm_cfg {
+ uint32_t subports_per_port_log2;
+ uint32_t pipes_per_subport_log2;
+} __attribute__((__packed__));
+
static int
tm_apply_check(struct rte_table_action_tm_params *p,
struct rte_table_action_tm_config *cfg)
@@ -397,26 +392,37 @@ tm_apply(struct tm_data *data,
return status;
/* Apply */
- data->queue_tc_color = 0;
data->subport = (uint16_t) p->subport_id;
data->pipe = p->pipe_id;
return 0;
}
+static uint32_t
+tm_sched_qindex(struct tm_data *data,
+ struct dscp_table_entry_data *dscp,
+ struct tm_cfg *tm)
+{
+ uint32_t result;
+
+ result = (data->subport << tm->pipes_per_subport_log2) + data->pipe;
+ result = result * RTE_TABLE_ACTION_TC_MAX + dscp->tc;
+ result = result * RTE_TABLE_ACTION_TC_QUEUE_MAX + dscp->queue;
+
+ return result;
+}
+
static __rte_always_inline void
pkt_work_tm(struct rte_mbuf *mbuf,
struct tm_data *data,
struct dscp_table_data *dscp_table,
- uint32_t dscp)
+ uint32_t dscp,
+ struct tm_cfg *tm)
{
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
- struct tm_data sched;
+ uint32_t queue = tm_sched_qindex(data, dscp_entry, tm);
- sched = *data;
- sched.queue_tc_color = dscp_entry->queue_tc_color;
- *sched_ptr = sched;
+ rte_mbuf_sched_set(mbuf, queue, dscp_entry->tc, dscp_entry->color);
}
/**
@@ -2440,6 +2446,7 @@ struct rte_table_action {
struct ap_data data;
struct dscp_table_data dscp_table;
struct meter_profile_data mp[METER_PROFILES_MAX];
+ struct tm_cfg tm;
};
struct rte_table_action *
@@ -2465,6 +2472,11 @@ rte_table_action_create(struct rte_table_action_profile *profile,
memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
memcpy(&action->data, &profile->data, sizeof(profile->data));
+ action->tm.subports_per_port_log2 =
+ __builtin_ctz(profile->cfg.tm.n_subports_per_port);
+ action->tm.pipes_per_subport_log2 =
+ __builtin_ctz(profile->cfg.tm.n_pipes_per_subport);
+
return action;
}
@@ -2580,17 +2592,13 @@ rte_table_action_dscp_table_update(struct rte_table_action *action,
&action->dscp_table.entry[i];
struct rte_table_action_dscp_table_entry *entry =
&table->entry[i];
- uint16_t queue_tc_color =
- MBUF_SCHED_QUEUE_TC_COLOR(entry->tc_queue_id,
- entry->tc_id,
- entry->color);
if ((dscp_mask & (1LLU << i)) == 0)
continue;
data->color = entry->color;
data->tc = entry->tc_id;
- data->queue_tc_color = queue_tc_color;
+ data->queue = entry->tc_queue_id;
}
return 0;
@@ -2882,7 +2890,8 @@ pkt_work(struct rte_mbuf *mbuf,
pkt_work_tm(mbuf,
data,
&action->dscp_table,
- dscp);
+ dscp,
+ &action->tm);
}
if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
@@ -3108,22 +3117,26 @@ pkt4_work(struct rte_mbuf **mbufs,
pkt_work_tm(mbuf0,
data0,
&action->dscp_table,
- dscp0);
+ dscp0,
+ &action->tm);
pkt_work_tm(mbuf1,
data1,
&action->dscp_table,
- dscp1);
+ dscp1,
+ &action->tm);
pkt_work_tm(mbuf2,
data2,
&action->dscp_table,
- dscp2);
+ dscp2,
+ &action->tm);
pkt_work_tm(mbuf3,
data3,
&action->dscp_table,
- dscp3);
+ dscp3,
+ &action->tm);
}
if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile
index 46c53ed71..644fd9d15 100644
--- a/lib/librte_sched/Makefile
+++ b/lib/librte_sched/Makefile
@@ -18,7 +18,7 @@ LDLIBS += -lrte_timer
EXPORT_MAP := rte_sched_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 587d5e602..a6d9a5886 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -41,6 +41,9 @@
#define RTE_SCHED_PIPE_INVALID UINT32_MAX
#define RTE_SCHED_BMP_POS_INVALID UINT32_MAX
+#define RTE_SCHED_QUEUES_PER_PIPE_LOG2 \
+ __builtin_ctz(RTE_SCHED_QUEUES_PER_PIPE)
+
/* Scaling for cycles_per_byte calculation
* Chosen so that minimum rate is 480 bit/sec
*/
@@ -128,22 +131,6 @@ enum grinder_state {
e_GRINDER_READ_MBUF
};
-/*
- * Path through the scheduler hierarchy used by the scheduler enqueue
- * operation to identify the destination queue for the current
- * packet. Stored in the field pkt.hash.sched of struct rte_mbuf of
- * each packet, typically written by the classification stage and read
- * by scheduler enqueue.
- */
-struct rte_sched_port_hierarchy {
- uint16_t queue:2; /**< Queue ID (0 .. 3) */
- uint16_t traffic_class:2; /**< Traffic class ID (0 .. 3)*/
- uint32_t color:2; /**< Color */
- uint16_t unused:10;
- uint16_t subport; /**< Subport ID */
- uint32_t pipe; /**< Pipe ID */
-};
-
struct rte_sched_grinder {
/* Pipe cache */
uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
@@ -228,6 +215,7 @@ struct rte_sched_port {
uint8_t *bmp_array;
struct rte_mbuf **queue_array;
uint8_t memory[0] __rte_cache_aligned;
+
} __rte_cache_aligned;
enum rte_sched_port_array {
@@ -242,13 +230,11 @@ enum rte_sched_port_array {
};
#ifdef RTE_SCHED_COLLECT_STATS
-
static inline uint32_t
rte_sched_port_queues_per_subport(struct rte_sched_port *port)
{
return RTE_SCHED_QUEUES_PER_PIPE * port->n_pipes_per_subport;
}
-
#endif
static inline uint32_t
@@ -1006,44 +992,56 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port,
return 0;
}
+static inline uint32_t
+rte_sched_port_qindex(struct rte_sched_port *port,
+ uint32_t subport,
+ uint32_t pipe,
+ uint32_t traffic_class,
+ uint32_t queue)
+{
+ uint32_t result;
+
+ result = (subport << __builtin_ctz(port->n_pipes_per_subport)) + pipe;
+ result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + traffic_class;
+ result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
+
+ return result;
+}
+
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
uint32_t subport, uint32_t pipe, uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color)
{
- struct rte_sched_port_hierarchy *sched
- = (struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- RTE_BUILD_BUG_ON(sizeof(*sched) > sizeof(pkt->hash.sched));
-
- sched->color = (uint32_t) color;
- sched->subport = subport;
- sched->pipe = pipe;
- sched->traffic_class = traffic_class;
- sched->queue = queue;
+ uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe,
+ traffic_class, queue);
+ rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color);
}
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- *subport = sched->subport;
- *pipe = sched->pipe;
- *traffic_class = sched->traffic_class;
- *queue = sched->queue;
+ uint32_t qid = rte_mbuf_sched_queue_read(pkt);
+
+ *subport = qid >>
+ (__builtin_ctz
+ (RTE_SCHED_QUEUES_PER_PIPE <<
+ __builtin_ctz(port->n_pipes_per_subport)
+ )
+ );
+ *pipe = qid >> RTE_SCHED_QUEUES_PER_PIPE_LOG2;
+ *traffic_class = rte_mbuf_sched_traffic_class_read(pkt);
+ *queue = qid & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1);
}
enum rte_meter_color
rte_sched_port_pkt_read_color(const struct rte_mbuf *pkt)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- return (enum rte_meter_color) sched->color;
+ return (enum rte_meter_color)rte_mbuf_sched_color_read(pkt);
}
int
@@ -1100,18 +1098,6 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
return 0;
}
-static inline uint32_t
-rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport, uint32_t pipe, uint32_t traffic_class, uint32_t queue)
-{
- uint32_t result;
-
- result = subport * port->n_pipes_per_subport + pipe;
- result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + traffic_class;
- result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
-
- return result;
-}
-
#ifdef RTE_SCHED_DEBUG
static inline int
@@ -1272,11 +1258,8 @@ rte_sched_port_enqueue_qptrs_prefetch0(struct rte_sched_port *port,
#ifdef RTE_SCHED_COLLECT_STATS
struct rte_sched_queue_extra *qe;
#endif
- uint32_t subport, pipe, traffic_class, queue, qindex;
-
- rte_sched_port_pkt_read_tree_path(pkt, &subport, &pipe, &traffic_class, &queue);
+ uint32_t qindex = rte_mbuf_sched_queue_read(pkt);
- qindex = rte_sched_port_qindex(port, subport, pipe, traffic_class, queue);
q = port->queue + qindex;
rte_prefetch0(q);
#ifdef RTE_SCHED_COLLECT_STATS
diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
index 84fa896de..243efa1d4 100644
--- a/lib/librte_sched/rte_sched.h
+++ b/lib/librte_sched/rte_sched.h
@@ -355,6 +355,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Scheduler hierarchy path write to packet descriptor. Typically
* called by the packet classification stage.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -369,7 +371,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Packet color set
*/
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
uint32_t subport, uint32_t pipe, uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color);
@@ -379,6 +382,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
* enqueue operation. The subport, pipe, traffic class and queue
* parameters need to be pre-allocated by the caller.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -392,7 +397,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
*
*/
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue);
diff --git a/test/test/test_sched.c b/test/test/test_sched.c
index 32e500ba9..40e411cab 100644
--- a/test/test/test_sched.c
+++ b/test/test/test_sched.c
@@ -76,7 +76,7 @@ create_mempool(void)
}
static void
-prepare_pkt(struct rte_mbuf *mbuf)
+prepare_pkt(struct rte_sched_port *port, struct rte_mbuf *mbuf)
{
struct ether_hdr *eth_hdr;
struct vlan_hdr *vlan1, *vlan2;
@@ -95,7 +95,8 @@ prepare_pkt(struct rte_mbuf *mbuf)
ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);
- rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW);
+ rte_sched_port_pkt_write(port, mbuf, SUBPORT, PIPE, TC, QUEUE,
+ e_RTE_METER_YELLOW);
/* 64 byte packet */
mbuf->pkt_len = 60;
@@ -138,7 +139,7 @@ test_sched(void)
for (i = 0; i < 10; i++) {
in_mbufs[i] = rte_pktmbuf_alloc(mp);
TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation failed\n");
- prepare_pkt(in_mbufs[i]);
+ prepare_pkt(port, in_mbufs[i]);
}
@@ -155,7 +156,7 @@ test_sched(void)
color = rte_sched_port_pkt_read_color(out_mbufs[i]);
TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong color\n");
- rte_sched_port_pkt_read_tree_path(out_mbufs[i],
+ rte_sched_port_pkt_read_tree_path(port, out_mbufs[i],
&subport, &pipe, &traffic_class, &queue);
TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong subport\n");
--
2.17.1
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCH v2 0/2] Timer library changes
@ 2018-12-07 17:52 4% ` Erik Gabriel Carrillo
2018-12-13 22:26 4% ` [dpdk-dev] [PATCH v3 0/2] Timer library changes Erik Gabriel Carrillo
0 siblings, 2 replies; 200+ results
From: Erik Gabriel Carrillo @ 2018-12-07 17:52 UTC (permalink / raw)
To: rsanford; +Cc: jerin.jacob, pbhagavatula, dev
This patch series modifies the timer library in such a way that
structures that used to be statically allocated in a process's data
segment are now allocated in shared memory. As these structures contain
lists of timers, new APIs are introduced that allow a caller to specify
the particular structure instance into which a timer should be inserted
or from which a timer should be removed. This enables primary and secondary
processes to modify the same timer list, which enables some
multi-process use cases that were not previously possible; e.g. a
secondary process can start a timer whose expiration is detected in a
primary process running a new flavor of timer_manage().
The original library API is mostly unchanged, though implementations are
updated to call into newly added functions with a default structure instance
ID that provides the original behavior. New functions are introduced to
enable applications to allocate structure instances to house timer
lists, and to reference them with an identifier when starting and
stopping timers, and finally, to manage the timer lists referenced with
an identifier.
My initial performance testing with the "timer_perf_autotest" test shows
no performance regression or improvement, and inspection of the
generated optimized code shows that the extra function call gets inlined
in the functions that now have an extra function call.
Depends on: https://patches.dpdk.org/patch/48417/
Changes in v2:
- split these changes out into their own series
- version the symbols where the existing ABI was updated, and
provide alternate implementation with behavior equivalent to original
behavior. Validate ABI compatibility with validate-abi.sh
- refactor changes to simplify patches
Erik Gabriel Carrillo (2):
timer: allow timer management in shared memory
timer: add function to stop all timers in a list
lib/librte_timer/Makefile | 1 +
lib/librte_timer/rte_timer.c | 558 ++++++++++++++++++++++++++++++---
lib/librte_timer/rte_timer.h | 258 ++++++++++++++-
lib/librte_timer/rte_timer_version.map | 23 ++
4 files changed, 795 insertions(+), 45 deletions(-)
--
2.6.4
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2 1/2] timer: allow timer management in shared memory
@ 2018-12-07 18:10 3% ` Stephen Hemminger
2018-12-07 19:21 4% ` Carrillo, Erik G
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2018-12-07 18:10 UTC (permalink / raw)
To: Erik Gabriel Carrillo; +Cc: rsanford, jerin.jacob, pbhagavatula, dev
On Fri, 7 Dec 2018 11:52:59 -0600
Erik Gabriel Carrillo <erik.g.carrillo@intel.com> wrote:
> Currently, the timer library uses a per-process table of structures to
> manage skiplists of timers presumably because timers contain arbitrary
> function pointers whose value may not resolve properly in other
> processes.
>
> However, if the same callback is used handle all timers, and that
> callback is only invoked in one process, then it woud be safe to allow
> the data structures to be allocated in shared memory, and to allow
> secondary processes to modify the timer lists. This would let timers be
> used in more multi-process scenarios.
>
> The library's global variables are wrapped with a struct, and an array
> of these structures is created in shared memory. The original APIs
> are updated to reference the zeroth entry in the array. This maintains
> the original behavior for both primary and secondary processes since
> the set intersection of their coremasks should be empty [1]. New APIs
> are introduced to enable the allocation/deallocation of other entries
> in the array.
>
> New variants of the APIs used to start and stop timers are introduced;
> they allow a caller to specify which array entry should be used to
> locate the timer list to insert into or delete from.
>
> Finally, a new variant of rte_timer_manage() is introduced, which
> allows a caller to specify which array entry should be used to locate
> the timer lists to process; it can also process multiple timer lists per
> invocation.
>
> [1] https://doc.dpdk.org/guides/prog_guide/multi_proc_support.html#multi-process-limitations
>
> Signed-off-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
Makes sense but it looks to me like an ABI breakage. Experimental isn't going to
work for this.
> +static uint32_t default_data_id; // id set to zero automatically
C++ style comments are not allowed per DPDK coding style.
Best to just drop the comment, it is stating the obvious.
> -/* Init the timer library. */
> +static inline int
> +timer_data_valid(uint32_t id)
> +{
> + return !!(rte_timer_data_arr[id].internal_flags & FL_ALLOCATED);
> +}
Don't need inline on static functions.
...
> +MAP_STATIC_SYMBOL(int rte_timer_manage(void), rte_timer_manage_v1902);
> +BIND_DEFAULT_SYMBOL(rte_timer_manage, _v1902, 19.02);
> +
> +int __rte_experimental
> +rte_timer_alt_manage(uint32_t timer_data_id,
> + unsigned int *poll_lcores,
> + int nb_poll_lcores,
> + rte_timer_alt_manage_cb_t f)
> +{
> + union rte_timer_status status;
> + struct rte_timer *tim, *next_tim, **pprev;
> + struct rte_timer *run_first_tims[RTE_MAX_LCORE];
> + unsigned int runlist_lcore_ids[RTE_MAX_LCORE];
> + unsigned int this_lcore = rte_lcore_id();
> + struct rte_timer *prev[MAX_SKIPLIST_DEPTH + 1];
> + uint64_t cur_time;
> + int i, j, ret;
> + int nb_runlists = 0;
> + struct rte_timer_data *data;
> + struct priv_timer *privp;
> + uint32_t poll_lcore;
> +
> + TIMER_DATA_VALID_GET_OR_ERR_RET(timer_data_id, data, -EINVAL);
> +
> + /* timer manager only runs on EAL thread with valid lcore_id */
> + assert(this_lcore < RTE_MAX_LCORE);
> +
> + __TIMER_STAT_ADD(data->priv_timer, manage, 1);
> +
> + if (poll_lcores == NULL) {
> + poll_lcores = (unsigned int []){rte_lcore_id()};
This isn't going to be safe. It assigns poll_lcores to an array
allocated on the stack.
> +
> + for (i = 0, poll_lcore = poll_lcores[i]; i < nb_poll_lcores;
> + poll_lcore = poll_lcores[++i]) {
> + privp = &data->priv_timer[poll_lcore];
> +
> + /* optimize for the case where per-cpu list is empty */
> + if (privp->pending_head.sl_next[0] == NULL)
> + continue;
> + cur_time = rte_get_timer_cycles();
> +
> +#ifdef RTE_ARCH_64
> + /* on 64-bit the value cached in the pending_head.expired will
> + * be updated atomically, so we can consult that for a quick
> + * check here outside the lock
> + */
> + if (likely(privp->pending_head.expire > cur_time))
> + continue;
> +#endif
This code needs to be optimized so that application can call this at a very
high rate without performance impact.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 1/2] timer: allow timer management in shared memory
2018-12-07 18:10 3% ` Stephen Hemminger
@ 2018-12-07 19:21 4% ` Carrillo, Erik G
0 siblings, 0 replies; 200+ results
From: Carrillo, Erik G @ 2018-12-07 19:21 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: rsanford, jerin.jacob, pbhagavatula, dev
Hi Stephen,
Thanks for the review. Some responses in-line:
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, December 7, 2018 12:10 PM
> To: Carrillo, Erik G <erik.g.carrillo@intel.com>
> Cc: rsanford@akamai.com; jerin.jacob@caviumnetworks.com;
> pbhagavatula@caviumnetworks.com; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 1/2] timer: allow timer management in
> shared memory
>
> On Fri, 7 Dec 2018 11:52:59 -0600
> Erik Gabriel Carrillo <erik.g.carrillo@intel.com> wrote:
>
> > Currently, the timer library uses a per-process table of structures to
> > manage skiplists of timers presumably because timers contain arbitrary
> > function pointers whose value may not resolve properly in other
> > processes.
> >
> > However, if the same callback is used handle all timers, and that
> > callback is only invoked in one process, then it woud be safe to allow
> > the data structures to be allocated in shared memory, and to allow
> > secondary processes to modify the timer lists. This would let timers
> > be used in more multi-process scenarios.
> >
> > The library's global variables are wrapped with a struct, and an array
> > of these structures is created in shared memory. The original APIs
> > are updated to reference the zeroth entry in the array. This maintains
> > the original behavior for both primary and secondary processes since
> > the set intersection of their coremasks should be empty [1]. New APIs
> > are introduced to enable the allocation/deallocation of other entries
> > in the array.
> >
> > New variants of the APIs used to start and stop timers are introduced;
> > they allow a caller to specify which array entry should be used to
> > locate the timer list to insert into or delete from.
> >
> > Finally, a new variant of rte_timer_manage() is introduced, which
> > allows a caller to specify which array entry should be used to locate
> > the timer lists to process; it can also process multiple timer lists
> > per invocation.
> >
> > [1]
> > https://doc.dpdk.org/guides/prog_guide/multi_proc_support.html#multi-
> p
> > rocess-limitations
> >
> > Signed-off-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
>
> Makes sense but it looks to me like an ABI breakage. Experimental isn't going
> to work for this.
For APIs that existed prior to this patch, I've duplicated them in a "19.02" node in
the map file; I only marked new APIs as experimental. I versioned each API in
order to maintain the prior interface as well. I tested ABI compatibility
with devtools/validate-abi.sh; it reported no errors detected. So I believe this
won't break the ABI, but if I need to change something I certainly will.
>
> > +static uint32_t default_data_id; // id set to zero automatically
>
> C++ style comments are not allowed per DPDK coding style.
> Best to just drop the comment, it is stating the obvious.
>
Sure - will do.
> > -/* Init the timer library. */
> > +static inline int
> > +timer_data_valid(uint32_t id)
> > +{
> > + return !!(rte_timer_data_arr[id].internal_flags & FL_ALLOCATED); }
>
> Don't need inline on static functions.
> ...
>
> > +MAP_STATIC_SYMBOL(int rte_timer_manage(void),
> > +rte_timer_manage_v1902); BIND_DEFAULT_SYMBOL(rte_timer_manage,
> > +_v1902, 19.02);
> > +
> > +int __rte_experimental
> > +rte_timer_alt_manage(uint32_t timer_data_id,
> > + unsigned int *poll_lcores,
> > + int nb_poll_lcores,
> > + rte_timer_alt_manage_cb_t f)
> > +{
> > + union rte_timer_status status;
> > + struct rte_timer *tim, *next_tim, **pprev;
> > + struct rte_timer *run_first_tims[RTE_MAX_LCORE];
> > + unsigned int runlist_lcore_ids[RTE_MAX_LCORE];
> > + unsigned int this_lcore = rte_lcore_id();
> > + struct rte_timer *prev[MAX_SKIPLIST_DEPTH + 1];
> > + uint64_t cur_time;
> > + int i, j, ret;
> > + int nb_runlists = 0;
> > + struct rte_timer_data *data;
> > + struct priv_timer *privp;
> > + uint32_t poll_lcore;
> > +
> > + TIMER_DATA_VALID_GET_OR_ERR_RET(timer_data_id, data, -
> EINVAL);
> > +
> > + /* timer manager only runs on EAL thread with valid lcore_id */
> > + assert(this_lcore < RTE_MAX_LCORE);
> > +
> > + __TIMER_STAT_ADD(data->priv_timer, manage, 1);
> > +
> > + if (poll_lcores == NULL) {
> > + poll_lcores = (unsigned int []){rte_lcore_id()};
>
>
> This isn't going to be safe. It assigns poll_lcores to an array allocated on the
> stack.
>
poll_lcores is allowed to be NULL when rte_timer_alt_manage() is called for
convenience; if it is NULL, then we create an array on the stack
containing one item and point poll_lcores at it. poll_lcores only needs to be
valid for the invocation of the function, so pointing to an array on the stack
seems fine. Did I miss the point?
> > +
> > + for (i = 0, poll_lcore = poll_lcores[i]; i < nb_poll_lcores;
> > + poll_lcore = poll_lcores[++i]) {
> > + privp = &data->priv_timer[poll_lcore];
> > +
> > + /* optimize for the case where per-cpu list is empty */
> > + if (privp->pending_head.sl_next[0] == NULL)
> > + continue;
> > + cur_time = rte_get_timer_cycles();
> > +
> > +#ifdef RTE_ARCH_64
> > + /* on 64-bit the value cached in the pending_head.expired
> will
> > + * be updated atomically, so we can consult that for a quick
> > + * check here outside the lock
> > + */
> > + if (likely(privp->pending_head.expire > cur_time))
> > + continue;
> > +#endif
>
>
> This code needs to be optimized so that application can call this at a very high
> rate without performance impact.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [RFC PATCH 2/3] mlx5: Implement support for read_clock
@ 2018-12-09 6:03 3% ` Shahaf Shuler
0 siblings, 0 replies; 200+ results
From: Shahaf Shuler @ 2018-12-09 6:03 UTC (permalink / raw)
To: Tom Barbette, dev
Cc: bruce.richardson, john.mcnamara, Thomas Monjalon, Ferruh Yigit,
Andrew Rybchenko, Yongseok Koh
Hi Tom,
See few comments.
Wednesday, November 28, 2018 11:52 AM, Tom Barbette:
> Subject: [RFC PATCH 2/3] mlx5: Implement support for read_clock
>
> Signed-off-by: Tom Barbette <barbette@kth.se>
> ---
> drivers/net/mlx5/mlx5.c | 1 +
> drivers/net/mlx5/mlx5.h | 1 +
> drivers/net/mlx5/mlx5_ethdev.c | 31
> +++++++++++++++++++++++++++++++
> drivers/net/mlx5/mlx5_glue.c | 8 ++++++++
> drivers/net/mlx5/mlx5_glue.h | 2 ++
> 5 files changed, 43 insertions(+)
>
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> 9e5cab169..ed799ab5a 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -372,6 +372,7 @@ const struct eth_dev_ops mlx5_dev_ops = {
> .xstats_reset = mlx5_xstats_reset,
> .xstats_get_names = mlx5_xstats_get_names,
> .dev_infos_get = mlx5_dev_infos_get,
> + .read_clock = mlx5_read_clock,
> .dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
> .vlan_filter_set = mlx5_vlan_filter_set,
> .rx_queue_setup = mlx5_rx_queue_setup, diff --git
> a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> bc500b2bc..3972debf5 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -258,6 +258,7 @@ int mlx5_set_flags(struct rte_eth_dev *dev, unsigned
> int keep,
> unsigned int flags);
> int mlx5_dev_configure(struct rte_eth_dev *dev); void
> mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info
> *info);
> +int mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *time);
> const uint32_t *mlx5_dev_supported_ptypes_get(struct rte_eth_dev
> *dev); int mlx5_link_update(struct rte_eth_dev *dev, int
> wait_to_complete); int mlx5_force_link_status_change(struct rte_eth_dev
> *dev, int status); diff --git a/drivers/net/mlx5/mlx5_ethdev.c
> b/drivers/net/mlx5/mlx5_ethdev.c index d178ed6a1..eb97ab27e 100644
> --- a/drivers/net/mlx5/mlx5_ethdev.c
> +++ b/drivers/net/mlx5/mlx5_ethdev.c
> @@ -557,6 +557,37 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev,
> struct rte_eth_dev_info *info)
> }
> }
>
> +/**
> + * Get device current raw clock counter
> + *
> + * @param dev
> + * Pointer to Ethernet device structure.
> + *
Above space is not needed.
> + * @param[out] time
> + * Current raw clock counter of the device.
> + *
> + * @return
> + * 0 if the clock has correctly been read
And if not?
> + */
> +int
> +mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock) {
> + struct priv *priv = dev->data->dev_private;
> + struct ibv_values_ex values;
> + int err = 0;
> +
> + values.comp_mask = IBV_VALUES_MASK_RAW_CLOCK;
> + err = mlx5_glue->query_rt_values_ex(priv->ctx, &values);
> + if (err != 0) {
> + DRV_LOG(WARNING, "Could not query the clock !");
> + return err;
> + }
> +
Above space is not needed.
> + *clock = values.raw_clock.tv_nsec;
> + return 0;
> +}
> +
> +
> /**
> * Get supported packet types.
> *
> diff --git a/drivers/net/mlx5/mlx5_glue.c b/drivers/net/mlx5/mlx5_glue.c
> index dd10ad6de..e23296519 100644
> --- a/drivers/net/mlx5/mlx5_glue.c
> +++ b/drivers/net/mlx5/mlx5_glue.c
> @@ -86,6 +86,13 @@ mlx5_glue_query_device_ex(struct ibv_context
> *context,
> return ibv_query_device_ex(context, input, attr); }
>
> +static int
> +mlx5_glue_query_rt_values_ex(struct ibv_context *context,
> + struct ibv_values_ex *values)
> +{
> + return ibv_query_rt_values_ex(context, values); }
> +
> static int
> mlx5_glue_query_port(struct ibv_context *context, uint8_t port_num,
> struct ibv_port_attr *port_attr) @@ -491,6 +498,7 @@
> const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){
> .close_device = mlx5_glue_close_device,
> .query_device = mlx5_glue_query_device,
> .query_device_ex = mlx5_glue_query_device_ex,
> + .query_rt_values_ex = mlx5_glue_query_rt_values_ex,
> .query_port = mlx5_glue_query_port,
> .create_comp_channel = mlx5_glue_create_comp_channel,
> .destroy_comp_channel = mlx5_glue_destroy_comp_channel, diff --
> git a/drivers/net/mlx5/mlx5_glue.h b/drivers/net/mlx5/mlx5_glue.h index
> 2d92ba8bc..31ebee72a 100644
> --- a/drivers/net/mlx5/mlx5_glue.h
> +++ b/drivers/net/mlx5/mlx5_glue.h
> @@ -70,6 +70,8 @@ struct mlx5_glue {
> int (*query_device_ex)(struct ibv_context *context,
> const struct ibv_query_device_ex_input *input,
> struct ibv_device_attr_ex *attr);
> + int (*query_rt_values_ex)(struct ibv_context *context,
> + struct ibv_values_ex *values);
You need to bump up the LIB_GLUE_VERSION to 19.02 on the makefile(s) as you change the lib glue ABI.
> int (*query_port)(struct ibv_context *context, uint8_t port_num,
> struct ibv_port_attr *port_attr);
> struct ibv_comp_channel *(*create_comp_channel)
> --
> 2.17.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] ethdev: support double precision RED queue weight
2018-11-29 6:12 3% ` Stephen Hemminger
@ 2018-12-10 5:43 0% ` Rao, Nikhil
2018-12-10 16:01 0% ` Stephen Hemminger
0 siblings, 1 reply; 200+ results
From: Rao, Nikhil @ 2018-12-10 5:43 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Dumitrescu, Cristian, Singh, Jasvinder, dev
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Thursday, November 29, 2018 11:43 AM
> To: Rao, Nikhil <nikhil.rao@intel.com>
> Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Singh, Jasvinder
> <jasvinder.singh@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH] ethdev: support double precision RED queue
> weight
>
> On Thu, 29 Nov 2018 11:24:42 +0530
> Nikhil Rao <nikhil.rao@intel.com> wrote:
>
> > RED queue weight is currently specified as a negated log of 2.
> >
> > Add support for RED queue weight to be specified in double precision
> > and TM capability flags for double precision and negated log2 RED
> > queue weight support.
> >
> > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
>
> Since this is an ABI break anyway, why not just commit to the new format?
Hi Stephen,
Can you please provide more detail on your comment ? are you suggesting replacing the wq_log2/wq_dp with a double ?
Thanks,
Nikhil
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: support double precision RED queue weight
2018-12-10 5:43 0% ` Rao, Nikhil
@ 2018-12-10 16:01 0% ` Stephen Hemminger
2019-01-10 6:23 0% ` Rao, Nikhil
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2018-12-10 16:01 UTC (permalink / raw)
To: Rao, Nikhil; +Cc: Dumitrescu, Cristian, Singh, Jasvinder, dev
On Mon, 10 Dec 2018 05:43:37 +0000
"Rao, Nikhil" <nikhil.rao@intel.com> wrote:
> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Thursday, November 29, 2018 11:43 AM
> > To: Rao, Nikhil <nikhil.rao@intel.com>
> > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Singh, Jasvinder
> > <jasvinder.singh@intel.com>; dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH] ethdev: support double precision RED queue
> > weight
> >
> > On Thu, 29 Nov 2018 11:24:42 +0530
> > Nikhil Rao <nikhil.rao@intel.com> wrote:
> >
> > > RED queue weight is currently specified as a negated log of 2.
> > >
> > > Add support for RED queue weight to be specified in double precision
> > > and TM capability flags for double precision and negated log2 RED
> > > queue weight support.
> > >
> > > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> >
> > Since this is an ABI break anyway, why not just commit to the new format?
>
> Hi Stephen,
>
> Can you please provide more detail on your comment ? are you suggesting replacing the wq_log2/wq_dp with a double ?
>
> Thanks,
> Nikhil
My comment is that since you are changing a structure layout, which would
break existing users; why not go farther and just fix the API to a better
version. I don't think any projects use this code anyway,
see my talk (https://github.com/shemminger/dpdk-metrics).
Isn't floating point going to be expensive. Or is it only during the setup
process, not enqueue/dequeue.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] libs/power: add p-state driver compatibility
2018-11-23 11:33 1% [dpdk-dev] [PATCH] libs/power: add p-state driver compatibility Liang Ma
@ 2018-12-10 16:08 0% ` Burakov, Anatoly
2018-12-14 11:13 1% ` [dpdk-dev] [PATCH v2] " Liang Ma
1 sibling, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-12-10 16:08 UTC (permalink / raw)
To: Liang Ma, david.hunt; +Cc: dev, lei.a.yao, ktraynor
On 23-Nov-18 11:33 AM, Liang Ma wrote:
> Previously, in order to use the power library, it was necessary
> for the user to disable the intel_pstate driver by adding
> “intel_pstate=disable” to the kernel command line for the system,
> which causes the acpi_cpufreq driver to be loaded in its place.
>
> This patch adds the ability for the power library use the intel-pstate
> driver.
>
> It adds a new suite of functions behind the current power library API,
> and will seamlessly set up the user facing API function pointers to
> the relevant functions depending on whether the system is running with
> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
> using kvm. The library API and ABI is unchanged.
>
> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
Hi Liang,
General comment: please do not break up log strings onto multiple lines.
It makes it harder to grep the codebase. Checkpatch will not warn about
log strings going over 80 characters.
> ---
> lib/librte_power/Makefile | 2 +
> lib/librte_power/meson.build | 4 +-
> lib/librte_power/power_pstate_cpufreq.c | 778 ++++++++++++++++++++++++++++++++
> lib/librte_power/power_pstate_cpufreq.h | 218 +++++++++
> lib/librte_power/rte_power.c | 43 +-
> lib/librte_power/rte_power.h | 3 +-
> 6 files changed, 1039 insertions(+), 9 deletions(-)
> create mode 100644 lib/librte_power/power_pstate_cpufreq.c
> create mode 100644 lib/librte_power/power_pstate_cpufreq.h
<snip>
> sources = files('rte_power.c', 'power_acpi_cpufreq.c',
> 'power_kvm_vm.c', 'guest_channel.c',
> - 'rte_power_empty_poll.c')
> + 'rte_power_empty_poll.c',
> + 'power_pstate_cpufreq.c')
> headers = files('rte_power.h','rte_power_empty_poll.h')
> -deps += ['timer']
> diff --git a/lib/librte_power/power_pstate_cpufreq.c b/lib/librte_power/power_pstate_cpufreq.c
> new file mode 100644
> index 0000000..f1dada8
> --- /dev/null
> +++ b/lib/librte_power/power_pstate_cpufreq.c
> @@ -0,0 +1,778 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2018 Intel Corporation
I believe it should be 2018.
> + */
> +
> +#include <stdio.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <signal.h>
> +#include <limits.h>
> +#include <errno.h>
> +
> +#include <rte_memcpy.h>
> +#include <rte_atomic.h>
> +
> +#include "power_pstate_cpufreq.h"
> +#include "power_common.h"
> +
<snip>
> +
> +static struct pstate_power_info lcore_power_info[RTE_MAX_LCORE];
> +
> +/**
> + * It is to read the specific MSR.
> + */
> +
> +static int32_t
> +power_rdmsr(int msr, uint64_t *val, unsigned int lcore_id)
> +{
> + int fd;
> + int ret;
int fd, ret?
> + char fullpath[PATH_MAX];
> +
> + snprintf(fullpath, sizeof(fullpath), POWER_MSR_PATH, lcore_id);
> +
> + fd = open(fullpath, O_RDONLY);
> +
> + if (fd < 0) {
> +
> + if (errno == EACCES)
> + RTE_LOG(ERR, POWER, "No access to %s\n", fullpath);
> +
> + if (errno == ENXIO)
> + RTE_LOG(ERR, POWER, "%s Not Exist!\n", fullpath);
How about:
RTE_LOG(ERR, POWER, "Error opening '%s': %s\n", fullpath, strerror(errno));
?
> +
> + return fd;
> + }
> +
> + ret = pread(fd, val, sizeof(uint64_t), msr);
Can pread fail?
> +
> + close(fd);
> +
> + POWER_DEBUG_TRACE("MSR Path %s, offset 0x%X for lcore %u\n",
> + fullpath, msr, lcore_id);
> +
> + POWER_DEBUG_TRACE("Ret value %d, content is 0x%lx\n", ret, *val);
> +
> + return ret;
> +}
> +
<snip>
> + if (fseek(pi->f_cur_max, 0, SEEK_SET) < 0) {
> + RTE_LOG(ERR, POWER, "Fail to set file position indicator to 0 "
> + "for setting frequency for lcore %u\n",
> + pi->lcore_id);
> + return -1;
> + }
> +
> + /* Turbo is available and enabled, first freq bucket is sys max freq */
> + if (pi->turbo_available && pi->turbo_enable && (idx == 0))
> +
> + target_freq = pi->sys_max_freq;
> +
> + else
> +
> + target_freq = pi->freqs[idx];
Unneeded whitespace?
> +
> +
> + /* Decrease freq, the min freq should be updated first */
> + if (idx > pi->curr_idx) {
> +
> + if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
> + RTE_LOG(ERR, POWER, "Fail to write new frequency for "
> + "lcore %u\n", pi->lcore_id);
> + return -1;
> + }
> +
> + if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
> + RTE_LOG(ERR, POWER, "Fail to write new frequency for "
> + "lcore %u\n", pi->lcore_id);
> + return -1;
> + }
> +
> + POWER_DEBUG_TRACE("Freqency[%u] to be set for lcore %u\n",
> + target_freq, pi->lcore_id);
Frequency :)
Also, i believe "Frequency[%u]" is misleading in this case, because the
value is not an index into an array, but is an actual target frequency.
I think "Frequency '%u'" would be more descriptive.
> +
> + fflush(pi->f_cur_min);
> + fflush(pi->f_cur_max);
> +
> + }
> +
> + /* Increase freq, the max freq should be updated first */
> + if (idx < pi->curr_idx) {
Else if?
> +
> + if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
> + RTE_LOG(ERR, POWER, "Fail to write new frequency for "
> + "lcore %u\n", pi->lcore_id);
> + return -1;
> + }
> +
> + if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
> + RTE_LOG(ERR, POWER, "Fail to write new frequency for "
> + "lcore %u\n", pi->lcore_id);
> + return -1;
> + }
Forgot POWER_DEBUG_TRACE?
> +
> + fflush(pi->f_cur_max);
> + fflush(pi->f_cur_min);
> + }
> +
> + pi->curr_idx = idx;
> +
> + return 1;
> +}
> +
<snip>
> + snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_GOVERNOR,
> + pi->lcore_id);
> + f = fopen(fullpath, "rw+");
> + FOPEN_OR_ERR_RET(f, ret);
> +
> + s = fgets(buf, sizeof(buf), f);
> + FOPS_OR_NULL_GOTO(s, out);
> +
> + /* Check if current governor is performance */
> + if (strncmp(buf, POWER_GOVERNOR_PERF,
> + sizeof(POWER_GOVERNOR_PERF)) == 0) {
Nitpick, but probably should be strlen, not sizeof?
> + ret = 0;
> + POWER_DEBUG_TRACE("Power management governor of lcore %u is "
> + "already performance\n", pi->lcore_id);
> + goto out;
> + }
> + /* Save the original governor */
> + snprintf(pi->governor_ori, sizeof(pi->governor_ori), "%s", buf);
> +
> + /* Write 'performance' to the governor */
> + val = fseek(f, 0, SEEK_SET);
> + FOPS_OR_ERR_GOTO(val, out);
> +
> + val = fputs(POWER_GOVERNOR_PERF, f);
> + FOPS_OR_ERR_GOTO(val, out);
> +
> + ret = 0;
> + RTE_LOG(INFO, POWER, "Power management governor of lcore %u has been "
> + "set to performance successfully\n", pi->lcore_id);
Do we want this as INFO? (it's OK if we do, just asking!)
> +out:
> + fclose(f);
> +
> + return ret;
> +}
> +
> +/**
> + * It is to check the governor and then set the original governor back if
> + * needed by writing the sys file.
> + */
> +static int
> +power_set_governor_original(struct pstate_power_info *pi)
> +{
<snip>
> + /* Write back the original governor */
> + val = fseek(f, 0, SEEK_SET);
> + FOPS_OR_ERR_GOTO(val, out);
> +
> + val = fputs(pi->governor_ori, f);
> + FOPS_OR_ERR_GOTO(val, out);
> +
> + ret = 0;
> + RTE_LOG(INFO, POWER, "Power management governor of lcore %u "
> + "has been set back to %s successfully\n",
> + pi->lcore_id, pi->governor_ori);
Same - do we want this as INFO?
> +out:
> + fclose(f);
> +
> + return ret;
> +}
> +
> +/**
> + * It is to get the available frequencies of the specific lcore by reading the
> + * sys file.
> + */
> +static int
> +power_get_available_freqs(struct pstate_power_info *pi)
> +{
> + FILE *f_min, *f_max;
> + int ret = -1;
> + char *p_min, *p_max;
> + char buf_min[BUFSIZ];
> + char buf_max[BUFSIZ];
> + char fullpath_min[PATH_MAX];
> + char fullpath_max[PATH_MAX];
> + char *s_min, *s_max;
> + uint32_t sys_min_freq = 0, sys_max_freq = 0, base_max_freq = 0;
> + uint32_t i, num_freqs = 0;
> +
> + snprintf(fullpath_max, sizeof(fullpath_max),
> + POWER_SYSFILE_BASE_MAX_FREQ,
> + pi->lcore_id);
> + snprintf(fullpath_min, sizeof(fullpath_min),
> + POWER_SYSFILE_BASE_MIN_FREQ,
> + pi->lcore_id);
> +
> + f_min = fopen(fullpath_min, "r");
> + FOPEN_OR_ERR_RET(f_min, ret);
> +
> + s_min = fgets(buf_min, sizeof(buf_min), f_min);
> + FOPS_OR_NULL_GOTO(s_min, out);
> +
> + f_max = fopen(fullpath_max, "r");
> + FOPEN_OR_ERR_RET(f_max, ret);
> +
> + s_max = fgets(buf_max, sizeof(buf_max), f_max);
> + FOPS_OR_NULL_GOTO(s_max, out);
> +
> +
> + /* Strip the line break if there is */
> + p_min = strchr(buf_min, '\n');
> + if (p_min != NULL)
> + *p_min = 0;
> +
> + p_max = strchr(buf_max, '\n');
> + if (p_max != NULL)
> + *p_max = 0;
Probably '\0' would be more correct.
> +
> + sys_min_freq = strtoul(buf_min, &p_min, POWER_CONVERT_TO_DECIMAL);
> + sys_max_freq = strtoul(buf_max, &p_max, POWER_CONVERT_TO_DECIMAL);
> +
> + if (sys_max_freq < sys_min_freq)
> + goto out;
This leaks fds. See below.
> +
> +
> + pi->sys_max_freq = sys_max_freq;
> +
> + base_max_freq = pi->non_turbo_max_ratio*BUS_FREQ;
spacing around multiplication :)
> +
> + POWER_DEBUG_TRACE("sys min %u, sys max %u, base_max %u\n",
> + sys_min_freq,
> + sys_max_freq,
> + base_max_freq);
> +
> + if (base_max_freq < sys_max_freq)
> +
> + pi->turbo_available = 1;
Extra whitespace.
> + else
> + pi->turbo_available = 0;
> +
> +
> + /* If turbo is available then there is one extra freq bucket
> + * to store the sys max freq which value is base_max +1
> + */
> + num_freqs = (base_max_freq - sys_min_freq)/BUS_FREQ + 1
> + + pi->turbo_available;
The '+' should be on the preceding line, also spacing.
> +
> + /* Generate the freq bucket array.
> + * If turbo is available the freq bucket[0] value is base_max +1
> + * the bucket[1] is base_max, bucket[2] is base_max - BUS_FREQ
> + * and so on.
> + * If turbo is not available bucket[0] is base_max and so on
> + */
> + for (i = 0, pi->nb_freqs = 0; i < num_freqs; i++) {
> +
Extra whitespace.
> + if ((i == 0) && pi->turbo_available)
> + pi->freqs[pi->nb_freqs++] = base_max_freq + 1;
> + else
> + pi->freqs[pi->nb_freqs++] =
> + base_max_freq - (i - pi->turbo_available)*BUS_FREQ;
Misleading indentation, also spacing around multiplication operator.
> + }
> +
> + ret = 0;
> +
> + POWER_DEBUG_TRACE("%d frequency(s) of lcore %u are available\n",
> + num_freqs, pi->lcore_id);
> +
> + fclose(f_min);
> + fclose(f_max);
> +
> +
> +out:
fclose should be after out, otherwise error path above will leak fd.
> + return ret;
> +}
> +
> +int
> +power_pstate_cpufreq_init(unsigned int lcore_id)
> +{
> + struct pstate_power_info *pi;
> +
> + if (lcore_id >= RTE_MAX_LCORE) {
> + RTE_LOG(ERR, POWER, "Lcore id %u can not exceeds %u\n",
Cannot exceed.
> + lcore_id, RTE_MAX_LCORE - 1U);
> + return -1;
> + }
> +
> + pi = &lcore_power_info[lcore_id];
> + if (rte_atomic32_cmpset(&(pi->state), POWER_IDLE, POWER_ONGOING)
> + == 0) {
> + RTE_LOG(INFO, POWER, "Power management of lcore %u is "
> + "in use\n", lcore_id);
> + return -1;
> + }
> +
> + pi->lcore_id = lcore_id;
Can we not set this until we're sure we didn't fail? Or do any of the
below calls rely on pi->lcore_id to be set?
> + /* Check and set the governor */
> + if (power_set_governor_performance(pi) < 0) {
> + RTE_LOG(ERR, POWER, "Cannot set governor of lcore %u to "
> + "performance\n", lcore_id);
> + goto fail;
> + }
> + /* Init for setting lcore frequency */
> + if (power_init_for_setting_freq(pi) < 0) {
> + RTE_LOG(ERR, POWER, "Cannot init for setting frequency for "
> + "lcore %u\n", lcore_id);
> + goto fail;
> + }
> +
> + /* Get the available frequencies */
> + if (power_get_available_freqs(pi) < 0) {
> + RTE_LOG(ERR, POWER, "Cannot get available frequencies of "
> + "lcore %u\n", lcore_id);
> + goto fail;
> + }
> +
> +
> + /* Set freq to max by default */
> + if (power_pstate_cpufreq_freq_max(lcore_id) < 0) {
> + RTE_LOG(ERR, POWER, "Cannot set frequency of lcore %u "
> + "to max\n", lcore_id);
> + goto fail;
> + }
> +
> + RTE_LOG(INFO, POWER, "Initialized successfully for lcore %u "
> + "power management\n", lcore_id);
Do we want this as INFO?
> + rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_USED);
> +
> + return 0;
> +
> +fail:
> + rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
> +
> + return -1;
> +}
> +
> +int
> +power_pstate_cpufreq_exit(unsigned int lcore_id)
> +{
> + struct pstate_power_info *pi;
> +
<snip>
> + /* Set the governor back to the original */
> + if (power_set_governor_original(pi) < 0) {
> + RTE_LOG(ERR, POWER, "Cannot set the governor of %u back "
> + "to the original\n", lcore_id);
> + goto fail;
> + }
> +
> + RTE_LOG(INFO, POWER, "Power management of lcore %u has exited from "
> + "'performance' mode and been set back to the "
> + "original\n", lcore_id);
Perhaps print out the original governor name? Also, i think it's better
to use the performance string define, rather than having it as part of
formatted message.
> + rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_IDLE);
> +
> + return 0;
> +
> +fail:
> + rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
> +
> + return -1;
> +}
> +
> +
> +uint32_t
> +power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
> +{
> + struct pstate_power_info *pi;
> +
> + if (lcore_id >= RTE_MAX_LCORE) {
> + RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
> + return -1;
> + }
> +
> + pi = &lcore_power_info[lcore_id];
> + if (num < pi->nb_freqs) {
> + RTE_LOG(ERR, POWER, "Buffer size is not enough\n");
> + return 0;
> + }
> + rte_memcpy(freqs, pi->freqs, pi->nb_freqs * sizeof(uint32_t));
Why rte_memcpy?
> +
> + return pi->nb_freqs;
> +}
> +
> +uint32_t
> +power_pstate_cpufreq_get_freq(unsigned int lcore_id)
> +{
> + if (lcore_id >= RTE_MAX_LCORE) {
> + RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
> + return RTE_POWER_INVALID_FREQ_INDEX;
> + }
> +
> + return lcore_power_info[lcore_id].curr_idx;
> +}
> +
<snip>
> + caps->turbo = !!(pi->turbo_available);
> +
> + return 0;
> +}
> diff --git a/lib/librte_power/power_pstate_cpufreq.h b/lib/librte_power/power_pstate_cpufreq.h
> new file mode 100644
> index 0000000..0fc917a
> --- /dev/null
> +++ b/lib/librte_power/power_pstate_cpufreq.h
> @@ -0,0 +1,218 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2018 Intel Corporation
I believe it should be just 2018.
> + */
> +
> +#ifndef _POWER_PSTATE_CPUFREQ_H
> +#define _POWER_PSTATE_CPUFREQ_H
> +
> +/**
> + * @file
> + * RTE Power Management via Intel Pstate driver
> + */
> +
> +#include <rte_common.h>
> +#include <rte_byteorder.h>
> +#include <rte_log.h>
> +#include <rte_string_fns.h>
> +#include "rte_power.h"
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
I don't think this is necessary. These extern declarations are only for
public API headers, so that C++ compilers could parse them. Since this
is not a public header, there's no need for extern C declaration.
> +
> +/**
> + * Initialize power management for a specific lcore. It will check and set the
> + * governor to performance for the lcore, get the available frequencies, and
> + * prepare to set new lcore frequency.
> + *
> + * @param lcore_id
> + * lcore id.
> + *
> + * @return
> + * - 0 on success.
> + * - Negative on error.
> + */
<snip>
> + *
> + * @return
> + * The number of available frequencies.
> + */
> +uint32_t power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs,
> + uint32_t num);
> +
> +/**
> + * Return the current index of available frequencies of a specific lcore. It
> + * will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)' if error.
This isn't a public API, so it's nitpicking, but any notes about return
value should be in the @return section.
> + * It should be protected outside of this function for threadsafe.
> + *
> + * @param lcore_id
> + * lcore id.
> + *
> + * @return
> + * The current index of available frequencies.
> + */
> +uint32_t power_pstate_cpufreq_get_freq(unsigned int lcore_id);
> +
> +/**
<snip>
> #include "rte_power.h"
> #include "power_acpi_cpufreq.h"
> #include "power_kvm_vm.h"
> +#include "power_pstate_cpufreq.h"
> #include "power_common.h"
>
> enum power_management_env global_default_env = PM_ENV_NOT_SET;
> @@ -29,6 +30,8 @@ rte_power_get_capabilities_t rte_power_get_capabilities;
> int
> rte_power_set_env(enum power_management_env env)
> {
> +
> +
This is probably unintended whitespace change.
> if (rte_atomic32_cmpset(&global_env_cfg_status, 0, 1) == 0) {
> return 0;
> }
> @@ -56,6 +59,19 @@ rte_power_set_env(enum power_management_env env)
> rte_power_freq_enable_turbo = power_kvm_vm_enable_turbo;
> rte_power_freq_disable_turbo = power_kvm_vm_disable_turbo;
> rte_power_get_capabilities = power_kvm_vm_get_capabilities;
> + } else if (env == PM_ENV_PSTATE_CPUFREQ) {
> + rte_power_freqs = power_pstate_cpufreq_freqs;
> + rte_power_get_freq = power_pstate_cpufreq_get_freq;
<snip>
> + if (global_default_env == PM_ENV_KVM_VM)
> return power_kvm_vm_init(lcore_id);
> - }
> +
> + if (global_default_env == PM_ENV_PSTATE_CPUFREQ)
> + return power_pstate_cpufreq_init(lcore_id);
> +
switch?
> /* Auto detect Environment */
> RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power "
> "management...\n");
> @@ -99,13 +118,23 @@ rte_power_init(unsigned int lcore_id)
> goto out;
> }
>
> - RTE_LOG(INFO, POWER, "Attempting to initialise VM power management...\n");
> + RTE_LOG(INFO, POWER, "Attempting to initialise PSTAT power "
> + "management...\n");
> + ret = power_pstate_cpufreq_init(lcore_id);
> + if (ret == 0) {
> + rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
> + goto out;
> + }
> +
> + RTE_LOG(INFO, POWER, "Attempting to initialise VM power "
> + "management...\n");
> ret = power_kvm_vm_init(lcore_id);
> if (ret == 0) {
> rte_power_set_env(PM_ENV_KVM_VM);
> goto out;
> }
> - RTE_LOG(ERR, POWER, "Unable to set Power Management Environment for lcore "
> + RTE_LOG(ERR, POWER, "Unable to set Power Management "
> + "Environment for lcore "
> "%u\n", lcore_id);
Perhaps this could be moved to a separate function, so that the code
could look like:
switch (global_default_env) {
case PM_ENV_ACPI:
return acpi_init();
case PM_ENV_KVM:
return kvm_init();
case PM_ENV_PSTATE:
return pstate_init();
default:
if (autodetect() < 0)
RTE_LOG("error");
return 0;
}
Or something like that.
> out:
> return ret;
> @@ -118,6 +147,8 @@ rte_power_exit(unsigned int lcore_id)
> return power_acpi_cpufreq_exit(lcore_id);
> if (global_default_env == PM_ENV_KVM_VM)
> return power_kvm_vm_exit(lcore_id);
> + if (global_default_env == PM_ENV_PSTATE_CPUFREQ)
> + return power_pstate_cpufreq_exit(lcore_id);
switch?
>
> RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit "
> "gracefully\n");
> diff --git a/lib/librte_power/rte_power.h b/lib/librte_power/rte_power.h
> index d70bc0b..c5e8f6b 100644
> --- a/lib/librte_power/rte_power.h
> +++ b/lib/librte_power/rte_power.h
> @@ -20,7 +20,8 @@ extern "C" {
> #endif
>
> /* Power Management Environment State */
> -enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM};
> +enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM,
> + PM_ENV_PSTATE_CPUFREQ};
I don't like this approach. While it can be argued that application
needs to be explicitly aware of whether it's using native (ACPI or
pstate) vs. KVM power management, there's no real reason for an
application to differentiate between ACPI and pstate modes.
Changing this would of course require a deprecation notice, so for now,
can we hide all of this behind ACPI mode, and auto-detect whether we
want ACPI or pstate mode? IMO it would be better for the user
application to use a somewhat misnamed ACPI option for both ACPI and
pstate modes, than to needlessly care about whether one or the other is
in use.
What do you think?
>
> /**
> * Set the default power management implementation. If this is not called prior
>
--
Thanks,
Anatoly
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2 1/5] mem: fix error code for segment fd API for external segs
@ 2018-12-11 16:43 4% ` Anatoly Burakov
2018-12-11 16:43 4% ` [dpdk-dev] [PATCH v2 2/5] memalloc: check for memfd support in segment fd API Anatoly Burakov
1 sibling, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-12-11 16:43 UTC (permalink / raw)
To: dev
Cc: John McNamara, Marko Kovacevic, przemyslawx.lal,
kuralamudhan.ramakrishnan, ivan.coughlan, tiwei.bie,
ray.kinsella, maxime.coquelin, stable
Segment fd API does not support getting segment fd's from
externally allocated memory, so return proper error code
on any attempts to do so. This changes API behavior, so
document the change as well.
Fixes: 5282bb1c3695 ("mem: allow memseg lists to be marked as external")
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
The API is experimental, no deprecation notice needed.
doc/guides/rel_notes/release_19_02.rst | 6 ++++++
lib/librte_eal/common/eal_common_memory.c | 12 ++++++++++++
2 files changed, 18 insertions(+)
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index a94fa86a7..ade41b9c8 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -84,6 +84,12 @@ API Changes
=========================================================
+* eal: segment fd API on Linux now sets error code to ``ENOTSUP`` in more cases
+ where segment fd API is not expected to be supported:
+
+ - On attempt to get segment fd for an externally allocated memory segment
+
+
ABI Changes
-----------
diff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c
index d47ea4938..999ba24b4 100644
--- a/lib/librte_eal/common/eal_common_memory.c
+++ b/lib/librte_eal/common/eal_common_memory.c
@@ -704,6 +704,12 @@ rte_memseg_get_fd_thread_unsafe(const struct rte_memseg *ms)
return -1;
}
+ /* segment fd API is not supported for external segments */
+ if (msl->external) {
+ rte_errno = ENOTSUP;
+ return -1;
+ }
+
ret = eal_memalloc_get_seg_fd(msl_idx, seg_idx);
if (ret < 0) {
rte_errno = -ret;
@@ -754,6 +760,12 @@ rte_memseg_get_fd_offset_thread_unsafe(const struct rte_memseg *ms,
return -1;
}
+ /* segment fd API is not supported for external segments */
+ if (msl->external) {
+ rte_errno = ENOTSUP;
+ return -1;
+ }
+
ret = eal_memalloc_get_seg_fd_offset(msl_idx, seg_idx, offset);
if (ret < 0) {
rte_errno = -ret;
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 2/5] memalloc: check for memfd support in segment fd API
2018-12-11 16:43 4% ` [dpdk-dev] [PATCH v2 1/5] mem: fix error code for segment fd API for external segs Anatoly Burakov
@ 2018-12-11 16:43 4% ` Anatoly Burakov
1 sibling, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-12-11 16:43 UTC (permalink / raw)
To: dev
Cc: John McNamara, Marko Kovacevic, przemyslawx.lal,
kuralamudhan.ramakrishnan, ivan.coughlan, tiwei.bie,
ray.kinsella, maxime.coquelin, stable
If memfd support was not compiled, or hugepage memfd support
is not available at runtime, the API will now return proper
error code, indicating that this API is unsupported. This
changes the API, so document the changes.
Fixes: 41dbdb68723b ("mem: add external API to retrieve page fd")
Fixes: 3a44687139eb ("mem: allow querying offset into segment fd")
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
The API is experimental, no deprecation notice needed.
doc/guides/rel_notes/release_19_02.rst | 2 ++
lib/librte_eal/linuxapp/eal/eal_memalloc.c | 40 +++++++++++++++++-----
2 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index ade41b9c8..960098582 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -88,6 +88,8 @@ API Changes
where segment fd API is not expected to be supported:
- On attempt to get segment fd for an externally allocated memory segment
+ - In cases where memfd support would have been required to provide segment
+ fd's (such as in-memory or no-huge mode)
ABI Changes
diff --git a/lib/librte_eal/linuxapp/eal/eal_memalloc.c b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
index 784939566..a93548b8c 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
@@ -23,6 +23,10 @@
#include <sys/time.h>
#include <signal.h>
#include <setjmp.h>
+#ifdef F_ADD_SEALS /* if file sealing is supported, so is memfd */
+#include <linux/memfd.h>
+#define MEMFD_SUPPORTED
+#endif
#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
#include <numa.h>
#include <numaif.h>
@@ -53,8 +57,8 @@ const int anonymous_hugepages_supported =
#endif
/*
- * we don't actually care if memfd itself is supported - we only need to check
- * if memfd supports hugetlbfs, as that already implies memfd support.
+ * we've already checked memfd support at compile-time, but we also need to
+ * check if we can create hugepage files with memfd.
*
* also, this is not a constant, because while we may be *compiled* with memfd
* hugetlbfs support, we might not be *running* on a system that supports memfd
@@ -63,10 +67,11 @@ const int anonymous_hugepages_supported =
*/
static int memfd_create_supported =
#ifdef MFD_HUGETLB
-#define MEMFD_SUPPORTED
1;
+#define RTE_MFD_HUGETLB MFD_HUGETLB
#else
0;
+#define RTE_MFD_HUGETLB 4U
#endif
/*
@@ -338,12 +343,12 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused,
int fd;
char segname[250]; /* as per manpage, limit is 249 bytes plus null */
+ int flags = RTE_MFD_HUGETLB | pagesz_flags(hi->hugepage_sz);
+
if (internal_config.single_file_segments) {
fd = fd_list[list_idx].memseg_list_fd;
if (fd < 0) {
- int flags = MFD_HUGETLB | pagesz_flags(hi->hugepage_sz);
-
snprintf(segname, sizeof(segname), "seg_%i", list_idx);
fd = memfd_create(segname, flags);
if (fd < 0) {
@@ -357,8 +362,6 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused,
fd = fd_list[list_idx].fds[seg_idx];
if (fd < 0) {
- int flags = MFD_HUGETLB | pagesz_flags(hi->hugepage_sz);
-
snprintf(segname, sizeof(segname), "seg_%i-%i",
list_idx, seg_idx);
fd = memfd_create(segname, flags);
@@ -1542,6 +1545,17 @@ int
eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
{
int fd;
+
+ if (internal_config.in_memory || internal_config.no_hugetlbfs) {
+#ifndef MEMFD_SUPPORTED
+ /* in in-memory or no-huge mode, we rely on memfd support */
+ return -ENOTSUP;
+#endif
+ /* memfd supported, but hugetlbfs memfd may not be */
+ if (!internal_config.no_hugetlbfs && !memfd_create_supported)
+ return -ENOTSUP;
+ }
+
if (internal_config.single_file_segments) {
fd = fd_list[list_idx].memseg_list_fd;
} else if (fd_list[list_idx].len == 0) {
@@ -1565,7 +1579,7 @@ test_memfd_create(void)
int pagesz_flag = pagesz_flags(pagesz);
int flags;
- flags = pagesz_flag | MFD_HUGETLB;
+ flags = pagesz_flag | RTE_MFD_HUGETLB;
int fd = memfd_create("test", flags);
if (fd < 0) {
/* we failed - let memalloc know this isn't working */
@@ -1589,6 +1603,16 @@ eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset)
{
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ if (internal_config.in_memory || internal_config.no_hugetlbfs) {
+#ifndef MEMFD_SUPPORTED
+ /* in in-memory or no-huge mode, we rely on memfd support */
+ return -ENOTSUP;
+#endif
+ /* memfd supported, but hugetlbfs memfd may not be */
+ if (!internal_config.no_hugetlbfs && !memfd_create_supported)
+ return -ENOTSUP;
+ }
+
/* fd_list not initialized? */
if (fd_list[list_idx].len == 0)
return -ENODEV;
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH 1/6] bitmap: remove deprecated bsf64 function
@ 2018-12-11 17:57 4% Anatoly Burakov
2018-12-11 17:57 4% ` [dpdk-dev] [PATCH 2/6] common: add bsf64 function similar to existing bsf32 Anatoly Burakov
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Anatoly Burakov @ 2018-12-11 17:57 UTC (permalink / raw)
To: dev
Cc: Neil Horman, John McNamara, Marko Kovacevic, Cristian Dumitrescu,
thomas, jasvinder.singh, jerin.jacob
The function rte_bsf64 was deprecated in a previous release, so
remove the function, and the deprecation notice associated with
it.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 5 -----
doc/guides/rel_notes/release_19_02.rst | 4 ++++
lib/librte_eal/common/include/rte_bitmap.h | 6 ------
3 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b48486d36..aa96d9b19 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -20,11 +20,6 @@ Deprecation Notices
* kvargs: The function ``rte_kvargs_process`` will get a new parameter
for returning key match count. It will ease handling of no-match case.
-* eal: function ``rte_bsf64`` in ``rte_bitmap.h`` has been renamed to
- ``rte_bsf64_safe`` and moved to ``rte_common.h``. A new ``rte_bsf64`` function
- will be added in the next release in ``rte_common.h`` that follows convention
- set by existing ``rte_bsf32`` function.
-
* eal: both declaring and identifying devices will be streamlined in v18.11.
New functions will appear to query a specific port from buses, classes of
device and device drivers. Device declaration will be made coherent with the
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index a94fa86a7..ff81357d4 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -84,6 +84,10 @@ API Changes
=========================================================
+* eal: function ``rte_bsf64`` in ``rte_bitmap.h`` has been renamed to
+ ``rte_bsf64_safe`` and moved to ``rte_common.h``.
+
+
ABI Changes
-----------
diff --git a/lib/librte_eal/common/include/rte_bitmap.h b/lib/librte_eal/common/include/rte_bitmap.h
index 77727c828..6b846f251 100644
--- a/lib/librte_eal/common/include/rte_bitmap.h
+++ b/lib/librte_eal/common/include/rte_bitmap.h
@@ -93,12 +93,6 @@ __rte_bitmap_index2_set(struct rte_bitmap *bmp)
bmp->index2 = (((bmp->index1 << RTE_BITMAP_SLAB_BIT_SIZE_LOG2) + bmp->offset1) << RTE_BITMAP_CL_SLAB_SIZE_LOG2);
}
-static inline int __rte_deprecated
-rte_bsf64(uint64_t slab, uint32_t *pos)
-{
- return rte_bsf64_safe(slab, pos);
-}
-
static inline uint32_t
__rte_bitmap_get_memory_footprint(uint32_t n_bits,
uint32_t *array1_byte_offset, uint32_t *array1_slabs,
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH 2/6] common: add bsf64 function similar to existing bsf32
2018-12-11 17:57 4% [dpdk-dev] [PATCH 1/6] bitmap: remove deprecated bsf64 function Anatoly Burakov
@ 2018-12-11 17:57 4% ` Anatoly Burakov
2018-12-20 12:09 4% ` [dpdk-dev] [PATCH v2 1/4] bitmap: remove deprecated bsf64 function Anatoly Burakov
2018-12-20 12:09 4% ` [dpdk-dev] [PATCH v2 2/4] common: add bsf64 and bsf32_safe functions Anatoly Burakov
2 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-12-11 17:57 UTC (permalink / raw)
To: dev
Cc: John McNamara, Marko Kovacevic, thomas, jasvinder.singh,
cristian.dumitrescu, jerin.jacob
Implement a new rte_bsf64 function that is following convention
set by existing rte_bsf32 function. Also, document the change in
release notes.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
doc/guides/rel_notes/release_19_02.rst | 4 +++-
lib/librte_eal/common/include/rte_common.h | 19 ++++++++++++++++++-
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index ff81357d4..1d56ad43e 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -85,7 +85,9 @@ API Changes
* eal: function ``rte_bsf64`` in ``rte_bitmap.h`` has been renamed to
- ``rte_bsf64_safe`` and moved to ``rte_common.h``.
+ ``rte_bsf64_safe`` and moved to ``rte_common.h``. A new ``rte_bsf64`` function
+ has been added in ``rte_common.h`` that follows convention set by existing
+ ``rte_bsf32`` function.
ABI Changes
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index 66cdf60b2..2735dcca7 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -482,6 +482,23 @@ rte_fls_u32(uint32_t x)
return (x == 0) ? 0 : 32 - __builtin_clz(x);
}
+/**
+ * Searches the input parameter for the least significant set bit
+ * (starting from zero).
+ * If a least significant 1 bit is found, its bit index is returned.
+ * If the content of the input parameter is zero, then the content of the return
+ * value is undefined.
+ * @param v
+ * input parameter, should not be zero.
+ * @return
+ * least significant set bit in the input parameter.
+ */
+static inline int
+rte_bsf64(uint64_t v)
+{
+ return (uint32_t)__builtin_ctzll(v);
+}
+
/**
* Searches the input parameter for the least significant set bit
* (starting from zero). Safe version (checks for input parameter being zero).
@@ -502,7 +519,7 @@ rte_bsf64_safe(uint64_t v, uint32_t *pos)
if (v == 0)
return 0;
- *pos = __builtin_ctzll(v);
+ *pos = rte_bsf64(v);
return 1;
}
--
2.17.1
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2 1/3] mbuf: implement generic format for sched field
2018-12-07 14:31 5% ` [dpdk-dev] [PATCH v2 1/3] " Reshma Pattan
@ 2018-12-11 19:02 0% ` Dumitrescu, Cristian
1 sibling, 0 replies; 200+ results
From: Dumitrescu, Cristian @ 2018-12-11 19:02 UTC (permalink / raw)
To: Pattan, Reshma, dev, jerin.jacob, Singh, Jasvinder
> -----Original Message-----
> From: Pattan, Reshma
> Sent: Friday, December 7, 2018 2:32 PM
> To: dev@dpdk.org; Dumitrescu, Cristian <cristian.dumitrescu@intel.com>;
> jerin.jacob@caviumnetworks.com; Singh, Jasvinder
> <jasvinder.singh@intel.com>
> Cc: Pattan, Reshma <reshma.pattan@intel.com>
> Subject: [PATCH v2 1/3] mbuf: implement generic format for sched field
>
> This patch implements the changes proposed in the deprecation
> notes [1][2].
>
> librte_mbuf changes:
> The mbuf::hash::sched field is updated to support generic
> definition in line with the ethdev TM and MTR APIs. The new generic
> format contains: queue ID, traffic class, color.
>
> Added public APIs to set and get these new fields to and from mbuf.
>
> librte_sched changes:
> In addtion, following API functions of the sched library have
> been modified with an additional parameter of type struct
> rte_sched_port to accommodate the changes made to mbuf sched field.
> (i) rte_sched_port_pkt_write()
> (ii) rte_sched_port_pkt_read_tree_path()
>
> librte_pipeline, qos_sched UT, qos_sched app are updated
> to make use of new changes.
>
> Also mbuf::hash::txadpater have been added for eventdev txq,
> rte_event_eth_tx_adapter_txq_set and
> rte_event_eth_tx_adapter_txq_get()
> are updated to use uses mbuf::hash::txadpater.txq.
>
> doc:
> Release notes updated.
> Removed deprecation notice for mbuf::hash::sched and sched API.
>
> [1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
> [2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
>
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
> ---
> doc/guides/rel_notes/deprecation.rst | 10 --
> doc/guides/rel_notes/release_19_02.rst | 15 ++-
> examples/qos_sched/app_thread.c | 7 +-
> examples/qos_sched/main.c | 1 +
> .../rte_event_eth_tx_adapter.h | 14 +--
> lib/librte_mbuf/Makefile | 2 +-
> lib/librte_mbuf/rte_mbuf.h | 112 +++++++++++++++++-
> lib/librte_pipeline/rte_table_action.c | 75 +++++++-----
> lib/librte_sched/Makefile | 2 +-
> lib/librte_sched/rte_sched.c | 97 +++++++--------
> lib/librte_sched/rte_sched.h | 10 +-
> test/test/test_sched.c | 9 +-
> 12 files changed, 234 insertions(+), 120 deletions(-)
>
<snip>
> diff --git a/doc/guides/rel_notes/release_19_02.rst
> b/doc/guides/rel_notes/release_19_02.rst
> index a94fa86a7..24ba00d04 100644
> --- a/doc/guides/rel_notes/release_19_02.rst
> +++ b/doc/guides/rel_notes/release_19_02.rst
> @@ -83,6 +83,11 @@ API Changes
> Also, make sure to start the actual text at the margin.
> =========================================================
>
> +* The below functions of the sched library have been modified with an
> + additional parameter of type ``struct rte_sched_port`` to accommodate
> + the changes made to mbuf::hash::sched field.
> + (i) rte_sched_port_pkt_write()
> + (ii) rte_sched_port_pkt_read_tree_path()
>
> ABI Changes
> -----------
> @@ -99,6 +104,12 @@ ABI Changes
> Also, make sure to start the actual text at the margin.
> =========================================================
>
> +* The mbuf::hash::sched field is updated to support generic
> + definition in line with the ethdev TM and MTR APIs. The new generic
> + format contains: ``queue ID, traffic class, color``.
> +
> +* The mbuf:hash:txadapter is now added for eventdev txq. The txadapter
> + format now contains ``reserved1, reserved2 and txq``.
>
IMO these changes are too small to make it to the release notes, I suggest we remove them from here.
<snip>
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index 3dbc6695e..accd98d9b 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -575,13 +575,23 @@ struct rte_mbuf {
> */
> } fdir; /**< Filter identifier if FDIR enabled */
> struct {
> - uint32_t lo;
> - uint32_t hi;
> + uint32_t queue_id; /**< Queue ID. */
> + uint8_t traffic_class;
> + /**< Traffic class ID. Traffic class 0 is high
> + * priority traffic class.
> + */
This comment is too fuzzy, my initial suggestion was: Traffic class 0 is the highest priority traffic class.
> + uint8_t color; /**< Color. */
Already suggested the following:
1. Include the new file "rte_color.h" in this file
2. Clearly connect this field to its real type, i.e. enum rte_color through the proper Doxygen syntax: /**< Color. @see enum rte_color. */
> + uint16_t reserved; /**< Reserved. */
> + } sched; /**< Hierarchical scheduler */
> + struct {
> + uint32_t reserved1;
> + uint16_t reserved2;
> + uint16_t txq;
> /**< The event eth Tx adapter uses this field
> * to store Tx queue id.
> * @see
> rte_event_eth_tx_adapter_txq_set()
> */
> - } sched; /**< Hierarchical scheduler */
> + } txadapter; /**< Eventdev ethdev Tx adapter */
> /**< User defined tags. See
> rte_distributor_process() */
> uint32_t usr;
> } hash; /**< hash information */
> @@ -2289,6 +2299,102 @@ rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
> */
> void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned
> dump_len);
>
> +/**
> + * Reads the value of an mbuf's sched queue_id field.
> + */
> +static inline uint32_t
> +rte_mbuf_sched_queue_read(const struct rte_mbuf *m)
> +{
> + return m->hash.sched.queue_id;
> +}
Let's name these functions *_get instead of *_read, which pairs up with the *_set functions below.
Applicable to all get/set functions: The comment should contain an imperative verb, i.e. "Get the value ...." instead of "Gets the value ...".
> +
> +/**
> + * Reads the value of an mbuf's sched traffic_class field.
> + */
> +static inline uint8_t
> +rte_mbuf_sched_traffic_class_read(const struct rte_mbuf *m)
> +{
> + return m->hash.sched.traffic_class;
> +}
> +
> +/**
> + * Reads the value of an mbuf's sched color field.
> + */
> +static inline uint8_t
> +rte_mbuf_sched_color_read(const struct rte_mbuf *m)
> +{
> + return m->hash.sched.color;
> +}
The type of the return value should be enum rte_color instead of uint8_t:
static inline enum rte_color
rte_mbuf_sched_color_read(const struct rte_mbuf *m)
{
return (enum rte_color)m->hash.sched.color;
}
> +
> +/**
> + * Sets an mbuf's sched queue_id to the defined value.
> + */
> +static inline void
> +rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t qid)
> +{
> + m->hash.sched.queue_id = qid;
> +}
Let's use the full name queue_id instead of qid, please.
> +
> +/**
> + * Sets an mbuf's sched traffic_class id to the defined value.
> + */
> +static inline void
> +rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t tc)
> +{
> + m->hash.sched.traffic_class = tc;
> +}
> +
Same here.
> +/**
> + * Sets an mbuf's sched color id to the defined value.
> + */
> +static inline void
> +rte_mbuf_sched_color_set(struct rte_mbuf *m, uint8_t color)
> +{
> + m->hash.sched.color = color;
> +}
The color parameter type should be enum rte_color, not uint8_t:
static inline void
rte_mbuf_sched_color_set(struct rte_mbuf *m, enum rte_color color)
{
m->hash.sched.color = (uint8_t)color;
}
> +
> +/**
> + * Reads the values of an mbuf's sched queue_id, traffic_class and color.
> + * @param m
> + * Mbuf to read
> + * @param qid
> + * Returns the queue id
> + * @param tc
> + * Returns the traffic class id
> + * @param color
> + * Returns the colour id
> + */
> +static inline void
> +rte_mbuf_sched_read(const struct rte_mbuf *m, uint32_t *qid,
> + uint8_t *tc,
> + uint8_t *color)
> +{
> + *qid = m->hash.sched.queue_id;
> + *tc = m->hash.sched.traffic_class;
> + *color = m->hash.sched.color;
> +}
Color type should be enum rte_color instead of uint8_t.
Full names, not abbreviated names, please.
Please move this function above with the other *_get functions (i.e. before any *_set function).
> +
> +/**
> + * Sets the mbuf's sched queue_id, traffic_class and color.
> + * @param m
> + * Mbuf to set
> + * @param qid
> + * Queue id value to be set
> + * @param tc
> + * Traffic class id value to be set
> + * @param color
> + * Color id to be set
> + */
> +static inline void
> +rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t qid,
> + uint8_t tc,
> + uint8_t color)
> +{
> + m->hash.sched.queue_id = qid;
> + m->hash.sched.traffic_class = tc;
> + m->hash.sched.color = color;
> +}
Color type should be enum rte_color instead of uint8_t.
Full names, not abbreviated names, please.
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/lib/librte_pipeline/rte_table_action.c
> b/lib/librte_pipeline/rte_table_action.c
> index 7c7c8dd82..f9768b9cc 100644
> --- a/lib/librte_pipeline/rte_table_action.c
> +++ b/lib/librte_pipeline/rte_table_action.c
> @@ -107,14 +107,6 @@ mtr_cfg_check(struct rte_table_action_mtr_config
> *mtr)
> return 0;
> }
>
> -#define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
> - ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
> - ((((uint64_t)(tc)) & 0x3) << 2) | \
> - ((((uint64_t)(color)) & 0x3) << 4)))
> -
> -#define MBUF_SCHED_COLOR(sched, color) \
> - (((sched) & (~0x30LLU)) | ((color) << 4))
> -
> struct mtr_trtcm_data {
> struct rte_meter_trtcm trtcm;
> uint64_t stats[e_RTE_METER_COLORS];
> @@ -176,7 +168,7 @@ mtr_data_size(struct rte_table_action_mtr_config
> *mtr)
> struct dscp_table_entry_data {
> enum rte_meter_color color;
> uint16_t tc;
> - uint16_t queue_tc_color;
> + uint32_t queue;
> };
In this data structure, let's rename queue as tc_queue, as it better illustrates what it is, i.e. queue within the traffic class.
In order to preserve the size of this data structure (8 bytes), let's use uint16_t to store tc_queue field.
>
> struct dscp_table_data {
> @@ -319,8 +311,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
> uint32_t dscp,
> uint16_t total_length)
> {
> - uint64_t drop_mask, sched;
> - uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
> + uint64_t drop_mask;
> struct dscp_table_entry_data *dscp_entry = &dscp_table-
> >entry[dscp];
> enum rte_meter_color color_in, color_meter, color_policer;
> uint32_t tc, mp_id;
> @@ -329,7 +320,6 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
> color_in = dscp_entry->color;
> data += tc;
> mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
> - sched = *sched_ptr;
>
> /* Meter */
> color_meter = rte_meter_trtcm_color_aware_check(
> @@ -346,7 +336,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
> drop_mask =
> MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
> color_policer =
> MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data,
> color_meter);
> - *sched_ptr = MBUF_SCHED_COLOR(sched, color_policer);
> + rte_mbuf_sched_color_set(mbuf, color_policer);
>
> return drop_mask;
> }
> @@ -368,11 +358,16 @@ tm_cfg_check(struct rte_table_action_tm_config
> *tm)
> }
>
> struct tm_data {
> - uint16_t queue_tc_color;
> uint16_t subport;
> uint32_t pipe;
> } __attribute__((__packed__));
>
In order to preserve the current size for this data structure (8 bytes), let's have subport type as uint32_t.
> +/* log2 representation of tm configuration */
I suggest to remove this comment.
> +struct tm_cfg {
> + uint32_t subports_per_port_log2;
> + uint32_t pipes_per_subport_log2;
> +} __attribute__((__packed__));
> +
For readability purpose, it is probably better to preserve the names, so please use n_subports_per_port_log2 and n_pipes_per_subport_log2.
> static int
> tm_apply_check(struct rte_table_action_tm_params *p,
> struct rte_table_action_tm_config *cfg)
> @@ -397,26 +392,37 @@ tm_apply(struct tm_data *data,
> return status;
>
> /* Apply */
> - data->queue_tc_color = 0;
> data->subport = (uint16_t) p->subport_id;
> data->pipe = p->pipe_id;
>
> return 0;
> }
>
> +static uint32_t
> +tm_sched_qindex(struct tm_data *data,
> + struct dscp_table_entry_data *dscp,
> + struct tm_cfg *tm)
> +{
> + uint32_t result;
> +
> + result = (data->subport << tm->pipes_per_subport_log2) + data-
> >pipe;
> + result = result * RTE_TABLE_ACTION_TC_MAX + dscp->tc;
> + result = result * RTE_TABLE_ACTION_TC_QUEUE_MAX + dscp-
> >queue;
> +
> + return result;
> +}
> +
We can do this in a single assignment (replace the multiplication with 4 by shift left with 2).
> static __rte_always_inline void
> pkt_work_tm(struct rte_mbuf *mbuf,
> struct tm_data *data,
> struct dscp_table_data *dscp_table,
> - uint32_t dscp)
> + uint32_t dscp,
> + struct tm_cfg *tm)
> {
> struct dscp_table_entry_data *dscp_entry = &dscp_table-
> >entry[dscp];
> - struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
> - struct tm_data sched;
> + uint32_t queue = tm_sched_qindex(data, dscp_entry, tm);
>
> - sched = *data;
> - sched.queue_tc_color = dscp_entry->queue_tc_color;
> - *sched_ptr = sched;
> + rte_mbuf_sched_set(mbuf, queue, dscp_entry->tc, dscp_entry-
> >color);
> }
>
> /**
> @@ -2440,6 +2446,7 @@ struct rte_table_action {
> struct ap_data data;
> struct dscp_table_data dscp_table;
> struct meter_profile_data mp[METER_PROFILES_MAX];
> + struct tm_cfg tm;
> };
>
> struct rte_table_action *
> @@ -2465,6 +2472,11 @@ rte_table_action_create(struct
> rte_table_action_profile *profile,
> memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
> memcpy(&action->data, &profile->data, sizeof(profile->data));
>
> + action->tm.subports_per_port_log2 =
> + __builtin_ctz(profile->cfg.tm.n_subports_per_port);
> + action->tm.pipes_per_subport_log2 =
> + __builtin_ctz(profile->cfg.tm.n_pipes_per_subport);
> +
> return action;
> }
>
> @@ -2580,17 +2592,13 @@ rte_table_action_dscp_table_update(struct
> rte_table_action *action,
> &action->dscp_table.entry[i];
> struct rte_table_action_dscp_table_entry *entry =
> &table->entry[i];
> - uint16_t queue_tc_color =
> - MBUF_SCHED_QUEUE_TC_COLOR(entry-
> >tc_queue_id,
> - entry->tc_id,
> - entry->color);
>
> if ((dscp_mask & (1LLU << i)) == 0)
> continue;
>
> data->color = entry->color;
> data->tc = entry->tc_id;
> - data->queue_tc_color = queue_tc_color;
> + data->queue = entry->tc_queue_id;
> }
>
> return 0;
> @@ -2882,7 +2890,8 @@ pkt_work(struct rte_mbuf *mbuf,
> pkt_work_tm(mbuf,
> data,
> &action->dscp_table,
> - dscp);
> + dscp,
> + &action->tm);
> }
>
> if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
> @@ -3108,22 +3117,26 @@ pkt4_work(struct rte_mbuf **mbufs,
> pkt_work_tm(mbuf0,
> data0,
> &action->dscp_table,
> - dscp0);
> + dscp0,
> + &action->tm);
>
> pkt_work_tm(mbuf1,
> data1,
> &action->dscp_table,
> - dscp1);
> + dscp1,
> + &action->tm);
>
> pkt_work_tm(mbuf2,
> data2,
> &action->dscp_table,
> - dscp2);
> + dscp2,
> + &action->tm);
>
> pkt_work_tm(mbuf3,
> data3,
> &action->dscp_table,
> - dscp3);
> + dscp3,
> + &action->tm);
> }
>
> if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
> diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile
> index 46c53ed71..644fd9d15 100644
> --- a/lib/librte_sched/Makefile
> +++ b/lib/librte_sched/Makefile
> @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer
>
> EXPORT_MAP := rte_sched_version.map
>
> -LIBABIVER := 1
> +LIBABIVER := 2
>
> #
> # all source are stored in SRCS-y
> diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
> index 587d5e602..a6d9a5886 100644
> --- a/lib/librte_sched/rte_sched.c
> +++ b/lib/librte_sched/rte_sched.c
> @@ -41,6 +41,9 @@
> #define RTE_SCHED_PIPE_INVALID UINT32_MAX
> #define RTE_SCHED_BMP_POS_INVALID UINT32_MAX
>
> +#define RTE_SCHED_QUEUES_PER_PIPE_LOG2 \
> + __builtin_ctz(RTE_SCHED_QUEUES_PER_PIPE)
> +
> /* Scaling for cycles_per_byte calculation
> * Chosen so that minimum rate is 480 bit/sec
> */
> @@ -128,22 +131,6 @@ enum grinder_state {
> e_GRINDER_READ_MBUF
> };
>
> -/*
> - * Path through the scheduler hierarchy used by the scheduler enqueue
> - * operation to identify the destination queue for the current
> - * packet. Stored in the field pkt.hash.sched of struct rte_mbuf of
> - * each packet, typically written by the classification stage and read
> - * by scheduler enqueue.
> - */
> -struct rte_sched_port_hierarchy {
> - uint16_t queue:2; /**< Queue ID (0 .. 3) */
> - uint16_t traffic_class:2; /**< Traffic class ID (0 .. 3)*/
> - uint32_t color:2; /**< Color */
> - uint16_t unused:10;
> - uint16_t subport; /**< Subport ID */
> - uint32_t pipe; /**< Pipe ID */
> -};
> -
> struct rte_sched_grinder {
> /* Pipe cache */
> uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
> @@ -228,6 +215,7 @@ struct rte_sched_port {
> uint8_t *bmp_array;
> struct rte_mbuf **queue_array;
> uint8_t memory[0] __rte_cache_aligned;
> +
> } __rte_cache_aligned;
>
> enum rte_sched_port_array {
> @@ -242,13 +230,11 @@ enum rte_sched_port_array {
> };
>
> #ifdef RTE_SCHED_COLLECT_STATS
> -
> static inline uint32_t
> rte_sched_port_queues_per_subport(struct rte_sched_port *port)
> {
> return RTE_SCHED_QUEUES_PER_PIPE * port-
> >n_pipes_per_subport;
> }
> -
> #endif
>
> static inline uint32_t
> @@ -1006,44 +992,56 @@ rte_sched_port_pipe_profile_add(struct
> rte_sched_port *port,
> return 0;
> }
>
> +static inline uint32_t
> +rte_sched_port_qindex(struct rte_sched_port *port,
> + uint32_t subport,
> + uint32_t pipe,
> + uint32_t traffic_class,
> + uint32_t queue)
> +{
> + uint32_t result;
> +
> + result = (subport << __builtin_ctz(port->n_pipes_per_subport)) +
> pipe;
> + result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE +
> traffic_class;
> + result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
> +
> + return result;
> +}
> +
> void
> -rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> +rte_sched_port_pkt_write(struct rte_sched_port *port,
> + struct rte_mbuf *pkt,
> uint32_t subport, uint32_t pipe, uint32_t
> traffic_class,
> uint32_t queue, enum rte_meter_color color)
> {
> - struct rte_sched_port_hierarchy *sched
> - = (struct rte_sched_port_hierarchy *) &pkt->hash.sched;
> -
> - RTE_BUILD_BUG_ON(sizeof(*sched) > sizeof(pkt->hash.sched));
> -
> - sched->color = (uint32_t) color;
> - sched->subport = subport;
> - sched->pipe = pipe;
> - sched->traffic_class = traffic_class;
> - sched->queue = queue;
> + uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe,
> + traffic_class, queue);
> + rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color);
> }
>
> void
> -rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
> +rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
> + const struct rte_mbuf *pkt,
> uint32_t *subport, uint32_t *pipe,
> uint32_t *traffic_class, uint32_t *queue)
> {
> - const struct rte_sched_port_hierarchy *sched
> - = (const struct rte_sched_port_hierarchy *) &pkt-
> >hash.sched;
> -
> - *subport = sched->subport;
> - *pipe = sched->pipe;
> - *traffic_class = sched->traffic_class;
> - *queue = sched->queue;
> + uint32_t qid = rte_mbuf_sched_queue_read(pkt);
> +
> + *subport = qid >>
> + (__builtin_ctz
> + (RTE_SCHED_QUEUES_PER_PIPE <<
> + __builtin_ctz(port->n_pipes_per_subport)
> + )
> + );
> + *pipe = qid >> RTE_SCHED_QUEUES_PER_PIPE_LOG2;
> + *traffic_class = rte_mbuf_sched_traffic_class_read(pkt);
> + *queue = qid & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1);
> }
>
> enum rte_meter_color
> rte_sched_port_pkt_read_color(const struct rte_mbuf *pkt)
> {
> - const struct rte_sched_port_hierarchy *sched
> - = (const struct rte_sched_port_hierarchy *) &pkt-
> >hash.sched;
> -
> - return (enum rte_meter_color) sched->color;
> + return (enum rte_meter_color)rte_mbuf_sched_color_read(pkt);
> }
>
> int
> @@ -1100,18 +1098,6 @@ rte_sched_queue_read_stats(struct
> rte_sched_port *port,
> return 0;
> }
>
> -static inline uint32_t
> -rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport,
> uint32_t pipe, uint32_t traffic_class, uint32_t queue)
> -{
> - uint32_t result;
> -
> - result = subport * port->n_pipes_per_subport + pipe;
> - result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE +
> traffic_class;
> - result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
> -
> - return result;
> -}
> -
> #ifdef RTE_SCHED_DEBUG
>
> static inline int
> @@ -1272,11 +1258,8 @@ rte_sched_port_enqueue_qptrs_prefetch0(struct
> rte_sched_port *port,
> #ifdef RTE_SCHED_COLLECT_STATS
> struct rte_sched_queue_extra *qe;
> #endif
> - uint32_t subport, pipe, traffic_class, queue, qindex;
> -
> - rte_sched_port_pkt_read_tree_path(pkt, &subport, &pipe,
> &traffic_class, &queue);
> + uint32_t qindex = rte_mbuf_sched_queue_read(pkt);
>
> - qindex = rte_sched_port_qindex(port, subport, pipe, traffic_class,
> queue);
> q = port->queue + qindex;
> rte_prefetch0(q);
> #ifdef RTE_SCHED_COLLECT_STATS
> diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
> index 84fa896de..243efa1d4 100644
> --- a/lib/librte_sched/rte_sched.h
> +++ b/lib/librte_sched/rte_sched.h
> @@ -355,6 +355,8 @@ rte_sched_queue_read_stats(struct rte_sched_port
> *port,
> * Scheduler hierarchy path write to packet descriptor. Typically
> * called by the packet classification stage.
> *
> + * @param port
> + * Handle to port scheduler instance
> * @param pkt
> * Packet descriptor handle
> * @param subport
> @@ -369,7 +371,8 @@ rte_sched_queue_read_stats(struct rte_sched_port
> *port,
> * Packet color set
> */
> void
> -rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> +rte_sched_port_pkt_write(struct rte_sched_port *port,
> + struct rte_mbuf *pkt,
> uint32_t subport, uint32_t pipe, uint32_t
> traffic_class,
> uint32_t queue, enum rte_meter_color color);
>
> @@ -379,6 +382,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> * enqueue operation. The subport, pipe, traffic class and queue
> * parameters need to be pre-allocated by the caller.
> *
> + * @param port
> + * Handle to port scheduler instance
> * @param pkt
> * Packet descriptor handle
> * @param subport
> @@ -392,7 +397,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> *
> */
> void
> -rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
> +rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
> + const struct rte_mbuf *pkt,
> uint32_t *subport, uint32_t *pipe,
> uint32_t *traffic_class, uint32_t *queue);
>
> diff --git a/test/test/test_sched.c b/test/test/test_sched.c
> index 32e500ba9..40e411cab 100644
> --- a/test/test/test_sched.c
> +++ b/test/test/test_sched.c
> @@ -76,7 +76,7 @@ create_mempool(void)
> }
>
> static void
> -prepare_pkt(struct rte_mbuf *mbuf)
> +prepare_pkt(struct rte_sched_port *port, struct rte_mbuf *mbuf)
> {
> struct ether_hdr *eth_hdr;
> struct vlan_hdr *vlan1, *vlan2;
> @@ -95,7 +95,8 @@ prepare_pkt(struct rte_mbuf *mbuf)
> ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);
>
>
> - rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE,
> e_RTE_METER_YELLOW);
> + rte_sched_port_pkt_write(port, mbuf, SUBPORT, PIPE, TC, QUEUE,
> + e_RTE_METER_YELLOW);
>
> /* 64 byte packet */
> mbuf->pkt_len = 60;
> @@ -138,7 +139,7 @@ test_sched(void)
> for (i = 0; i < 10; i++) {
> in_mbufs[i] = rte_pktmbuf_alloc(mp);
> TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation
> failed\n");
> - prepare_pkt(in_mbufs[i]);
> + prepare_pkt(port, in_mbufs[i]);
> }
>
>
> @@ -155,7 +156,7 @@ test_sched(void)
> color = rte_sched_port_pkt_read_color(out_mbufs[i]);
> TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong
> color\n");
>
> - rte_sched_port_pkt_read_tree_path(out_mbufs[i],
> + rte_sched_port_pkt_read_tree_path(port, out_mbufs[i],
> &subport, &pipe, &traffic_class, &queue);
>
> TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong
> subport\n");
> --
> 2.17.1
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3 1/5] mem: fix error code for segment fd API for external segs
@ 2018-12-13 11:43 4% ` Anatoly Burakov
2018-12-13 11:43 4% ` [dpdk-dev] [PATCH v3 2/5] memalloc: check for memfd support in segment fd API Anatoly Burakov
2 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-12-13 11:43 UTC (permalink / raw)
To: dev
Cc: John McNamara, Marko Kovacevic, przemyslawx.lal,
kuralamudhan.ramakrishnan, ivan.coughlan, tiwei.bie,
ray.kinsella, maxime.coquelin, stable
Segment fd API does not support getting segment fd's from
externally allocated memory, so return proper error code
on any attempts to do so. This changes API behavior, so
document the change as well.
Fixes: 5282bb1c3695 ("mem: allow memseg lists to be marked as external")
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Tiwei Bie <tiwei.bie@intel.com>
---
Notes:
The API is experimental, no deprecation notice needed.
doc/guides/rel_notes/release_19_02.rst | 6 ++++++
lib/librte_eal/common/eal_common_memory.c | 12 ++++++++++++
2 files changed, 18 insertions(+)
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index a94fa86a7..ade41b9c8 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -84,6 +84,12 @@ API Changes
=========================================================
+* eal: segment fd API on Linux now sets error code to ``ENOTSUP`` in more cases
+ where segment fd API is not expected to be supported:
+
+ - On attempt to get segment fd for an externally allocated memory segment
+
+
ABI Changes
-----------
diff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c
index d47ea4938..999ba24b4 100644
--- a/lib/librte_eal/common/eal_common_memory.c
+++ b/lib/librte_eal/common/eal_common_memory.c
@@ -704,6 +704,12 @@ rte_memseg_get_fd_thread_unsafe(const struct rte_memseg *ms)
return -1;
}
+ /* segment fd API is not supported for external segments */
+ if (msl->external) {
+ rte_errno = ENOTSUP;
+ return -1;
+ }
+
ret = eal_memalloc_get_seg_fd(msl_idx, seg_idx);
if (ret < 0) {
rte_errno = -ret;
@@ -754,6 +760,12 @@ rte_memseg_get_fd_offset_thread_unsafe(const struct rte_memseg *ms,
return -1;
}
+ /* segment fd API is not supported for external segments */
+ if (msl->external) {
+ rte_errno = ENOTSUP;
+ return -1;
+ }
+
ret = eal_memalloc_get_seg_fd_offset(msl_idx, seg_idx, offset);
if (ret < 0) {
rte_errno = -ret;
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3 2/5] memalloc: check for memfd support in segment fd API
2018-12-13 11:43 4% ` [dpdk-dev] [PATCH v3 1/5] mem: fix error code for segment fd API for external segs Anatoly Burakov
@ 2018-12-13 11:43 4% ` Anatoly Burakov
2 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-12-13 11:43 UTC (permalink / raw)
To: dev
Cc: John McNamara, Marko Kovacevic, przemyslawx.lal,
kuralamudhan.ramakrishnan, ivan.coughlan, tiwei.bie,
ray.kinsella, maxime.coquelin, stable
If memfd support was not compiled, or hugepage memfd support
is not available at runtime, the API will now return proper
error code, indicating that this API is unsupported. This
changes the API, so document the changes.
Fixes: 41dbdb68723b ("mem: add external API to retrieve page fd")
Fixes: 3a44687139eb ("mem: allow querying offset into segment fd")
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Tiwei Bie <tiwei.bie@intel.com>
---
Notes:
The API is experimental, no deprecation notice needed.
doc/guides/rel_notes/release_19_02.rst | 2 ++
lib/librte_eal/linuxapp/eal/eal_memalloc.c | 40 +++++++++++++++++-----
2 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index ade41b9c8..960098582 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -88,6 +88,8 @@ API Changes
where segment fd API is not expected to be supported:
- On attempt to get segment fd for an externally allocated memory segment
+ - In cases where memfd support would have been required to provide segment
+ fd's (such as in-memory or no-huge mode)
ABI Changes
diff --git a/lib/librte_eal/linuxapp/eal/eal_memalloc.c b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
index 784939566..a93548b8c 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
@@ -23,6 +23,10 @@
#include <sys/time.h>
#include <signal.h>
#include <setjmp.h>
+#ifdef F_ADD_SEALS /* if file sealing is supported, so is memfd */
+#include <linux/memfd.h>
+#define MEMFD_SUPPORTED
+#endif
#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
#include <numa.h>
#include <numaif.h>
@@ -53,8 +57,8 @@ const int anonymous_hugepages_supported =
#endif
/*
- * we don't actually care if memfd itself is supported - we only need to check
- * if memfd supports hugetlbfs, as that already implies memfd support.
+ * we've already checked memfd support at compile-time, but we also need to
+ * check if we can create hugepage files with memfd.
*
* also, this is not a constant, because while we may be *compiled* with memfd
* hugetlbfs support, we might not be *running* on a system that supports memfd
@@ -63,10 +67,11 @@ const int anonymous_hugepages_supported =
*/
static int memfd_create_supported =
#ifdef MFD_HUGETLB
-#define MEMFD_SUPPORTED
1;
+#define RTE_MFD_HUGETLB MFD_HUGETLB
#else
0;
+#define RTE_MFD_HUGETLB 4U
#endif
/*
@@ -338,12 +343,12 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused,
int fd;
char segname[250]; /* as per manpage, limit is 249 bytes plus null */
+ int flags = RTE_MFD_HUGETLB | pagesz_flags(hi->hugepage_sz);
+
if (internal_config.single_file_segments) {
fd = fd_list[list_idx].memseg_list_fd;
if (fd < 0) {
- int flags = MFD_HUGETLB | pagesz_flags(hi->hugepage_sz);
-
snprintf(segname, sizeof(segname), "seg_%i", list_idx);
fd = memfd_create(segname, flags);
if (fd < 0) {
@@ -357,8 +362,6 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused,
fd = fd_list[list_idx].fds[seg_idx];
if (fd < 0) {
- int flags = MFD_HUGETLB | pagesz_flags(hi->hugepage_sz);
-
snprintf(segname, sizeof(segname), "seg_%i-%i",
list_idx, seg_idx);
fd = memfd_create(segname, flags);
@@ -1542,6 +1545,17 @@ int
eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
{
int fd;
+
+ if (internal_config.in_memory || internal_config.no_hugetlbfs) {
+#ifndef MEMFD_SUPPORTED
+ /* in in-memory or no-huge mode, we rely on memfd support */
+ return -ENOTSUP;
+#endif
+ /* memfd supported, but hugetlbfs memfd may not be */
+ if (!internal_config.no_hugetlbfs && !memfd_create_supported)
+ return -ENOTSUP;
+ }
+
if (internal_config.single_file_segments) {
fd = fd_list[list_idx].memseg_list_fd;
} else if (fd_list[list_idx].len == 0) {
@@ -1565,7 +1579,7 @@ test_memfd_create(void)
int pagesz_flag = pagesz_flags(pagesz);
int flags;
- flags = pagesz_flag | MFD_HUGETLB;
+ flags = pagesz_flag | RTE_MFD_HUGETLB;
int fd = memfd_create("test", flags);
if (fd < 0) {
/* we failed - let memalloc know this isn't working */
@@ -1589,6 +1603,16 @@ eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset)
{
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+ if (internal_config.in_memory || internal_config.no_hugetlbfs) {
+#ifndef MEMFD_SUPPORTED
+ /* in in-memory or no-huge mode, we rely on memfd support */
+ return -ENOTSUP;
+#endif
+ /* memfd supported, but hugetlbfs memfd may not be */
+ if (!internal_config.no_hugetlbfs && !memfd_create_supported)
+ return -ENOTSUP;
+ }
+
/* fd_list not initialized? */
if (fd_list[list_idx].len == 0)
return -ENODEV;
--
2.17.1
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] pdump: remove deprecated APIs
2018-12-03 2:58 6% ` [dpdk-dev] [PATCH] " Tiwei Bie
@ 2018-12-13 17:15 0% ` Pattan, Reshma
2018-12-19 0:28 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Pattan, Reshma @ 2018-12-13 17:15 UTC (permalink / raw)
To: Bie, Tiwei, dev; +Cc: Mcnamara, John, Kovacevic, Marko
Hi,
> -----Original Message-----
> From: Bie, Tiwei
> Sent: Monday, December 3, 2018 2:59 AM
> To: dev@dpdk.org
> Cc: Pattan, Reshma <reshma.pattan@intel.com>; Mcnamara, John
> <john.mcnamara@intel.com>; Kovacevic, Marko <marko.kovacevic@intel.com>
> Subject: [PATCH] pdump: remove deprecated APIs
>
> We already changed to use generic IPC in pdump since below commit:
>
> commit 660098d61f57 ("pdump: use generic multi-process channel")
>
> The `rte_pdump_set_socket_dir()`, the `path` parameter of `rte_pdump_init()`
> and the `enum rte_pdump_socktype` have been deprecated since then. This
> commit removes these deprecated APIs and also bumps the pdump ABI.
>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> ---
> changes:
> - update release notes;
> - minor updates in pdump_lib.rst;
>
> app/test-pmd/testpmd.c | 2 +-
> doc/guides/prog_guide/pdump_lib.rst | 18 ++++--------------
> doc/guides/rel_notes/deprecation.rst | 7 -------
> doc/guides/rel_notes/release_19_02.rst | 6 +++++-
> lib/librte_pdump/Makefile | 2 +-
> lib/librte_pdump/meson.build | 2 +-
> lib/librte_pdump/rte_pdump.c | 9 +--------
> lib/librte_pdump/rte_pdump.h | 34 +---------------------------------
> lib/librte_pdump/rte_pdump_version.map | 1 -
> 9 files changed, 14 insertions(+), 67 deletions(-)
>
Reviewed-by: Reshma Pattan <reshma.pattan@intel.com>
Acked-by: Reshma Pattan <reshma.pattan@intel.com>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3 2/2] mbuf: implement generic format for sched field
@ 2018-12-13 18:08 1% ` Reshma Pattan
2018-12-14 22:52 0% ` Dumitrescu, Cristian
1 sibling, 1 reply; 200+ results
From: Reshma Pattan @ 2018-12-13 18:08 UTC (permalink / raw)
To: dev, jerin.jacob, nikhil.rao, jasvinder.singh, cristian.dumitrescu
Cc: Reshma Pattan
This patch implements the changes proposed in the deprecation
notes [1][2].
librte_mbuf changes:
The mbuf::hash::sched field is updated to support generic
definition in line with the ethdev TM and MTR APIs. The new generic
format contains: queue ID, traffic class, color.
Added public APIs to set and get these new fields to and from mbuf.
librte_sched changes:
In addtion, following API functions of the sched library have
been modified with an additional parameter of type struct
rte_sched_port to accommodate the changes made to mbuf sched field.
(i) rte_sched_port_pkt_write()
(ii) rte_sched_port_pkt_read_tree_path()
librte_pipeline, qos_sched UT, qos_sched app are updated
to make use of new changes.
Also mbuf::hash::txadapter has been added for eventdev txq,
rte_event_eth_tx_adapter_txq_set and rte_event_eth_tx_adapter_txq_get()
are updated to use uses mbuf::hash::txadapter.txq.
doc:
Release notes updated.
Removed deprecation notice for mbuf::hash::sched and sched API.
[1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
[2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
---
v3: addressed review comments given in the below link.
http://patches.dpdk.org/patch/48587/
Updated library ABI versioning in meson build.
---
---
doc/guides/rel_notes/deprecation.rst | 10 --
doc/guides/rel_notes/release_19_02.rst | 4 +-
examples/qos_sched/app_thread.c | 7 +-
examples/qos_sched/main.c | 1 +
.../rte_event_eth_tx_adapter.h | 18 ++-
lib/librte_mbuf/Makefile | 2 +-
lib/librte_mbuf/meson.build | 2 +-
lib/librte_mbuf/rte_mbuf.h | 114 +++++++++++++++++-
lib/librte_pipeline/rte_table_action.c | 43 ++-----
lib/librte_sched/Makefile | 2 +-
lib/librte_sched/meson.build | 1 +
lib/librte_sched/rte_sched.c | 90 ++++++--------
lib/librte_sched/rte_sched.h | 10 +-
test/test/test_sched.c | 9 +-
14 files changed, 191 insertions(+), 122 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b48486d36..60e081a54 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,16 +49,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* mbuf: The opaque ``mbuf->hash.sched`` field will be updated to support generic
- definition in line with the ethdev TM and MTR APIs. Currently, this field
- is defined in librte_sched in a non-generic way. The new generic format
- will contain: queue ID, traffic class, color. Field size will not change.
-
-* sched: Some API functions will change prototype due to the above
- deprecation note for mbuf->hash.sched, e.g. ``rte_sched_port_pkt_write()``
- and ``rte_sched_port_pkt_read()`` will likely have an additional parameter
- of type ``struct rte_sched_port``.
-
* mbuf: the macro ``RTE_MBUF_INDIRECT()`` will be removed in v18.08 or later and
replaced with ``RTE_MBUF_CLONED()`` which is already added in v18.05. As
``EXT_ATTACHED_MBUF`` is newly introduced in v18.05, ``RTE_MBUF_INDIRECT()``
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index a94fa86a7..deadaafa9 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -146,7 +146,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_kvargs.so.1
librte_latencystats.so.1
librte_lpm.so.2
- librte_mbuf.so.4
+ + librte_mbuf.so.5
librte_member.so.1
librte_mempool.so.5
librte_meter.so.2
@@ -168,7 +168,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_rawdev.so.1
librte_reorder.so.1
librte_ring.so.2
- librte_sched.so.1
+ + librte_sched.so.2
librte_security.so.1
librte_table.so.3
librte_timer.so.1
diff --git a/examples/qos_sched/app_thread.c b/examples/qos_sched/app_thread.c
index a59274236..bec4deee3 100644
--- a/examples/qos_sched/app_thread.c
+++ b/examples/qos_sched/app_thread.c
@@ -73,8 +73,11 @@ app_rx_thread(struct thread_conf **confs)
for(i = 0; i < nb_rx; i++) {
get_pkt_sched(rx_mbufs[i],
&subport, &pipe, &traffic_class, &queue, &color);
- rte_sched_port_pkt_write(rx_mbufs[i], subport, pipe,
- traffic_class, queue, (enum rte_meter_color) color);
+ rte_sched_port_pkt_write(conf->sched_port,
+ rx_mbufs[i],
+ subport, pipe,
+ traffic_class, queue,
+ (enum rte_meter_color) color);
}
if (unlikely(rte_ring_sp_enqueue_bulk(conf->rx_ring,
diff --git a/examples/qos_sched/main.c b/examples/qos_sched/main.c
index e7c97bd64..c0ed16b68 100644
--- a/examples/qos_sched/main.c
+++ b/examples/qos_sched/main.c
@@ -55,6 +55,7 @@ app_main_loop(__attribute__((unused))void *dummy)
flow->rx_thread.rx_port = flow->rx_port;
flow->rx_thread.rx_ring = flow->rx_ring;
flow->rx_thread.rx_queue = flow->rx_queue;
+ flow->rx_thread.sched_port = flow->sched_port;
rx_confs[rx_idx++] = &flow->rx_thread;
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index 81456d4a9..2a50656d9 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -63,13 +63,11 @@
* function can be used to retrieve the adapter's service function ID.
*
* The ethernet port and transmit queue index to transmit the mbuf on are
- * specified using the mbuf port and the higher 16 bits of
- * struct rte_mbuf::hash::sched:hi. The application should use the
- * rte_event_eth_tx_adapter_txq_set() and rte_event_eth_tx_adapter_txq_get()
- * functions to access the transmit queue index since it is expected that the
- * transmit queue will be eventually defined within struct rte_mbuf and using
- * these macros will help with minimizing application impact due to
- * a change in how the transmit queue index is specified.
+ * specified using the mbuf port struct rte_mbuf::hash::txadapter:txq.
+ * The application should use the rte_event_eth_tx_adapter_txq_set()
+ * and rte_event_eth_tx_adapter_txq_get() functions to access the transmit
+ * queue index, using these macros will help with minimizing application
+ * impact due to a change in how the transmit queue index is specified.
*/
#ifdef __cplusplus
@@ -300,8 +298,7 @@ rte_event_eth_tx_adapter_queue_del(uint8_t id,
static __rte_always_inline void __rte_experimental
rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- p[1] = queue;
+ pkt->hash.txadapter.txq = queue;
}
/**
@@ -320,8 +317,7 @@ rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
static __rte_always_inline uint16_t __rte_experimental
rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- return p[1];
+ return pkt->hash.txadapter.txq;
}
/**
diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
index e2b98a254..8c4c7d790 100644
--- a/lib/librte_mbuf/Makefile
+++ b/lib/librte_mbuf/Makefile
@@ -11,7 +11,7 @@ LDLIBS += -lrte_eal -lrte_mempool
EXPORT_MAP := rte_mbuf_version.map
-LIBABIVER := 4
+LIBABIVER := 5
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
index 94d9c4c96..e37da0250 100644
--- a/lib/librte_mbuf/meson.build
+++ b/lib/librte_mbuf/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 4
+version = 5
sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
deps += ['mempool']
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 3dbc6695e..032237321 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -34,6 +34,7 @@
#include <stdint.h>
#include <rte_compat.h>
#include <rte_common.h>
+#include <rte_color.h>
#include <rte_config.h>
#include <rte_mempool.h>
#include <rte_memory.h>
@@ -575,13 +576,24 @@ struct rte_mbuf {
*/
} fdir; /**< Filter identifier if FDIR enabled */
struct {
- uint32_t lo;
- uint32_t hi;
+ uint32_t queue_id; /**< Queue ID. */
+ uint8_t traffic_class;
+ /**< Traffic class ID. Traffic class 0
+ * is the highest priority traffic class.
+ */
+ uint8_t color;
+ /**< Color. @see enum rte_color.*/
+ uint16_t reserved; /**< Reserved. */
+ } sched; /**< Hierarchical scheduler */
+ struct {
+ uint32_t reserved1;
+ uint16_t reserved2;
+ uint16_t txq;
/**< The event eth Tx adapter uses this field
* to store Tx queue id.
* @see rte_event_eth_tx_adapter_txq_set()
*/
- } sched; /**< Hierarchical scheduler */
+ } txadapter; /**< Eventdev ethdev Tx adapter */
/**< User defined tags. See rte_distributor_process() */
uint32_t usr;
} hash; /**< hash information */
@@ -2289,6 +2301,102 @@ rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
*/
void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
+/**
+ * Get the value of mbuf sched queue_id field.
+ */
+static inline uint32_t
+rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.queue_id;
+}
+
+/**
+ * Get the value of mbuf sched traffic_class field.
+ */
+static inline uint8_t
+rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.traffic_class;
+}
+
+/**
+ * Get the value of mbuf sched color field.
+ */
+static inline enum rte_color
+rte_mbuf_sched_color_get(const struct rte_mbuf *m)
+{
+ return (enum rte_color)m->hash.sched.color;
+}
+
+/**
+ * Get the values of mbuf sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to read
+ * @param queue_id
+ * Returns the queue id
+ * @param traffic_class
+ * Returns the traffic class id
+ * @param color
+ * Returns the colour id
+ */
+static inline void
+rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
+ uint8_t *traffic_class,
+ enum rte_color *color)
+{
+ *queue_id = m->hash.sched.queue_id;
+ *traffic_class = m->hash.sched.traffic_class;
+ *color = (enum rte_color)m->hash.sched.color;
+}
+
+/**
+ * Set the mbuf sched queue_id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
+{
+ m->hash.sched.queue_id = queue_id;
+}
+
+/**
+ * Set the mbuf sched traffic_class id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
+{
+ m->hash.sched.traffic_class = traffic_class;
+}
+
+/**
+ * Set the mbuf sched color id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_color_set(struct rte_mbuf *m, enum rte_color color)
+{
+ m->hash.sched.color = (uint8_t)color;
+}
+
+/**
+ * Set the mbuf sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to set
+ * @param queue_id
+ * Queue id value to be set
+ * @param traffic_class
+ * Traffic class id value to be set
+ * @param color
+ * Color id to be set
+ */
+static inline void
+rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t queue_id,
+ uint8_t traffic_class,
+ enum rte_color color)
+{
+ m->hash.sched.queue_id = queue_id;
+ m->hash.sched.traffic_class = traffic_class;
+ m->hash.sched.color = (uint8_t)color;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 7c7c8dd82..3158301ff 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -107,14 +107,6 @@ mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
return 0;
}
-#define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
- ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
- ((((uint64_t)(tc)) & 0x3) << 2) | \
- ((((uint64_t)(color)) & 0x3) << 4)))
-
-#define MBUF_SCHED_COLOR(sched, color) \
- (((sched) & (~0x30LLU)) | ((color) << 4))
-
struct mtr_trtcm_data {
struct rte_meter_trtcm trtcm;
uint64_t stats[e_RTE_METER_COLORS];
@@ -176,7 +168,7 @@ mtr_data_size(struct rte_table_action_mtr_config *mtr)
struct dscp_table_entry_data {
enum rte_meter_color color;
uint16_t tc;
- uint16_t queue_tc_color;
+ uint16_t tc_queue;
};
struct dscp_table_data {
@@ -319,8 +311,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
uint32_t dscp,
uint16_t total_length)
{
- uint64_t drop_mask, sched;
- uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
+ uint64_t drop_mask;
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
enum rte_meter_color color_in, color_meter, color_policer;
uint32_t tc, mp_id;
@@ -329,7 +320,6 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
color_in = dscp_entry->color;
data += tc;
mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
- sched = *sched_ptr;
/* Meter */
color_meter = rte_meter_trtcm_color_aware_check(
@@ -346,7 +336,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
color_policer =
MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- *sched_ptr = MBUF_SCHED_COLOR(sched, color_policer);
+ rte_mbuf_sched_color_set(mbuf, color_policer);
return drop_mask;
}
@@ -368,9 +358,8 @@ tm_cfg_check(struct rte_table_action_tm_config *tm)
}
struct tm_data {
- uint16_t queue_tc_color;
- uint16_t subport;
- uint32_t pipe;
+ uint32_t queue_id;
+ uint32_t reserved;
} __attribute__((__packed__));
static int
@@ -397,9 +386,9 @@ tm_apply(struct tm_data *data,
return status;
/* Apply */
- data->queue_tc_color = 0;
- data->subport = (uint16_t) p->subport_id;
- data->pipe = p->pipe_id;
+ data->queue_id = p->subport_id <<
+ (__builtin_ctz(cfg->n_pipes_per_subport) + 4) |
+ p->pipe_id << 4;
return 0;
}
@@ -411,12 +400,10 @@ pkt_work_tm(struct rte_mbuf *mbuf,
uint32_t dscp)
{
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
- struct tm_data sched;
-
- sched = *data;
- sched.queue_tc_color = dscp_entry->queue_tc_color;
- *sched_ptr = sched;
+ uint32_t queue_id = data->queue_id |
+ (dscp_entry->tc << 2) |
+ dscp_entry->tc_queue;
+ rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc, dscp_entry->color);
}
/**
@@ -2580,17 +2567,13 @@ rte_table_action_dscp_table_update(struct rte_table_action *action,
&action->dscp_table.entry[i];
struct rte_table_action_dscp_table_entry *entry =
&table->entry[i];
- uint16_t queue_tc_color =
- MBUF_SCHED_QUEUE_TC_COLOR(entry->tc_queue_id,
- entry->tc_id,
- entry->color);
if ((dscp_mask & (1LLU << i)) == 0)
continue;
data->color = entry->color;
data->tc = entry->tc_id;
- data->queue_tc_color = queue_tc_color;
+ data->tc_queue = entry->tc_queue_id;
}
return 0;
diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile
index 46c53ed71..644fd9d15 100644
--- a/lib/librte_sched/Makefile
+++ b/lib/librte_sched/Makefile
@@ -18,7 +18,7 @@ LDLIBS += -lrte_timer
EXPORT_MAP := rte_sched_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build
index f85d64df8..8e989e5f6 100644
--- a/lib/librte_sched/meson.build
+++ b/lib/librte_sched/meson.build
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
+version = 2
sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c')
headers = files('rte_sched.h', 'rte_sched_common.h',
'rte_red.h', 'rte_approx.h')
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 587d5e602..3b8b2b038 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -128,22 +128,6 @@ enum grinder_state {
e_GRINDER_READ_MBUF
};
-/*
- * Path through the scheduler hierarchy used by the scheduler enqueue
- * operation to identify the destination queue for the current
- * packet. Stored in the field pkt.hash.sched of struct rte_mbuf of
- * each packet, typically written by the classification stage and read
- * by scheduler enqueue.
- */
-struct rte_sched_port_hierarchy {
- uint16_t queue:2; /**< Queue ID (0 .. 3) */
- uint16_t traffic_class:2; /**< Traffic class ID (0 .. 3)*/
- uint32_t color:2; /**< Color */
- uint16_t unused:10;
- uint16_t subport; /**< Subport ID */
- uint32_t pipe; /**< Pipe ID */
-};
-
struct rte_sched_grinder {
/* Pipe cache */
uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
@@ -185,6 +169,7 @@ struct rte_sched_port {
/* User parameters */
uint32_t n_subports_per_port;
uint32_t n_pipes_per_subport;
+ uint32_t n_pipes_per_subport_log2;
uint32_t rate;
uint32_t mtu;
uint32_t frame_overhead;
@@ -645,6 +630,8 @@ rte_sched_port_config(struct rte_sched_port_params *params)
/* User parameters */
port->n_subports_per_port = params->n_subports_per_port;
port->n_pipes_per_subport = params->n_pipes_per_subport;
+ port->n_pipes_per_subport_log2 =
+ __builtin_ctz(params->n_pipes_per_subport);
port->rate = params->rate;
port->mtu = params->mtu + params->frame_overhead;
port->frame_overhead = params->frame_overhead;
@@ -1006,44 +993,52 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port,
return 0;
}
+static inline uint32_t
+rte_sched_port_qindex(struct rte_sched_port *port,
+ uint32_t subport,
+ uint32_t pipe,
+ uint32_t traffic_class,
+ uint32_t queue)
+{
+ return ((subport & (port->n_subports_per_port - 1)) <<
+ (port->n_pipes_per_subport_log2 + 4)) |
+ ((pipe & (port->n_pipes_per_subport - 1)) << 4) |
+ ((traffic_class &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << 2) |
+ (queue & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1));
+}
+
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
- uint32_t subport, uint32_t pipe, uint32_t traffic_class,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
+ uint32_t subport, uint32_t pipe,
+ uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color)
{
- struct rte_sched_port_hierarchy *sched
- = (struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- RTE_BUILD_BUG_ON(sizeof(*sched) > sizeof(pkt->hash.sched));
-
- sched->color = (uint32_t) color;
- sched->subport = subport;
- sched->pipe = pipe;
- sched->traffic_class = traffic_class;
- sched->queue = queue;
+ uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe,
+ traffic_class, queue);
+ rte_mbuf_sched_set(pkt, queue_id, traffic_class, (enum rte_color)color);
}
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
+ uint32_t queue_id = rte_mbuf_sched_queue_get(pkt);
- *subport = sched->subport;
- *pipe = sched->pipe;
- *traffic_class = sched->traffic_class;
- *queue = sched->queue;
+ *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4);
+ *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1);
+ *traffic_class = (queue_id >> 2) &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1);
+ *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1);
}
enum rte_meter_color
rte_sched_port_pkt_read_color(const struct rte_mbuf *pkt)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- return (enum rte_meter_color) sched->color;
+ return (enum rte_meter_color)rte_mbuf_sched_color_get(pkt);
}
int
@@ -1100,18 +1095,6 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
return 0;
}
-static inline uint32_t
-rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport, uint32_t pipe, uint32_t traffic_class, uint32_t queue)
-{
- uint32_t result;
-
- result = subport * port->n_pipes_per_subport + pipe;
- result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + traffic_class;
- result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
-
- return result;
-}
-
#ifdef RTE_SCHED_DEBUG
static inline int
@@ -1272,11 +1255,8 @@ rte_sched_port_enqueue_qptrs_prefetch0(struct rte_sched_port *port,
#ifdef RTE_SCHED_COLLECT_STATS
struct rte_sched_queue_extra *qe;
#endif
- uint32_t subport, pipe, traffic_class, queue, qindex;
-
- rte_sched_port_pkt_read_tree_path(pkt, &subport, &pipe, &traffic_class, &queue);
+ uint32_t qindex = rte_mbuf_sched_queue_get(pkt);
- qindex = rte_sched_port_qindex(port, subport, pipe, traffic_class, queue);
q = port->queue + qindex;
rte_prefetch0(q);
#ifdef RTE_SCHED_COLLECT_STATS
diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
index 84fa896de..243efa1d4 100644
--- a/lib/librte_sched/rte_sched.h
+++ b/lib/librte_sched/rte_sched.h
@@ -355,6 +355,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Scheduler hierarchy path write to packet descriptor. Typically
* called by the packet classification stage.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -369,7 +371,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Packet color set
*/
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
uint32_t subport, uint32_t pipe, uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color);
@@ -379,6 +382,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
* enqueue operation. The subport, pipe, traffic class and queue
* parameters need to be pre-allocated by the caller.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -392,7 +397,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
*
*/
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue);
diff --git a/test/test/test_sched.c b/test/test/test_sched.c
index 32e500ba9..40e411cab 100644
--- a/test/test/test_sched.c
+++ b/test/test/test_sched.c
@@ -76,7 +76,7 @@ create_mempool(void)
}
static void
-prepare_pkt(struct rte_mbuf *mbuf)
+prepare_pkt(struct rte_sched_port *port, struct rte_mbuf *mbuf)
{
struct ether_hdr *eth_hdr;
struct vlan_hdr *vlan1, *vlan2;
@@ -95,7 +95,8 @@ prepare_pkt(struct rte_mbuf *mbuf)
ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);
- rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW);
+ rte_sched_port_pkt_write(port, mbuf, SUBPORT, PIPE, TC, QUEUE,
+ e_RTE_METER_YELLOW);
/* 64 byte packet */
mbuf->pkt_len = 60;
@@ -138,7 +139,7 @@ test_sched(void)
for (i = 0; i < 10; i++) {
in_mbufs[i] = rte_pktmbuf_alloc(mp);
TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation failed\n");
- prepare_pkt(in_mbufs[i]);
+ prepare_pkt(port, in_mbufs[i]);
}
@@ -155,7 +156,7 @@ test_sched(void)
color = rte_sched_port_pkt_read_color(out_mbufs[i]);
TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong color\n");
- rte_sched_port_pkt_read_tree_path(out_mbufs[i],
+ rte_sched_port_pkt_read_tree_path(port, out_mbufs[i],
&subport, &pipe, &traffic_class, &queue);
TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong subport\n");
--
2.17.1
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v3 0/2] Timer library changes
2018-12-07 17:52 4% ` [dpdk-dev] [PATCH v2 0/2] Timer library changes Erik Gabriel Carrillo
@ 2018-12-13 22:26 4% ` Erik Gabriel Carrillo
2018-12-19 3:35 0% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Erik Gabriel Carrillo @ 2018-12-13 22:26 UTC (permalink / raw)
To: rsanford; +Cc: stephen, jerin.jacob, pbhagavatula, dev
This patch series modifies the timer library in such a way that
structures that used to be statically allocated in a process's data
segment are now allocated in shared memory. As these structures contain
lists of timers, new APIs are introduced that allow a caller to specify
the particular structure instance into which a timer should be inserted
or from which a timer should be removed. This enables primary and
secondary processes to modify the same timer list, which enables some
multi-process use cases that were not previously possible; e.g. a
secondary process can start a timer whose expiration is detected in a
primary process running a new flavor of timer_manage().
The original library API is mostly unchanged, though implementations are
updated to call into newly added functions with a default structure
instance ID that provides the original behavior. New functions are
introduced to enable applications to allocate structure instances to
house timer lists, and to reference them with an identifier when
starting and stopping timers, and finally, to manage the timer lists
referenced with an identifier.
My initial performance testing with the "timer_perf_autotest" test shows
no performance regression or improvement, and inspection of the
generated optimized code shows that the extra function call gets inlined
in the functions that now have an extra function call.
Depends on: https://patches.dpdk.org/patch/48417/
Changes in v3:
- remove C++ style comment in first patch in series (Stephen)
Changes in v2:
- split these changes out into their own series
- version the symbols where the existing ABI was updated, and
provide alternate implementation with behavior equivalent to original
behavior. Validated ABI compatibility with validate-abi.sh
- refactor changes to simplify patches
Erik Gabriel Carrillo (2):
timer: allow timer management in shared memory
timer: add function to stop all timers in a list
lib/librte_timer/Makefile | 1 +
lib/librte_timer/rte_timer.c | 558 ++++++++++++++++++++++++++++++---
lib/librte_timer/rte_timer.h | 258 ++++++++++++++-
lib/librte_timer/rte_timer_version.map | 23 ++
4 files changed, 795 insertions(+), 45 deletions(-)
--
2.6.4
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2] libs/power: add p-state driver compatibility
2018-11-23 11:33 1% [dpdk-dev] [PATCH] libs/power: add p-state driver compatibility Liang Ma
2018-12-10 16:08 0% ` Burakov, Anatoly
@ 2018-12-14 11:13 1% ` Liang Ma
2018-12-14 12:20 0% ` Burakov, Anatoly
2018-12-14 13:11 1% ` [dpdk-dev] [PATCH v3] " Liang Ma
1 sibling, 2 replies; 200+ results
From: Liang Ma @ 2018-12-14 11:13 UTC (permalink / raw)
To: david.hunt; +Cc: dev, anatoly.burakov, Liang Ma
Previously, in order to use the power library, it was necessary
for the user to disable the intel_pstate driver by adding
“intel_pstate=disable” to the kernel command line for the system,
which causes the acpi_cpufreq driver to be loaded in its place.
This patch adds the ability for the power library use the intel-pstate
driver.
It adds a new suite of functions behind the current power library API,
and will seamlessly set up the user facing API function pointers to
the relevant functions depending on whether the system is running with
acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
using kvm. The library API and ABI is unchanged.
Signed-off-by: Liang Ma <liang.j.ma@intel.com>
---
lib/librte_power/Makefile | 2 +
lib/librte_power/meson.build | 4 +-
lib/librte_power/power_pstate_cpufreq.c | 770 ++++++++++++++++++++++++++++++++
lib/librte_power/power_pstate_cpufreq.h | 218 +++++++++
lib/librte_power/rte_power.c | 48 +-
lib/librte_power/rte_power.h | 3 +-
6 files changed, 1032 insertions(+), 13 deletions(-)
create mode 100644 lib/librte_power/power_pstate_cpufreq.c
create mode 100644 lib/librte_power/power_pstate_cpufreq.h
diff --git a/lib/librte_power/Makefile b/lib/librte_power/Makefile
index 9bec668..ab77152 100644
--- a/lib/librte_power/Makefile
+++ b/lib/librte_power/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
# library name
LIB = librte_power.a
+CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 -fno-strict-aliasing
LDLIBS += -lrte_eal -lrte_timer
@@ -17,6 +18,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_POWER) := rte_power.c power_acpi_cpufreq.c
SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_kvm_vm.c guest_channel.c
SRCS-$(CONFIG_RTE_LIBRTE_POWER) += rte_power_empty_poll.c
+SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_pstate_cpufreq.c
# install this header file
SYMLINK-$(CONFIG_RTE_LIBRTE_POWER)-include := rte_power.h rte_power_empty_poll.h
diff --git a/lib/librte_power/meson.build b/lib/librte_power/meson.build
index 9ed8b56..14a2128 100644
--- a/lib/librte_power/meson.build
+++ b/lib/librte_power/meson.build
@@ -6,6 +6,6 @@ if host_machine.system() != 'linux'
endif
sources = files('rte_power.c', 'power_acpi_cpufreq.c',
'power_kvm_vm.c', 'guest_channel.c',
- 'rte_power_empty_poll.c')
+ 'rte_power_empty_poll.c',
+ 'power_pstate_cpufreq.c')
headers = files('rte_power.h','rte_power_empty_poll.h')
-deps += ['timer']
diff --git a/lib/librte_power/power_pstate_cpufreq.c b/lib/librte_power/power_pstate_cpufreq.c
new file mode 100644
index 0000000..1711484
--- /dev/null
+++ b/lib/librte_power/power_pstate_cpufreq.c
@@ -0,0 +1,770 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <rte_memcpy.h>
+#include <rte_atomic.h>
+
+#include "power_pstate_cpufreq.h"
+#include "power_common.h"
+
+
+#ifdef RTE_LIBRTE_POWER_DEBUG
+#define POWER_DEBUG_TRACE(fmt, args...) do { \
+ RTE_LOG(ERR, POWER, "%s: " fmt, __func__, ## args); \
+} while (0)
+#else
+#define POWER_DEBUG_TRACE(fmt, args...)
+#endif
+
+#define FOPEN_OR_ERR_RET(f, retval) do { \
+ if ((f) == NULL) { \
+ RTE_LOG(ERR, POWER, "File not openned\n"); \
+ return retval; \
+ } \
+} while (0)
+
+#define FOPS_OR_NULL_GOTO(ret, label) do { \
+ if ((ret) == NULL) { \
+ RTE_LOG(ERR, POWER, "fgets returns nothing\n"); \
+ goto label; \
+ } \
+} while (0)
+
+#define FOPS_OR_ERR_GOTO(ret, label) do { \
+ if ((ret) < 0) { \
+ RTE_LOG(ERR, POWER, "File operations failed\n"); \
+ goto label; \
+ } \
+} while (0)
+
+
+#define POWER_CONVERT_TO_DECIMAL 10
+#define BUS_FREQ 100000
+
+#define POWER_GOVERNOR_PERF "performance"
+#define POWER_SYSFILE_GOVERNOR \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_governor"
+#define POWER_SYSFILE_MAX_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_max_freq"
+#define POWER_SYSFILE_MIN_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_min_freq"
+#define POWER_SYSFILE_CUR_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq"
+#define POWER_SYSFILE_BASE_MAX_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_max_freq"
+#define POWER_SYSFILE_BASE_MIN_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_min_freq"
+#define POWER_MSR_PATH "/dev/cpu/%u/msr"
+
+/*
+ * MSR related
+ */
+#define PLATFORM_INFO 0x0CE
+#define NON_TURBO_MASK 0xFF00
+#define NON_TURBO_OFFSET 0x8
+
+
+enum power_state {
+ POWER_IDLE = 0,
+ POWER_ONGOING,
+ POWER_USED,
+ POWER_UNKNOWN
+};
+
+struct pstate_power_info {
+ unsigned int lcore_id; /**< Logical core id */
+ uint32_t freqs[RTE_MAX_LCORE_FREQS]; /**< Frequency array */
+ uint32_t nb_freqs; /**< number of available freqs */
+ FILE *f_cur_min; /**< FD of scaling_min */
+ FILE *f_cur_max; /**< FD of scaling_max */
+ char governor_ori[32]; /**< Original governor name */
+ uint32_t curr_idx; /**< Freq index in freqs array */
+ uint32_t non_turbo_max_ratio; /**< Non Turbo Max ratio */
+ uint32_t sys_max_freq; /**< system wide max freq */
+ volatile uint32_t state; /**< Power in use state */
+ uint16_t turbo_available; /**< Turbo Boost available */
+ uint16_t turbo_enable; /**< Turbo Boost enable/disable */
+} __rte_cache_aligned;
+
+
+static struct pstate_power_info lcore_power_info[RTE_MAX_LCORE];
+
+/**
+ * It is to read the specific MSR.
+ */
+
+static int32_t
+power_rdmsr(int msr, uint64_t *val, unsigned int lcore_id)
+{
+ int fd, ret;
+ char fullpath[PATH_MAX];
+
+ snprintf(fullpath, sizeof(fullpath), POWER_MSR_PATH, lcore_id);
+
+ fd = open(fullpath, O_RDONLY);
+
+ if (fd < 0) {
+ RTE_LOG(ERR, POWER, "Error opening '%s': %s\n", fullpath,
+ strerror(errno));
+ return fd;
+ }
+
+ ret = pread(fd, val, sizeof(uint64_t), msr);
+
+ if (ret < 0) {
+ RTE_LOG(ERR, POWER, "Error reading '%s': %s\n", fullpath,
+ strerror(errno));
+ goto out;
+ }
+
+ POWER_DEBUG_TRACE("MSR Path %s, offset 0x%X for lcore %u\n",
+ fullpath, msr, lcore_id);
+
+ POWER_DEBUG_TRACE("Ret value %d, content is 0x%lx\n", ret, *val);
+
+out: close(fd);
+ return ret;
+}
+
+/**
+ * It is to fopen the sys file for the future setting the lcore frequency.
+ */
+static int
+power_init_for_setting_freq(struct pstate_power_info *pi)
+{
+ FILE *f_min, *f_max;
+ char fullpath_min[PATH_MAX];
+ char fullpath_max[PATH_MAX];
+ uint64_t max_non_turbo = 0;
+
+ snprintf(fullpath_min, sizeof(fullpath_min), POWER_SYSFILE_MIN_FREQ,
+ pi->lcore_id);
+
+ f_min = fopen(fullpath_min, "rw+");
+ FOPEN_OR_ERR_RET(f_min, -1);
+
+ snprintf(fullpath_max, sizeof(fullpath_max), POWER_SYSFILE_MAX_FREQ,
+ pi->lcore_id);
+
+ f_max = fopen(fullpath_max, "rw+");
+ FOPEN_OR_ERR_RET(f_max, -1);
+
+ pi->f_cur_min = f_min;
+ pi->f_cur_max = f_max;
+
+ /* Add MSR read to detect turbo status */
+
+ if (power_rdmsr(PLATFORM_INFO, &max_non_turbo, pi->lcore_id) < 0)
+ return -1;
+
+ max_non_turbo = (max_non_turbo&NON_TURBO_MASK)>>NON_TURBO_OFFSET;
+
+ POWER_DEBUG_TRACE("no turbo perf %lu\n", max_non_turbo);
+
+ pi->non_turbo_max_ratio = max_non_turbo;
+
+ return 0;
+}
+
+static int
+set_freq_internal(struct pstate_power_info *pi, uint32_t idx)
+{
+ uint32_t target_freq = 0;
+
+ if (idx >= RTE_MAX_LCORE_FREQS || idx >= pi->nb_freqs) {
+ RTE_LOG(ERR, POWER, "Invalid frequency index %u, which "
+ "should be less than %u\n", idx, pi->nb_freqs);
+ return -1;
+ }
+
+ /* Check if it is the same as current */
+ if (idx == pi->curr_idx)
+ return 0;
+
+ /* Because Intel Pstate Driver only allow user change min/max hint
+ * User need change the min/max as same value.
+ */
+ if (fseek(pi->f_cur_min, 0, SEEK_SET) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to set file position indicator to 0 "
+ "for setting frequency for lcore %u\n",
+ pi->lcore_id);
+ return -1;
+ }
+
+ if (fseek(pi->f_cur_max, 0, SEEK_SET) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to set file position indicator to 0 "
+ "for setting frequency for lcore %u\n",
+ pi->lcore_id);
+ return -1;
+ }
+
+ /* Turbo is available and enabled, first freq bucket is sys max freq */
+ if (pi->turbo_available && pi->turbo_enable && (idx == 0))
+ target_freq = pi->sys_max_freq;
+ else
+ target_freq = pi->freqs[idx];
+
+ /* Decrease freq, the min freq should be updated first */
+ if (idx > pi->curr_idx) {
+
+ if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ POWER_DEBUG_TRACE("Freqency '%u' to be set for lcore %u\n",
+ target_freq, pi->lcore_id);
+
+ fflush(pi->f_cur_min);
+ fflush(pi->f_cur_max);
+
+ }
+
+ /* Increase freq, the max freq should be updated first */
+ if (idx < pi->curr_idx) {
+
+ if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ POWER_DEBUG_TRACE("Freqency '%u' to be set for lcore %u\n",
+ target_freq, pi->lcore_id);
+
+ fflush(pi->f_cur_max);
+ fflush(pi->f_cur_min);
+ }
+
+ pi->curr_idx = idx;
+
+ return 1;
+}
+
+/**
+ * It is to check the current scaling governor by reading sys file, and then
+ * set it into 'performance' if it is not by writing the sys file. The original
+ * governor will be saved for rolling back.
+ */
+static int
+power_set_governor_performance(struct pstate_power_info *pi)
+{
+ FILE *f;
+ int ret = -1;
+ char buf[BUFSIZ];
+ char fullpath[PATH_MAX];
+ char *s;
+ int val;
+
+ snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_GOVERNOR,
+ pi->lcore_id);
+ f = fopen(fullpath, "rw+");
+ FOPEN_OR_ERR_RET(f, ret);
+
+ s = fgets(buf, sizeof(buf), f);
+ FOPS_OR_NULL_GOTO(s, out);
+
+ /* Check if current governor is performance */
+ if (strncmp(buf, POWER_GOVERNOR_PERF,
+ sizeof(POWER_GOVERNOR_PERF)) == 0) {
+ ret = 0;
+ POWER_DEBUG_TRACE("Power management governor of lcore %u is "
+ "already performance\n", pi->lcore_id);
+ goto out;
+ }
+ /* Save the original governor */
+ snprintf(pi->governor_ori, sizeof(pi->governor_ori), "%s", buf);
+
+ /* Write 'performance' to the governor */
+ val = fseek(f, 0, SEEK_SET);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ val = fputs(POWER_GOVERNOR_PERF, f);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ ret = 0;
+ RTE_LOG(INFO, POWER, "Power management governor of lcore %u has been "
+ "set to performance successfully\n", pi->lcore_id);
+out:
+ fclose(f);
+
+ return ret;
+}
+
+/**
+ * It is to check the governor and then set the original governor back if
+ * needed by writing the sys file.
+ */
+static int
+power_set_governor_original(struct pstate_power_info *pi)
+{
+ FILE *f;
+ int ret = -1;
+ char buf[BUFSIZ];
+ char fullpath[PATH_MAX];
+ char *s;
+ int val;
+
+ snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_GOVERNOR,
+ pi->lcore_id);
+ f = fopen(fullpath, "rw+");
+ FOPEN_OR_ERR_RET(f, ret);
+
+ s = fgets(buf, sizeof(buf), f);
+ FOPS_OR_NULL_GOTO(s, out);
+
+ /* Check if the governor to be set is the same as current */
+ if (strncmp(buf, pi->governor_ori, sizeof(pi->governor_ori)) == 0) {
+ ret = 0;
+ POWER_DEBUG_TRACE("Power management governor of lcore %u "
+ "has already been set to %s\n",
+ pi->lcore_id, pi->governor_ori);
+ goto out;
+ }
+
+ /* Write back the original governor */
+ val = fseek(f, 0, SEEK_SET);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ val = fputs(pi->governor_ori, f);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ ret = 0;
+ RTE_LOG(INFO, POWER, "Power management governor of lcore %u "
+ "has been set back to %s successfully\n",
+ pi->lcore_id, pi->governor_ori);
+out:
+ fclose(f);
+
+ return ret;
+}
+
+/**
+ * It is to get the available frequencies of the specific lcore by reading the
+ * sys file.
+ */
+static int
+power_get_available_freqs(struct pstate_power_info *pi)
+{
+ FILE *f_min, *f_max;
+ int ret = -1;
+ char *p_min, *p_max;
+ char buf_min[BUFSIZ];
+ char buf_max[BUFSIZ];
+ char fullpath_min[PATH_MAX];
+ char fullpath_max[PATH_MAX];
+ char *s_min, *s_max;
+ uint32_t sys_min_freq = 0, sys_max_freq = 0, base_max_freq = 0;
+ uint32_t i, num_freqs = 0;
+
+ snprintf(fullpath_max, sizeof(fullpath_max),
+ POWER_SYSFILE_BASE_MAX_FREQ,
+ pi->lcore_id);
+ snprintf(fullpath_min, sizeof(fullpath_min),
+ POWER_SYSFILE_BASE_MIN_FREQ,
+ pi->lcore_id);
+
+ f_min = fopen(fullpath_min, "r");
+ FOPEN_OR_ERR_RET(f_min, ret);
+
+ f_max = fopen(fullpath_max, "r");
+ FOPEN_OR_ERR_RET(f_max, ret);
+
+ s_min = fgets(buf_min, sizeof(buf_min), f_min);
+ FOPS_OR_NULL_GOTO(s_min, out);
+
+ s_max = fgets(buf_max, sizeof(buf_max), f_max);
+ FOPS_OR_NULL_GOTO(s_max, out);
+
+
+ /* Strip the line break if there is */
+ p_min = strchr(buf_min, '\n');
+ if (p_min != NULL)
+ *p_min = 0;
+
+ p_max = strchr(buf_max, '\n');
+ if (p_max != NULL)
+ *p_max = 0;
+
+ sys_min_freq = strtoul(buf_min, &p_min, POWER_CONVERT_TO_DECIMAL);
+ sys_max_freq = strtoul(buf_max, &p_max, POWER_CONVERT_TO_DECIMAL);
+
+ if (sys_max_freq < sys_min_freq)
+ goto out;
+
+ pi->sys_max_freq = sys_max_freq;
+
+ base_max_freq = pi->non_turbo_max_ratio * BUS_FREQ;
+
+ POWER_DEBUG_TRACE("sys min %u, sys max %u, base_max %u\n",
+ sys_min_freq,
+ sys_max_freq,
+ base_max_freq);
+
+ if (base_max_freq < sys_max_freq)
+ pi->turbo_available = 1;
+ else
+ pi->turbo_available = 0;
+
+ /* If turbo is available then there is one extra freq bucket
+ * to store the sys max freq which value is base_max +1
+ */
+ num_freqs = (base_max_freq - sys_min_freq) / BUS_FREQ + 1 +
+ pi->turbo_available;
+
+ /* Generate the freq bucket array.
+ * If turbo is available the freq bucket[0] value is base_max +1
+ * the bucket[1] is base_max, bucket[2] is base_max - BUS_FREQ
+ * and so on.
+ * If turbo is not available bucket[0] is base_max and so on
+ */
+ for (i = 0, pi->nb_freqs = 0; i < num_freqs; i++) {
+ if ((i == 0) && pi->turbo_available)
+ pi->freqs[pi->nb_freqs++] = base_max_freq + 1;
+ else
+ pi->freqs[pi->nb_freqs++] =
+ base_max_freq - (i - pi->turbo_available) * BUS_FREQ;
+ }
+
+ ret = 0;
+
+ POWER_DEBUG_TRACE("%d frequency(s) of lcore %u are available\n",
+ num_freqs, pi->lcore_id);
+
+out:
+ fclose(f_min);
+ fclose(f_max);
+
+ return ret;
+}
+
+int
+power_pstate_cpufreq_init(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Lcore id %u can not exceed %u\n",
+ lcore_id, RTE_MAX_LCORE - 1U);
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (rte_atomic32_cmpset(&(pi->state), POWER_IDLE, POWER_ONGOING)
+ == 0) {
+ RTE_LOG(INFO, POWER, "Power management of lcore %u is "
+ "in use\n", lcore_id);
+ return -1;
+ }
+
+ pi->lcore_id = lcore_id;
+ /* Check and set the governor */
+ if (power_set_governor_performance(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set governor of lcore %u to "
+ "performance\n", lcore_id);
+ goto fail;
+ }
+ /* Init for setting lcore frequency */
+ if (power_init_for_setting_freq(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot init for setting frequency for "
+ "lcore %u\n", lcore_id);
+ goto fail;
+ }
+
+ /* Get the available frequencies */
+ if (power_get_available_freqs(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot get available frequencies of "
+ "lcore %u\n", lcore_id);
+ goto fail;
+ }
+
+
+ /* Set freq to max by default */
+ if (power_pstate_cpufreq_freq_max(lcore_id) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set frequency of lcore %u "
+ "to max\n", lcore_id);
+ goto fail;
+ }
+
+ RTE_LOG(INFO, POWER, "Initialized successfully for lcore %u "
+ "power management\n", lcore_id);
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_USED);
+
+ return 0;
+
+fail:
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
+
+ return -1;
+}
+
+int
+power_pstate_cpufreq_exit(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Lcore id %u can not exceeds %u\n",
+ lcore_id, RTE_MAX_LCORE - 1U);
+ return -1;
+ }
+ pi = &lcore_power_info[lcore_id];
+
+ if (rte_atomic32_cmpset(&(pi->state), POWER_USED, POWER_ONGOING)
+ == 0) {
+ RTE_LOG(INFO, POWER, "Power management of lcore %u is "
+ "not used\n", lcore_id);
+ return -1;
+ }
+
+ /* Close FD of setting freq */
+ fclose(pi->f_cur_min);
+ fclose(pi->f_cur_max);
+ pi->f_cur_min = NULL;
+ pi->f_cur_max = NULL;
+
+ /* Set the governor back to the original */
+ if (power_set_governor_original(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set the governor of %u back "
+ "to the original\n", lcore_id);
+ goto fail;
+ }
+
+ RTE_LOG(INFO, POWER, "Power management of lcore %u has exited from "
+ "'performance' mode and been set back to the "
+ "original\n", lcore_id);
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_IDLE);
+
+ return 0;
+
+fail:
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
+
+ return -1;
+}
+
+
+uint32_t
+power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (num < pi->nb_freqs) {
+ RTE_LOG(ERR, POWER, "Buffer size is not enough\n");
+ return 0;
+ }
+ rte_memcpy(freqs, pi->freqs, pi->nb_freqs * sizeof(uint32_t));
+
+ return pi->nb_freqs;
+}
+
+uint32_t
+power_pstate_cpufreq_get_freq(unsigned int lcore_id)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return RTE_POWER_INVALID_FREQ_INDEX;
+ }
+
+ return lcore_power_info[lcore_id].curr_idx;
+}
+
+
+int
+power_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ return set_freq_internal(&(lcore_power_info[lcore_id]), index);
+}
+
+int
+power_pstate_cpufreq_freq_up(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (pi->curr_idx == 0)
+ return 0;
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->curr_idx - 1);
+}
+
+int
+power_pstate_cpufreq_freq_down(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (pi->curr_idx + 1 == pi->nb_freqs)
+ return 0;
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->curr_idx + 1);
+}
+
+int
+power_pstate_cpufreq_freq_max(unsigned int lcore_id)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ /* Frequencies in the array are from high to low. */
+ if (lcore_power_info[lcore_id].turbo_available) {
+ if (lcore_power_info[lcore_id].turbo_enable)
+ /* Set to Turbo */
+ return set_freq_internal(
+ &lcore_power_info[lcore_id], 0);
+ else
+ /* Set to max non-turbo */
+ return set_freq_internal(
+ &lcore_power_info[lcore_id], 1);
+ } else
+ return set_freq_internal(&lcore_power_info[lcore_id], 0);
+}
+
+
+int
+power_pstate_cpufreq_freq_min(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->nb_freqs - 1);
+}
+
+
+int
+power_pstate_turbo_status(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ return pi->turbo_enable;
+}
+
+int
+power_pstate_enable_turbo(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ if (pi->turbo_available)
+ pi->turbo_enable = 1;
+ else {
+ pi->turbo_enable = 0;
+ RTE_LOG(ERR, POWER,
+ "Failed to enable turbo on lcore %u\n",
+ lcore_id);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+power_pstate_disable_turbo(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ pi->turbo_enable = 0;
+
+
+ return 0;
+}
+
+
+int power_pstate_get_capabilities(unsigned int lcore_id,
+ struct rte_power_core_capabilities *caps)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+ if (caps == NULL) {
+ RTE_LOG(ERR, POWER, "Invalid argument\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ caps->capabilities = 0;
+ caps->turbo = !!(pi->turbo_available);
+
+ return 0;
+}
diff --git a/lib/librte_power/power_pstate_cpufreq.h b/lib/librte_power/power_pstate_cpufreq.h
new file mode 100644
index 0000000..2f11128
--- /dev/null
+++ b/lib/librte_power/power_pstate_cpufreq.h
@@ -0,0 +1,218 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#ifndef _POWER_PSTATE_CPUFREQ_H
+#define _POWER_PSTATE_CPUFREQ_H
+
+/**
+ * @file
+ * RTE Power Management via Intel Pstate driver
+ */
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_string_fns.h>
+#include "rte_power.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize power management for a specific lcore. It will check and set the
+ * governor to performance for the lcore, get the available frequencies, and
+ * prepare to set new lcore frequency.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_init(unsigned int lcore_id);
+
+/**
+ * Exit power management on a specific lcore. It will set the governor to which
+ * is before initialized.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_exit(unsigned int lcore_id);
+
+/**
+ * Get the available frequencies of a specific lcore. The return value will be
+ * the minimal one of the total number of available frequencies and the number
+ * of buffer. The index of available frequencies used in other interfaces
+ * should be in the range of 0 to this return value.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param freqs
+ * The buffer array to save the frequencies.
+ * @param num
+ * The number of frequencies to get.
+ *
+ * @return
+ * The number of available frequencies.
+ */
+uint32_t power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs,
+ uint32_t num);
+
+/**
+ * Return the current index of available frequencies of a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * The current index of available frequencies.
+ * If error, it will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)'.
+ */
+uint32_t power_pstate_cpufreq_get_freq(unsigned int lcore_id);
+
+/**
+ * Set the new frequency for a specific lcore by indicating the index of
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param index
+ * The index of available frequencies.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index);
+
+/**
+ * Scale up the frequency of a specific lcore according to the available
+ * frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_up(unsigned int lcore_id);
+
+/**
+ * Scale down the frequency of a specific lcore according to the available
+ * frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_down(unsigned int lcore_id);
+
+/**
+ * Scale up the frequency of a specific lcore to the highest according to the
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_max(unsigned int lcore_id);
+
+/**
+ * Scale down the frequency of a specific lcore to the lowest according to the
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_min(unsigned int lcore_id);
+
+/**
+ * Get the turbo status of a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 Turbo Boost is enabled on this lcore.
+ * - 0 Turbo Boost is disabled on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_turbo_status(unsigned int lcore_id);
+
+/**
+ * Enable Turbo Boost on a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 Turbo Boost is enabled successfully on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_enable_turbo(unsigned int lcore_id);
+
+/**
+ * Disable Turbo Boost on a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 Turbo Boost disabled successfully on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_disable_turbo(unsigned int lcore_id);
+
+/**
+ * Returns power capabilities for a specific lcore.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param caps
+ * pointer to rte_power_core_capabilities object.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_get_capabilities(unsigned int lcore_id,
+ struct rte_power_core_capabilities *caps);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_power/rte_power.c b/lib/librte_power/rte_power.c
index 208b791..a05fbef 100644
--- a/lib/librte_power/rte_power.c
+++ b/lib/librte_power/rte_power.c
@@ -7,6 +7,7 @@
#include "rte_power.h"
#include "power_acpi_cpufreq.h"
#include "power_kvm_vm.h"
+#include "power_pstate_cpufreq.h"
#include "power_common.h"
enum power_management_env global_default_env = PM_ENV_NOT_SET;
@@ -56,6 +57,19 @@ rte_power_set_env(enum power_management_env env)
rte_power_freq_enable_turbo = power_kvm_vm_enable_turbo;
rte_power_freq_disable_turbo = power_kvm_vm_disable_turbo;
rte_power_get_capabilities = power_kvm_vm_get_capabilities;
+ } else if (env == PM_ENV_PSTATE_CPUFREQ) {
+ rte_power_freqs = power_pstate_cpufreq_freqs;
+ rte_power_get_freq = power_pstate_cpufreq_get_freq;
+ rte_power_set_freq = power_pstate_cpufreq_set_freq;
+ rte_power_freq_up = power_pstate_cpufreq_freq_up;
+ rte_power_freq_down = power_pstate_cpufreq_freq_down;
+ rte_power_freq_min = power_pstate_cpufreq_freq_min;
+ rte_power_freq_max = power_pstate_cpufreq_freq_max;
+ rte_power_turbo_status = power_pstate_turbo_status;
+ rte_power_freq_enable_turbo = power_pstate_enable_turbo;
+ rte_power_freq_disable_turbo = power_pstate_disable_turbo;
+ rte_power_get_capabilities = power_pstate_get_capabilities;
+
} else {
RTE_LOG(ERR, POWER, "Invalid Power Management Environment(%d) set\n",
env);
@@ -64,7 +78,6 @@ rte_power_set_env(enum power_management_env env)
}
global_default_env = env;
return 0;
-
}
void
@@ -84,21 +97,32 @@ rte_power_init(unsigned int lcore_id)
{
int ret = -1;
- if (global_default_env == PM_ENV_ACPI_CPUFREQ) {
+ switch (global_default_env) {
+ case PM_ENV_ACPI_CPUFREQ:
return power_acpi_cpufreq_init(lcore_id);
- }
- if (global_default_env == PM_ENV_KVM_VM) {
+ case PM_ENV_KVM_VM:
return power_kvm_vm_init(lcore_id);
+ case PM_ENV_PSTATE_CPUFREQ:
+ return power_pstate_cpufreq_init(lcore_id);
+ default:
+ RTE_LOG(INFO, POWER, "Env isn't set yet!\n");
}
+
/* Auto detect Environment */
- RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power "
- "management...\n");
+ RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power management...\n");
ret = power_acpi_cpufreq_init(lcore_id);
if (ret == 0) {
rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
goto out;
}
+ RTE_LOG(INFO, POWER, "Attempting to initialise PSTAT power management...\n");
+ ret = power_pstate_cpufreq_init(lcore_id);
+ if (ret == 0) {
+ rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
+ goto out;
+ }
+
RTE_LOG(INFO, POWER, "Attempting to initialise VM power management...\n");
ret = power_kvm_vm_init(lcore_id);
if (ret == 0) {
@@ -114,13 +138,17 @@ rte_power_init(unsigned int lcore_id)
int
rte_power_exit(unsigned int lcore_id)
{
- if (global_default_env == PM_ENV_ACPI_CPUFREQ)
+ switch (global_default_env) {
+ case PM_ENV_ACPI_CPUFREQ:
return power_acpi_cpufreq_exit(lcore_id);
- if (global_default_env == PM_ENV_KVM_VM)
+ case PM_ENV_KVM_VM:
return power_kvm_vm_exit(lcore_id);
+ case PM_ENV_PSTATE_CPUFREQ:
+ return power_pstate_cpufreq_exit(lcore_id);
+ default:
+ RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit gracefully\n");
- RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit "
- "gracefully\n");
+ }
return -1;
}
diff --git a/lib/librte_power/rte_power.h b/lib/librte_power/rte_power.h
index d70bc0b..c5e8f6b 100644
--- a/lib/librte_power/rte_power.h
+++ b/lib/librte_power/rte_power.h
@@ -20,7 +20,8 @@ extern "C" {
#endif
/* Power Management Environment State */
-enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM};
+enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM,
+ PM_ENV_PSTATE_CPUFREQ};
/**
* Set the default power management implementation. If this is not called prior
--
2.7.5
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH v2] libs/power: add p-state driver compatibility
2018-12-14 11:13 1% ` [dpdk-dev] [PATCH v2] " Liang Ma
@ 2018-12-14 12:20 0% ` Burakov, Anatoly
2018-12-14 13:11 1% ` [dpdk-dev] [PATCH v3] " Liang Ma
1 sibling, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-12-14 12:20 UTC (permalink / raw)
To: Liang Ma, david.hunt; +Cc: dev
On 14-Dec-18 11:13 AM, Liang Ma wrote:
> Previously, in order to use the power library, it was necessary
> for the user to disable the intel_pstate driver by adding
> “intel_pstate=disable” to the kernel command line for the system,
> which causes the acpi_cpufreq driver to be loaded in its place.
>
> This patch adds the ability for the power library use the intel-pstate
> driver.
>
> It adds a new suite of functions behind the current power library API,
> and will seamlessly set up the user facing API function pointers to
> the relevant functions depending on whether the system is running with
> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
> using kvm. The library API and ABI is unchanged.
>
> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> ---
<snip>
> sources = files('rte_power.c', 'power_acpi_cpufreq.c',
> 'power_kvm_vm.c', 'guest_channel.c',
> - 'rte_power_empty_poll.c')
> + 'rte_power_empty_poll.c',
> + 'power_pstate_cpufreq.c')
> headers = files('rte_power.h','rte_power_empty_poll.h')
> -deps += ['timer']
> diff --git a/lib/librte_power/power_pstate_cpufreq.c b/lib/librte_power/power_pstate_cpufreq.c
> new file mode 100644
> index 0000000..1711484
> --- /dev/null
> +++ b/lib/librte_power/power_pstate_cpufreq.c
> @@ -0,0 +1,770 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2018 Intel Corporation
Like i said in comments to previous revision, copyright date here is
wrong - you're creating a new file. This file wasn't created in 2010. It
should just say "2018".
Other than that, LGTM
Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
--
Thanks,
Anatoly
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-14 11:13 1% ` [dpdk-dev] [PATCH v2] " Liang Ma
2018-12-14 12:20 0% ` Burakov, Anatoly
@ 2018-12-14 13:11 1% ` Liang Ma
2018-12-19 3:18 0% ` Thomas Monjalon
2018-12-20 14:43 1% ` [dpdk-dev] [PATCH v4] " Liang Ma
1 sibling, 2 replies; 200+ results
From: Liang Ma @ 2018-12-14 13:11 UTC (permalink / raw)
To: david.hunt; +Cc: dev, anatoly.burakov, Liang Ma
Previously, in order to use the power library, it was necessary
for the user to disable the intel_pstate driver by adding
“intel_pstate=disable” to the kernel command line for the system,
which causes the acpi_cpufreq driver to be loaded in its place.
This patch adds the ability for the power library use the intel-pstate
driver.
It adds a new suite of functions behind the current power library API,
and will seamlessly set up the user facing API function pointers to
the relevant functions depending on whether the system is running with
acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
using kvm. The library API and ABI is unchanged.
Signed-off-by: Liang Ma <liang.j.ma@intel.com>
Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
lib/librte_power/Makefile | 2 +
lib/librte_power/meson.build | 4 +-
lib/librte_power/power_pstate_cpufreq.c | 770 ++++++++++++++++++++++++++++++++
lib/librte_power/power_pstate_cpufreq.h | 218 +++++++++
lib/librte_power/rte_power.c | 48 +-
lib/librte_power/rte_power.h | 3 +-
6 files changed, 1032 insertions(+), 13 deletions(-)
create mode 100644 lib/librte_power/power_pstate_cpufreq.c
create mode 100644 lib/librte_power/power_pstate_cpufreq.h
diff --git a/lib/librte_power/Makefile b/lib/librte_power/Makefile
index 9bec668..ab77152 100644
--- a/lib/librte_power/Makefile
+++ b/lib/librte_power/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
# library name
LIB = librte_power.a
+CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 -fno-strict-aliasing
LDLIBS += -lrte_eal -lrte_timer
@@ -17,6 +18,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_POWER) := rte_power.c power_acpi_cpufreq.c
SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_kvm_vm.c guest_channel.c
SRCS-$(CONFIG_RTE_LIBRTE_POWER) += rte_power_empty_poll.c
+SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_pstate_cpufreq.c
# install this header file
SYMLINK-$(CONFIG_RTE_LIBRTE_POWER)-include := rte_power.h rte_power_empty_poll.h
diff --git a/lib/librte_power/meson.build b/lib/librte_power/meson.build
index 9ed8b56..14a2128 100644
--- a/lib/librte_power/meson.build
+++ b/lib/librte_power/meson.build
@@ -6,6 +6,6 @@ if host_machine.system() != 'linux'
endif
sources = files('rte_power.c', 'power_acpi_cpufreq.c',
'power_kvm_vm.c', 'guest_channel.c',
- 'rte_power_empty_poll.c')
+ 'rte_power_empty_poll.c',
+ 'power_pstate_cpufreq.c')
headers = files('rte_power.h','rte_power_empty_poll.h')
-deps += ['timer']
diff --git a/lib/librte_power/power_pstate_cpufreq.c b/lib/librte_power/power_pstate_cpufreq.c
new file mode 100644
index 0000000..dd6a20c
--- /dev/null
+++ b/lib/librte_power/power_pstate_cpufreq.c
@@ -0,0 +1,770 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2018 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <rte_memcpy.h>
+#include <rte_atomic.h>
+
+#include "power_pstate_cpufreq.h"
+#include "power_common.h"
+
+
+#ifdef RTE_LIBRTE_POWER_DEBUG
+#define POWER_DEBUG_TRACE(fmt, args...) do { \
+ RTE_LOG(ERR, POWER, "%s: " fmt, __func__, ## args); \
+} while (0)
+#else
+#define POWER_DEBUG_TRACE(fmt, args...)
+#endif
+
+#define FOPEN_OR_ERR_RET(f, retval) do { \
+ if ((f) == NULL) { \
+ RTE_LOG(ERR, POWER, "File not openned\n"); \
+ return retval; \
+ } \
+} while (0)
+
+#define FOPS_OR_NULL_GOTO(ret, label) do { \
+ if ((ret) == NULL) { \
+ RTE_LOG(ERR, POWER, "fgets returns nothing\n"); \
+ goto label; \
+ } \
+} while (0)
+
+#define FOPS_OR_ERR_GOTO(ret, label) do { \
+ if ((ret) < 0) { \
+ RTE_LOG(ERR, POWER, "File operations failed\n"); \
+ goto label; \
+ } \
+} while (0)
+
+
+#define POWER_CONVERT_TO_DECIMAL 10
+#define BUS_FREQ 100000
+
+#define POWER_GOVERNOR_PERF "performance"
+#define POWER_SYSFILE_GOVERNOR \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_governor"
+#define POWER_SYSFILE_MAX_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_max_freq"
+#define POWER_SYSFILE_MIN_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_min_freq"
+#define POWER_SYSFILE_CUR_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq"
+#define POWER_SYSFILE_BASE_MAX_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_max_freq"
+#define POWER_SYSFILE_BASE_MIN_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_min_freq"
+#define POWER_MSR_PATH "/dev/cpu/%u/msr"
+
+/*
+ * MSR related
+ */
+#define PLATFORM_INFO 0x0CE
+#define NON_TURBO_MASK 0xFF00
+#define NON_TURBO_OFFSET 0x8
+
+
+enum power_state {
+ POWER_IDLE = 0,
+ POWER_ONGOING,
+ POWER_USED,
+ POWER_UNKNOWN
+};
+
+struct pstate_power_info {
+ unsigned int lcore_id; /**< Logical core id */
+ uint32_t freqs[RTE_MAX_LCORE_FREQS]; /**< Frequency array */
+ uint32_t nb_freqs; /**< number of available freqs */
+ FILE *f_cur_min; /**< FD of scaling_min */
+ FILE *f_cur_max; /**< FD of scaling_max */
+ char governor_ori[32]; /**< Original governor name */
+ uint32_t curr_idx; /**< Freq index in freqs array */
+ uint32_t non_turbo_max_ratio; /**< Non Turbo Max ratio */
+ uint32_t sys_max_freq; /**< system wide max freq */
+ volatile uint32_t state; /**< Power in use state */
+ uint16_t turbo_available; /**< Turbo Boost available */
+ uint16_t turbo_enable; /**< Turbo Boost enable/disable */
+} __rte_cache_aligned;
+
+
+static struct pstate_power_info lcore_power_info[RTE_MAX_LCORE];
+
+/**
+ * It is to read the specific MSR.
+ */
+
+static int32_t
+power_rdmsr(int msr, uint64_t *val, unsigned int lcore_id)
+{
+ int fd, ret;
+ char fullpath[PATH_MAX];
+
+ snprintf(fullpath, sizeof(fullpath), POWER_MSR_PATH, lcore_id);
+
+ fd = open(fullpath, O_RDONLY);
+
+ if (fd < 0) {
+ RTE_LOG(ERR, POWER, "Error opening '%s': %s\n", fullpath,
+ strerror(errno));
+ return fd;
+ }
+
+ ret = pread(fd, val, sizeof(uint64_t), msr);
+
+ if (ret < 0) {
+ RTE_LOG(ERR, POWER, "Error reading '%s': %s\n", fullpath,
+ strerror(errno));
+ goto out;
+ }
+
+ POWER_DEBUG_TRACE("MSR Path %s, offset 0x%X for lcore %u\n",
+ fullpath, msr, lcore_id);
+
+ POWER_DEBUG_TRACE("Ret value %d, content is 0x%lx\n", ret, *val);
+
+out: close(fd);
+ return ret;
+}
+
+/**
+ * It is to fopen the sys file for the future setting the lcore frequency.
+ */
+static int
+power_init_for_setting_freq(struct pstate_power_info *pi)
+{
+ FILE *f_min, *f_max;
+ char fullpath_min[PATH_MAX];
+ char fullpath_max[PATH_MAX];
+ uint64_t max_non_turbo = 0;
+
+ snprintf(fullpath_min, sizeof(fullpath_min), POWER_SYSFILE_MIN_FREQ,
+ pi->lcore_id);
+
+ f_min = fopen(fullpath_min, "rw+");
+ FOPEN_OR_ERR_RET(f_min, -1);
+
+ snprintf(fullpath_max, sizeof(fullpath_max), POWER_SYSFILE_MAX_FREQ,
+ pi->lcore_id);
+
+ f_max = fopen(fullpath_max, "rw+");
+ FOPEN_OR_ERR_RET(f_max, -1);
+
+ pi->f_cur_min = f_min;
+ pi->f_cur_max = f_max;
+
+ /* Add MSR read to detect turbo status */
+
+ if (power_rdmsr(PLATFORM_INFO, &max_non_turbo, pi->lcore_id) < 0)
+ return -1;
+
+ max_non_turbo = (max_non_turbo&NON_TURBO_MASK)>>NON_TURBO_OFFSET;
+
+ POWER_DEBUG_TRACE("no turbo perf %lu\n", max_non_turbo);
+
+ pi->non_turbo_max_ratio = max_non_turbo;
+
+ return 0;
+}
+
+static int
+set_freq_internal(struct pstate_power_info *pi, uint32_t idx)
+{
+ uint32_t target_freq = 0;
+
+ if (idx >= RTE_MAX_LCORE_FREQS || idx >= pi->nb_freqs) {
+ RTE_LOG(ERR, POWER, "Invalid frequency index %u, which "
+ "should be less than %u\n", idx, pi->nb_freqs);
+ return -1;
+ }
+
+ /* Check if it is the same as current */
+ if (idx == pi->curr_idx)
+ return 0;
+
+ /* Because Intel Pstate Driver only allow user change min/max hint
+ * User need change the min/max as same value.
+ */
+ if (fseek(pi->f_cur_min, 0, SEEK_SET) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to set file position indicator to 0 "
+ "for setting frequency for lcore %u\n",
+ pi->lcore_id);
+ return -1;
+ }
+
+ if (fseek(pi->f_cur_max, 0, SEEK_SET) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to set file position indicator to 0 "
+ "for setting frequency for lcore %u\n",
+ pi->lcore_id);
+ return -1;
+ }
+
+ /* Turbo is available and enabled, first freq bucket is sys max freq */
+ if (pi->turbo_available && pi->turbo_enable && (idx == 0))
+ target_freq = pi->sys_max_freq;
+ else
+ target_freq = pi->freqs[idx];
+
+ /* Decrease freq, the min freq should be updated first */
+ if (idx > pi->curr_idx) {
+
+ if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ POWER_DEBUG_TRACE("Freqency '%u' to be set for lcore %u\n",
+ target_freq, pi->lcore_id);
+
+ fflush(pi->f_cur_min);
+ fflush(pi->f_cur_max);
+
+ }
+
+ /* Increase freq, the max freq should be updated first */
+ if (idx < pi->curr_idx) {
+
+ if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ POWER_DEBUG_TRACE("Freqency '%u' to be set for lcore %u\n",
+ target_freq, pi->lcore_id);
+
+ fflush(pi->f_cur_max);
+ fflush(pi->f_cur_min);
+ }
+
+ pi->curr_idx = idx;
+
+ return 1;
+}
+
+/**
+ * It is to check the current scaling governor by reading sys file, and then
+ * set it into 'performance' if it is not by writing the sys file. The original
+ * governor will be saved for rolling back.
+ */
+static int
+power_set_governor_performance(struct pstate_power_info *pi)
+{
+ FILE *f;
+ int ret = -1;
+ char buf[BUFSIZ];
+ char fullpath[PATH_MAX];
+ char *s;
+ int val;
+
+ snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_GOVERNOR,
+ pi->lcore_id);
+ f = fopen(fullpath, "rw+");
+ FOPEN_OR_ERR_RET(f, ret);
+
+ s = fgets(buf, sizeof(buf), f);
+ FOPS_OR_NULL_GOTO(s, out);
+
+ /* Check if current governor is performance */
+ if (strncmp(buf, POWER_GOVERNOR_PERF,
+ sizeof(POWER_GOVERNOR_PERF)) == 0) {
+ ret = 0;
+ POWER_DEBUG_TRACE("Power management governor of lcore %u is "
+ "already performance\n", pi->lcore_id);
+ goto out;
+ }
+ /* Save the original governor */
+ snprintf(pi->governor_ori, sizeof(pi->governor_ori), "%s", buf);
+
+ /* Write 'performance' to the governor */
+ val = fseek(f, 0, SEEK_SET);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ val = fputs(POWER_GOVERNOR_PERF, f);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ ret = 0;
+ RTE_LOG(INFO, POWER, "Power management governor of lcore %u has been "
+ "set to performance successfully\n", pi->lcore_id);
+out:
+ fclose(f);
+
+ return ret;
+}
+
+/**
+ * It is to check the governor and then set the original governor back if
+ * needed by writing the sys file.
+ */
+static int
+power_set_governor_original(struct pstate_power_info *pi)
+{
+ FILE *f;
+ int ret = -1;
+ char buf[BUFSIZ];
+ char fullpath[PATH_MAX];
+ char *s;
+ int val;
+
+ snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_GOVERNOR,
+ pi->lcore_id);
+ f = fopen(fullpath, "rw+");
+ FOPEN_OR_ERR_RET(f, ret);
+
+ s = fgets(buf, sizeof(buf), f);
+ FOPS_OR_NULL_GOTO(s, out);
+
+ /* Check if the governor to be set is the same as current */
+ if (strncmp(buf, pi->governor_ori, sizeof(pi->governor_ori)) == 0) {
+ ret = 0;
+ POWER_DEBUG_TRACE("Power management governor of lcore %u "
+ "has already been set to %s\n",
+ pi->lcore_id, pi->governor_ori);
+ goto out;
+ }
+
+ /* Write back the original governor */
+ val = fseek(f, 0, SEEK_SET);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ val = fputs(pi->governor_ori, f);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ ret = 0;
+ RTE_LOG(INFO, POWER, "Power management governor of lcore %u "
+ "has been set back to %s successfully\n",
+ pi->lcore_id, pi->governor_ori);
+out:
+ fclose(f);
+
+ return ret;
+}
+
+/**
+ * It is to get the available frequencies of the specific lcore by reading the
+ * sys file.
+ */
+static int
+power_get_available_freqs(struct pstate_power_info *pi)
+{
+ FILE *f_min, *f_max;
+ int ret = -1;
+ char *p_min, *p_max;
+ char buf_min[BUFSIZ];
+ char buf_max[BUFSIZ];
+ char fullpath_min[PATH_MAX];
+ char fullpath_max[PATH_MAX];
+ char *s_min, *s_max;
+ uint32_t sys_min_freq = 0, sys_max_freq = 0, base_max_freq = 0;
+ uint32_t i, num_freqs = 0;
+
+ snprintf(fullpath_max, sizeof(fullpath_max),
+ POWER_SYSFILE_BASE_MAX_FREQ,
+ pi->lcore_id);
+ snprintf(fullpath_min, sizeof(fullpath_min),
+ POWER_SYSFILE_BASE_MIN_FREQ,
+ pi->lcore_id);
+
+ f_min = fopen(fullpath_min, "r");
+ FOPEN_OR_ERR_RET(f_min, ret);
+
+ f_max = fopen(fullpath_max, "r");
+ FOPEN_OR_ERR_RET(f_max, ret);
+
+ s_min = fgets(buf_min, sizeof(buf_min), f_min);
+ FOPS_OR_NULL_GOTO(s_min, out);
+
+ s_max = fgets(buf_max, sizeof(buf_max), f_max);
+ FOPS_OR_NULL_GOTO(s_max, out);
+
+
+ /* Strip the line break if there is */
+ p_min = strchr(buf_min, '\n');
+ if (p_min != NULL)
+ *p_min = 0;
+
+ p_max = strchr(buf_max, '\n');
+ if (p_max != NULL)
+ *p_max = 0;
+
+ sys_min_freq = strtoul(buf_min, &p_min, POWER_CONVERT_TO_DECIMAL);
+ sys_max_freq = strtoul(buf_max, &p_max, POWER_CONVERT_TO_DECIMAL);
+
+ if (sys_max_freq < sys_min_freq)
+ goto out;
+
+ pi->sys_max_freq = sys_max_freq;
+
+ base_max_freq = pi->non_turbo_max_ratio * BUS_FREQ;
+
+ POWER_DEBUG_TRACE("sys min %u, sys max %u, base_max %u\n",
+ sys_min_freq,
+ sys_max_freq,
+ base_max_freq);
+
+ if (base_max_freq < sys_max_freq)
+ pi->turbo_available = 1;
+ else
+ pi->turbo_available = 0;
+
+ /* If turbo is available then there is one extra freq bucket
+ * to store the sys max freq which value is base_max +1
+ */
+ num_freqs = (base_max_freq - sys_min_freq) / BUS_FREQ + 1 +
+ pi->turbo_available;
+
+ /* Generate the freq bucket array.
+ * If turbo is available the freq bucket[0] value is base_max +1
+ * the bucket[1] is base_max, bucket[2] is base_max - BUS_FREQ
+ * and so on.
+ * If turbo is not available bucket[0] is base_max and so on
+ */
+ for (i = 0, pi->nb_freqs = 0; i < num_freqs; i++) {
+ if ((i == 0) && pi->turbo_available)
+ pi->freqs[pi->nb_freqs++] = base_max_freq + 1;
+ else
+ pi->freqs[pi->nb_freqs++] =
+ base_max_freq - (i - pi->turbo_available) * BUS_FREQ;
+ }
+
+ ret = 0;
+
+ POWER_DEBUG_TRACE("%d frequency(s) of lcore %u are available\n",
+ num_freqs, pi->lcore_id);
+
+out:
+ fclose(f_min);
+ fclose(f_max);
+
+ return ret;
+}
+
+int
+power_pstate_cpufreq_init(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Lcore id %u can not exceed %u\n",
+ lcore_id, RTE_MAX_LCORE - 1U);
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (rte_atomic32_cmpset(&(pi->state), POWER_IDLE, POWER_ONGOING)
+ == 0) {
+ RTE_LOG(INFO, POWER, "Power management of lcore %u is "
+ "in use\n", lcore_id);
+ return -1;
+ }
+
+ pi->lcore_id = lcore_id;
+ /* Check and set the governor */
+ if (power_set_governor_performance(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set governor of lcore %u to "
+ "performance\n", lcore_id);
+ goto fail;
+ }
+ /* Init for setting lcore frequency */
+ if (power_init_for_setting_freq(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot init for setting frequency for "
+ "lcore %u\n", lcore_id);
+ goto fail;
+ }
+
+ /* Get the available frequencies */
+ if (power_get_available_freqs(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot get available frequencies of "
+ "lcore %u\n", lcore_id);
+ goto fail;
+ }
+
+
+ /* Set freq to max by default */
+ if (power_pstate_cpufreq_freq_max(lcore_id) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set frequency of lcore %u "
+ "to max\n", lcore_id);
+ goto fail;
+ }
+
+ RTE_LOG(INFO, POWER, "Initialized successfully for lcore %u "
+ "power management\n", lcore_id);
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_USED);
+
+ return 0;
+
+fail:
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
+
+ return -1;
+}
+
+int
+power_pstate_cpufreq_exit(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Lcore id %u can not exceeds %u\n",
+ lcore_id, RTE_MAX_LCORE - 1U);
+ return -1;
+ }
+ pi = &lcore_power_info[lcore_id];
+
+ if (rte_atomic32_cmpset(&(pi->state), POWER_USED, POWER_ONGOING)
+ == 0) {
+ RTE_LOG(INFO, POWER, "Power management of lcore %u is "
+ "not used\n", lcore_id);
+ return -1;
+ }
+
+ /* Close FD of setting freq */
+ fclose(pi->f_cur_min);
+ fclose(pi->f_cur_max);
+ pi->f_cur_min = NULL;
+ pi->f_cur_max = NULL;
+
+ /* Set the governor back to the original */
+ if (power_set_governor_original(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set the governor of %u back "
+ "to the original\n", lcore_id);
+ goto fail;
+ }
+
+ RTE_LOG(INFO, POWER, "Power management of lcore %u has exited from "
+ "'performance' mode and been set back to the "
+ "original\n", lcore_id);
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_IDLE);
+
+ return 0;
+
+fail:
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
+
+ return -1;
+}
+
+
+uint32_t
+power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (num < pi->nb_freqs) {
+ RTE_LOG(ERR, POWER, "Buffer size is not enough\n");
+ return 0;
+ }
+ rte_memcpy(freqs, pi->freqs, pi->nb_freqs * sizeof(uint32_t));
+
+ return pi->nb_freqs;
+}
+
+uint32_t
+power_pstate_cpufreq_get_freq(unsigned int lcore_id)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return RTE_POWER_INVALID_FREQ_INDEX;
+ }
+
+ return lcore_power_info[lcore_id].curr_idx;
+}
+
+
+int
+power_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ return set_freq_internal(&(lcore_power_info[lcore_id]), index);
+}
+
+int
+power_pstate_cpufreq_freq_up(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (pi->curr_idx == 0)
+ return 0;
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->curr_idx - 1);
+}
+
+int
+power_pstate_cpufreq_freq_down(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (pi->curr_idx + 1 == pi->nb_freqs)
+ return 0;
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->curr_idx + 1);
+}
+
+int
+power_pstate_cpufreq_freq_max(unsigned int lcore_id)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ /* Frequencies in the array are from high to low. */
+ if (lcore_power_info[lcore_id].turbo_available) {
+ if (lcore_power_info[lcore_id].turbo_enable)
+ /* Set to Turbo */
+ return set_freq_internal(
+ &lcore_power_info[lcore_id], 0);
+ else
+ /* Set to max non-turbo */
+ return set_freq_internal(
+ &lcore_power_info[lcore_id], 1);
+ } else
+ return set_freq_internal(&lcore_power_info[lcore_id], 0);
+}
+
+
+int
+power_pstate_cpufreq_freq_min(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->nb_freqs - 1);
+}
+
+
+int
+power_pstate_turbo_status(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ return pi->turbo_enable;
+}
+
+int
+power_pstate_enable_turbo(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ if (pi->turbo_available)
+ pi->turbo_enable = 1;
+ else {
+ pi->turbo_enable = 0;
+ RTE_LOG(ERR, POWER,
+ "Failed to enable turbo on lcore %u\n",
+ lcore_id);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+power_pstate_disable_turbo(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ pi->turbo_enable = 0;
+
+
+ return 0;
+}
+
+
+int power_pstate_get_capabilities(unsigned int lcore_id,
+ struct rte_power_core_capabilities *caps)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+ if (caps == NULL) {
+ RTE_LOG(ERR, POWER, "Invalid argument\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ caps->capabilities = 0;
+ caps->turbo = !!(pi->turbo_available);
+
+ return 0;
+}
diff --git a/lib/librte_power/power_pstate_cpufreq.h b/lib/librte_power/power_pstate_cpufreq.h
new file mode 100644
index 0000000..b0019f5
--- /dev/null
+++ b/lib/librte_power/power_pstate_cpufreq.h
@@ -0,0 +1,218 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2018 Intel Corporation
+ */
+
+#ifndef _POWER_PSTATE_CPUFREQ_H
+#define _POWER_PSTATE_CPUFREQ_H
+
+/**
+ * @file
+ * RTE Power Management via Intel Pstate driver
+ */
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_string_fns.h>
+#include "rte_power.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize power management for a specific lcore. It will check and set the
+ * governor to performance for the lcore, get the available frequencies, and
+ * prepare to set new lcore frequency.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_init(unsigned int lcore_id);
+
+/**
+ * Exit power management on a specific lcore. It will set the governor to which
+ * is before initialized.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_exit(unsigned int lcore_id);
+
+/**
+ * Get the available frequencies of a specific lcore. The return value will be
+ * the minimal one of the total number of available frequencies and the number
+ * of buffer. The index of available frequencies used in other interfaces
+ * should be in the range of 0 to this return value.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param freqs
+ * The buffer array to save the frequencies.
+ * @param num
+ * The number of frequencies to get.
+ *
+ * @return
+ * The number of available frequencies.
+ */
+uint32_t power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs,
+ uint32_t num);
+
+/**
+ * Return the current index of available frequencies of a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * The current index of available frequencies.
+ * If error, it will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)'.
+ */
+uint32_t power_pstate_cpufreq_get_freq(unsigned int lcore_id);
+
+/**
+ * Set the new frequency for a specific lcore by indicating the index of
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param index
+ * The index of available frequencies.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index);
+
+/**
+ * Scale up the frequency of a specific lcore according to the available
+ * frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_up(unsigned int lcore_id);
+
+/**
+ * Scale down the frequency of a specific lcore according to the available
+ * frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_down(unsigned int lcore_id);
+
+/**
+ * Scale up the frequency of a specific lcore to the highest according to the
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_max(unsigned int lcore_id);
+
+/**
+ * Scale down the frequency of a specific lcore to the lowest according to the
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_min(unsigned int lcore_id);
+
+/**
+ * Get the turbo status of a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 Turbo Boost is enabled on this lcore.
+ * - 0 Turbo Boost is disabled on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_turbo_status(unsigned int lcore_id);
+
+/**
+ * Enable Turbo Boost on a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 Turbo Boost is enabled successfully on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_enable_turbo(unsigned int lcore_id);
+
+/**
+ * Disable Turbo Boost on a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 Turbo Boost disabled successfully on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_disable_turbo(unsigned int lcore_id);
+
+/**
+ * Returns power capabilities for a specific lcore.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param caps
+ * pointer to rte_power_core_capabilities object.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_get_capabilities(unsigned int lcore_id,
+ struct rte_power_core_capabilities *caps);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_power/rte_power.c b/lib/librte_power/rte_power.c
index 208b791..a05fbef 100644
--- a/lib/librte_power/rte_power.c
+++ b/lib/librte_power/rte_power.c
@@ -7,6 +7,7 @@
#include "rte_power.h"
#include "power_acpi_cpufreq.h"
#include "power_kvm_vm.h"
+#include "power_pstate_cpufreq.h"
#include "power_common.h"
enum power_management_env global_default_env = PM_ENV_NOT_SET;
@@ -56,6 +57,19 @@ rte_power_set_env(enum power_management_env env)
rte_power_freq_enable_turbo = power_kvm_vm_enable_turbo;
rte_power_freq_disable_turbo = power_kvm_vm_disable_turbo;
rte_power_get_capabilities = power_kvm_vm_get_capabilities;
+ } else if (env == PM_ENV_PSTATE_CPUFREQ) {
+ rte_power_freqs = power_pstate_cpufreq_freqs;
+ rte_power_get_freq = power_pstate_cpufreq_get_freq;
+ rte_power_set_freq = power_pstate_cpufreq_set_freq;
+ rte_power_freq_up = power_pstate_cpufreq_freq_up;
+ rte_power_freq_down = power_pstate_cpufreq_freq_down;
+ rte_power_freq_min = power_pstate_cpufreq_freq_min;
+ rte_power_freq_max = power_pstate_cpufreq_freq_max;
+ rte_power_turbo_status = power_pstate_turbo_status;
+ rte_power_freq_enable_turbo = power_pstate_enable_turbo;
+ rte_power_freq_disable_turbo = power_pstate_disable_turbo;
+ rte_power_get_capabilities = power_pstate_get_capabilities;
+
} else {
RTE_LOG(ERR, POWER, "Invalid Power Management Environment(%d) set\n",
env);
@@ -64,7 +78,6 @@ rte_power_set_env(enum power_management_env env)
}
global_default_env = env;
return 0;
-
}
void
@@ -84,21 +97,32 @@ rte_power_init(unsigned int lcore_id)
{
int ret = -1;
- if (global_default_env == PM_ENV_ACPI_CPUFREQ) {
+ switch (global_default_env) {
+ case PM_ENV_ACPI_CPUFREQ:
return power_acpi_cpufreq_init(lcore_id);
- }
- if (global_default_env == PM_ENV_KVM_VM) {
+ case PM_ENV_KVM_VM:
return power_kvm_vm_init(lcore_id);
+ case PM_ENV_PSTATE_CPUFREQ:
+ return power_pstate_cpufreq_init(lcore_id);
+ default:
+ RTE_LOG(INFO, POWER, "Env isn't set yet!\n");
}
+
/* Auto detect Environment */
- RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power "
- "management...\n");
+ RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power management...\n");
ret = power_acpi_cpufreq_init(lcore_id);
if (ret == 0) {
rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
goto out;
}
+ RTE_LOG(INFO, POWER, "Attempting to initialise PSTAT power management...\n");
+ ret = power_pstate_cpufreq_init(lcore_id);
+ if (ret == 0) {
+ rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
+ goto out;
+ }
+
RTE_LOG(INFO, POWER, "Attempting to initialise VM power management...\n");
ret = power_kvm_vm_init(lcore_id);
if (ret == 0) {
@@ -114,13 +138,17 @@ rte_power_init(unsigned int lcore_id)
int
rte_power_exit(unsigned int lcore_id)
{
- if (global_default_env == PM_ENV_ACPI_CPUFREQ)
+ switch (global_default_env) {
+ case PM_ENV_ACPI_CPUFREQ:
return power_acpi_cpufreq_exit(lcore_id);
- if (global_default_env == PM_ENV_KVM_VM)
+ case PM_ENV_KVM_VM:
return power_kvm_vm_exit(lcore_id);
+ case PM_ENV_PSTATE_CPUFREQ:
+ return power_pstate_cpufreq_exit(lcore_id);
+ default:
+ RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit gracefully\n");
- RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit "
- "gracefully\n");
+ }
return -1;
}
diff --git a/lib/librte_power/rte_power.h b/lib/librte_power/rte_power.h
index d70bc0b..c5e8f6b 100644
--- a/lib/librte_power/rte_power.h
+++ b/lib/librte_power/rte_power.h
@@ -20,7 +20,8 @@ extern "C" {
#endif
/* Power Management Environment State */
-enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM};
+enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM,
+ PM_ENV_PSTATE_CPUFREQ};
/**
* Set the default power management implementation. If this is not called prior
--
2.7.5
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v4 00/10] ipsec: new library for IPsec data-path processing
@ 2018-12-14 16:29 2% ` Konstantin Ananyev
2018-12-21 13:32 0% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Konstantin Ananyev @ 2018-12-14 16:29 UTC (permalink / raw)
To: dev; +Cc: Konstantin Ananyev
This patch series depends on the patch:
http://patches.dpdk.org/patch/48044/
to be applied first.
v3 -> v4
- Changes to adress Declan comments
- Update docs
v2 -> v3
- Several fixes for IPv6 support
- Extra checks for input parameters in public APi functions
v1 -> v2
- Changes to get into account l2_len for outbound transport packets
(Qi comments)
- Several bug fixes
- Some code restructured
- Update MAINTAINERS file
RFCv2 -> v1
- Changes per Jerin comments
- Implement transport mode
- Several bug fixes
- UT largely reworked and extended
This patch introduces a new library within DPDK: librte_ipsec.
The aim is to provide DPDK native high performance library for IPsec
data-path processing.
The library is supposed to utilize existing DPDK crypto-dev and
security API to provide application with transparent IPsec
processing API.
The library is concentrated on data-path protocols processing
(ESP and AH), IKE protocol(s) implementation is out of scope
for that library.
Current patch introduces SA-level API.
SA (low) level API
==================
API described below operates on SA level.
It provides functionality that allows user for given SA to process
inbound and outbound IPsec packets.
To be more specific:
- for inbound ESP/AH packets perform decryption, authentication,
integrity checking, remove ESP/AH related headers
- for outbound packets perform payload encryption, attach ICV,
update/add IP headers, add ESP/AH headers/trailers,
setup related mbuf felids (ol_flags, tx_offloads, etc.).
- initialize/un-initialize given SA based on user provided parameters.
The following functionality:
- match inbound/outbound packets to particular SA
- manage crypto/security devices
- provide SAD/SPD related functionality
- determine what crypto/security device has to be used
for given packet(s)
is out of scope for SA-level API.
SA-level API is based on top of crypto-dev/security API and relies on
them
to perform actual cipher and integrity checking.
To have an ability to easily map crypto/security sessions into related
IPSec SA opaque userdata field was added into
rte_cryptodev_sym_session and rte_security_session structures.
That implies ABI change for both librte_crytpodev and librte_security.
Due to the nature of crypto-dev API (enqueue/deque model) we use
asynchronous API for IPsec packets destined to be processed
by crypto-device.
Expected API call sequence would be:
/* enqueue for processing by crypto-device */
rte_ipsec_pkt_crypto_prepare(...);
rte_cryptodev_enqueue_burst(...);
/* dequeue from crypto-device and do final processing (if any) */
rte_cryptodev_dequeue_burst(...);
rte_ipsec_pkt_crypto_group(...); /* optional */
rte_ipsec_pkt_process(...);
Though for packets destined for inline processing no extra overhead
is required and synchronous API call: rte_ipsec_pkt_process()
is sufficient for that case.
Current implementation supports all four currently defined
rte_security types.
Though to accommodate future custom implementations function pointers
model is used for both for *crypto_prepare* and *process*
impelementations.
Konstantin Ananyev (10):
cryptodev: add opaque userdata pointer into crypto sym session
security: add opaque userdata pointer into security session
net: add ESP trailer structure definition
lib: introduce ipsec library
ipsec: add SA data-path API
ipsec: implement SA data-path API
ipsec: rework SA replay window/SQN for MT environment
ipsec: helper functions to group completed crypto-ops
test/ipsec: introduce functional test
doc: add IPsec library guide
MAINTAINERS | 5 +
config/common_base | 5 +
doc/guides/prog_guide/index.rst | 1 +
doc/guides/prog_guide/ipsec_lib.rst | 74 +
doc/guides/rel_notes/release_19_02.rst | 10 +
lib/Makefile | 2 +
lib/librte_cryptodev/rte_cryptodev.h | 2 +
lib/librte_ipsec/Makefile | 27 +
lib/librte_ipsec/crypto.h | 123 ++
lib/librte_ipsec/iph.h | 84 +
lib/librte_ipsec/ipsec_sqn.h | 343 ++++
lib/librte_ipsec/meson.build | 10 +
lib/librte_ipsec/pad.h | 45 +
lib/librte_ipsec/rte_ipsec.h | 153 ++
lib/librte_ipsec/rte_ipsec_group.h | 151 ++
lib/librte_ipsec/rte_ipsec_sa.h | 172 ++
lib/librte_ipsec/rte_ipsec_version.map | 15 +
lib/librte_ipsec/sa.c | 1407 +++++++++++++++
lib/librte_ipsec/sa.h | 98 ++
lib/librte_ipsec/ses.c | 45 +
lib/librte_net/rte_esp.h | 10 +-
lib/librte_security/rte_security.h | 2 +
lib/meson.build | 2 +
mk/rte.app.mk | 2 +
test/test/Makefile | 3 +
test/test/meson.build | 3 +
test/test/test_ipsec.c | 2209 ++++++++++++++++++++++++
27 files changed, 5002 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/prog_guide/ipsec_lib.rst
create mode 100644 lib/librte_ipsec/Makefile
create mode 100644 lib/librte_ipsec/crypto.h
create mode 100644 lib/librte_ipsec/iph.h
create mode 100644 lib/librte_ipsec/ipsec_sqn.h
create mode 100644 lib/librte_ipsec/meson.build
create mode 100644 lib/librte_ipsec/pad.h
create mode 100644 lib/librte_ipsec/rte_ipsec.h
create mode 100644 lib/librte_ipsec/rte_ipsec_group.h
create mode 100644 lib/librte_ipsec/rte_ipsec_sa.h
create mode 100644 lib/librte_ipsec/rte_ipsec_version.map
create mode 100644 lib/librte_ipsec/sa.c
create mode 100644 lib/librte_ipsec/sa.h
create mode 100644 lib/librte_ipsec/ses.c
create mode 100644 test/test/test_ipsec.c
--
2.17.1
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH] eal: simplify RTE_PMD_DEBUG_TRACE
@ 2018-12-14 21:57 3% ` Stephen Hemminger
0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2018-12-14 21:57 UTC (permalink / raw)
To: Jeff Shaw; +Cc: Mattias Rönnblom, dev
On Fri, 14 Dec 2018 13:20:07 -0800
Jeff Shaw <jeffrey.b.shaw@intel.com> wrote:
> On Fri, Dec 14, 2018 at 12:50:55PM -0800, Stephen Hemminger wrote:
> > Use rte_log directly, eliminating no longer used rte_pmd_dev_trace
> > function. This removes variable length array which is problem on
> > Windows and other compilers not doing C99.
> >
> > Also, drop unused RTE_PROC_PRIMARY macros.
> >
> > Reported-by: Jeff Shaw <jeffrey.b.shaw@intel.com>
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > ---
> > lib/librte_eal/common/include/rte_dev.h | 43 ++-----------------------
> > 1 file changed, 3 insertions(+), 40 deletions(-)
> >
> > diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
> > index a9724dc9181c..e496da440028 100644
> > --- a/lib/librte_eal/common/include/rte_dev.h
> > +++ b/lib/librte_eal/common/include/rte_dev.h
> > @@ -43,54 +43,17 @@ typedef void (*rte_dev_event_cb_fn)(const char *device_name,
> > enum rte_dev_event_type event,
> > void *cb_arg);
> >
> > -__attribute__((format(printf, 2, 0)))
> > -static inline void
> > -rte_pmd_debug_trace(const char *func_name, const char *fmt, ...)
> > -{
> > - va_list ap;
> > -
> > - va_start(ap, fmt);
> > -
> > - {
> > - char buffer[vsnprintf(NULL, 0, fmt, ap) + 1];
> > -
> > - va_end(ap);
> > -
> > - va_start(ap, fmt);
> > - vsnprintf(buffer, sizeof(buffer), fmt, ap);
> > - va_end(ap);
> > -
> > - rte_log(RTE_LOG_ERR, RTE_LOGTYPE_PMD, "%s: %s",
> > - func_name, buffer);
> > - }
> > -}
> > -
>
> Will this break applications that try to use this function? Because it is not
> a documented function, is there no guarantee it will be present?
It shouldn't be visible as part of EAL. Any code that was built that had
old MACRO would still run (ABI compatible) because it was inline.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 2/2] mbuf: implement generic format for sched field
2018-12-13 18:08 1% ` [dpdk-dev] [PATCH v3 2/2] mbuf: implement generic format for sched field Reshma Pattan
@ 2018-12-14 22:52 0% ` Dumitrescu, Cristian
0 siblings, 0 replies; 200+ results
From: Dumitrescu, Cristian @ 2018-12-14 22:52 UTC (permalink / raw)
To: Pattan, Reshma, dev, jerin.jacob, Rao, Nikhil, Singh, Jasvinder
> -----Original Message-----
> From: Pattan, Reshma
> Sent: Thursday, December 13, 2018 6:09 PM
> To: dev@dpdk.org; jerin.jacob@caviumnetworks.com; Rao, Nikhil
> <nikhil.rao@intel.com>; Singh, Jasvinder <jasvinder.singh@intel.com>;
> Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Cc: Pattan, Reshma <reshma.pattan@intel.com>
> Subject: [PATCH v3 2/2] mbuf: implement generic format for sched field
>
> This patch implements the changes proposed in the deprecation
> notes [1][2].
>
> librte_mbuf changes:
> The mbuf::hash::sched field is updated to support generic
> definition in line with the ethdev TM and MTR APIs. The new generic
> format contains: queue ID, traffic class, color.
>
> Added public APIs to set and get these new fields to and from mbuf.
>
> librte_sched changes:
> In addtion, following API functions of the sched library have
> been modified with an additional parameter of type struct
> rte_sched_port to accommodate the changes made to mbuf sched field.
> (i) rte_sched_port_pkt_write()
> (ii) rte_sched_port_pkt_read_tree_path()
>
> librte_pipeline, qos_sched UT, qos_sched app are updated
> to make use of new changes.
>
> Also mbuf::hash::txadapter has been added for eventdev txq,
> rte_event_eth_tx_adapter_txq_set and
> rte_event_eth_tx_adapter_txq_get()
> are updated to use uses mbuf::hash::txadapter.txq.
>
> doc:
> Release notes updated.
> Removed deprecation notice for mbuf::hash::sched and sched API.
>
> [1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
> [2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
>
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
> ---
> v3: addressed review comments given in the below link.
> http://patches.dpdk.org/patch/48587/
> Updated library ABI versioning in meson build.
> ---
> ---
> doc/guides/rel_notes/deprecation.rst | 10 --
> doc/guides/rel_notes/release_19_02.rst | 4 +-
> examples/qos_sched/app_thread.c | 7 +-
> examples/qos_sched/main.c | 1 +
> .../rte_event_eth_tx_adapter.h | 18 ++-
> lib/librte_mbuf/Makefile | 2 +-
> lib/librte_mbuf/meson.build | 2 +-
> lib/librte_mbuf/rte_mbuf.h | 114 +++++++++++++++++-
> lib/librte_pipeline/rte_table_action.c | 43 ++-----
> lib/librte_sched/Makefile | 2 +-
> lib/librte_sched/meson.build | 1 +
> lib/librte_sched/rte_sched.c | 90 ++++++--------
> lib/librte_sched/rte_sched.h | 10 +-
> test/test/test_sched.c | 9 +-
> 14 files changed, 191 insertions(+), 122 deletions(-)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst
> b/doc/guides/rel_notes/deprecation.rst
> index b48486d36..60e081a54 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -49,16 +49,6 @@ Deprecation Notices
> structure would be made internal (or removed if all dependencies are
> cleared)
> in future releases.
>
> -* mbuf: The opaque ``mbuf->hash.sched`` field will be updated to support
> generic
> - definition in line with the ethdev TM and MTR APIs. Currently, this field
> - is defined in librte_sched in a non-generic way. The new generic format
> - will contain: queue ID, traffic class, color. Field size will not change.
> -
> -* sched: Some API functions will change prototype due to the above
> - deprecation note for mbuf->hash.sched, e.g.
> ``rte_sched_port_pkt_write()``
> - and ``rte_sched_port_pkt_read()`` will likely have an additional parameter
> - of type ``struct rte_sched_port``.
> -
> * mbuf: the macro ``RTE_MBUF_INDIRECT()`` will be removed in v18.08 or
> later and
> replaced with ``RTE_MBUF_CLONED()`` which is already added in v18.05. As
> ``EXT_ATTACHED_MBUF`` is newly introduced in v18.05,
> ``RTE_MBUF_INDIRECT()``
> diff --git a/doc/guides/rel_notes/release_19_02.rst
> b/doc/guides/rel_notes/release_19_02.rst
> index a94fa86a7..deadaafa9 100644
> --- a/doc/guides/rel_notes/release_19_02.rst
> +++ b/doc/guides/rel_notes/release_19_02.rst
> @@ -146,7 +146,7 @@ The libraries prepended with a plus sign were
> incremented in this version.
> librte_kvargs.so.1
> librte_latencystats.so.1
> librte_lpm.so.2
> - librte_mbuf.so.4
> + + librte_mbuf.so.5
> librte_member.so.1
> librte_mempool.so.5
> librte_meter.so.2
> @@ -168,7 +168,7 @@ The libraries prepended with a plus sign were
> incremented in this version.
> librte_rawdev.so.1
> librte_reorder.so.1
> librte_ring.so.2
> - librte_sched.so.1
> + + librte_sched.so.2
> librte_security.so.1
> librte_table.so.3
> librte_timer.so.1
> diff --git a/examples/qos_sched/app_thread.c
> b/examples/qos_sched/app_thread.c
> index a59274236..bec4deee3 100644
> --- a/examples/qos_sched/app_thread.c
> +++ b/examples/qos_sched/app_thread.c
> @@ -73,8 +73,11 @@ app_rx_thread(struct thread_conf **confs)
> for(i = 0; i < nb_rx; i++) {
> get_pkt_sched(rx_mbufs[i],
> &subport, &pipe,
> &traffic_class, &queue, &color);
> - rte_sched_port_pkt_write(rx_mbufs[i],
> subport, pipe,
> - traffic_class, queue, (enum
> rte_meter_color) color);
> + rte_sched_port_pkt_write(conf-
> >sched_port,
> + rx_mbufs[i],
> + subport, pipe,
> + traffic_class, queue,
> + (enum rte_meter_color)
> color);
> }
>
> if (unlikely(rte_ring_sp_enqueue_bulk(conf-
> >rx_ring,
> diff --git a/examples/qos_sched/main.c b/examples/qos_sched/main.c
> index e7c97bd64..c0ed16b68 100644
> --- a/examples/qos_sched/main.c
> +++ b/examples/qos_sched/main.c
> @@ -55,6 +55,7 @@ app_main_loop(__attribute__((unused))void *dummy)
> flow->rx_thread.rx_port = flow->rx_port;
> flow->rx_thread.rx_ring = flow->rx_ring;
> flow->rx_thread.rx_queue = flow->rx_queue;
> + flow->rx_thread.sched_port = flow->sched_port;
>
> rx_confs[rx_idx++] = &flow->rx_thread;
>
> diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> index 81456d4a9..2a50656d9 100644
> --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> @@ -63,13 +63,11 @@
> * function can be used to retrieve the adapter's service function ID.
> *
> * The ethernet port and transmit queue index to transmit the mbuf on are
> - * specified using the mbuf port and the higher 16 bits of
> - * struct rte_mbuf::hash::sched:hi. The application should use the
> - * rte_event_eth_tx_adapter_txq_set() and
> rte_event_eth_tx_adapter_txq_get()
> - * functions to access the transmit queue index since it is expected that the
> - * transmit queue will be eventually defined within struct rte_mbuf and
> using
> - * these macros will help with minimizing application impact due to
> - * a change in how the transmit queue index is specified.
> + * specified using the mbuf port struct rte_mbuf::hash::txadapter:txq.
> + * The application should use the rte_event_eth_tx_adapter_txq_set()
> + * and rte_event_eth_tx_adapter_txq_get() functions to access the
> transmit
> + * queue index, using these macros will help with minimizing application
> + * impact due to a change in how the transmit queue index is specified.
> */
>
> #ifdef __cplusplus
> @@ -300,8 +298,7 @@ rte_event_eth_tx_adapter_queue_del(uint8_t id,
> static __rte_always_inline void __rte_experimental
> rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
> {
> - uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
> - p[1] = queue;
> + pkt->hash.txadapter.txq = queue;
> }
>
> /**
> @@ -320,8 +317,7 @@ rte_event_eth_tx_adapter_txq_set(struct rte_mbuf
> *pkt, uint16_t queue)
> static __rte_always_inline uint16_t __rte_experimental
> rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
> {
> - uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
> - return p[1];
> + return pkt->hash.txadapter.txq;
> }
>
> /**
> diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
> index e2b98a254..8c4c7d790 100644
> --- a/lib/librte_mbuf/Makefile
> +++ b/lib/librte_mbuf/Makefile
> @@ -11,7 +11,7 @@ LDLIBS += -lrte_eal -lrte_mempool
>
> EXPORT_MAP := rte_mbuf_version.map
>
> -LIBABIVER := 4
> +LIBABIVER := 5
>
> # all source are stored in SRCS-y
> SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c
> rte_mbuf_pool_ops.c
> diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
> index 94d9c4c96..e37da0250 100644
> --- a/lib/librte_mbuf/meson.build
> +++ b/lib/librte_mbuf/meson.build
> @@ -1,7 +1,7 @@
> # SPDX-License-Identifier: BSD-3-Clause
> # Copyright(c) 2017 Intel Corporation
>
> -version = 4
> +version = 5
> sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
> headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
> deps += ['mempool']
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index 3dbc6695e..032237321 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -34,6 +34,7 @@
> #include <stdint.h>
> #include <rte_compat.h>
> #include <rte_common.h>
> +#include <rte_color.h>
> #include <rte_config.h>
> #include <rte_mempool.h>
> #include <rte_memory.h>
> @@ -575,13 +576,24 @@ struct rte_mbuf {
> */
> } fdir; /**< Filter identifier if FDIR enabled */
> struct {
> - uint32_t lo;
> - uint32_t hi;
> + uint32_t queue_id; /**< Queue ID. */
> + uint8_t traffic_class;
> + /**< Traffic class ID. Traffic class 0
> + * is the highest priority traffic class.
> + */
> + uint8_t color;
> + /**< Color. @see enum rte_color.*/
> + uint16_t reserved; /**< Reserved. */
> + } sched; /**< Hierarchical scheduler */
New idea: let's make this an explicit struct rte_mbuf_sched that we instantiate here: struct rte_mbuf_sched sched;
> + struct {
> + uint32_t reserved1;
> + uint16_t reserved2;
> + uint16_t txq;
> /**< The event eth Tx adapter uses this field
> * to store Tx queue id.
> * @see
> rte_event_eth_tx_adapter_txq_set()
> */
> - } sched; /**< Hierarchical scheduler */
> + } txadapter; /**< Eventdev ethdev Tx adapter */
> /**< User defined tags. See
> rte_distributor_process() */
> uint32_t usr;
> } hash; /**< hash information */
> @@ -2289,6 +2301,102 @@ rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
> */
> void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned
> dump_len);
>
> +/**
> + * Get the value of mbuf sched queue_id field.
> + */
> +static inline uint32_t
> +rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
> +{
> + return m->hash.sched.queue_id;
> +}
> +
> +/**
> + * Get the value of mbuf sched traffic_class field.
> + */
> +static inline uint8_t
> +rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
> +{
> + return m->hash.sched.traffic_class;
> +}
> +
> +/**
> + * Get the value of mbuf sched color field.
> + */
> +static inline enum rte_color
> +rte_mbuf_sched_color_get(const struct rte_mbuf *m)
> +{
> + return (enum rte_color)m->hash.sched.color;
> +}
> +
> +/**
> + * Get the values of mbuf sched queue_id, traffic_class and color.
> + * @param m
> + * Mbuf to read
> + * @param queue_id
> + * Returns the queue id
> + * @param traffic_class
> + * Returns the traffic class id
> + * @param color
> + * Returns the colour id
> + */
> +static inline void
> +rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
> + uint8_t *traffic_class,
> + enum rte_color *color)
> +{
> + *queue_id = m->hash.sched.queue_id;
> + *traffic_class = m->hash.sched.traffic_class;
> + *color = (enum rte_color)m->hash.sched.color;
For performance reasons, let's ask the compiler to read all sched fields in a single operation as opposed to 3:
struct rte_mbuf_sched sched = m->hash.sched;
*queue_id = sched.queue_id;
*traffic_class = sched.traffic_class;
*color = (enum rte_colo)sched.color;
> +}
> +
> +/**
> + * Set the mbuf sched queue_id to the defined value.
> + */
> +static inline void
> +rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
> +{
> + m->hash.sched.queue_id = queue_id;
> +}
> +
> +/**
> + * Set the mbuf sched traffic_class id to the defined value.
> + */
> +static inline void
> +rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t
> traffic_class)
> +{
> + m->hash.sched.traffic_class = traffic_class;
> +}
> +
> +/**
> + * Set the mbuf sched color id to the defined value.
> + */
> +static inline void
> +rte_mbuf_sched_color_set(struct rte_mbuf *m, enum rte_color color)
> +{
> + m->hash.sched.color = (uint8_t)color;
> +}
> +
> +/**
> + * Set the mbuf sched queue_id, traffic_class and color.
> + * @param m
> + * Mbuf to set
> + * @param queue_id
> + * Queue id value to be set
> + * @param traffic_class
> + * Traffic class id value to be set
> + * @param color
> + * Color id to be set
> + */
> +static inline void
> +rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t queue_id,
> + uint8_t traffic_class,
> + enum rte_color color)
> +{
> + m->hash.sched.queue_id = queue_id;
> + m->hash.sched.traffic_class = traffic_class;
> + m->hash.sched.color = (uint8_t)color;
For performance reasons, let's combine all writes in a single access:
m->hash.sched = (struct rte_mbuf_sched){
.queue_id = queue_id,
.traffic_class = traffic_class,
.color = (uint8_t)color,
};
> +}
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/lib/librte_pipeline/rte_table_action.c
> b/lib/librte_pipeline/rte_table_action.c
> index 7c7c8dd82..3158301ff 100644
> --- a/lib/librte_pipeline/rte_table_action.c
> +++ b/lib/librte_pipeline/rte_table_action.c
> @@ -107,14 +107,6 @@ mtr_cfg_check(struct rte_table_action_mtr_config
> *mtr)
> return 0;
> }
>
> -#define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
> - ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
> - ((((uint64_t)(tc)) & 0x3) << 2) | \
> - ((((uint64_t)(color)) & 0x3) << 4)))
> -
> -#define MBUF_SCHED_COLOR(sched, color) \
> - (((sched) & (~0x30LLU)) | ((color) << 4))
> -
> struct mtr_trtcm_data {
> struct rte_meter_trtcm trtcm;
> uint64_t stats[e_RTE_METER_COLORS];
> @@ -176,7 +168,7 @@ mtr_data_size(struct rte_table_action_mtr_config
> *mtr)
> struct dscp_table_entry_data {
> enum rte_meter_color color;
> uint16_t tc;
> - uint16_t queue_tc_color;
> + uint16_t tc_queue;
> };
>
> struct dscp_table_data {
> @@ -319,8 +311,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
> uint32_t dscp,
> uint16_t total_length)
> {
> - uint64_t drop_mask, sched;
> - uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
> + uint64_t drop_mask;
> struct dscp_table_entry_data *dscp_entry = &dscp_table-
> >entry[dscp];
> enum rte_meter_color color_in, color_meter, color_policer;
> uint32_t tc, mp_id;
> @@ -329,7 +320,6 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
> color_in = dscp_entry->color;
> data += tc;
> mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
> - sched = *sched_ptr;
>
> /* Meter */
> color_meter = rte_meter_trtcm_color_aware_check(
> @@ -346,7 +336,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
> drop_mask =
> MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
> color_policer =
> MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data,
> color_meter);
> - *sched_ptr = MBUF_SCHED_COLOR(sched, color_policer);
> + rte_mbuf_sched_color_set(mbuf, color_policer);
>
> return drop_mask;
> }
> @@ -368,9 +358,8 @@ tm_cfg_check(struct rte_table_action_tm_config
> *tm)
> }
>
> struct tm_data {
> - uint16_t queue_tc_color;
> - uint16_t subport;
> - uint32_t pipe;
> + uint32_t queue_id;
> + uint32_t reserved;
> } __attribute__((__packed__));
>
> static int
> @@ -397,9 +386,9 @@ tm_apply(struct tm_data *data,
> return status;
>
> /* Apply */
> - data->queue_tc_color = 0;
> - data->subport = (uint16_t) p->subport_id;
> - data->pipe = p->pipe_id;
> + data->queue_id = p->subport_id <<
> + (__builtin_ctz(cfg->n_pipes_per_subport) +
> 4) |
> + p->pipe_id << 4;
>
> return 0;
> }
> @@ -411,12 +400,10 @@ pkt_work_tm(struct rte_mbuf *mbuf,
> uint32_t dscp)
> {
> struct dscp_table_entry_data *dscp_entry = &dscp_table-
> >entry[dscp];
> - struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
> - struct tm_data sched;
> -
> - sched = *data;
> - sched.queue_tc_color = dscp_entry->queue_tc_color;
> - *sched_ptr = sched;
> + uint32_t queue_id = data->queue_id |
> + (dscp_entry->tc << 2) |
> + dscp_entry->tc_queue;
> + rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc, dscp_entry-
> >color);
> }
>
> /**
> @@ -2580,17 +2567,13 @@ rte_table_action_dscp_table_update(struct
> rte_table_action *action,
> &action->dscp_table.entry[i];
> struct rte_table_action_dscp_table_entry *entry =
> &table->entry[i];
> - uint16_t queue_tc_color =
> - MBUF_SCHED_QUEUE_TC_COLOR(entry-
> >tc_queue_id,
> - entry->tc_id,
> - entry->color);
>
> if ((dscp_mask & (1LLU << i)) == 0)
> continue;
>
> data->color = entry->color;
> data->tc = entry->tc_id;
> - data->queue_tc_color = queue_tc_color;
> + data->tc_queue = entry->tc_queue_id;
> }
>
> return 0;
> diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile
> index 46c53ed71..644fd9d15 100644
> --- a/lib/librte_sched/Makefile
> +++ b/lib/librte_sched/Makefile
> @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer
>
> EXPORT_MAP := rte_sched_version.map
>
> -LIBABIVER := 1
> +LIBABIVER := 2
>
> #
> # all source are stored in SRCS-y
> diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build
> index f85d64df8..8e989e5f6 100644
> --- a/lib/librte_sched/meson.build
> +++ b/lib/librte_sched/meson.build
> @@ -1,6 +1,7 @@
> # SPDX-License-Identifier: BSD-3-Clause
> # Copyright(c) 2017 Intel Corporation
>
> +version = 2
> sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c')
> headers = files('rte_sched.h', 'rte_sched_common.h',
> 'rte_red.h', 'rte_approx.h')
> diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
> index 587d5e602..3b8b2b038 100644
> --- a/lib/librte_sched/rte_sched.c
> +++ b/lib/librte_sched/rte_sched.c
> @@ -128,22 +128,6 @@ enum grinder_state {
> e_GRINDER_READ_MBUF
> };
>
> -/*
> - * Path through the scheduler hierarchy used by the scheduler enqueue
> - * operation to identify the destination queue for the current
> - * packet. Stored in the field pkt.hash.sched of struct rte_mbuf of
> - * each packet, typically written by the classification stage and read
> - * by scheduler enqueue.
> - */
> -struct rte_sched_port_hierarchy {
> - uint16_t queue:2; /**< Queue ID (0 .. 3) */
> - uint16_t traffic_class:2; /**< Traffic class ID (0 .. 3)*/
> - uint32_t color:2; /**< Color */
> - uint16_t unused:10;
> - uint16_t subport; /**< Subport ID */
> - uint32_t pipe; /**< Pipe ID */
> -};
> -
> struct rte_sched_grinder {
> /* Pipe cache */
> uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
> @@ -185,6 +169,7 @@ struct rte_sched_port {
> /* User parameters */
> uint32_t n_subports_per_port;
> uint32_t n_pipes_per_subport;
> + uint32_t n_pipes_per_subport_log2;
> uint32_t rate;
> uint32_t mtu;
> uint32_t frame_overhead;
> @@ -645,6 +630,8 @@ rte_sched_port_config(struct
> rte_sched_port_params *params)
> /* User parameters */
> port->n_subports_per_port = params->n_subports_per_port;
> port->n_pipes_per_subport = params->n_pipes_per_subport;
> + port->n_pipes_per_subport_log2 =
> + __builtin_ctz(params->n_pipes_per_subport);
> port->rate = params->rate;
> port->mtu = params->mtu + params->frame_overhead;
> port->frame_overhead = params->frame_overhead;
> @@ -1006,44 +993,52 @@ rte_sched_port_pipe_profile_add(struct
> rte_sched_port *port,
> return 0;
> }
>
> +static inline uint32_t
> +rte_sched_port_qindex(struct rte_sched_port *port,
> + uint32_t subport,
> + uint32_t pipe,
> + uint32_t traffic_class,
> + uint32_t queue)
> +{
> + return ((subport & (port->n_subports_per_port - 1)) <<
> + (port->n_pipes_per_subport_log2 + 4)) |
> + ((pipe & (port->n_pipes_per_subport - 1)) << 4) |
> + ((traffic_class &
> + (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) <<
> 2) |
> + (queue &
> (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1));
> +}
> +
> void
> -rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> - uint32_t subport, uint32_t pipe, uint32_t
> traffic_class,
> +rte_sched_port_pkt_write(struct rte_sched_port *port,
> + struct rte_mbuf *pkt,
> + uint32_t subport, uint32_t pipe,
> + uint32_t traffic_class,
> uint32_t queue, enum rte_meter_color color)
> {
> - struct rte_sched_port_hierarchy *sched
> - = (struct rte_sched_port_hierarchy *) &pkt->hash.sched;
> -
> - RTE_BUILD_BUG_ON(sizeof(*sched) > sizeof(pkt->hash.sched));
> -
> - sched->color = (uint32_t) color;
> - sched->subport = subport;
> - sched->pipe = pipe;
> - sched->traffic_class = traffic_class;
> - sched->queue = queue;
> + uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe,
> + traffic_class, queue);
> + rte_mbuf_sched_set(pkt, queue_id, traffic_class, (enum
> rte_color)color);
> }
>
> void
> -rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
> +rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
> + const struct rte_mbuf *pkt,
> uint32_t *subport, uint32_t *pipe,
> uint32_t *traffic_class, uint32_t *queue)
> {
> - const struct rte_sched_port_hierarchy *sched
> - = (const struct rte_sched_port_hierarchy *) &pkt-
> >hash.sched;
> + uint32_t queue_id = rte_mbuf_sched_queue_get(pkt);
>
> - *subport = sched->subport;
> - *pipe = sched->pipe;
> - *traffic_class = sched->traffic_class;
> - *queue = sched->queue;
> + *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4);
> + *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1);
> + *traffic_class = (queue_id >> 2) &
> + (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE -
> 1);
> + *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS -
> 1);
> }
>
> enum rte_meter_color
> rte_sched_port_pkt_read_color(const struct rte_mbuf *pkt)
> {
> - const struct rte_sched_port_hierarchy *sched
> - = (const struct rte_sched_port_hierarchy *) &pkt-
> >hash.sched;
> -
> - return (enum rte_meter_color) sched->color;
> + return (enum rte_meter_color)rte_mbuf_sched_color_get(pkt);
No need to convert to enum, as this function return value is already of enum type.
> }
>
> int
> @@ -1100,18 +1095,6 @@ rte_sched_queue_read_stats(struct
> rte_sched_port *port,
> return 0;
> }
>
> -static inline uint32_t
> -rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport,
> uint32_t pipe, uint32_t traffic_class, uint32_t queue)
> -{
> - uint32_t result;
> -
> - result = subport * port->n_pipes_per_subport + pipe;
> - result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE +
> traffic_class;
> - result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
> -
> - return result;
> -}
> -
> #ifdef RTE_SCHED_DEBUG
>
> static inline int
> @@ -1272,11 +1255,8 @@ rte_sched_port_enqueue_qptrs_prefetch0(struct
> rte_sched_port *port,
> #ifdef RTE_SCHED_COLLECT_STATS
> struct rte_sched_queue_extra *qe;
> #endif
> - uint32_t subport, pipe, traffic_class, queue, qindex;
> -
> - rte_sched_port_pkt_read_tree_path(pkt, &subport, &pipe,
> &traffic_class, &queue);
> + uint32_t qindex = rte_mbuf_sched_queue_get(pkt);
>
> - qindex = rte_sched_port_qindex(port, subport, pipe, traffic_class,
> queue);
> q = port->queue + qindex;
> rte_prefetch0(q);
> #ifdef RTE_SCHED_COLLECT_STATS
> diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
> index 84fa896de..243efa1d4 100644
> --- a/lib/librte_sched/rte_sched.h
> +++ b/lib/librte_sched/rte_sched.h
> @@ -355,6 +355,8 @@ rte_sched_queue_read_stats(struct rte_sched_port
> *port,
> * Scheduler hierarchy path write to packet descriptor. Typically
> * called by the packet classification stage.
> *
> + * @param port
> + * Handle to port scheduler instance
> * @param pkt
> * Packet descriptor handle
> * @param subport
> @@ -369,7 +371,8 @@ rte_sched_queue_read_stats(struct rte_sched_port
> *port,
> * Packet color set
> */
> void
> -rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> +rte_sched_port_pkt_write(struct rte_sched_port *port,
> + struct rte_mbuf *pkt,
> uint32_t subport, uint32_t pipe, uint32_t
> traffic_class,
> uint32_t queue, enum rte_meter_color color);
>
> @@ -379,6 +382,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> * enqueue operation. The subport, pipe, traffic class and queue
> * parameters need to be pre-allocated by the caller.
> *
> + * @param port
> + * Handle to port scheduler instance
> * @param pkt
> * Packet descriptor handle
> * @param subport
> @@ -392,7 +397,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> *
> */
> void
> -rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
> +rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
> + const struct rte_mbuf *pkt,
> uint32_t *subport, uint32_t *pipe,
> uint32_t *traffic_class, uint32_t *queue);
>
> diff --git a/test/test/test_sched.c b/test/test/test_sched.c
> index 32e500ba9..40e411cab 100644
> --- a/test/test/test_sched.c
> +++ b/test/test/test_sched.c
> @@ -76,7 +76,7 @@ create_mempool(void)
> }
>
> static void
> -prepare_pkt(struct rte_mbuf *mbuf)
> +prepare_pkt(struct rte_sched_port *port, struct rte_mbuf *mbuf)
> {
> struct ether_hdr *eth_hdr;
> struct vlan_hdr *vlan1, *vlan2;
> @@ -95,7 +95,8 @@ prepare_pkt(struct rte_mbuf *mbuf)
> ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);
>
>
> - rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE,
> e_RTE_METER_YELLOW);
> + rte_sched_port_pkt_write(port, mbuf, SUBPORT, PIPE, TC, QUEUE,
> + e_RTE_METER_YELLOW);
>
> /* 64 byte packet */
> mbuf->pkt_len = 60;
> @@ -138,7 +139,7 @@ test_sched(void)
> for (i = 0; i < 10; i++) {
> in_mbufs[i] = rte_pktmbuf_alloc(mp);
> TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation
> failed\n");
> - prepare_pkt(in_mbufs[i]);
> + prepare_pkt(port, in_mbufs[i]);
> }
>
>
> @@ -155,7 +156,7 @@ test_sched(void)
> color = rte_sched_port_pkt_read_color(out_mbufs[i]);
> TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong
> color\n");
>
> - rte_sched_port_pkt_read_tree_path(out_mbufs[i],
> + rte_sched_port_pkt_read_tree_path(port, out_mbufs[i],
> &subport, &pipe, &traffic_class, &queue);
>
> TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong
> subport\n");
> --
> 2.17.1
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [RFC] kni: remove ethtool support
@ 2018-12-18 1:25 1% Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-12-18 1:25 UTC (permalink / raw)
To: dev, Thomas Monjalon, John McNamara, Marko Kovacevic; +Cc: Ferruh Yigit
Current design requires kernel drivers and they need to be probed by
Linux up to some level so that they can be usable by DPDK for ethtool
support, this requires maintaining the Linux drivers in DPDK.
Also ethtool support is limited and hard, if not impossible, to expand
to other PMDs.
Since KNI ethtool support is not used commonly, if not used at all,
removing the support for the sake of simplicity and maintenance.
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
config/common_base | 1 -
.../sample_app_ug/kernel_nic_interface.rst | 10 -
examples/kni/main.c | 9 -
kernel/linux/kni/Kbuild | 4 +-
kernel/linux/kni/Makefile | 26 +-
kernel/linux/kni/ethtool/README | 71 -
kernel/linux/kni/ethtool/igb/e1000_82575.c | 3650 ------
kernel/linux/kni/ethtool/igb/e1000_82575.h | 494 -
kernel/linux/kni/ethtool/igb/e1000_api.c | 1144 --
kernel/linux/kni/ethtool/igb/e1000_api.h | 142 -
kernel/linux/kni/ethtool/igb/e1000_defines.h | 1365 --
kernel/linux/kni/ethtool/igb/e1000_hw.h | 778 --
kernel/linux/kni/ethtool/igb/e1000_i210.c | 894 --
kernel/linux/kni/ethtool/igb/e1000_i210.h | 76 -
kernel/linux/kni/ethtool/igb/e1000_mac.c | 2081 ----
kernel/linux/kni/ethtool/igb/e1000_mac.h | 65 -
kernel/linux/kni/ethtool/igb/e1000_manage.c | 539 -
kernel/linux/kni/ethtool/igb/e1000_manage.h | 74 -
kernel/linux/kni/ethtool/igb/e1000_mbx.c | 510 -
kernel/linux/kni/ethtool/igb/e1000_mbx.h | 72 -
kernel/linux/kni/ethtool/igb/e1000_nvm.c | 950 --
kernel/linux/kni/ethtool/igb/e1000_nvm.h | 60 -
kernel/linux/kni/ethtool/igb/e1000_osdep.h | 121 -
kernel/linux/kni/ethtool/igb/e1000_phy.c | 3392 -----
kernel/linux/kni/ethtool/igb/e1000_phy.h | 241 -
kernel/linux/kni/ethtool/igb/e1000_regs.h | 631 -
kernel/linux/kni/ethtool/igb/igb.h | 844 --
kernel/linux/kni/ethtool/igb/igb_ethtool.c | 2851 -----
kernel/linux/kni/ethtool/igb/igb_main.c | 10344 ----------------
kernel/linux/kni/ethtool/igb/igb_param.c | 832 --
kernel/linux/kni/ethtool/igb/igb_regtest.h | 234 -
kernel/linux/kni/ethtool/igb/igb_vmdq.c | 421 -
kernel/linux/kni/ethtool/igb/igb_vmdq.h | 31 -
kernel/linux/kni/ethtool/igb/kcompat.h | 3945 ------
kernel/linux/kni/ethtool/igb/meson.build | 16 -
kernel/linux/kni/ethtool/ixgbe/ixgbe.h | 912 --
kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.c | 1281 --
kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.h | 29 -
kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.c | 2299 ----
kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.h | 43 -
kernel/linux/kni/ethtool/ixgbe/ixgbe_api.c | 1142 --
kernel/linux/kni/ethtool/ixgbe/ixgbe_api.h | 153 -
kernel/linux/kni/ethtool/ixgbe/ixgbe_common.c | 4067 ------
kernel/linux/kni/ethtool/ixgbe/ixgbe_common.h | 125 -
kernel/linux/kni/ethtool/ixgbe/ixgbe_dcb.h | 153 -
.../linux/kni/ethtool/ixgbe/ixgbe_ethtool.c | 2894 -----
kernel/linux/kni/ethtool/ixgbe/ixgbe_fcoe.h | 76 -
kernel/linux/kni/ethtool/ixgbe/ixgbe_main.c | 2951 -----
kernel/linux/kni/ethtool/ixgbe/ixgbe_mbx.h | 90 -
kernel/linux/kni/ethtool/ixgbe/ixgbe_osdep.h | 117 -
kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.c | 1832 ---
kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.h | 122 -
kernel/linux/kni/ethtool/ixgbe/ixgbe_type.h | 3239 -----
kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.c | 922 --
kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.h | 43 -
kernel/linux/kni/ethtool/ixgbe/kcompat.c | 1231 --
kernel/linux/kni/ethtool/ixgbe/kcompat.h | 3140 -----
kernel/linux/kni/ethtool/ixgbe/meson.build | 13 -
kernel/linux/kni/ethtool/meson.build | 5 -
kernel/linux/kni/kni_dev.h | 8 -
kernel/linux/kni/kni_ethtool.c | 229 -
kernel/linux/kni/kni_misc.c | 82 +-
kernel/linux/kni/meson.build | 9 +-
lib/librte_kni/rte_kni.c | 5 -
lib/librte_kni/rte_kni.h | 4 +-
65 files changed, 15 insertions(+), 64119 deletions(-)
delete mode 100644 kernel/linux/kni/ethtool/README
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_82575.c
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_82575.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_api.c
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_api.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_defines.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_hw.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_i210.c
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_i210.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_mac.c
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_mac.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_manage.c
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_manage.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_mbx.c
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_mbx.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_nvm.c
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_nvm.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_osdep.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_phy.c
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_phy.h
delete mode 100644 kernel/linux/kni/ethtool/igb/e1000_regs.h
delete mode 100644 kernel/linux/kni/ethtool/igb/igb.h
delete mode 100644 kernel/linux/kni/ethtool/igb/igb_ethtool.c
delete mode 100644 kernel/linux/kni/ethtool/igb/igb_main.c
delete mode 100644 kernel/linux/kni/ethtool/igb/igb_param.c
delete mode 100644 kernel/linux/kni/ethtool/igb/igb_regtest.h
delete mode 100644 kernel/linux/kni/ethtool/igb/igb_vmdq.c
delete mode 100644 kernel/linux/kni/ethtool/igb/igb_vmdq.h
delete mode 100644 kernel/linux/kni/ethtool/igb/kcompat.h
delete mode 100644 kernel/linux/kni/ethtool/igb/meson.build
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.c
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.c
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_api.c
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_api.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_common.c
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_common.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_dcb.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_fcoe.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_main.c
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_mbx.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_osdep.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.c
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_type.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.c
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/kcompat.c
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/kcompat.h
delete mode 100644 kernel/linux/kni/ethtool/ixgbe/meson.build
delete mode 100644 kernel/linux/kni/ethtool/meson.build
delete mode 100644 kernel/linux/kni/kni_ethtool.c
diff --git a/config/common_base b/config/common_base
index d12ae98bc..8c1a330e0 100644
--- a/config/common_base
+++ b/config/common_base
@@ -890,7 +890,6 @@ CONFIG_RTE_PIPELINE_STATS_COLLECT=n
CONFIG_RTE_LIBRTE_KNI=n
CONFIG_RTE_LIBRTE_PMD_KNI=n
CONFIG_RTE_KNI_KMOD=n
-CONFIG_RTE_KNI_KMOD_ETHTOOL=n
CONFIG_RTE_KNI_PREEMPT_DEFAULT=y
#
diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst
index 6acdf0fff..2d07ff241 100644
--- a/doc/guides/sample_app_ug/kernel_nic_interface.rst
+++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst
@@ -262,16 +262,6 @@ Change the MTU size:
# ifconfig vEth0_0 mtu 1450
-If DPDK is compiled with ``CONFIG_RTE_KNI_KMOD_ETHTOOL=y`` and an Intel
-NIC is used, the user can use ``ethtool`` on the KNI interface as if it
-were a normal Linux kernel interface.
-
-Displaying the NIC registers:
-
-.. code-block:: console
-
- # ethtool -d vEth0_0
-
When the ``kni`` application is closed, all the KNI interfaces are deleted
from the Linux kernel.
diff --git a/examples/kni/main.c b/examples/kni/main.c
index e37b1ad36..c468ffd19 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -885,19 +885,10 @@ kni_alloc(uint16_t port_id)
if (i == 0) {
struct rte_kni_ops ops;
struct rte_eth_dev_info dev_info;
- const struct rte_pci_device *pci_dev;
- const struct rte_bus *bus = NULL;
memset(&dev_info, 0, sizeof(dev_info));
rte_eth_dev_info_get(port_id, &dev_info);
- if (dev_info.device)
- bus = rte_bus_find_by_device(dev_info.device);
- if (bus && !strcmp(bus->name, "pci")) {
- pci_dev = RTE_DEV_TO_PCI(dev_info.device);
- conf.addr = pci_dev->addr;
- conf.id = pci_dev->id;
- }
/* Get the interface default mac address */
rte_eth_macaddr_get(port_id,
(struct ether_addr *)&conf.mac_addr);
diff --git a/kernel/linux/kni/Kbuild b/kernel/linux/kni/Kbuild
index de5c27f32..e5452d6c0 100644
--- a/kernel/linux/kni/Kbuild
+++ b/kernel/linux/kni/Kbuild
@@ -3,6 +3,4 @@
ccflags-y := $(MODULE_CFLAGS)
obj-m := rte_kni.o
-rte_kni-y := $(patsubst $(src)/%.c,%.o,$(wildcard $(src)/*.c)) \
- $(patsubst $(src)/%.c,%.o,$(wildcard $(src)/ethtool/ixgbe/*.c)) \
- $(patsubst $(src)/%.c,%.o,$(wildcard $(src)/ethtool/igb/*.c))
+rte_kni-y := $(patsubst $(src)/%.c,%.o,$(wildcard $(src)/*.c))
diff --git a/kernel/linux/kni/Makefile b/kernel/linux/kni/Makefile
index 282be7b68..595bac261 100644
--- a/kernel/linux/kni/Makefile
+++ b/kernel/linux/kni/Makefile
@@ -12,7 +12,7 @@ MODULE = rte_kni
# CFLAGS
#
MODULE_CFLAGS += -I$(SRCDIR) --param max-inline-insns-single=50
-MODULE_CFLAGS += -I$(RTE_OUTPUT)/include -I$(SRCDIR)/ethtool/ixgbe -I$(SRCDIR)/ethtool/igb
+MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
MODULE_CFLAGS += -Wall -Werror
@@ -30,29 +30,5 @@ endif
#
SRCS-y := kni_misc.c
SRCS-y += kni_net.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += kni_ethtool.c
-
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_main.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_api.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_common.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_ethtool.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_82599.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_82598.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_x540.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_phy.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/kcompat.c
-
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_82575.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_i210.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_api.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_mac.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_manage.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_mbx.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_nvm.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_phy.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/igb_ethtool.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/igb_main.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/igb_param.c
-SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/igb_vmdq.c
include $(RTE_SDK)/mk/rte.module.mk
diff --git a/kernel/linux/kni/ethtool/README b/kernel/linux/kni/ethtool/README
deleted file mode 100644
index af36738ad..000000000
--- a/kernel/linux/kni/ethtool/README
+++ /dev/null
@@ -1,71 +0,0 @@
-.. SPDX-License-Identifier: BSD-3-Clause
- Copyright(c) 2010-2014 Intel Corporation.
-
-Description
-
-In order to support ethtool in Kernel NIC Interface, the standard Linux kernel
-drivers of ixgbe/igb are needed to be reused here. ixgbe-3.9.17 is the version
-modified from in kernel NIC interface kernel module to support ixgbe NIC, and
-igb-3.4.8 is the version modified from in kernel NIC interface kernel module to
-support igb NIC.
-
-The source code package of ixgbe can be downloaded from sourceforge.net as below.
-http://sourceforge.net/projects/e1000/files/ixgbe%20stable/
-Below source files are copied or modified from ixgbe.
-
-ixgbe_82598.h
-ixgbe_82599.c
-ixgbe_82599.h
-ixgbe_api.c
-ixgbe_api.h
-ixgbe_common.c
-ixgbe_common.h
-ixgbe_dcb.h
-ixgbe_ethtool.c
-ixgbe_fcoe.h
-ixgbe.h
-ixgbe_main.c
-ixgbe_mbx.h
-ixgbe_osdep.h
-ixgbe_phy.c
-ixgbe_phy.h
-ixgbe_sriov.h
-ixgbe_type.h
-kcompat.c
-kcompat.h
-
-The source code package of igb can be downloaded from sourceforge.net as below.
-http://sourceforge.net/projects/e1000/files/igb%20stable/
-Below source files are copied or modified from igb.
-
-e1000_82575.c
-e1000_82575.h
-e1000_api.c
-e1000_api.h
-e1000_defines.h
-e1000_hw.h
-e1000_mac.c
-e1000_mac.h
-e1000_manage.c
-e1000_manage.h
-e1000_mbx.c
-e1000_mbx.h
-e1000_nvm.c
-e1000_nvm.h
-e1000_osdep.h
-e1000_phy.c
-e1000_phy.h
-e1000_regs.h
-igb_ethtool.c
-igb.h
-igb_main.c
-igb_param.c
-igb_procfs.c
-igb_regtest.h
-igb_sysfs.c
-igb_vmdq.c
-igb_vmdq.h
-kcompat.c
-kcompat_ethtool.c
-kcompat.h
-
diff --git a/kernel/linux/kni/ethtool/igb/e1000_82575.c b/kernel/linux/kni/ethtool/igb/e1000_82575.c
deleted file mode 100644
index 98346709d..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_82575.c
+++ /dev/null
@@ -1,3650 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/*
- * 82575EB Gigabit Network Connection
- * 82575EB Gigabit Backplane Connection
- * 82575GB Gigabit Network Connection
- * 82576 Gigabit Network Connection
- * 82576 Quad Port Gigabit Mezzanine Adapter
- * 82580 Gigabit Network Connection
- * I350 Gigabit Network Connection
- */
-
-#include "e1000_api.h"
-#include "e1000_i210.h"
-
-static s32 e1000_init_phy_params_82575(struct e1000_hw *hw);
-static s32 e1000_init_mac_params_82575(struct e1000_hw *hw);
-static s32 e1000_acquire_phy_82575(struct e1000_hw *hw);
-static void e1000_release_phy_82575(struct e1000_hw *hw);
-static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw);
-static void e1000_release_nvm_82575(struct e1000_hw *hw);
-static s32 e1000_check_for_link_82575(struct e1000_hw *hw);
-static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw);
-static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw);
-static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
- u16 *duplex);
-static s32 e1000_init_hw_82575(struct e1000_hw *hw);
-static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
-static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
- u16 *data);
-static s32 e1000_reset_hw_82575(struct e1000_hw *hw);
-static s32 e1000_reset_hw_82580(struct e1000_hw *hw);
-static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw,
- u32 offset, u16 *data);
-static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw,
- u32 offset, u16 data);
-static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw,
- bool active);
-static s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw,
- bool active);
-static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
- bool active);
-static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw);
-static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw);
-static s32 e1000_get_media_type_82575(struct e1000_hw *hw);
-static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw);
-static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data);
-static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
- u32 offset, u16 data);
-static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
-static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
-static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
- u16 *speed, u16 *duplex);
-static s32 e1000_get_phy_id_82575(struct e1000_hw *hw);
-static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
-static bool e1000_sgmii_active_82575(struct e1000_hw *hw);
-static s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
-static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
-static void e1000_config_collision_dist_82575(struct e1000_hw *hw);
-static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
-static void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw);
-static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw);
-static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
-static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw);
-static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw);
-static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw);
-static s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw,
- u16 offset);
-static s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw,
- u16 offset);
-static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw);
-static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw);
-static void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value);
-static void e1000_clear_vfta_i350(struct e1000_hw *hw);
-
-static void e1000_i2c_start(struct e1000_hw *hw);
-static void e1000_i2c_stop(struct e1000_hw *hw);
-static s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data);
-static s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data);
-static s32 e1000_get_i2c_ack(struct e1000_hw *hw);
-static s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data);
-static s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data);
-static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
-static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
-static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data);
-static bool e1000_get_i2c_data(u32 *i2cctl);
-
-static const u16 e1000_82580_rxpbs_table[] = {
- 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
-#define E1000_82580_RXPBS_TABLE_SIZE \
- (sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
-
-
-/**
- * e1000_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
- * @hw: pointer to the HW structure
- *
- * Called to determine if the I2C pins are being used for I2C or as an
- * external MDIO interface since the two options are mutually exclusive.
- **/
-static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw)
-{
- u32 reg = 0;
- bool ext_mdio = false;
-
- DEBUGFUNC("e1000_sgmii_uses_mdio_82575");
-
- switch (hw->mac.type) {
- case e1000_82575:
- case e1000_82576:
- reg = E1000_READ_REG(hw, E1000_MDIC);
- ext_mdio = !!(reg & E1000_MDIC_DEST);
- break;
- case e1000_82580:
- case e1000_i350:
- case e1000_i354:
- case e1000_i210:
- case e1000_i211:
- reg = E1000_READ_REG(hw, E1000_MDICNFG);
- ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
- break;
- default:
- break;
- }
- return ext_mdio;
-}
-
-/**
- * e1000_init_phy_params_82575 - Init PHY func ptrs.
- * @hw: pointer to the HW structure
- **/
-static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
- u32 ctrl_ext;
-
- DEBUGFUNC("e1000_init_phy_params_82575");
-
- phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic;
- phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic;
-
- if (hw->phy.media_type != e1000_media_type_copper) {
- phy->type = e1000_phy_none;
- goto out;
- }
-
- phy->ops.power_up = e1000_power_up_phy_copper;
- phy->ops.power_down = e1000_power_down_phy_copper_82575;
-
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
- phy->reset_delay_us = 100;
-
- phy->ops.acquire = e1000_acquire_phy_82575;
- phy->ops.check_reset_block = e1000_check_reset_block_generic;
- phy->ops.commit = e1000_phy_sw_reset_generic;
- phy->ops.get_cfg_done = e1000_get_cfg_done_82575;
- phy->ops.release = e1000_release_phy_82575;
-
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
-
- if (e1000_sgmii_active_82575(hw)) {
- phy->ops.reset = e1000_phy_hw_reset_sgmii_82575;
- ctrl_ext |= E1000_CTRL_I2C_ENA;
- } else {
- phy->ops.reset = e1000_phy_hw_reset_generic;
- ctrl_ext &= ~E1000_CTRL_I2C_ENA;
- }
-
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
- e1000_reset_mdicnfg_82580(hw);
-
- if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) {
- phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
- phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
- } else {
- switch (hw->mac.type) {
- case e1000_82580:
- case e1000_i350:
- case e1000_i354:
- phy->ops.read_reg = e1000_read_phy_reg_82580;
- phy->ops.write_reg = e1000_write_phy_reg_82580;
- break;
- case e1000_i210:
- case e1000_i211:
- phy->ops.read_reg = e1000_read_phy_reg_gs40g;
- phy->ops.write_reg = e1000_write_phy_reg_gs40g;
- break;
- default:
- phy->ops.read_reg = e1000_read_phy_reg_igp;
- phy->ops.write_reg = e1000_write_phy_reg_igp;
- }
- }
-
- /* Set phy->phy_addr and phy->id. */
- ret_val = e1000_get_phy_id_82575(hw);
-
- /* Verify phy id and set remaining function pointers */
- switch (phy->id) {
- case M88E1543_E_PHY_ID:
- case I347AT4_E_PHY_ID:
- case M88E1112_E_PHY_ID:
- case M88E1340M_E_PHY_ID:
- case M88E1111_I_PHY_ID:
- phy->type = e1000_phy_m88;
- phy->ops.check_polarity = e1000_check_polarity_m88;
- phy->ops.get_info = e1000_get_phy_info_m88;
- if (phy->id == I347AT4_E_PHY_ID ||
- phy->id == M88E1112_E_PHY_ID ||
- phy->id == M88E1340M_E_PHY_ID)
- phy->ops.get_cable_length =
- e1000_get_cable_length_m88_gen2;
- else if (phy->id == M88E1543_E_PHY_ID)
- phy->ops.get_cable_length =
- e1000_get_cable_length_m88_gen2;
- else
- phy->ops.get_cable_length = e1000_get_cable_length_m88;
- phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
- /* Check if this PHY is configured for media swap. */
- if (phy->id == M88E1112_E_PHY_ID) {
- u16 data;
-
- ret_val = phy->ops.write_reg(hw,
- E1000_M88E1112_PAGE_ADDR,
- 2);
- if (ret_val)
- goto out;
-
- ret_val = phy->ops.read_reg(hw,
- E1000_M88E1112_MAC_CTRL_1,
- &data);
- if (ret_val)
- goto out;
-
- data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >>
- E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT;
- if (data == E1000_M88E1112_AUTO_COPPER_SGMII ||
- data == E1000_M88E1112_AUTO_COPPER_BASEX)
- hw->mac.ops.check_for_link =
- e1000_check_for_link_media_swap;
- }
- break;
- case IGP03E1000_E_PHY_ID:
- case IGP04E1000_E_PHY_ID:
- phy->type = e1000_phy_igp_3;
- phy->ops.check_polarity = e1000_check_polarity_igp;
- phy->ops.get_info = e1000_get_phy_info_igp;
- phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
- phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
- phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
- phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
- break;
- case I82580_I_PHY_ID:
- case I350_I_PHY_ID:
- phy->type = e1000_phy_82580;
- phy->ops.check_polarity = e1000_check_polarity_82577;
- phy->ops.force_speed_duplex =
- e1000_phy_force_speed_duplex_82577;
- phy->ops.get_cable_length = e1000_get_cable_length_82577;
- phy->ops.get_info = e1000_get_phy_info_82577;
- phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
- phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
- break;
- case I210_I_PHY_ID:
- phy->type = e1000_phy_i210;
- phy->ops.check_polarity = e1000_check_polarity_m88;
- phy->ops.get_info = e1000_get_phy_info_m88;
- phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2;
- phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
- phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
- phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
- break;
- default:
- ret_val = -E1000_ERR_PHY;
- goto out;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_init_nvm_params_82575 - Init NVM func ptrs.
- * @hw: pointer to the HW structure
- **/
-s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 eecd = E1000_READ_REG(hw, E1000_EECD);
- u16 size;
-
- DEBUGFUNC("e1000_init_nvm_params_82575");
-
- size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
- E1000_EECD_SIZE_EX_SHIFT);
- /*
- * Added to a constant, "size" becomes the left-shift value
- * for setting word_size.
- */
- size += NVM_WORD_SIZE_BASE_SHIFT;
-
- /* Just in case size is out of range, cap it to the largest
- * EEPROM size supported
- */
- if (size > 15)
- size = 15;
-
- nvm->word_size = 1 << size;
- if (hw->mac.type < e1000_i210) {
- nvm->opcode_bits = 8;
- nvm->delay_usec = 1;
-
- switch (nvm->override) {
- case e1000_nvm_override_spi_large:
- nvm->page_size = 32;
- nvm->address_bits = 16;
- break;
- case e1000_nvm_override_spi_small:
- nvm->page_size = 8;
- nvm->address_bits = 8;
- break;
- default:
- nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
- nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ?
- 16 : 8;
- break;
- }
- if (nvm->word_size == (1 << 15))
- nvm->page_size = 128;
-
- nvm->type = e1000_nvm_eeprom_spi;
- } else {
- nvm->type = e1000_nvm_flash_hw;
- }
-
- /* Function Pointers */
- nvm->ops.acquire = e1000_acquire_nvm_82575;
- nvm->ops.release = e1000_release_nvm_82575;
- if (nvm->word_size < (1 << 15))
- nvm->ops.read = e1000_read_nvm_eerd;
- else
- nvm->ops.read = e1000_read_nvm_spi;
-
- nvm->ops.write = e1000_write_nvm_spi;
- nvm->ops.validate = e1000_validate_nvm_checksum_generic;
- nvm->ops.update = e1000_update_nvm_checksum_generic;
- nvm->ops.valid_led_default = e1000_valid_led_default_82575;
-
- /* override generic family function pointers for specific descendants */
- switch (hw->mac.type) {
- case e1000_82580:
- nvm->ops.validate = e1000_validate_nvm_checksum_82580;
- nvm->ops.update = e1000_update_nvm_checksum_82580;
- break;
- case e1000_i350:
- //case e1000_i354:
- nvm->ops.validate = e1000_validate_nvm_checksum_i350;
- nvm->ops.update = e1000_update_nvm_checksum_i350;
- break;
- default:
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_init_mac_params_82575 - Init MAC func ptrs.
- * @hw: pointer to the HW structure
- **/
-static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
-
- DEBUGFUNC("e1000_init_mac_params_82575");
-
- /* Derives media type */
- e1000_get_media_type_82575(hw);
- /* Set mta register count */
- mac->mta_reg_count = 128;
- /* Set uta register count */
- mac->uta_reg_count = (hw->mac.type == e1000_82575) ? 0 : 128;
- /* Set rar entry count */
- mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
- if (mac->type == e1000_82576)
- mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
- if (mac->type == e1000_82580)
- mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
- if (mac->type == e1000_i350 || mac->type == e1000_i354)
- mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
-
- /* Enable EEE default settings for EEE supported devices */
- if (mac->type >= e1000_i350)
- dev_spec->eee_disable = false;
-
- /* Allow a single clear of the SW semaphore on I210 and newer */
- if (mac->type >= e1000_i210)
- dev_spec->clear_semaphore_once = true;
-
- /* Set if part includes ASF firmware */
- mac->asf_firmware_present = true;
- /* FWSM register */
- mac->has_fwsm = true;
- /* ARC supported; valid only if manageability features are enabled. */
- mac->arc_subsystem_valid =
- !!(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK);
-
- /* Function pointers */
-
- /* bus type/speed/width */
- mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
- /* reset */
- if (mac->type >= e1000_82580)
- mac->ops.reset_hw = e1000_reset_hw_82580;
- else
- mac->ops.reset_hw = e1000_reset_hw_82575;
- /* hw initialization */
- mac->ops.init_hw = e1000_init_hw_82575;
- /* link setup */
- mac->ops.setup_link = e1000_setup_link_generic;
- /* physical interface link setup */
- mac->ops.setup_physical_interface =
- (hw->phy.media_type == e1000_media_type_copper)
- ? e1000_setup_copper_link_82575 : e1000_setup_serdes_link_82575;
- /* physical interface shutdown */
- mac->ops.shutdown_serdes = e1000_shutdown_serdes_link_82575;
- /* physical interface power up */
- mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575;
- /* check for link */
- mac->ops.check_for_link = e1000_check_for_link_82575;
- /* read mac address */
- mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
- /* configure collision distance */
- mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
- /* multicast address update */
- mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
- if (hw->mac.type == e1000_i350 || mac->type == e1000_i354) {
- /* writing VFTA */
- mac->ops.write_vfta = e1000_write_vfta_i350;
- /* clearing VFTA */
- mac->ops.clear_vfta = e1000_clear_vfta_i350;
- } else {
- /* writing VFTA */
- mac->ops.write_vfta = e1000_write_vfta_generic;
- /* clearing VFTA */
- mac->ops.clear_vfta = e1000_clear_vfta_generic;
- }
- if (hw->mac.type >= e1000_82580)
- mac->ops.validate_mdi_setting =
- e1000_validate_mdi_setting_crossover_generic;
- /* ID LED init */
- mac->ops.id_led_init = e1000_id_led_init_generic;
- /* blink LED */
- mac->ops.blink_led = e1000_blink_led_generic;
- /* setup LED */
- mac->ops.setup_led = e1000_setup_led_generic;
- /* cleanup LED */
- mac->ops.cleanup_led = e1000_cleanup_led_generic;
- /* turn on/off LED */
- mac->ops.led_on = e1000_led_on_generic;
- mac->ops.led_off = e1000_led_off_generic;
- /* clear hardware counters */
- mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
- /* link info */
- mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
- /* get thermal sensor data */
- mac->ops.get_thermal_sensor_data =
- e1000_get_thermal_sensor_data_generic;
- mac->ops.init_thermal_sensor_thresh =
- e1000_init_thermal_sensor_thresh_generic;
- /* acquire SW_FW sync */
- mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575;
- mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575;
- if (mac->type >= e1000_i210) {
- mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210;
- mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210;
- }
-
- /* set lan id for port to determine which phy lock to use */
- hw->mac.ops.set_lan_id(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_init_function_pointers_82575 - Init func ptrs.
- * @hw: pointer to the HW structure
- *
- * Called to initialize all function pointers and parameters.
- **/
-void e1000_init_function_pointers_82575(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_init_function_pointers_82575");
-
- hw->mac.ops.init_params = e1000_init_mac_params_82575;
- hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
- hw->phy.ops.init_params = e1000_init_phy_params_82575;
- hw->mbx.ops.init_params = e1000_init_mbx_params_pf;
-}
-
-/**
- * e1000_acquire_phy_82575 - Acquire rights to access PHY
- * @hw: pointer to the HW structure
- *
- * Acquire access rights to the correct PHY.
- **/
-static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
-{
- u16 mask = E1000_SWFW_PHY0_SM;
-
- DEBUGFUNC("e1000_acquire_phy_82575");
-
- if (hw->bus.func == E1000_FUNC_1)
- mask = E1000_SWFW_PHY1_SM;
- else if (hw->bus.func == E1000_FUNC_2)
- mask = E1000_SWFW_PHY2_SM;
- else if (hw->bus.func == E1000_FUNC_3)
- mask = E1000_SWFW_PHY3_SM;
-
- return hw->mac.ops.acquire_swfw_sync(hw, mask);
-}
-
-/**
- * e1000_release_phy_82575 - Release rights to access PHY
- * @hw: pointer to the HW structure
- *
- * A wrapper to release access rights to the correct PHY.
- **/
-static void e1000_release_phy_82575(struct e1000_hw *hw)
-{
- u16 mask = E1000_SWFW_PHY0_SM;
-
- DEBUGFUNC("e1000_release_phy_82575");
-
- if (hw->bus.func == E1000_FUNC_1)
- mask = E1000_SWFW_PHY1_SM;
- else if (hw->bus.func == E1000_FUNC_2)
- mask = E1000_SWFW_PHY2_SM;
- else if (hw->bus.func == E1000_FUNC_3)
- mask = E1000_SWFW_PHY3_SM;
-
- hw->mac.ops.release_swfw_sync(hw, mask);
-}
-
-/**
- * e1000_read_phy_reg_sgmii_82575 - Read PHY register using sgmii
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Reads the PHY register at offset using the serial gigabit media independent
- * interface and stores the retrieved information in data.
- **/
-static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
- u16 *data)
-{
- s32 ret_val = -E1000_ERR_PARAM;
-
- DEBUGFUNC("e1000_read_phy_reg_sgmii_82575");
-
- if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
- DEBUGOUT1("PHY Address %u is out of range\n", offset);
- goto out;
- }
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- goto out;
-
- ret_val = e1000_read_phy_reg_i2c(hw, offset, data);
-
- hw->phy.ops.release(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_write_phy_reg_sgmii_82575 - Write PHY register using sgmii
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Writes the data to PHY register at the offset using the serial gigabit
- * media independent interface.
- **/
-static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
- u16 data)
-{
- s32 ret_val = -E1000_ERR_PARAM;
-
- DEBUGFUNC("e1000_write_phy_reg_sgmii_82575");
-
- if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
- DEBUGOUT1("PHY Address %d is out of range\n", offset);
- goto out;
- }
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- goto out;
-
- ret_val = e1000_write_phy_reg_i2c(hw, offset, data);
-
- hw->phy.ops.release(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_get_phy_id_82575 - Retrieve PHY addr and id
- * @hw: pointer to the HW structure
- *
- * Retrieves the PHY address and ID for both PHY's which do and do not use
- * sgmi interface.
- **/
-static s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
- u16 phy_id;
- u32 ctrl_ext;
- u32 mdic;
-
- DEBUGFUNC("e1000_get_phy_id_82575");
-
- /* i354 devices can have a PHY that needs an extra read for id */
- if (hw->mac.type == e1000_i354)
- e1000_get_phy_id(hw);
-
-
- /*
- * For SGMII PHYs, we try the list of possible addresses until
- * we find one that works. For non-SGMII PHYs
- * (e.g. integrated copper PHYs), an address of 1 should
- * work. The result of this function should mean phy->phy_addr
- * and phy->id are set correctly.
- */
- if (!e1000_sgmii_active_82575(hw)) {
- phy->addr = 1;
- ret_val = e1000_get_phy_id(hw);
- goto out;
- }
-
- if (e1000_sgmii_uses_mdio_82575(hw)) {
- switch (hw->mac.type) {
- case e1000_82575:
- case e1000_82576:
- mdic = E1000_READ_REG(hw, E1000_MDIC);
- mdic &= E1000_MDIC_PHY_MASK;
- phy->addr = mdic >> E1000_MDIC_PHY_SHIFT;
- break;
- case e1000_82580:
- case e1000_i350:
- case e1000_i354:
- case e1000_i210:
- case e1000_i211:
- mdic = E1000_READ_REG(hw, E1000_MDICNFG);
- mdic &= E1000_MDICNFG_PHY_MASK;
- phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
- break;
- default:
- ret_val = -E1000_ERR_PHY;
- goto out;
- break;
- }
- ret_val = e1000_get_phy_id(hw);
- goto out;
- }
-
- /* Power on sgmii phy if it is disabled */
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- E1000_WRITE_REG(hw, E1000_CTRL_EXT,
- ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA);
- E1000_WRITE_FLUSH(hw);
- msec_delay(300);
-
- /*
- * The address field in the I2CCMD register is 3 bits and 0 is invalid.
- * Therefore, we need to test 1-7
- */
- for (phy->addr = 1; phy->addr < 8; phy->addr++) {
- ret_val = e1000_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id);
- if (ret_val == E1000_SUCCESS) {
- DEBUGOUT2("Vendor ID 0x%08X read at address %u\n",
- phy_id, phy->addr);
- /*
- * At the time of this writing, The M88 part is
- * the only supported SGMII PHY product.
- */
- if (phy_id == M88_VENDOR)
- break;
- } else {
- DEBUGOUT1("PHY address %u was unreadable\n",
- phy->addr);
- }
- }
-
- /* A valid PHY type couldn't be found. */
- if (phy->addr == 8) {
- phy->addr = 0;
- ret_val = -E1000_ERR_PHY;
- } else {
- ret_val = e1000_get_phy_id(hw);
- }
-
- /* restore previous sfp cage power state */
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_phy_hw_reset_sgmii_82575 - Performs a PHY reset
- * @hw: pointer to the HW structure
- *
- * Resets the PHY using the serial gigabit media independent interface.
- **/
-static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
-
- /*
- * This isn't a true "hard" reset, but is the only reset
- * available to us at this time.
- */
-
- DEBUGOUT("Soft resetting SGMII attached PHY...\n");
-
- if (!(hw->phy.ops.write_reg))
- goto out;
-
- /*
- * SFP documentation requires the following to configure the SPF module
- * to work on SGMII. No further documentation is given.
- */
- ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
- if (ret_val)
- goto out;
-
- ret_val = hw->phy.ops.commit(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
- * @hw: pointer to the HW structure
- * @active: true to enable LPLU, false to disable
- *
- * Sets the LPLU D0 state according to the active flag. When
- * activating LPLU this function also disables smart speed
- * and vice versa. LPLU will not be activated unless the
- * device autonegotiation advertisement meets standards of
- * either 10 or 10/100 or 10/100/1000 at all duplexes.
- * This is a function pointer entry point only called by
- * PHY setup routines.
- **/
-static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
- u16 data;
-
- DEBUGFUNC("e1000_set_d0_lplu_state_82575");
-
- if (!(hw->phy.ops.read_reg))
- goto out;
-
- ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
- if (ret_val)
- goto out;
-
- if (active) {
- data |= IGP02E1000_PM_D0_LPLU;
- ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- data);
- if (ret_val)
- goto out;
-
- /* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- goto out;
- } else {
- data &= ~IGP02E1000_PM_D0_LPLU;
- ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- data);
- /*
- * LPLU and SmartSpeed are mutually exclusive. LPLU is used
- * during Dx states where the power conservation is most
- * important. During driver activity we should enable
- * SmartSpeed, so performance is maintained.
- */
- if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = phy->ops.read_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- goto out;
-
- data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- goto out;
- } else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = phy->ops.read_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- goto out;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- goto out;
- }
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_set_d0_lplu_state_82580 - Set Low Power Linkup D0 state
- * @hw: pointer to the HW structure
- * @active: true to enable LPLU, false to disable
- *
- * Sets the LPLU D0 state according to the active flag. When
- * activating LPLU this function also disables smart speed
- * and vice versa. LPLU will not be activated unless the
- * device autonegotiation advertisement meets standards of
- * either 10 or 10/100 or 10/100/1000 at all duplexes.
- * This is a function pointer entry point only called by
- * PHY setup routines.
- **/
-static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
- u32 data;
-
- DEBUGFUNC("e1000_set_d0_lplu_state_82580");
-
- data = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
-
- if (active) {
- data |= E1000_82580_PM_D0_LPLU;
-
- /* When LPLU is enabled, we should disable SmartSpeed */
- data &= ~E1000_82580_PM_SPD;
- } else {
- data &= ~E1000_82580_PM_D0_LPLU;
-
- /*
- * LPLU and SmartSpeed are mutually exclusive. LPLU is used
- * during Dx states where the power conservation is most
- * important. During driver activity we should enable
- * SmartSpeed, so performance is maintained.
- */
- if (phy->smart_speed == e1000_smart_speed_on)
- data |= E1000_82580_PM_SPD;
- else if (phy->smart_speed == e1000_smart_speed_off)
- data &= ~E1000_82580_PM_SPD;
- }
-
- E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
- return ret_val;
-}
-
-/**
- * e1000_set_d3_lplu_state_82580 - Sets low power link up state for D3
- * @hw: pointer to the HW structure
- * @active: boolean used to enable/disable lplu
- *
- * Success returns 0, Failure returns 1
- *
- * The low power link up (lplu) state is set to the power management level D3
- * and SmartSpeed is disabled when active is true, else clear lplu for D3
- * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
- * is used during Dx states where the power conservation is most important.
- * During driver activity, SmartSpeed should be enabled so performance is
- * maintained.
- **/
-s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
- u32 data;
-
- DEBUGFUNC("e1000_set_d3_lplu_state_82580");
-
- data = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
-
- if (!active) {
- data &= ~E1000_82580_PM_D3_LPLU;
- /*
- * LPLU and SmartSpeed are mutually exclusive. LPLU is used
- * during Dx states where the power conservation is most
- * important. During driver activity we should enable
- * SmartSpeed, so performance is maintained.
- */
- if (phy->smart_speed == e1000_smart_speed_on)
- data |= E1000_82580_PM_SPD;
- else if (phy->smart_speed == e1000_smart_speed_off)
- data &= ~E1000_82580_PM_SPD;
- } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
- (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
- (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
- data |= E1000_82580_PM_D3_LPLU;
- /* When LPLU is enabled, we should disable SmartSpeed */
- data &= ~E1000_82580_PM_SPD;
- }
-
- E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
- return ret_val;
-}
-
-/**
- * e1000_acquire_nvm_82575 - Request for access to EEPROM
- * @hw: pointer to the HW structure
- *
- * Acquire the necessary semaphores for exclusive access to the EEPROM.
- * Set the EEPROM access request bit and wait for EEPROM access grant bit.
- * Return successful if access grant bit set, else clear the request for
- * EEPROM access and return -E1000_ERR_NVM (-1).
- **/
-static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_acquire_nvm_82575");
-
- ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
- if (ret_val)
- goto out;
-
- /*
- * Check if there is some access
- * error this access may hook on
- */
- if (hw->mac.type == e1000_i350) {
- u32 eecd = E1000_READ_REG(hw, E1000_EECD);
- if (eecd & (E1000_EECD_BLOCKED | E1000_EECD_ABORT |
- E1000_EECD_TIMEOUT)) {
- /* Clear all access error flags */
- E1000_WRITE_REG(hw, E1000_EECD, eecd |
- E1000_EECD_ERROR_CLR);
- DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
- }
- }
- if (hw->mac.type == e1000_82580) {
- u32 eecd = E1000_READ_REG(hw, E1000_EECD);
- if (eecd & E1000_EECD_BLOCKED) {
- /* Clear access error flag */
- E1000_WRITE_REG(hw, E1000_EECD, eecd |
- E1000_EECD_BLOCKED);
- DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
- }
- }
-
-
- ret_val = e1000_acquire_nvm_generic(hw);
- if (ret_val)
- e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_release_nvm_82575 - Release exclusive access to EEPROM
- * @hw: pointer to the HW structure
- *
- * Stop any current commands to the EEPROM and clear the EEPROM request bit,
- * then release the semaphores acquired.
- **/
-static void e1000_release_nvm_82575(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_release_nvm_82575");
-
- e1000_release_nvm_generic(hw);
-
- e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
-}
-
-/**
- * e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
- * will also specify which port we're acquiring the lock for.
- **/
-static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
- u32 swmask = mask;
- u32 fwmask = mask << 16;
- s32 ret_val = E1000_SUCCESS;
- s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
-
- DEBUGFUNC("e1000_acquire_swfw_sync_82575");
-
- while (i < timeout) {
- if (e1000_get_hw_semaphore_generic(hw)) {
- ret_val = -E1000_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- if (!(swfw_sync & (fwmask | swmask)))
- break;
-
- /*
- * Firmware currently using resource (fwmask)
- * or other software thread using resource (swmask)
- */
- e1000_put_hw_semaphore_generic(hw);
- msec_delay_irq(5);
- i++;
- }
-
- if (i == timeout) {
- DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
- ret_val = -E1000_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync |= swmask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_release_swfw_sync_82575 - Release SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Release the SW/FW semaphore used to access the PHY or NVM. The mask
- * will also specify which port we're releasing the lock for.
- **/
-static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
-
- DEBUGFUNC("e1000_release_swfw_sync_82575");
-
- while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS)
- ; /* Empty */
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- swfw_sync &= ~mask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
-}
-
-/**
- * e1000_get_cfg_done_82575 - Read config done bit
- * @hw: pointer to the HW structure
- *
- * Read the management control register for the config done bit for
- * completion status. NOTE: silicon which is EEPROM-less will fail trying
- * to read the config done bit, so an error is *ONLY* logged and returns
- * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon
- * would not be able to be reset or change link.
- **/
-static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
-{
- s32 timeout = PHY_CFG_TIMEOUT;
- s32 ret_val = E1000_SUCCESS;
- u32 mask = E1000_NVM_CFG_DONE_PORT_0;
-
- DEBUGFUNC("e1000_get_cfg_done_82575");
-
- if (hw->bus.func == E1000_FUNC_1)
- mask = E1000_NVM_CFG_DONE_PORT_1;
- else if (hw->bus.func == E1000_FUNC_2)
- mask = E1000_NVM_CFG_DONE_PORT_2;
- else if (hw->bus.func == E1000_FUNC_3)
- mask = E1000_NVM_CFG_DONE_PORT_3;
- while (timeout) {
- if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)
- break;
- msec_delay(1);
- timeout--;
- }
- if (!timeout)
- DEBUGOUT("MNG configuration cycle has not completed.\n");
-
- /* If EEPROM is not marked present, init the PHY manually */
- if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) &&
- (hw->phy.type == e1000_phy_igp_3))
- e1000_phy_init_script_igp3(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_get_link_up_info_82575 - Get link speed/duplex info
- * @hw: pointer to the HW structure
- * @speed: stores the current speed
- * @duplex: stores the current duplex
- *
- * This is a wrapper function, if using the serial gigabit media independent
- * interface, use PCS to retrieve the link speed and duplex information.
- * Otherwise, use the generic function to get the link speed and duplex info.
- **/
-static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
- u16 *duplex)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_get_link_up_info_82575");
-
- if (hw->phy.media_type != e1000_media_type_copper)
- ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, speed,
- duplex);
- else
- ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed,
- duplex);
-
- return ret_val;
-}
-
-/**
- * e1000_check_for_link_82575 - Check for link
- * @hw: pointer to the HW structure
- *
- * If sgmii is enabled, then use the pcs register to determine link, otherwise
- * use the generic interface for determining link.
- **/
-static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 speed, duplex;
-
- DEBUGFUNC("e1000_check_for_link_82575");
-
- if (hw->phy.media_type != e1000_media_type_copper) {
- ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed,
- &duplex);
- /*
- * Use this flag to determine if link needs to be checked or
- * not. If we have link clear the flag so that we do not
- * continue to check for link.
- */
- hw->mac.get_link_status = !hw->mac.serdes_has_link;
-
- /*
- * Configure Flow Control now that Auto-Neg has completed.
- * First, we need to restore the desired flow control
- * settings because we may have had to re-autoneg with a
- * different link partner.
- */
- ret_val = e1000_config_fc_after_link_up_generic(hw);
- if (ret_val)
- DEBUGOUT("Error configuring flow control\n");
- } else {
- ret_val = e1000_check_for_copper_link_generic(hw);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_check_for_link_media_swap - Check which M88E1112 interface linked
- * @hw: pointer to the HW structure
- *
- * Poll the M88E1112 interfaces to see which interface achieved link.
- */
-static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
- u8 port = 0;
-
- DEBUGFUNC("e1000_check_for_link_media_swap");
-
- /* Check the copper medium. */
- ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
- if (ret_val)
- return ret_val;
-
- if (data & E1000_M88E1112_STATUS_LINK)
- port = E1000_MEDIA_PORT_COPPER;
-
- /* Check the other medium. */
- ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data);
- if (ret_val)
- return ret_val;
-
- if (data & E1000_M88E1112_STATUS_LINK)
- port = E1000_MEDIA_PORT_OTHER;
-
- /* Determine if a swap needs to happen. */
- if (port && (hw->dev_spec._82575.media_port != port)) {
- hw->dev_spec._82575.media_port = port;
- hw->dev_spec._82575.media_changed = true;
- } else {
- ret_val = e1000_check_for_link_82575(hw);
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_power_up_serdes_link_82575 - Power up the serdes link after shutdown
- * @hw: pointer to the HW structure
- **/
-static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw)
-{
- u32 reg;
-
- DEBUGFUNC("e1000_power_up_serdes_link_82575");
-
- if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
- !e1000_sgmii_active_82575(hw))
- return;
-
- /* Enable PCS to turn on link */
- reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
- reg |= E1000_PCS_CFG_PCS_EN;
- E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
-
- /* Power up the laser */
- reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
- reg &= ~E1000_CTRL_EXT_SDP3_DATA;
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
-
- /* flush the write to verify completion */
- E1000_WRITE_FLUSH(hw);
- msec_delay(1);
-}
-
-/**
- * e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
- * @hw: pointer to the HW structure
- * @speed: stores the current speed
- * @duplex: stores the current duplex
- *
- * Using the physical coding sub-layer (PCS), retrieve the current speed and
- * duplex, then store the values in the pointers provided.
- **/
-static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
- u16 *speed, u16 *duplex)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 pcs;
- u32 status;
-
- DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
-
- /*
- * Read the PCS Status register for link state. For non-copper mode,
- * the status register is not accurate. The PCS status register is
- * used instead.
- */
- pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT);
-
- /*
- * The link up bit determines when link is up on autoneg.
- */
- if (pcs & E1000_PCS_LSTS_LINK_OK) {
- mac->serdes_has_link = true;
-
- /* Detect and store PCS speed */
- if (pcs & E1000_PCS_LSTS_SPEED_1000)
- *speed = SPEED_1000;
- else if (pcs & E1000_PCS_LSTS_SPEED_100)
- *speed = SPEED_100;
- else
- *speed = SPEED_10;
-
- /* Detect and store PCS duplex */
- if (pcs & E1000_PCS_LSTS_DUPLEX_FULL)
- *duplex = FULL_DUPLEX;
- else
- *duplex = HALF_DUPLEX;
-
- /* Check if it is an I354 2.5Gb backplane connection. */
- if (mac->type == e1000_i354) {
- status = E1000_READ_REG(hw, E1000_STATUS);
- if ((status & E1000_STATUS_2P5_SKU) &&
- !(status & E1000_STATUS_2P5_SKU_OVER)) {
- *speed = SPEED_2500;
- *duplex = FULL_DUPLEX;
- DEBUGOUT("2500 Mbs, ");
- DEBUGOUT("Full Duplex\n");
- }
- }
-
- } else {
- mac->serdes_has_link = false;
- *speed = 0;
- *duplex = 0;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_shutdown_serdes_link_82575 - Remove link during power down
- * @hw: pointer to the HW structure
- *
- * In the case of serdes shut down sfp and PCS on driver unload
- * when management pass through is not enabled.
- **/
-void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw)
-{
- u32 reg;
-
- DEBUGFUNC("e1000_shutdown_serdes_link_82575");
-
- if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
- !e1000_sgmii_active_82575(hw))
- return;
-
- if (!e1000_enable_mng_pass_thru(hw)) {
- /* Disable PCS to turn off link */
- reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
- reg &= ~E1000_PCS_CFG_PCS_EN;
- E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
-
- /* shutdown the laser */
- reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
- reg |= E1000_CTRL_EXT_SDP3_DATA;
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
-
- /* flush the write to verify completion */
- E1000_WRITE_FLUSH(hw);
- msec_delay(1);
- }
-
- return;
-}
-
-/**
- * e1000_reset_hw_82575 - Reset hardware
- * @hw: pointer to the HW structure
- *
- * This resets the hardware into a known state.
- **/
-static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 ret_val;
-
- DEBUGFUNC("e1000_reset_hw_82575");
-
- /*
- * Prevent the PCI-E bus from sticking if there is no TLP connection
- * on the last TLP read/write transaction when MAC is reset.
- */
- ret_val = e1000_disable_pcie_master_generic(hw);
- if (ret_val)
- DEBUGOUT("PCI-E Master disable polling has failed.\n");
-
- /* set the completion timeout for interface */
- ret_val = e1000_set_pcie_completion_timeout(hw);
- if (ret_val)
- DEBUGOUT("PCI-E Set completion timeout has failed.\n");
-
- DEBUGOUT("Masking off all interrupts\n");
- E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
-
- E1000_WRITE_REG(hw, E1000_RCTL, 0);
- E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
- E1000_WRITE_FLUSH(hw);
-
- msec_delay(10);
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
-
- DEBUGOUT("Issuing a global reset to MAC\n");
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
-
- ret_val = e1000_get_auto_rd_done_generic(hw);
- if (ret_val) {
- /*
- * When auto config read does not complete, do not
- * return with an error. This can happen in situations
- * where there is no eeprom and prevents getting link.
- */
- DEBUGOUT("Auto Read Done did not complete\n");
- }
-
- /* If EEPROM is not present, run manual init scripts */
- if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
- e1000_reset_init_script_82575(hw);
-
- /* Clear any pending interrupt events. */
- E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
- E1000_READ_REG(hw, E1000_ICR);
-
- /* Install any alternate MAC address into RAR0 */
- ret_val = e1000_check_alt_mac_addr_generic(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_init_hw_82575 - Initialize hardware
- * @hw: pointer to the HW structure
- *
- * This inits the hardware readying it for operation.
- **/
-static s32 e1000_init_hw_82575(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val;
- u16 i, rar_count = mac->rar_entry_count;
-
- DEBUGFUNC("e1000_init_hw_82575");
-
- /* Initialize identification LED */
- ret_val = mac->ops.id_led_init(hw);
- if (ret_val) {
- DEBUGOUT("Error initializing identification LED\n");
- /* This is not fatal and we should not stop init due to this */
- }
-
- /* Disabling VLAN filtering */
- DEBUGOUT("Initializing the IEEE VLAN\n");
- mac->ops.clear_vfta(hw);
-
- /* Setup the receive address */
- e1000_init_rx_addrs_generic(hw, rar_count);
-
- /* Zero out the Multicast HASH table */
- DEBUGOUT("Zeroing the MTA\n");
- for (i = 0; i < mac->mta_reg_count; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
-
- /* Zero out the Unicast HASH table */
- DEBUGOUT("Zeroing the UTA\n");
- for (i = 0; i < mac->uta_reg_count; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0);
-
- /* Setup link and flow control */
- ret_val = mac->ops.setup_link(hw);
-
- /* Set the default MTU size */
- hw->dev_spec._82575.mtu = 1500;
-
- /*
- * Clear all of the statistics registers (clear on read). It is
- * important that we do this after we have tried to establish link
- * because the symbol error count will increment wildly if there
- * is no link.
- */
- e1000_clear_hw_cntrs_82575(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_setup_copper_link_82575 - Configure copper link settings
- * @hw: pointer to the HW structure
- *
- * Configures the link for auto-neg or forced speed and duplex. Then we check
- * for link, once link is established calls to configure collision distance
- * and flow control are called.
- **/
-static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 ret_val;
- u32 phpm_reg;
-
- DEBUGFUNC("e1000_setup_copper_link_82575");
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- ctrl |= E1000_CTRL_SLU;
- ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-
- /* Clear Go Link Disconnect bit on supported devices */
- switch (hw->mac.type) {
- case e1000_82580:
- case e1000_i350:
- case e1000_i210:
- case e1000_i211:
- phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
- phpm_reg &= ~E1000_82580_PM_GO_LINKD;
- E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
- break;
- default:
- break;
- }
-
- ret_val = e1000_setup_serdes_link_82575(hw);
- if (ret_val)
- goto out;
-
- if (e1000_sgmii_active_82575(hw) && !hw->phy.reset_disable) {
- /* allow time for SFP cage time to power up phy */
- msec_delay(300);
-
- ret_val = hw->phy.ops.reset(hw);
- if (ret_val) {
- DEBUGOUT("Error resetting the PHY.\n");
- goto out;
- }
- }
- switch (hw->phy.type) {
- case e1000_phy_i210:
- case e1000_phy_m88:
- switch (hw->phy.id) {
- case I347AT4_E_PHY_ID:
- case M88E1112_E_PHY_ID:
- case M88E1340M_E_PHY_ID:
- case M88E1543_E_PHY_ID:
- case I210_I_PHY_ID:
- ret_val = e1000_copper_link_setup_m88_gen2(hw);
- break;
- default:
- ret_val = e1000_copper_link_setup_m88(hw);
- break;
- }
- break;
- case e1000_phy_igp_3:
- ret_val = e1000_copper_link_setup_igp(hw);
- break;
- case e1000_phy_82580:
- ret_val = e1000_copper_link_setup_82577(hw);
- break;
- default:
- ret_val = -E1000_ERR_PHY;
- break;
- }
-
- if (ret_val)
- goto out;
-
- ret_val = e1000_setup_copper_link_generic(hw);
-out:
- return ret_val;
-}
-
-/**
- * e1000_setup_serdes_link_82575 - Setup link for serdes
- * @hw: pointer to the HW structure
- *
- * Configure the physical coding sub-layer (PCS) link. The PCS link is
- * used on copper connections where the serialized gigabit media independent
- * interface (sgmii), or serdes fiber is being used. Configures the link
- * for auto-negotiation or forces speed/duplex.
- **/
-static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
-{
- u32 ctrl_ext, ctrl_reg, reg, anadv_reg;
- bool pcs_autoneg;
- s32 ret_val = E1000_SUCCESS;
- u16 data;
-
- DEBUGFUNC("e1000_setup_serdes_link_82575");
-
- if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
- !e1000_sgmii_active_82575(hw))
- return ret_val;
-
- /*
- * On the 82575, SerDes loopback mode persists until it is
- * explicitly turned off or a power cycle is performed. A read to
- * the register does not indicate its status. Therefore, we ensure
- * loopback mode is disabled during initialization.
- */
- E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
-
- /* power on the sfp cage if present */
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
-
- ctrl_reg = E1000_READ_REG(hw, E1000_CTRL);
- ctrl_reg |= E1000_CTRL_SLU;
-
- /* set both sw defined pins on 82575/82576*/
- if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576)
- ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1;
-
- reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
-
- /* default pcs_autoneg to the same setting as mac autoneg */
- pcs_autoneg = hw->mac.autoneg;
-
- switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
- case E1000_CTRL_EXT_LINK_MODE_SGMII:
- /* sgmii mode lets the phy handle forcing speed/duplex */
- pcs_autoneg = true;
- /* autoneg time out should be disabled for SGMII mode */
- reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
- break;
- case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
- /* disable PCS autoneg and support parallel detect only */
- pcs_autoneg = false;
- /* fall through to default case */
- default:
- if (hw->mac.type == e1000_82575 ||
- hw->mac.type == e1000_82576) {
- ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- if (data & E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT)
- pcs_autoneg = false;
- }
-
- /*
- * non-SGMII modes only supports a speed of 1000/Full for the
- * link so it is best to just force the MAC and let the pcs
- * link either autoneg or be forced to 1000/Full
- */
- ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
- E1000_CTRL_FD | E1000_CTRL_FRCDPX;
-
- /* set speed of 1000/Full if speed/duplex is forced */
- reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL;
- break;
- }
-
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg);
-
- /*
- * New SerDes mode allows for forcing speed or autonegotiating speed
- * at 1gb. Autoneg should be default set by most drivers. This is the
- * mode that will be compatible with older link partners and switches.
- * However, both are supported by the hardware and some drivers/tools.
- */
- reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
- E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
-
- if (pcs_autoneg) {
- /* Set PCS register for autoneg */
- reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
- E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
-
- /* Disable force flow control for autoneg */
- reg &= ~E1000_PCS_LCTL_FORCE_FCTRL;
-
- /* Configure flow control advertisement for autoneg */
- anadv_reg = E1000_READ_REG(hw, E1000_PCS_ANADV);
- anadv_reg &= ~(E1000_TXCW_ASM_DIR | E1000_TXCW_PAUSE);
-
- switch (hw->fc.requested_mode) {
- case e1000_fc_full:
- case e1000_fc_rx_pause:
- anadv_reg |= E1000_TXCW_ASM_DIR;
- anadv_reg |= E1000_TXCW_PAUSE;
- break;
- case e1000_fc_tx_pause:
- anadv_reg |= E1000_TXCW_ASM_DIR;
- break;
- default:
- break;
- }
-
- E1000_WRITE_REG(hw, E1000_PCS_ANADV, anadv_reg);
-
- DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg);
- } else {
- /* Set PCS register for forced link */
- reg |= E1000_PCS_LCTL_FSD; /* Force Speed */
-
- /* Force flow control for forced link */
- reg |= E1000_PCS_LCTL_FORCE_FCTRL;
-
- DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg);
- }
-
- E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
-
- if (!pcs_autoneg && !e1000_sgmii_active_82575(hw))
- e1000_force_mac_fc_generic(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_get_media_type_82575 - derives current media type.
- * @hw: pointer to the HW structure
- *
- * The media type is chosen reflecting few settings.
- * The following are taken into account:
- * - link mode set in the current port Init Control Word #3
- * - current link mode settings in CSR register
- * - MDIO vs. I2C PHY control interface chosen
- * - SFP module media type
- **/
-static s32 e1000_get_media_type_82575(struct e1000_hw *hw)
-{
- struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
- s32 ret_val = E1000_SUCCESS;
- u32 ctrl_ext = 0;
- u32 link_mode = 0;
-
- /* Set internal phy as default */
- dev_spec->sgmii_active = false;
- dev_spec->module_plugged = false;
-
- /* Get CSR setting */
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
-
- /* extract link mode setting */
- link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
-
- switch (link_mode) {
- case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
- hw->phy.media_type = e1000_media_type_internal_serdes;
- break;
- case E1000_CTRL_EXT_LINK_MODE_GMII:
- hw->phy.media_type = e1000_media_type_copper;
- break;
- case E1000_CTRL_EXT_LINK_MODE_SGMII:
- /* Get phy control interface type set (MDIO vs. I2C)*/
- if (e1000_sgmii_uses_mdio_82575(hw)) {
- hw->phy.media_type = e1000_media_type_copper;
- dev_spec->sgmii_active = true;
- break;
- }
- /* fall through for I2C based SGMII */
- case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
- /* read media type from SFP EEPROM */
- ret_val = e1000_set_sfp_media_type_82575(hw);
- if ((ret_val != E1000_SUCCESS) ||
- (hw->phy.media_type == e1000_media_type_unknown)) {
- /*
- * If media type was not identified then return media
- * type defined by the CTRL_EXT settings.
- */
- hw->phy.media_type = e1000_media_type_internal_serdes;
-
- if (link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII) {
- hw->phy.media_type = e1000_media_type_copper;
- dev_spec->sgmii_active = true;
- }
-
- break;
- }
-
- /* do not change link mode for 100BaseFX */
- if (dev_spec->eth_flags.e100_base_fx)
- break;
-
- /* change current link mode setting */
- ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
-
- if (hw->phy.media_type == e1000_media_type_copper)
- ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII;
- else
- ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
-
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
-
- break;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_set_sfp_media_type_82575 - derives SFP module media type.
- * @hw: pointer to the HW structure
- *
- * The media type is chosen based on SFP module.
- * compatibility flags retrieved from SFP ID EEPROM.
- **/
-static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_ERR_CONFIG;
- u32 ctrl_ext = 0;
- struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
- struct sfp_e1000_flags *eth_flags = &dev_spec->eth_flags;
- u8 tranceiver_type = 0;
- s32 timeout = 3;
-
- /* Turn I2C interface ON and power on sfp cage */
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA);
-
- E1000_WRITE_FLUSH(hw);
-
- /* Read SFP module data */
- while (timeout) {
- ret_val = e1000_read_sfp_data_byte(hw,
- E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET),
- &tranceiver_type);
- if (ret_val == E1000_SUCCESS)
- break;
- msec_delay(100);
- timeout--;
- }
- if (ret_val != E1000_SUCCESS)
- goto out;
-
- ret_val = e1000_read_sfp_data_byte(hw,
- E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET),
- (u8 *)eth_flags);
- if (ret_val != E1000_SUCCESS)
- goto out;
-
- /* Check if there is some SFP module plugged and powered */
- if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) ||
- (tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) {
- dev_spec->module_plugged = true;
- if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) {
- hw->phy.media_type = e1000_media_type_internal_serdes;
- } else if (eth_flags->e100_base_fx) {
- dev_spec->sgmii_active = true;
- hw->phy.media_type = e1000_media_type_internal_serdes;
- } else if (eth_flags->e1000_base_t) {
- dev_spec->sgmii_active = true;
- hw->phy.media_type = e1000_media_type_copper;
- } else {
- hw->phy.media_type = e1000_media_type_unknown;
- DEBUGOUT("PHY module has not been recognized\n");
- goto out;
- }
- } else {
- hw->phy.media_type = e1000_media_type_unknown;
- }
- ret_val = E1000_SUCCESS;
-out:
- /* Restore I2C interface setting */
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
- return ret_val;
-}
-
-/**
- * e1000_valid_led_default_82575 - Verify a valid default LED config
- * @hw: pointer to the HW structure
- * @data: pointer to the NVM (EEPROM)
- *
- * Read the EEPROM for the current default LED configuration. If the
- * LED configuration is not valid, set to a valid LED configuration.
- **/
-static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_valid_led_default_82575");
-
- ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- goto out;
- }
-
- if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
- switch (hw->phy.media_type) {
- case e1000_media_type_internal_serdes:
- *data = ID_LED_DEFAULT_82575_SERDES;
- break;
- case e1000_media_type_copper:
- default:
- *data = ID_LED_DEFAULT;
- break;
- }
- }
-out:
- return ret_val;
-}
-
-/**
- * e1000_sgmii_active_82575 - Return sgmii state
- * @hw: pointer to the HW structure
- *
- * 82575 silicon has a serialized gigabit media independent interface (sgmii)
- * which can be enabled for use in the embedded applications. Simply
- * return the current state of the sgmii interface.
- **/
-static bool e1000_sgmii_active_82575(struct e1000_hw *hw)
-{
- struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
- return dev_spec->sgmii_active;
-}
-
-/**
- * e1000_reset_init_script_82575 - Inits HW defaults after reset
- * @hw: pointer to the HW structure
- *
- * Inits recommended HW defaults after a reset when there is no EEPROM
- * detected. This is only for the 82575.
- **/
-static s32 e1000_reset_init_script_82575(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_reset_init_script_82575");
-
- if (hw->mac.type == e1000_82575) {
- DEBUGOUT("Running reset init script for 82575\n");
- /* SerDes configuration via SERDESCTRL */
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x00, 0x0C);
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x01, 0x78);
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x1B, 0x23);
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x23, 0x15);
-
- /* CCM configuration via CCMCTL register */
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x14, 0x00);
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x10, 0x00);
-
- /* PCIe lanes configuration */
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x00, 0xEC);
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x61, 0xDF);
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x34, 0x05);
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL, 0x2F, 0x81);
-
- /* PCIe PLL Configuration */
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x02, 0x47);
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x14, 0x00);
- e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x10, 0x00);
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_mac_addr_82575 - Read device MAC address
- * @hw: pointer to the HW structure
- **/
-static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_read_mac_addr_82575");
-
- /*
- * If there's an alternate MAC address place it in RAR0
- * so that it will override the Si installed default perm
- * address.
- */
- ret_val = e1000_check_alt_mac_addr_generic(hw);
- if (ret_val)
- goto out;
-
- ret_val = e1000_read_mac_addr_generic(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_config_collision_dist_82575 - Configure collision distance
- * @hw: pointer to the HW structure
- *
- * Configures the collision distance to the default value and is used
- * during link setup.
- **/
-static void e1000_config_collision_dist_82575(struct e1000_hw *hw)
-{
- u32 tctl_ext;
-
- DEBUGFUNC("e1000_config_collision_dist_82575");
-
- tctl_ext = E1000_READ_REG(hw, E1000_TCTL_EXT);
-
- tctl_ext &= ~E1000_TCTL_EXT_COLD;
- tctl_ext |= E1000_COLLISION_DISTANCE << E1000_TCTL_EXT_COLD_SHIFT;
-
- E1000_WRITE_REG(hw, E1000_TCTL_EXT, tctl_ext);
- E1000_WRITE_FLUSH(hw);
-}
-
-/**
- * e1000_power_down_phy_copper_82575 - Remove link during PHY power down
- * @hw: pointer to the HW structure
- *
- * In the case of a PHY power down to save power, or to turn off link during a
- * driver unload, or wake on lan is not enabled, remove the link.
- **/
-static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
-
- if (!(phy->ops.check_reset_block))
- return;
-
- /* If the management interface is not enabled, then power down */
- if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw)))
- e1000_power_down_phy_copper(hw);
-
- return;
-}
-
-/**
- * e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
- * @hw: pointer to the HW structure
- *
- * Clears the hardware counters by reading the counter registers.
- **/
-static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_clear_hw_cntrs_82575");
-
- e1000_clear_hw_cntrs_base_generic(hw);
-
- E1000_READ_REG(hw, E1000_PRC64);
- E1000_READ_REG(hw, E1000_PRC127);
- E1000_READ_REG(hw, E1000_PRC255);
- E1000_READ_REG(hw, E1000_PRC511);
- E1000_READ_REG(hw, E1000_PRC1023);
- E1000_READ_REG(hw, E1000_PRC1522);
- E1000_READ_REG(hw, E1000_PTC64);
- E1000_READ_REG(hw, E1000_PTC127);
- E1000_READ_REG(hw, E1000_PTC255);
- E1000_READ_REG(hw, E1000_PTC511);
- E1000_READ_REG(hw, E1000_PTC1023);
- E1000_READ_REG(hw, E1000_PTC1522);
-
- E1000_READ_REG(hw, E1000_ALGNERRC);
- E1000_READ_REG(hw, E1000_RXERRC);
- E1000_READ_REG(hw, E1000_TNCRS);
- E1000_READ_REG(hw, E1000_CEXTERR);
- E1000_READ_REG(hw, E1000_TSCTC);
- E1000_READ_REG(hw, E1000_TSCTFC);
-
- E1000_READ_REG(hw, E1000_MGTPRC);
- E1000_READ_REG(hw, E1000_MGTPDC);
- E1000_READ_REG(hw, E1000_MGTPTC);
-
- E1000_READ_REG(hw, E1000_IAC);
- E1000_READ_REG(hw, E1000_ICRXOC);
-
- E1000_READ_REG(hw, E1000_ICRXPTC);
- E1000_READ_REG(hw, E1000_ICRXATC);
- E1000_READ_REG(hw, E1000_ICTXPTC);
- E1000_READ_REG(hw, E1000_ICTXATC);
- E1000_READ_REG(hw, E1000_ICTXQEC);
- E1000_READ_REG(hw, E1000_ICTXQMTC);
- E1000_READ_REG(hw, E1000_ICRXDMTC);
-
- E1000_READ_REG(hw, E1000_CBTMPC);
- E1000_READ_REG(hw, E1000_HTDPMC);
- E1000_READ_REG(hw, E1000_CBRMPC);
- E1000_READ_REG(hw, E1000_RPTHC);
- E1000_READ_REG(hw, E1000_HGPTC);
- E1000_READ_REG(hw, E1000_HTCBDPC);
- E1000_READ_REG(hw, E1000_HGORCL);
- E1000_READ_REG(hw, E1000_HGORCH);
- E1000_READ_REG(hw, E1000_HGOTCL);
- E1000_READ_REG(hw, E1000_HGOTCH);
- E1000_READ_REG(hw, E1000_LENERRS);
-
- /* This register should not be read in copper configurations */
- if ((hw->phy.media_type == e1000_media_type_internal_serdes) ||
- e1000_sgmii_active_82575(hw))
- E1000_READ_REG(hw, E1000_SCVPC);
-}
-
-/**
- * e1000_rx_fifo_flush_82575 - Clean rx fifo after Rx enable
- * @hw: pointer to the HW structure
- *
- * After rx enable if managability is enabled then there is likely some
- * bad data at the start of the fifo and possibly in the DMA fifo. This
- * function clears the fifos and flushes any packets that came in as rx was
- * being enabled.
- **/
-void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
-{
- u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
- int i, ms_wait;
-
- DEBUGFUNC("e1000_rx_fifo_workaround_82575");
- if (hw->mac.type != e1000_82575 ||
- !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
- return;
-
- /* Disable all Rx queues */
- for (i = 0; i < 4; i++) {
- rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
- E1000_WRITE_REG(hw, E1000_RXDCTL(i),
- rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
- }
- /* Poll all queues to verify they have shut down */
- for (ms_wait = 0; ms_wait < 10; ms_wait++) {
- msec_delay(1);
- rx_enabled = 0;
- for (i = 0; i < 4; i++)
- rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i));
- if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
- break;
- }
-
- if (ms_wait == 10)
- DEBUGOUT("Queue disable timed out after 10ms\n");
-
- /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
- * incoming packets are rejected. Set enable and wait 2ms so that
- * any packet that was coming in as RCTL.EN was set is flushed
- */
- rfctl = E1000_READ_REG(hw, E1000_RFCTL);
- E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
-
- rlpml = E1000_READ_REG(hw, E1000_RLPML);
- E1000_WRITE_REG(hw, E1000_RLPML, 0);
-
- rctl = E1000_READ_REG(hw, E1000_RCTL);
- temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
- temp_rctl |= E1000_RCTL_LPE;
-
- E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl);
- E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN);
- E1000_WRITE_FLUSH(hw);
- msec_delay(2);
-
- /* Enable Rx queues that were previously enabled and restore our
- * previous state
- */
- for (i = 0; i < 4; i++)
- E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]);
- E1000_WRITE_REG(hw, E1000_RCTL, rctl);
- E1000_WRITE_FLUSH(hw);
-
- E1000_WRITE_REG(hw, E1000_RLPML, rlpml);
- E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
-
- /* Flush receive errors generated by workaround */
- E1000_READ_REG(hw, E1000_ROC);
- E1000_READ_REG(hw, E1000_RNBC);
- E1000_READ_REG(hw, E1000_MPC);
-}
-
-/**
- * e1000_set_pcie_completion_timeout - set pci-e completion timeout
- * @hw: pointer to the HW structure
- *
- * The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
- * however the hardware default for these parts is 500us to 1ms which is less
- * than the 10ms recommended by the pci-e spec. To address this we need to
- * increase the value to either 10ms to 200ms for capability version 1 config,
- * or 16ms to 55ms for version 2.
- **/
-static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw)
-{
- u32 gcr = E1000_READ_REG(hw, E1000_GCR);
- s32 ret_val = E1000_SUCCESS;
- u16 pcie_devctl2;
-
- /* only take action if timeout value is defaulted to 0 */
- if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
- goto out;
-
- /*
- * if capababilities version is type 1 we can write the
- * timeout of 10ms to 200ms through the GCR register
- */
- if (!(gcr & E1000_GCR_CAP_VER2)) {
- gcr |= E1000_GCR_CMPL_TMOUT_10ms;
- goto out;
- }
-
- /*
- * for version 2 capabilities we need to write the config space
- * directly in order to set the completion timeout value for
- * 16ms to 55ms
- */
- ret_val = e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
- &pcie_devctl2);
- if (ret_val)
- goto out;
-
- pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
-
- ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
- &pcie_devctl2);
-out:
- /* disable completion timeout resend */
- gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
-
- E1000_WRITE_REG(hw, E1000_GCR, gcr);
- return ret_val;
-}
-
-/**
- * e1000_vmdq_set_anti_spoofing_pf - enable or disable anti-spoofing
- * @hw: pointer to the hardware struct
- * @enable: state to enter, either enabled or disabled
- * @pf: Physical Function pool - do not set anti-spoofing for the PF
- *
- * enables/disables L2 switch anti-spoofing functionality.
- **/
-void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
-{
- u32 reg_val, reg_offset;
-
- switch (hw->mac.type) {
- case e1000_82576:
- reg_offset = E1000_DTXSWC;
- break;
- case e1000_i350:
- case e1000_i354:
- reg_offset = E1000_TXSWC;
- break;
- default:
- return;
- }
-
- reg_val = E1000_READ_REG(hw, reg_offset);
- if (enable) {
- reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK |
- E1000_DTXSWC_VLAN_SPOOF_MASK);
- /* The PF can spoof - it has to in order to
- * support emulation mode NICs
- */
- reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
- } else {
- reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
- E1000_DTXSWC_VLAN_SPOOF_MASK);
- }
- E1000_WRITE_REG(hw, reg_offset, reg_val);
-}
-
-/**
- * e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
- * @hw: pointer to the hardware struct
- * @enable: state to enter, either enabled or disabled
- *
- * enables/disables L2 switch loopback functionality.
- **/
-void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
-{
- u32 dtxswc;
-
- switch (hw->mac.type) {
- case e1000_82576:
- dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
- if (enable)
- dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
- else
- dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
- E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
- break;
- case e1000_i350:
- case e1000_i354:
- dtxswc = E1000_READ_REG(hw, E1000_TXSWC);
- if (enable)
- dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
- else
- dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
- E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc);
- break;
- default:
- /* Currently no other hardware supports loopback */
- break;
- }
-
-
-}
-
-/**
- * e1000_vmdq_set_replication_pf - enable or disable vmdq replication
- * @hw: pointer to the hardware struct
- * @enable: state to enter, either enabled or disabled
- *
- * enables/disables replication of packets across multiple pools.
- **/
-void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
-{
- u32 vt_ctl = E1000_READ_REG(hw, E1000_VT_CTL);
-
- if (enable)
- vt_ctl |= E1000_VT_CTL_VM_REPL_EN;
- else
- vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN;
-
- E1000_WRITE_REG(hw, E1000_VT_CTL, vt_ctl);
-}
-
-/**
- * e1000_read_phy_reg_82580 - Read 82580 MDI control register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Reads the MDI control register in the PHY at offset and stores the
- * information read to data.
- **/
-static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_read_phy_reg_82580");
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- goto out;
-
- ret_val = e1000_read_phy_reg_mdic(hw, offset, data);
-
- hw->phy.ops.release(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_write_phy_reg_82580 - Write 82580 MDI control register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write to register at offset
- *
- * Writes data to MDI control register in the PHY at offset.
- **/
-static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_write_phy_reg_82580");
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- goto out;
-
- ret_val = e1000_write_phy_reg_mdic(hw, offset, data);
-
- hw->phy.ops.release(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits
- * @hw: pointer to the HW structure
- *
- * This resets the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on
- * the values found in the EEPROM. This addresses an issue in which these
- * bits are not restored from EEPROM after reset.
- **/
-static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u32 mdicnfg;
- u16 nvm_data = 0;
-
- DEBUGFUNC("e1000_reset_mdicnfg_82580");
-
- if (hw->mac.type != e1000_82580)
- goto out;
- if (!e1000_sgmii_active_82575(hw))
- goto out;
-
- ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
- NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
- &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- goto out;
- }
-
- mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG);
- if (nvm_data & NVM_WORD24_EXT_MDIO)
- mdicnfg |= E1000_MDICNFG_EXT_MDIO;
- if (nvm_data & NVM_WORD24_COM_MDIO)
- mdicnfg |= E1000_MDICNFG_COM_MDIO;
- E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg);
-out:
- return ret_val;
-}
-
-/**
- * e1000_reset_hw_82580 - Reset hardware
- * @hw: pointer to the HW structure
- *
- * This resets function or entire device (all ports, etc.)
- * to a known state.
- **/
-static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- /* BH SW mailbox bit in SW_FW_SYNC */
- u16 swmbsw_mask = E1000_SW_SYNCH_MB;
- u32 ctrl;
- bool global_device_reset = hw->dev_spec._82575.global_device_reset;
-
- DEBUGFUNC("e1000_reset_hw_82580");
-
- hw->dev_spec._82575.global_device_reset = false;
-
- /* 82580 does not reliably do global_device_reset due to hw errata */
- if (hw->mac.type == e1000_82580)
- global_device_reset = false;
-
- /* Get current control state. */
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
-
- /*
- * Prevent the PCI-E bus from sticking if there is no TLP connection
- * on the last TLP read/write transaction when MAC is reset.
- */
- ret_val = e1000_disable_pcie_master_generic(hw);
- if (ret_val)
- DEBUGOUT("PCI-E Master disable polling has failed.\n");
-
- DEBUGOUT("Masking off all interrupts\n");
- E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
- E1000_WRITE_REG(hw, E1000_RCTL, 0);
- E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
- E1000_WRITE_FLUSH(hw);
-
- msec_delay(10);
-
- /* Determine whether or not a global dev reset is requested */
- if (global_device_reset && hw->mac.ops.acquire_swfw_sync(hw,
- swmbsw_mask))
- global_device_reset = false;
-
- if (global_device_reset && !(E1000_READ_REG(hw, E1000_STATUS) &
- E1000_STAT_DEV_RST_SET))
- ctrl |= E1000_CTRL_DEV_RST;
- else
- ctrl |= E1000_CTRL_RST;
-
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
-
- /* Add delay to insure DEV_RST has time to complete */
- if (global_device_reset)
- msec_delay(5);
-
- ret_val = e1000_get_auto_rd_done_generic(hw);
- if (ret_val) {
- /*
- * When auto config read does not complete, do not
- * return with an error. This can happen in situations
- * where there is no eeprom and prevents getting link.
- */
- DEBUGOUT("Auto Read Done did not complete\n");
- }
-
- /* clear global device reset status bit */
- E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET);
-
- /* Clear any pending interrupt events. */
- E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
- E1000_READ_REG(hw, E1000_ICR);
-
- ret_val = e1000_reset_mdicnfg_82580(hw);
- if (ret_val)
- DEBUGOUT("Could not reset MDICNFG based on EEPROM\n");
-
- /* Install any alternate MAC address into RAR0 */
- ret_val = e1000_check_alt_mac_addr_generic(hw);
-
- /* Release semaphore */
- if (global_device_reset)
- hw->mac.ops.release_swfw_sync(hw, swmbsw_mask);
-
- return ret_val;
-}
-
-/**
- * e1000_rxpbs_adjust_82580 - adjust RXPBS value to reflect actual Rx PBA size
- * @data: data received by reading RXPBS register
- *
- * The 82580 uses a table based approach for packet buffer allocation sizes.
- * This function converts the retrieved value into the correct table value
- * 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
- * 0x0 36 72 144 1 2 4 8 16
- * 0x8 35 70 140 rsv rsv rsv rsv rsv
- */
-u16 e1000_rxpbs_adjust_82580(u32 data)
-{
- u16 ret_val = 0;
-
- if (data < E1000_82580_RXPBS_TABLE_SIZE)
- ret_val = e1000_82580_rxpbs_table[data];
-
- return ret_val;
-}
-
-/**
- * e1000_validate_nvm_checksum_with_offset - Validate EEPROM
- * checksum
- * @hw: pointer to the HW structure
- * @offset: offset in words of the checksum protected region
- *
- * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
- * and then verifies that the sum of the EEPROM is equal to 0xBABA.
- **/
-s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
-{
- s32 ret_val = E1000_SUCCESS;
- u16 checksum = 0;
- u16 i, nvm_data;
-
- DEBUGFUNC("e1000_validate_nvm_checksum_with_offset");
-
- for (i = offset; i < ((NVM_CHECKSUM_REG + offset) + 1); i++) {
- ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- goto out;
- }
- checksum += nvm_data;
- }
-
- if (checksum != (u16) NVM_SUM) {
- DEBUGOUT("NVM Checksum Invalid\n");
- ret_val = -E1000_ERR_NVM;
- goto out;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_update_nvm_checksum_with_offset - Update EEPROM
- * checksum
- * @hw: pointer to the HW structure
- * @offset: offset in words of the checksum protected region
- *
- * Updates the EEPROM checksum by reading/adding each word of the EEPROM
- * up to the checksum. Then calculates the EEPROM checksum and writes the
- * value to the EEPROM.
- **/
-s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
-{
- s32 ret_val;
- u16 checksum = 0;
- u16 i, nvm_data;
-
- DEBUGFUNC("e1000_update_nvm_checksum_with_offset");
-
- for (i = offset; i < (NVM_CHECKSUM_REG + offset); i++) {
- ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error while updating checksum.\n");
- goto out;
- }
- checksum += nvm_data;
- }
- checksum = (u16) NVM_SUM - checksum;
- ret_val = hw->nvm.ops.write(hw, (NVM_CHECKSUM_REG + offset), 1,
- &checksum);
- if (ret_val)
- DEBUGOUT("NVM Write Error while updating checksum.\n");
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_validate_nvm_checksum_82580 - Validate EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Calculates the EEPROM section checksum by reading/adding each word of
- * the EEPROM and then verifies that the sum of the EEPROM is
- * equal to 0xBABA.
- **/
-static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u16 eeprom_regions_count = 1;
- u16 j, nvm_data;
- u16 nvm_offset;
-
- DEBUGFUNC("e1000_validate_nvm_checksum_82580");
-
- ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- goto out;
- }
-
- if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) {
- /* if chekcsums compatibility bit is set validate checksums
- * for all 4 ports. */
- eeprom_regions_count = 4;
- }
-
- for (j = 0; j < eeprom_regions_count; j++) {
- nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
- ret_val = e1000_validate_nvm_checksum_with_offset(hw,
- nvm_offset);
- if (ret_val != E1000_SUCCESS)
- goto out;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_update_nvm_checksum_82580 - Update EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Updates the EEPROM section checksums for all 4 ports by reading/adding
- * each word of the EEPROM up to the checksum. Then calculates the EEPROM
- * checksum and writes the value to the EEPROM.
- **/
-static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 j, nvm_data;
- u16 nvm_offset;
-
- DEBUGFUNC("e1000_update_nvm_checksum_82580");
-
- ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error while updating checksum compatibility bit.\n");
- goto out;
- }
-
- if (!(nvm_data & NVM_COMPATIBILITY_BIT_MASK)) {
- /* set compatibility bit to validate checksums appropriately */
- nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK;
- ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1,
- &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Write Error while updating checksum compatibility bit.\n");
- goto out;
- }
- }
-
- for (j = 0; j < 4; j++) {
- nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
- ret_val = e1000_update_nvm_checksum_with_offset(hw, nvm_offset);
- if (ret_val)
- goto out;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_validate_nvm_checksum_i350 - Validate EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Calculates the EEPROM section checksum by reading/adding each word of
- * the EEPROM and then verifies that the sum of the EEPROM is
- * equal to 0xBABA.
- **/
-static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u16 j;
- u16 nvm_offset;
-
- DEBUGFUNC("e1000_validate_nvm_checksum_i350");
-
- for (j = 0; j < 4; j++) {
- nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
- ret_val = e1000_validate_nvm_checksum_with_offset(hw,
- nvm_offset);
- if (ret_val != E1000_SUCCESS)
- goto out;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_update_nvm_checksum_i350 - Update EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Updates the EEPROM section checksums for all 4 ports by reading/adding
- * each word of the EEPROM up to the checksum. Then calculates the EEPROM
- * checksum and writes the value to the EEPROM.
- **/
-static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u16 j;
- u16 nvm_offset;
-
- DEBUGFUNC("e1000_update_nvm_checksum_i350");
-
- for (j = 0; j < 4; j++) {
- nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j);
- ret_val = e1000_update_nvm_checksum_with_offset(hw, nvm_offset);
- if (ret_val != E1000_SUCCESS)
- goto out;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * __e1000_access_emi_reg - Read/write EMI register
- * @hw: pointer to the HW structure
- * @addr: EMI address to program
- * @data: pointer to value to read/write from/to the EMI address
- * @read: boolean flag to indicate read or write
- **/
-static s32 __e1000_access_emi_reg(struct e1000_hw *hw, u16 address,
- u16 *data, bool read)
-{
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("__e1000_access_emi_reg");
-
- ret_val = hw->phy.ops.write_reg(hw, E1000_EMIADD, address);
- if (ret_val)
- return ret_val;
-
- if (read)
- ret_val = hw->phy.ops.read_reg(hw, E1000_EMIDATA, data);
- else
- ret_val = hw->phy.ops.write_reg(hw, E1000_EMIDATA, *data);
-
- return ret_val;
-}
-
-/**
- * e1000_read_emi_reg - Read Extended Management Interface register
- * @hw: pointer to the HW structure
- * @addr: EMI address to program
- * @data: value to be read from the EMI address
- **/
-s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
-{
- DEBUGFUNC("e1000_read_emi_reg");
-
- return __e1000_access_emi_reg(hw, addr, data, true);
-}
-
-/**
- * e1000_set_eee_i350 - Enable/disable EEE support
- * @hw: pointer to the HW structure
- *
- * Enable/disable EEE based on setting in dev_spec structure.
- *
- **/
-s32 e1000_set_eee_i350(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u32 ipcnfg, eeer;
-
- DEBUGFUNC("e1000_set_eee_i350");
-
- if ((hw->mac.type < e1000_i350) ||
- (hw->phy.media_type != e1000_media_type_copper))
- goto out;
- ipcnfg = E1000_READ_REG(hw, E1000_IPCNFG);
- eeer = E1000_READ_REG(hw, E1000_EEER);
-
- /* enable or disable per user setting */
- if (!(hw->dev_spec._82575.eee_disable)) {
- u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU);
-
- ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
- eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
- E1000_EEER_LPI_FC);
-
- /* This bit should not be set in normal operation. */
- if (eee_su & E1000_EEE_SU_LPI_CLK_STP)
- DEBUGOUT("LPI Clock Stop Bit should not be set!\n");
- } else {
- ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
- eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
- E1000_EEER_LPI_FC);
- }
- E1000_WRITE_REG(hw, E1000_IPCNFG, ipcnfg);
- E1000_WRITE_REG(hw, E1000_EEER, eeer);
- E1000_READ_REG(hw, E1000_IPCNFG);
- E1000_READ_REG(hw, E1000_EEER);
-out:
-
- return ret_val;
-}
-
-/**
- * e1000_set_eee_i354 - Enable/disable EEE support
- * @hw: pointer to the HW structure
- *
- * Enable/disable EEE legacy mode based on setting in dev_spec structure.
- *
- **/
-s32 e1000_set_eee_i354(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
- u16 phy_data;
-
- DEBUGFUNC("e1000_set_eee_i354");
-
- if ((hw->phy.media_type != e1000_media_type_copper) ||
- ((phy->id != M88E1543_E_PHY_ID)))
- goto out;
-
- if (!hw->dev_spec._82575.eee_disable) {
- /* Switch to PHY page 18. */
- ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 18);
- if (ret_val)
- goto out;
-
- ret_val = phy->ops.read_reg(hw, E1000_M88E1543_EEE_CTRL_1,
- &phy_data);
- if (ret_val)
- goto out;
-
- phy_data |= E1000_M88E1543_EEE_CTRL_1_MS;
- ret_val = phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1,
- phy_data);
- if (ret_val)
- goto out;
-
- /* Return the PHY to page 0. */
- ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
- if (ret_val)
- goto out;
-
- /* Turn on EEE advertisement. */
- ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
- E1000_EEE_ADV_DEV_I354,
- &phy_data);
- if (ret_val)
- goto out;
-
- phy_data |= E1000_EEE_ADV_100_SUPPORTED |
- E1000_EEE_ADV_1000_SUPPORTED;
- ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
- E1000_EEE_ADV_DEV_I354,
- phy_data);
- } else {
- /* Turn off EEE advertisement. */
- ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
- E1000_EEE_ADV_DEV_I354,
- &phy_data);
- if (ret_val)
- goto out;
-
- phy_data &= ~(E1000_EEE_ADV_100_SUPPORTED |
- E1000_EEE_ADV_1000_SUPPORTED);
- ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
- E1000_EEE_ADV_DEV_I354,
- phy_data);
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_get_eee_status_i354 - Get EEE status
- * @hw: pointer to the HW structure
- * @status: EEE status
- *
- * Get EEE status by guessing based on whether Tx or Rx LPI indications have
- * been received.
- **/
-s32 e1000_get_eee_status_i354(struct e1000_hw *hw, bool *status)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
- u16 phy_data;
-
- DEBUGFUNC("e1000_get_eee_status_i354");
-
- /* Check if EEE is supported on this device. */
- if ((hw->phy.media_type != e1000_media_type_copper) ||
- ((phy->id != M88E1543_E_PHY_ID)))
- goto out;
-
- ret_val = e1000_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,
- E1000_PCS_STATUS_DEV_I354,
- &phy_data);
- if (ret_val)
- goto out;
-
- *status = phy_data & (E1000_PCS_STATUS_TX_LPI_RCVD |
- E1000_PCS_STATUS_RX_LPI_RCVD) ? true : false;
-
-out:
- return ret_val;
-}
-
-/* Due to a hw errata, if the host tries to configure the VFTA register
- * while performing queries from the BMC or DMA, then the VFTA in some
- * cases won't be written.
- */
-
-/**
- * e1000_clear_vfta_i350 - Clear VLAN filter table
- * @hw: pointer to the HW structure
- *
- * Clears the register array which contains the VLAN filter table by
- * setting all the values to 0.
- **/
-void e1000_clear_vfta_i350(struct e1000_hw *hw)
-{
- u32 offset;
- int i;
-
- DEBUGFUNC("e1000_clear_vfta_350");
-
- for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
- for (i = 0; i < 10; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
-
- E1000_WRITE_FLUSH(hw);
- }
-}
-
-/**
- * e1000_write_vfta_i350 - Write value to VLAN filter table
- * @hw: pointer to the HW structure
- * @offset: register offset in VLAN filter table
- * @value: register value written to VLAN filter table
- *
- * Writes value at the given offset in the register array which stores
- * the VLAN filter table.
- **/
-void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
-{
- int i;
-
- DEBUGFUNC("e1000_write_vfta_350");
-
- for (i = 0; i < 10; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
-
- E1000_WRITE_FLUSH(hw);
-}
-
-
-/**
- * e1000_set_i2c_bb - Enable I2C bit-bang
- * @hw: pointer to the HW structure
- *
- * Enable I2C bit-bang interface
- *
- **/
-s32 e1000_set_i2c_bb(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u32 ctrl_ext, i2cparams;
-
- DEBUGFUNC("e1000_set_i2c_bb");
-
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- ctrl_ext |= E1000_CTRL_I2C_ENA;
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH(hw);
-
- i2cparams = E1000_READ_REG(hw, E1000_I2CPARAMS);
- i2cparams |= E1000_I2CBB_EN;
- i2cparams |= E1000_I2C_DATA_OE_N;
- i2cparams |= E1000_I2C_CLK_OE_N;
- E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cparams);
- E1000_WRITE_FLUSH(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_read_i2c_byte_generic - Reads 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to read
- * @dev_addr: device address
- * @data: value read
- *
- * Performs byte read operation over I2C interface at
- * a specified device address.
- **/
-s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data)
-{
- s32 status = E1000_SUCCESS;
- u32 max_retry = 10;
- u32 retry = 1;
- u16 swfw_mask = 0;
-
- bool nack = true;
-
- DEBUGFUNC("e1000_read_i2c_byte_generic");
-
- swfw_mask = E1000_SWFW_PHY0_SM;
-
- do {
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)
- != E1000_SUCCESS) {
- status = E1000_ERR_SWFW_SYNC;
- goto read_byte_out;
- }
-
- e1000_i2c_start(hw);
-
- /* Device Address and write indication */
- status = e1000_clock_out_i2c_byte(hw, dev_addr);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_get_i2c_ack(hw);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_clock_out_i2c_byte(hw, byte_offset);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_get_i2c_ack(hw);
- if (status != E1000_SUCCESS)
- goto fail;
-
- e1000_i2c_start(hw);
-
- /* Device Address and read indication */
- status = e1000_clock_out_i2c_byte(hw, (dev_addr | 0x1));
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_get_i2c_ack(hw);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_clock_in_i2c_byte(hw, data);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_clock_out_i2c_bit(hw, nack);
- if (status != E1000_SUCCESS)
- goto fail;
-
- e1000_i2c_stop(hw);
- break;
-
-fail:
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
- msec_delay(100);
- e1000_i2c_bus_clear(hw);
- retry++;
- if (retry < max_retry)
- DEBUGOUT("I2C byte read error - Retrying.\n");
- else
- DEBUGOUT("I2C byte read error.\n");
-
- } while (retry < max_retry);
-
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-
-read_byte_out:
-
- return status;
-}
-
-/**
- * e1000_write_i2c_byte_generic - Writes 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to write
- * @dev_addr: device address
- * @data: value to write
- *
- * Performs byte write operation over I2C interface at
- * a specified device address.
- **/
-s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data)
-{
- s32 status = E1000_SUCCESS;
- u32 max_retry = 1;
- u32 retry = 0;
- u16 swfw_mask = 0;
-
- DEBUGFUNC("e1000_write_i2c_byte_generic");
-
- swfw_mask = E1000_SWFW_PHY0_SM;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) {
- status = E1000_ERR_SWFW_SYNC;
- goto write_byte_out;
- }
-
- do {
- e1000_i2c_start(hw);
-
- status = e1000_clock_out_i2c_byte(hw, dev_addr);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_get_i2c_ack(hw);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_clock_out_i2c_byte(hw, byte_offset);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_get_i2c_ack(hw);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_clock_out_i2c_byte(hw, data);
- if (status != E1000_SUCCESS)
- goto fail;
-
- status = e1000_get_i2c_ack(hw);
- if (status != E1000_SUCCESS)
- goto fail;
-
- e1000_i2c_stop(hw);
- break;
-
-fail:
- e1000_i2c_bus_clear(hw);
- retry++;
- if (retry < max_retry)
- DEBUGOUT("I2C byte write error - Retrying.\n");
- else
- DEBUGOUT("I2C byte write error.\n");
- } while (retry < max_retry);
-
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-
-write_byte_out:
-
- return status;
-}
-
-/**
- * e1000_i2c_start - Sets I2C start condition
- * @hw: pointer to hardware structure
- *
- * Sets I2C start condition (High -> Low on SDA while SCL is High)
- **/
-static void e1000_i2c_start(struct e1000_hw *hw)
-{
- u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
-
- DEBUGFUNC("e1000_i2c_start");
-
- /* Start condition must begin with data and clock high */
- e1000_set_i2c_data(hw, &i2cctl, 1);
- e1000_raise_i2c_clk(hw, &i2cctl);
-
- /* Setup time for start condition (4.7us) */
- usec_delay(E1000_I2C_T_SU_STA);
-
- e1000_set_i2c_data(hw, &i2cctl, 0);
-
- /* Hold time for start condition (4us) */
- usec_delay(E1000_I2C_T_HD_STA);
-
- e1000_lower_i2c_clk(hw, &i2cctl);
-
- /* Minimum low period of clock is 4.7 us */
- usec_delay(E1000_I2C_T_LOW);
-
-}
-
-/**
- * e1000_i2c_stop - Sets I2C stop condition
- * @hw: pointer to hardware structure
- *
- * Sets I2C stop condition (Low -> High on SDA while SCL is High)
- **/
-static void e1000_i2c_stop(struct e1000_hw *hw)
-{
- u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
-
- DEBUGFUNC("e1000_i2c_stop");
-
- /* Stop condition must begin with data low and clock high */
- e1000_set_i2c_data(hw, &i2cctl, 0);
- e1000_raise_i2c_clk(hw, &i2cctl);
-
- /* Setup time for stop condition (4us) */
- usec_delay(E1000_I2C_T_SU_STO);
-
- e1000_set_i2c_data(hw, &i2cctl, 1);
-
- /* bus free time between stop and start (4.7us)*/
- usec_delay(E1000_I2C_T_BUF);
-}
-
-/**
- * e1000_clock_in_i2c_byte - Clocks in one byte via I2C
- * @hw: pointer to hardware structure
- * @data: data byte to clock in
- *
- * Clocks in one byte data via I2C data/clock
- **/
-static s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data)
-{
- s32 i;
- bool bit = 0;
-
- DEBUGFUNC("e1000_clock_in_i2c_byte");
-
- *data = 0;
- for (i = 7; i >= 0; i--) {
- e1000_clock_in_i2c_bit(hw, &bit);
- *data |= bit << i;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_clock_out_i2c_byte - Clocks out one byte via I2C
- * @hw: pointer to hardware structure
- * @data: data byte clocked out
- *
- * Clocks out one byte data via I2C data/clock
- **/
-static s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data)
-{
- s32 status = E1000_SUCCESS;
- s32 i;
- u32 i2cctl;
- bool bit = 0;
-
- DEBUGFUNC("e1000_clock_out_i2c_byte");
-
- for (i = 7; i >= 0; i--) {
- bit = (data >> i) & 0x1;
- status = e1000_clock_out_i2c_bit(hw, bit);
-
- if (status != E1000_SUCCESS)
- break;
- }
-
- /* Release SDA line (set high) */
- i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
-
- i2cctl |= E1000_I2C_DATA_OE_N;
- E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cctl);
- E1000_WRITE_FLUSH(hw);
-
- return status;
-}
-
-/**
- * e1000_get_i2c_ack - Polls for I2C ACK
- * @hw: pointer to hardware structure
- *
- * Clocks in/out one bit via I2C data/clock
- **/
-static s32 e1000_get_i2c_ack(struct e1000_hw *hw)
-{
- s32 status = E1000_SUCCESS;
- u32 i = 0;
- u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
- u32 timeout = 10;
- bool ack = true;
-
- DEBUGFUNC("e1000_get_i2c_ack");
-
- e1000_raise_i2c_clk(hw, &i2cctl);
-
- /* Minimum high period of clock is 4us */
- usec_delay(E1000_I2C_T_HIGH);
-
- /* Wait until SCL returns high */
- for (i = 0; i < timeout; i++) {
- usec_delay(1);
- i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
- if (i2cctl & E1000_I2C_CLK_IN)
- break;
- }
- if (!(i2cctl & E1000_I2C_CLK_IN))
- return E1000_ERR_I2C;
-
- ack = e1000_get_i2c_data(&i2cctl);
- if (ack) {
- DEBUGOUT("I2C ack was not received.\n");
- status = E1000_ERR_I2C;
- }
-
- e1000_lower_i2c_clk(hw, &i2cctl);
-
- /* Minimum low period of clock is 4.7 us */
- usec_delay(E1000_I2C_T_LOW);
-
- return status;
-}
-
-/**
- * e1000_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
- * @hw: pointer to hardware structure
- * @data: read data value
- *
- * Clocks in one bit via I2C data/clock
- **/
-static s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data)
-{
- u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
-
- DEBUGFUNC("e1000_clock_in_i2c_bit");
-
- e1000_raise_i2c_clk(hw, &i2cctl);
-
- /* Minimum high period of clock is 4us */
- usec_delay(E1000_I2C_T_HIGH);
-
- i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
- *data = e1000_get_i2c_data(&i2cctl);
-
- e1000_lower_i2c_clk(hw, &i2cctl);
-
- /* Minimum low period of clock is 4.7 us */
- usec_delay(E1000_I2C_T_LOW);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
- * @hw: pointer to hardware structure
- * @data: data value to write
- *
- * Clocks out one bit via I2C data/clock
- **/
-static s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data)
-{
- s32 status;
- u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
-
- DEBUGFUNC("e1000_clock_out_i2c_bit");
-
- status = e1000_set_i2c_data(hw, &i2cctl, data);
- if (status == E1000_SUCCESS) {
- e1000_raise_i2c_clk(hw, &i2cctl);
-
- /* Minimum high period of clock is 4us */
- usec_delay(E1000_I2C_T_HIGH);
-
- e1000_lower_i2c_clk(hw, &i2cctl);
-
- /* Minimum low period of clock is 4.7 us.
- * This also takes care of the data hold time.
- */
- usec_delay(E1000_I2C_T_LOW);
- } else {
- status = E1000_ERR_I2C;
- DEBUGOUT1("I2C data was not set to %X\n", data);
- }
-
- return status;
-}
-/**
- * e1000_raise_i2c_clk - Raises the I2C SCL clock
- * @hw: pointer to hardware structure
- * @i2cctl: Current value of I2CCTL register
- *
- * Raises the I2C clock line '0'->'1'
- **/
-static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl)
-{
- DEBUGFUNC("e1000_raise_i2c_clk");
-
- *i2cctl |= E1000_I2C_CLK_OUT;
- *i2cctl &= ~E1000_I2C_CLK_OE_N;
- E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
- E1000_WRITE_FLUSH(hw);
-
- /* SCL rise time (1000ns) */
- usec_delay(E1000_I2C_T_RISE);
-}
-
-/**
- * e1000_lower_i2c_clk - Lowers the I2C SCL clock
- * @hw: pointer to hardware structure
- * @i2cctl: Current value of I2CCTL register
- *
- * Lowers the I2C clock line '1'->'0'
- **/
-static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl)
-{
-
- DEBUGFUNC("e1000_lower_i2c_clk");
-
- *i2cctl &= ~E1000_I2C_CLK_OUT;
- *i2cctl &= ~E1000_I2C_CLK_OE_N;
- E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
- E1000_WRITE_FLUSH(hw);
-
- /* SCL fall time (300ns) */
- usec_delay(E1000_I2C_T_FALL);
-}
-
-/**
- * e1000_set_i2c_data - Sets the I2C data bit
- * @hw: pointer to hardware structure
- * @i2cctl: Current value of I2CCTL register
- * @data: I2C data value (0 or 1) to set
- *
- * Sets the I2C data bit
- **/
-static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data)
-{
- s32 status = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_set_i2c_data");
-
- if (data)
- *i2cctl |= E1000_I2C_DATA_OUT;
- else
- *i2cctl &= ~E1000_I2C_DATA_OUT;
-
- *i2cctl &= ~E1000_I2C_DATA_OE_N;
- *i2cctl |= E1000_I2C_CLK_OE_N;
- E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl);
- E1000_WRITE_FLUSH(hw);
-
- /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
- usec_delay(E1000_I2C_T_RISE + E1000_I2C_T_FALL + E1000_I2C_T_SU_DATA);
-
- *i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
- if (data != e1000_get_i2c_data(i2cctl)) {
- status = E1000_ERR_I2C;
- DEBUGOUT1("Error - I2C data was not set to %X.\n", data);
- }
-
- return status;
-}
-
-/**
- * e1000_get_i2c_data - Reads the I2C SDA data bit
- * @hw: pointer to hardware structure
- * @i2cctl: Current value of I2CCTL register
- *
- * Returns the I2C data bit value
- **/
-static bool e1000_get_i2c_data(u32 *i2cctl)
-{
- bool data;
-
- DEBUGFUNC("e1000_get_i2c_data");
-
- if (*i2cctl & E1000_I2C_DATA_IN)
- data = 1;
- else
- data = 0;
-
- return data;
-}
-
-/**
- * e1000_i2c_bus_clear - Clears the I2C bus
- * @hw: pointer to hardware structure
- *
- * Clears the I2C bus by sending nine clock pulses.
- * Used when data line is stuck low.
- **/
-void e1000_i2c_bus_clear(struct e1000_hw *hw)
-{
- u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
- u32 i;
-
- DEBUGFUNC("e1000_i2c_bus_clear");
-
- e1000_i2c_start(hw);
-
- e1000_set_i2c_data(hw, &i2cctl, 1);
-
- for (i = 0; i < 9; i++) {
- e1000_raise_i2c_clk(hw, &i2cctl);
-
- /* Min high period of clock is 4us */
- usec_delay(E1000_I2C_T_HIGH);
-
- e1000_lower_i2c_clk(hw, &i2cctl);
-
- /* Min low period of clock is 4.7us*/
- usec_delay(E1000_I2C_T_LOW);
- }
-
- e1000_i2c_start(hw);
-
- /* Put the i2c bus back to default state */
- e1000_i2c_stop(hw);
-}
-
-static const u8 e1000_emc_temp_data[4] = {
- E1000_EMC_INTERNAL_DATA,
- E1000_EMC_DIODE1_DATA,
- E1000_EMC_DIODE2_DATA,
- E1000_EMC_DIODE3_DATA
-};
-static const u8 e1000_emc_therm_limit[4] = {
- E1000_EMC_INTERNAL_THERM_LIMIT,
- E1000_EMC_DIODE1_THERM_LIMIT,
- E1000_EMC_DIODE2_THERM_LIMIT,
- E1000_EMC_DIODE3_THERM_LIMIT
-};
-
-/**
- * e1000_get_thermal_sensor_data_generic - Gathers thermal sensor data
- * @hw: pointer to hardware structure
- *
- * Updates the temperatures in mac.thermal_sensor_data
- **/
-s32 e1000_get_thermal_sensor_data_generic(struct e1000_hw *hw)
-{
- s32 status = E1000_SUCCESS;
- u16 ets_offset;
- u16 ets_cfg;
- u16 ets_sensor;
- u8 num_sensors;
- u8 sensor_index;
- u8 sensor_location;
- u8 i;
- struct e1000_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
-
- DEBUGFUNC("e1000_get_thermal_sensor_data_generic");
-
- if ((hw->mac.type != e1000_i350) || (hw->bus.func != 0))
- return E1000_NOT_IMPLEMENTED;
-
- data->sensor[0].temp = (E1000_READ_REG(hw, E1000_THMJT) & 0xFF);
-
- /* Return the internal sensor only if ETS is unsupported */
- e1000_read_nvm(hw, NVM_ETS_CFG, 1, &ets_offset);
- if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF))
- return status;
-
- e1000_read_nvm(hw, ets_offset, 1, &ets_cfg);
- if (((ets_cfg & NVM_ETS_TYPE_MASK) >> NVM_ETS_TYPE_SHIFT)
- != NVM_ETS_TYPE_EMC)
- return E1000_NOT_IMPLEMENTED;
-
- num_sensors = (ets_cfg & NVM_ETS_NUM_SENSORS_MASK);
- if (num_sensors > E1000_MAX_SENSORS)
- num_sensors = E1000_MAX_SENSORS;
-
- for (i = 1; i < num_sensors; i++) {
- e1000_read_nvm(hw, (ets_offset + i), 1, &ets_sensor);
- sensor_index = ((ets_sensor & NVM_ETS_DATA_INDEX_MASK) >>
- NVM_ETS_DATA_INDEX_SHIFT);
- sensor_location = ((ets_sensor & NVM_ETS_DATA_LOC_MASK) >>
- NVM_ETS_DATA_LOC_SHIFT);
-
- if (sensor_location != 0)
- hw->phy.ops.read_i2c_byte(hw,
- e1000_emc_temp_data[sensor_index],
- E1000_I2C_THERMAL_SENSOR_ADDR,
- &data->sensor[i].temp);
- }
- return status;
-}
-
-/**
- * e1000_init_thermal_sensor_thresh_generic - Sets thermal sensor thresholds
- * @hw: pointer to hardware structure
- *
- * Sets the thermal sensor thresholds according to the NVM map
- * and save off the threshold and location values into mac.thermal_sensor_data
- **/
-s32 e1000_init_thermal_sensor_thresh_generic(struct e1000_hw *hw)
-{
- s32 status = E1000_SUCCESS;
- u16 ets_offset;
- u16 ets_cfg;
- u16 ets_sensor;
- u8 low_thresh_delta;
- u8 num_sensors;
- u8 sensor_index;
- u8 sensor_location;
- u8 therm_limit;
- u8 i;
- struct e1000_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
-
- DEBUGFUNC("e1000_init_thermal_sensor_thresh_generic");
-
- if ((hw->mac.type != e1000_i350) || (hw->bus.func != 0))
- return E1000_NOT_IMPLEMENTED;
-
- memset(data, 0, sizeof(struct e1000_thermal_sensor_data));
-
- data->sensor[0].location = 0x1;
- data->sensor[0].caution_thresh =
- (E1000_READ_REG(hw, E1000_THHIGHTC) & 0xFF);
- data->sensor[0].max_op_thresh =
- (E1000_READ_REG(hw, E1000_THLOWTC) & 0xFF);
-
- /* Return the internal sensor only if ETS is unsupported */
- e1000_read_nvm(hw, NVM_ETS_CFG, 1, &ets_offset);
- if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF))
- return status;
-
- e1000_read_nvm(hw, ets_offset, 1, &ets_cfg);
- if (((ets_cfg & NVM_ETS_TYPE_MASK) >> NVM_ETS_TYPE_SHIFT)
- != NVM_ETS_TYPE_EMC)
- return E1000_NOT_IMPLEMENTED;
-
- low_thresh_delta = ((ets_cfg & NVM_ETS_LTHRES_DELTA_MASK) >>
- NVM_ETS_LTHRES_DELTA_SHIFT);
- num_sensors = (ets_cfg & NVM_ETS_NUM_SENSORS_MASK);
-
- for (i = 1; i <= num_sensors; i++) {
- e1000_read_nvm(hw, (ets_offset + i), 1, &ets_sensor);
- sensor_index = ((ets_sensor & NVM_ETS_DATA_INDEX_MASK) >>
- NVM_ETS_DATA_INDEX_SHIFT);
- sensor_location = ((ets_sensor & NVM_ETS_DATA_LOC_MASK) >>
- NVM_ETS_DATA_LOC_SHIFT);
- therm_limit = ets_sensor & NVM_ETS_DATA_HTHRESH_MASK;
-
- hw->phy.ops.write_i2c_byte(hw,
- e1000_emc_therm_limit[sensor_index],
- E1000_I2C_THERMAL_SENSOR_ADDR,
- therm_limit);
-
- if ((i < E1000_MAX_SENSORS) && (sensor_location != 0)) {
- data->sensor[i].location = sensor_location;
- data->sensor[i].caution_thresh = therm_limit;
- data->sensor[i].max_op_thresh = therm_limit -
- low_thresh_delta;
- }
- }
- return status;
-}
diff --git a/kernel/linux/kni/ethtool/igb/e1000_82575.h b/kernel/linux/kni/ethtool/igb/e1000_82575.h
deleted file mode 100644
index 2e0dbb2fb..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_82575.h
+++ /dev/null
@@ -1,494 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_82575_H_
-#define _E1000_82575_H_
-
-#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
- (ID_LED_DEF1_DEF2 << 8) | \
- (ID_LED_DEF1_DEF2 << 4) | \
- (ID_LED_OFF1_ON2))
-/*
- * Receive Address Register Count
- * Number of high/low register pairs in the RAR. The RAR (Receive Address
- * Registers) holds the directed and multicast addresses that we monitor.
- * These entries are also used for MAC-based filtering.
- */
-/*
- * For 82576, there are an additional set of RARs that begin at an offset
- * separate from the first set of RARs.
- */
-#define E1000_RAR_ENTRIES_82575 16
-#define E1000_RAR_ENTRIES_82576 24
-#define E1000_RAR_ENTRIES_82580 24
-#define E1000_RAR_ENTRIES_I350 32
-#define E1000_SW_SYNCH_MB 0x00000100
-#define E1000_STAT_DEV_RST_SET 0x00100000
-#define E1000_CTRL_DEV_RST 0x20000000
-
-struct e1000_adv_data_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- union {
- u32 data;
- struct {
- u32 datalen:16; /* Data buffer length */
- u32 rsvd:4;
- u32 dtyp:4; /* Descriptor type */
- u32 dcmd:8; /* Descriptor command */
- } config;
- } lower;
- union {
- u32 data;
- struct {
- u32 status:4; /* Descriptor status */
- u32 idx:4;
- u32 popts:6; /* Packet Options */
- u32 paylen:18; /* Payload length */
- } options;
- } upper;
-};
-
-#define E1000_TXD_DTYP_ADV_C 0x2 /* Advanced Context Descriptor */
-#define E1000_TXD_DTYP_ADV_D 0x3 /* Advanced Data Descriptor */
-#define E1000_ADV_TXD_CMD_DEXT 0x20 /* Descriptor extension (0 = legacy) */
-#define E1000_ADV_TUCMD_IPV4 0x2 /* IP Packet Type: 1=IPv4 */
-#define E1000_ADV_TUCMD_IPV6 0x0 /* IP Packet Type: 0=IPv6 */
-#define E1000_ADV_TUCMD_L4T_UDP 0x0 /* L4 Packet TYPE of UDP */
-#define E1000_ADV_TUCMD_L4T_TCP 0x4 /* L4 Packet TYPE of TCP */
-#define E1000_ADV_TUCMD_MKRREQ 0x10 /* Indicates markers are required */
-#define E1000_ADV_DCMD_EOP 0x1 /* End of Packet */
-#define E1000_ADV_DCMD_IFCS 0x2 /* Insert FCS (Ethernet CRC) */
-#define E1000_ADV_DCMD_RS 0x8 /* Report Status */
-#define E1000_ADV_DCMD_VLE 0x40 /* Add VLAN tag */
-#define E1000_ADV_DCMD_TSE 0x80 /* TCP Seg enable */
-/* Extended Device Control */
-#define E1000_CTRL_EXT_NSICR 0x00000001 /* Disable Intr Clear all on read */
-
-struct e1000_adv_context_desc {
- union {
- u32 ip_config;
- struct {
- u32 iplen:9;
- u32 maclen:7;
- u32 vlan_tag:16;
- } fields;
- } ip_setup;
- u32 seq_num;
- union {
- u64 l4_config;
- struct {
- u32 mkrloc:9;
- u32 tucmd:11;
- u32 dtyp:4;
- u32 adv:8;
- u32 rsvd:4;
- u32 idx:4;
- u32 l4len:8;
- u32 mss:16;
- } fields;
- } l4_setup;
-};
-
-/* SRRCTL bit definitions */
-#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
-#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00
-#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
-#define E1000_SRRCTL_DESCTYPE_LEGACY 0x00000000
-#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
-#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000
-#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
-#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000
-#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
-#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000
-#define E1000_SRRCTL_TIMESTAMP 0x40000000
-#define E1000_SRRCTL_DROP_EN 0x80000000
-
-#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F
-#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00
-
-#define E1000_TX_HEAD_WB_ENABLE 0x1
-#define E1000_TX_SEQNUM_WB_ENABLE 0x2
-
-#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002
-#define E1000_MRQC_ENABLE_VMDQ 0x00000003
-#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005
-#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
-#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
-#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
-#define E1000_MRQC_ENABLE_RSS_8Q 0x00000002
-
-#define E1000_VMRCTL_MIRROR_PORT_SHIFT 8
-#define E1000_VMRCTL_MIRROR_DSTPORT_MASK (7 << \
- E1000_VMRCTL_MIRROR_PORT_SHIFT)
-#define E1000_VMRCTL_POOL_MIRROR_ENABLE (1 << 0)
-#define E1000_VMRCTL_UPLINK_MIRROR_ENABLE (1 << 1)
-#define E1000_VMRCTL_DOWNLINK_MIRROR_ENABLE (1 << 2)
-
-#define E1000_EICR_TX_QUEUE ( \
- E1000_EICR_TX_QUEUE0 | \
- E1000_EICR_TX_QUEUE1 | \
- E1000_EICR_TX_QUEUE2 | \
- E1000_EICR_TX_QUEUE3)
-
-#define E1000_EICR_RX_QUEUE ( \
- E1000_EICR_RX_QUEUE0 | \
- E1000_EICR_RX_QUEUE1 | \
- E1000_EICR_RX_QUEUE2 | \
- E1000_EICR_RX_QUEUE3)
-
-#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE
-#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE
-
-#define EIMS_ENABLE_MASK ( \
- E1000_EIMS_RX_QUEUE | \
- E1000_EIMS_TX_QUEUE | \
- E1000_EIMS_TCP_TIMER | \
- E1000_EIMS_OTHER)
-
-/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
-#define E1000_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */
-#define E1000_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */
-#define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
-#define E1000_IMIREXT_CTRL_URG 0x00002000 /* Check URG bit in header */
-#define E1000_IMIREXT_CTRL_ACK 0x00004000 /* Check ACK bit in header */
-#define E1000_IMIREXT_CTRL_PSH 0x00008000 /* Check PSH bit in header */
-#define E1000_IMIREXT_CTRL_RST 0x00010000 /* Check RST bit in header */
-#define E1000_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */
-#define E1000_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */
-#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of ctrl bits */
-
-/* Receive Descriptor - Advanced */
-union e1000_adv_rx_desc {
- struct {
- __le64 pkt_addr; /* Packet buffer address */
- __le64 hdr_addr; /* Header buffer address */
- } read;
- struct {
- struct {
- union {
- __le32 data;
- struct {
- __le16 pkt_info; /*RSS type, Pkt type*/
- /* Split Header, header buffer len */
- __le16 hdr_info;
- } hs_rss;
- } lo_dword;
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length; /* Packet length */
- __le16 vlan; /* VLAN tag */
- } upper;
- } wb; /* writeback */
-};
-
-#define E1000_RXDADV_RSSTYPE_MASK 0x0000000F
-#define E1000_RXDADV_RSSTYPE_SHIFT 12
-#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
-#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
-#define E1000_RXDADV_SPLITHEADER_EN 0x00001000
-#define E1000_RXDADV_SPH 0x8000
-#define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */
-#define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */
-#define E1000_RXDADV_ERR_HBO 0x00800000
-
-/* RSS Hash results */
-#define E1000_RXDADV_RSSTYPE_NONE 0x00000000
-#define E1000_RXDADV_RSSTYPE_IPV4_TCP 0x00000001
-#define E1000_RXDADV_RSSTYPE_IPV4 0x00000002
-#define E1000_RXDADV_RSSTYPE_IPV6_TCP 0x00000003
-#define E1000_RXDADV_RSSTYPE_IPV6_EX 0x00000004
-#define E1000_RXDADV_RSSTYPE_IPV6 0x00000005
-#define E1000_RXDADV_RSSTYPE_IPV6_TCP_EX 0x00000006
-#define E1000_RXDADV_RSSTYPE_IPV4_UDP 0x00000007
-#define E1000_RXDADV_RSSTYPE_IPV6_UDP 0x00000008
-#define E1000_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009
-
-/* RSS Packet Types as indicated in the receive descriptor */
-#define E1000_RXDADV_PKTTYPE_NONE 0x00000000
-#define E1000_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPV4 hdr present */
-#define E1000_RXDADV_PKTTYPE_IPV4_EX 0x00000020 /* IPV4 hdr + extensions */
-#define E1000_RXDADV_PKTTYPE_IPV6 0x00000040 /* IPV6 hdr present */
-#define E1000_RXDADV_PKTTYPE_IPV6_EX 0x00000080 /* IPV6 hdr + extensions */
-#define E1000_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */
-#define E1000_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */
-#define E1000_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */
-#define E1000_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */
-
-#define E1000_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */
-#define E1000_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */
-#define E1000_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */
-#define E1000_RXDADV_PKTTYPE_ETQF 0x00008000 /* PKTTYPE is ETQF index */
-#define E1000_RXDADV_PKTTYPE_ETQF_MASK 0x00000070 /* ETQF has 8 indices */
-#define E1000_RXDADV_PKTTYPE_ETQF_SHIFT 4 /* Right-shift 4 bits */
-
-/* LinkSec results */
-/* Security Processing bit Indication */
-#define E1000_RXDADV_LNKSEC_STATUS_SECP 0x00020000
-#define E1000_RXDADV_LNKSEC_ERROR_BIT_MASK 0x18000000
-#define E1000_RXDADV_LNKSEC_ERROR_NO_SA_MATCH 0x08000000
-#define E1000_RXDADV_LNKSEC_ERROR_REPLAY_ERROR 0x10000000
-#define E1000_RXDADV_LNKSEC_ERROR_BAD_SIG 0x18000000
-
-#define E1000_RXDADV_IPSEC_STATUS_SECP 0x00020000
-#define E1000_RXDADV_IPSEC_ERROR_BIT_MASK 0x18000000
-#define E1000_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL 0x08000000
-#define E1000_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000
-#define E1000_RXDADV_IPSEC_ERROR_AUTHENTICATION_FAILED 0x18000000
-
-/* Transmit Descriptor - Advanced */
-union e1000_adv_tx_desc {
- struct {
- __le64 buffer_addr; /* Address of descriptor's data buf */
- __le32 cmd_type_len;
- __le32 olinfo_status;
- } read;
- struct {
- __le64 rsvd; /* Reserved */
- __le32 nxtseq_seed;
- __le32 status;
- } wb;
-};
-
-/* Adv Transmit Descriptor Config Masks */
-#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
-#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
-#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
-#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
-#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
-#define E1000_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
-#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
-#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
-#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
-#define E1000_ADVTXD_MAC_LINKSEC 0x00040000 /* Apply LinkSec on pkt */
-#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp pkt */
-#define E1000_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED prsnt in WB */
-#define E1000_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
-#define E1000_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
-#define E1000_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
-#define E1000_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
-/* 1st & Last TSO-full iSCSI PDU*/
-#define E1000_ADVTXD_POPTS_ISCO_FULL 0x00001800
-#define E1000_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */
-#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
-
-/* Context descriptors */
-struct e1000_adv_tx_context_desc {
- __le32 vlan_macip_lens;
- __le32 seqnum_seed;
- __le32 type_tucmd_mlhl;
- __le32 mss_l4len_idx;
-};
-
-#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
-#define E1000_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
-#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
-#define E1000_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
-#define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
-#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
-#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */
-#define E1000_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
-/* IPSec Encrypt Enable for ESP */
-#define E1000_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000
-/* Req requires Markers and CRC */
-#define E1000_ADVTXD_TUCMD_MKRREQ 0x00002000
-#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
-#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
-/* Adv ctxt IPSec SA IDX mask */
-#define E1000_ADVTXD_IPSEC_SA_INDEX_MASK 0x000000FF
-/* Adv ctxt IPSec ESP len mask */
-#define E1000_ADVTXD_IPSEC_ESP_LEN_MASK 0x000000FF
-
-/* Additional Transmit Descriptor Control definitions */
-#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
-#define E1000_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. wbk flushing */
-/* Tx Queue Arbitration Priority 0=low, 1=high */
-#define E1000_TXDCTL_PRIORITY 0x08000000
-
-/* Additional Receive Descriptor Control definitions */
-#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
-#define E1000_RXDCTL_SWFLSH 0x04000000 /* Rx Desc. wbk flushing */
-
-/* Direct Cache Access (DCA) definitions */
-#define E1000_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */
-#define E1000_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */
-
-#define E1000_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */
-#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
-
-#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
-#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
-#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header ena */
-#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload ena */
-#define E1000_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx Desc Relax Order */
-
-#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
-#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
-#define E1000_DCA_TXCTRL_DESC_RRO_EN (1 << 9) /* Tx rd Desc Relax Order */
-#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
-#define E1000_DCA_TXCTRL_DATA_RRO_EN (1 << 13) /* Tx rd data Relax Order */
-
-#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
-#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
-#define E1000_DCA_TXCTRL_CPUID_SHIFT_82576 24 /* Tx CPUID */
-#define E1000_DCA_RXCTRL_CPUID_SHIFT_82576 24 /* Rx CPUID */
-
-/* Additional interrupt register bit definitions */
-#define E1000_ICR_LSECPNS 0x00000020 /* PN threshold - server */
-#define E1000_IMS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */
-#define E1000_ICS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */
-
-/* ETQF register bit definitions */
-#define E1000_ETQF_FILTER_ENABLE (1 << 26)
-#define E1000_ETQF_IMM_INT (1 << 29)
-#define E1000_ETQF_1588 (1 << 30)
-#define E1000_ETQF_QUEUE_ENABLE (1 << 31)
-/*
- * ETQF filter list: one static filter per filter consumer. This is
- * to avoid filter collisions later. Add new filters
- * here!!
- *
- * Current filters:
- * EAPOL 802.1x (0x888e): Filter 0
- */
-#define E1000_ETQF_FILTER_EAPOL 0
-
-#define E1000_FTQF_VF_BP 0x00008000
-#define E1000_FTQF_1588_TIME_STAMP 0x08000000
-#define E1000_FTQF_MASK 0xF0000000
-#define E1000_FTQF_MASK_PROTO_BP 0x10000000
-#define E1000_FTQF_MASK_SOURCE_ADDR_BP 0x20000000
-#define E1000_FTQF_MASK_DEST_ADDR_BP 0x40000000
-#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000
-
-#define E1000_NVM_APME_82575 0x0400
-#define MAX_NUM_VFS 7
-
-#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof cntrl */
-#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof cntrl */
-#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
-#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8
-#define E1000_DTXSWC_LLE_SHIFT 16
-#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */
-
-/* Easy defines for setting default pool, would normally be left a zero */
-#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
-#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT)
-
-/* Other useful VMD_CTL register defines */
-#define E1000_VT_CTL_IGNORE_MAC (1 << 28)
-#define E1000_VT_CTL_DISABLE_DEF_POOL (1 << 29)
-#define E1000_VT_CTL_VM_REPL_EN (1 << 30)
-
-/* Per VM Offload register setup */
-#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */
-#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */
-#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */
-#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */
-#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */
-#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */
-#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */
-#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */
-#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
-#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */
-
-#define E1000_VMOLR_VPE 0x00800000 /* VLAN promiscuous enable */
-#define E1000_VMOLR_UPE 0x20000000 /* Unicast promisuous enable */
-#define E1000_DVMOLR_HIDVLAN 0x20000000 /* Vlan hiding enable */
-#define E1000_DVMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
-#define E1000_DVMOLR_STRCRC 0x80000000 /* CRC stripping enable */
-
-#define E1000_PBRWAC_WALPB 0x00000007 /* Wrap around event on LAN Rx PB */
-#define E1000_PBRWAC_PBE 0x00000008 /* Rx packet buffer empty */
-
-#define E1000_VLVF_ARRAY_SIZE 32
-#define E1000_VLVF_VLANID_MASK 0x00000FFF
-#define E1000_VLVF_POOLSEL_SHIFT 12
-#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT)
-#define E1000_VLVF_LVLAN 0x00100000
-#define E1000_VLVF_VLANID_ENABLE 0x80000000
-
-#define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */
-#define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */
-
-#define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */
-
-#define E1000_IOVCTL 0x05BBC
-#define E1000_IOVCTL_REUSE_VFQ 0x00000001
-
-#define E1000_RPLOLR_STRVLAN 0x40000000
-#define E1000_RPLOLR_STRCRC 0x80000000
-
-#define E1000_TCTL_EXT_COLD 0x000FFC00
-#define E1000_TCTL_EXT_COLD_SHIFT 10
-
-#define E1000_DTXCTL_8023LL 0x0004
-#define E1000_DTXCTL_VLAN_ADDED 0x0008
-#define E1000_DTXCTL_OOS_ENABLE 0x0010
-#define E1000_DTXCTL_MDP_EN 0x0020
-#define E1000_DTXCTL_SPOOF_INT 0x0040
-
-#define E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT (1 << 14)
-
-#define ALL_QUEUES 0xFFFF
-
-/* Rx packet buffer size defines */
-#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
-void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable);
-void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf);
-void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
-s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
-
-u16 e1000_rxpbs_adjust_82580(u32 data);
-s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data);
-s32 e1000_set_eee_i350(struct e1000_hw *);
-s32 e1000_set_eee_i354(struct e1000_hw *);
-s32 e1000_get_eee_status_i354(struct e1000_hw *, bool *);
-#define E1000_I2C_THERMAL_SENSOR_ADDR 0xF8
-#define E1000_EMC_INTERNAL_DATA 0x00
-#define E1000_EMC_INTERNAL_THERM_LIMIT 0x20
-#define E1000_EMC_DIODE1_DATA 0x01
-#define E1000_EMC_DIODE1_THERM_LIMIT 0x19
-#define E1000_EMC_DIODE2_DATA 0x23
-#define E1000_EMC_DIODE2_THERM_LIMIT 0x1A
-#define E1000_EMC_DIODE3_DATA 0x2A
-#define E1000_EMC_DIODE3_THERM_LIMIT 0x30
-
-s32 e1000_get_thermal_sensor_data_generic(struct e1000_hw *hw);
-s32 e1000_init_thermal_sensor_thresh_generic(struct e1000_hw *hw);
-
-/* I2C SDA and SCL timing parameters for standard mode */
-#define E1000_I2C_T_HD_STA 4
-#define E1000_I2C_T_LOW 5
-#define E1000_I2C_T_HIGH 4
-#define E1000_I2C_T_SU_STA 5
-#define E1000_I2C_T_HD_DATA 5
-#define E1000_I2C_T_SU_DATA 1
-#define E1000_I2C_T_RISE 1
-#define E1000_I2C_T_FALL 1
-#define E1000_I2C_T_SU_STO 4
-#define E1000_I2C_T_BUF 5
-
-s32 e1000_set_i2c_bb(struct e1000_hw *hw);
-s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data);
-s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data);
-void e1000_i2c_bus_clear(struct e1000_hw *hw);
-#endif /* _E1000_82575_H_ */
diff --git a/kernel/linux/kni/ethtool/igb/e1000_api.c b/kernel/linux/kni/ethtool/igb/e1000_api.c
deleted file mode 100644
index 3e54e50ed..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_api.c
+++ /dev/null
@@ -1,1144 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "e1000_api.h"
-
-/**
- * e1000_init_mac_params - Initialize MAC function pointers
- * @hw: pointer to the HW structure
- *
- * This function initializes the function pointers for the MAC
- * set of functions. Called by drivers or by e1000_setup_init_funcs.
- **/
-s32 e1000_init_mac_params(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
-
- if (hw->mac.ops.init_params) {
- ret_val = hw->mac.ops.init_params(hw);
- if (ret_val) {
- DEBUGOUT("MAC Initialization Error\n");
- goto out;
- }
- } else {
- DEBUGOUT("mac.init_mac_params was NULL\n");
- ret_val = -E1000_ERR_CONFIG;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_init_nvm_params - Initialize NVM function pointers
- * @hw: pointer to the HW structure
- *
- * This function initializes the function pointers for the NVM
- * set of functions. Called by drivers or by e1000_setup_init_funcs.
- **/
-s32 e1000_init_nvm_params(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
-
- if (hw->nvm.ops.init_params) {
- ret_val = hw->nvm.ops.init_params(hw);
- if (ret_val) {
- DEBUGOUT("NVM Initialization Error\n");
- goto out;
- }
- } else {
- DEBUGOUT("nvm.init_nvm_params was NULL\n");
- ret_val = -E1000_ERR_CONFIG;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_init_phy_params - Initialize PHY function pointers
- * @hw: pointer to the HW structure
- *
- * This function initializes the function pointers for the PHY
- * set of functions. Called by drivers or by e1000_setup_init_funcs.
- **/
-s32 e1000_init_phy_params(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
-
- if (hw->phy.ops.init_params) {
- ret_val = hw->phy.ops.init_params(hw);
- if (ret_val) {
- DEBUGOUT("PHY Initialization Error\n");
- goto out;
- }
- } else {
- DEBUGOUT("phy.init_phy_params was NULL\n");
- ret_val = -E1000_ERR_CONFIG;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_init_mbx_params - Initialize mailbox function pointers
- * @hw: pointer to the HW structure
- *
- * This function initializes the function pointers for the PHY
- * set of functions. Called by drivers or by e1000_setup_init_funcs.
- **/
-s32 e1000_init_mbx_params(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
-
- if (hw->mbx.ops.init_params) {
- ret_val = hw->mbx.ops.init_params(hw);
- if (ret_val) {
- DEBUGOUT("Mailbox Initialization Error\n");
- goto out;
- }
- } else {
- DEBUGOUT("mbx.init_mbx_params was NULL\n");
- ret_val = -E1000_ERR_CONFIG;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_set_mac_type - Sets MAC type
- * @hw: pointer to the HW structure
- *
- * This function sets the mac type of the adapter based on the
- * device ID stored in the hw structure.
- * MUST BE FIRST FUNCTION CALLED (explicitly or through
- * e1000_setup_init_funcs()).
- **/
-s32 e1000_set_mac_type(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_set_mac_type");
-
- switch (hw->device_id) {
- case E1000_DEV_ID_82575EB_COPPER:
- case E1000_DEV_ID_82575EB_FIBER_SERDES:
- case E1000_DEV_ID_82575GB_QUAD_COPPER:
- mac->type = e1000_82575;
- break;
- case E1000_DEV_ID_82576:
- case E1000_DEV_ID_82576_FIBER:
- case E1000_DEV_ID_82576_SERDES:
- case E1000_DEV_ID_82576_QUAD_COPPER:
- case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
- case E1000_DEV_ID_82576_NS:
- case E1000_DEV_ID_82576_NS_SERDES:
- case E1000_DEV_ID_82576_SERDES_QUAD:
- mac->type = e1000_82576;
- break;
- case E1000_DEV_ID_82580_COPPER:
- case E1000_DEV_ID_82580_FIBER:
- case E1000_DEV_ID_82580_SERDES:
- case E1000_DEV_ID_82580_SGMII:
- case E1000_DEV_ID_82580_COPPER_DUAL:
- case E1000_DEV_ID_82580_QUAD_FIBER:
- case E1000_DEV_ID_DH89XXCC_SGMII:
- case E1000_DEV_ID_DH89XXCC_SERDES:
- case E1000_DEV_ID_DH89XXCC_BACKPLANE:
- case E1000_DEV_ID_DH89XXCC_SFP:
- mac->type = e1000_82580;
- break;
- case E1000_DEV_ID_I350_COPPER:
- case E1000_DEV_ID_I350_FIBER:
- case E1000_DEV_ID_I350_SERDES:
- case E1000_DEV_ID_I350_SGMII:
- case E1000_DEV_ID_I350_DA4:
- mac->type = e1000_i350;
- break;
- case E1000_DEV_ID_I210_COPPER_FLASHLESS:
- case E1000_DEV_ID_I210_SERDES_FLASHLESS:
- case E1000_DEV_ID_I210_COPPER:
- case E1000_DEV_ID_I210_COPPER_OEM1:
- case E1000_DEV_ID_I210_COPPER_IT:
- case E1000_DEV_ID_I210_FIBER:
- case E1000_DEV_ID_I210_SERDES:
- case E1000_DEV_ID_I210_SGMII:
- mac->type = e1000_i210;
- break;
- case E1000_DEV_ID_I211_COPPER:
- mac->type = e1000_i211;
- break;
-
- case E1000_DEV_ID_I354_BACKPLANE_1GBPS:
- case E1000_DEV_ID_I354_SGMII:
- case E1000_DEV_ID_I354_BACKPLANE_2_5GBPS:
- mac->type = e1000_i354;
- break;
- default:
- /* Should never have loaded on this device */
- ret_val = -E1000_ERR_MAC_INIT;
- break;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_setup_init_funcs - Initializes function pointers
- * @hw: pointer to the HW structure
- * @init_device: true will initialize the rest of the function pointers
- * getting the device ready for use. false will only set
- * MAC type and the function pointers for the other init
- * functions. Passing false will not generate any hardware
- * reads or writes.
- *
- * This function must be called by a driver in order to use the rest
- * of the 'shared' code files. Called by drivers only.
- **/
-s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
-{
- s32 ret_val;
-
- /* Can't do much good without knowing the MAC type. */
- ret_val = e1000_set_mac_type(hw);
- if (ret_val) {
- DEBUGOUT("ERROR: MAC type could not be set properly.\n");
- goto out;
- }
-
- if (!hw->hw_addr) {
- DEBUGOUT("ERROR: Registers not mapped\n");
- ret_val = -E1000_ERR_CONFIG;
- goto out;
- }
-
- /*
- * Init function pointers to generic implementations. We do this first
- * allowing a driver module to override it afterward.
- */
- e1000_init_mac_ops_generic(hw);
- e1000_init_phy_ops_generic(hw);
- e1000_init_nvm_ops_generic(hw);
- e1000_init_mbx_ops_generic(hw);
-
- /*
- * Set up the init function pointers. These are functions within the
- * adapter family file that sets up function pointers for the rest of
- * the functions in that family.
- */
- switch (hw->mac.type) {
- case e1000_82575:
- case e1000_82576:
- case e1000_82580:
- case e1000_i350:
- case e1000_i354:
- e1000_init_function_pointers_82575(hw);
- break;
- case e1000_i210:
- case e1000_i211:
- e1000_init_function_pointers_i210(hw);
- break;
- default:
- DEBUGOUT("Hardware not supported\n");
- ret_val = -E1000_ERR_CONFIG;
- break;
- }
-
- /*
- * Initialize the rest of the function pointers. These require some
- * register reads/writes in some cases.
- */
- if (!(ret_val) && init_device) {
- ret_val = e1000_init_mac_params(hw);
- if (ret_val)
- goto out;
-
- ret_val = e1000_init_nvm_params(hw);
- if (ret_val)
- goto out;
-
- ret_val = e1000_init_phy_params(hw);
- if (ret_val)
- goto out;
-
- ret_val = e1000_init_mbx_params(hw);
- if (ret_val)
- goto out;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_get_bus_info - Obtain bus information for adapter
- * @hw: pointer to the HW structure
- *
- * This will obtain information about the HW bus for which the
- * adapter is attached and stores it in the hw structure. This is a
- * function pointer entry point called by drivers.
- **/
-s32 e1000_get_bus_info(struct e1000_hw *hw)
-{
- if (hw->mac.ops.get_bus_info)
- return hw->mac.ops.get_bus_info(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_clear_vfta - Clear VLAN filter table
- * @hw: pointer to the HW structure
- *
- * This clears the VLAN filter table on the adapter. This is a function
- * pointer entry point called by drivers.
- **/
-void e1000_clear_vfta(struct e1000_hw *hw)
-{
- if (hw->mac.ops.clear_vfta)
- hw->mac.ops.clear_vfta(hw);
-}
-
-/**
- * e1000_write_vfta - Write value to VLAN filter table
- * @hw: pointer to the HW structure
- * @offset: the 32-bit offset in which to write the value to.
- * @value: the 32-bit value to write at location offset.
- *
- * This writes a 32-bit value to a 32-bit offset in the VLAN filter
- * table. This is a function pointer entry point called by drivers.
- **/
-void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
-{
- if (hw->mac.ops.write_vfta)
- hw->mac.ops.write_vfta(hw, offset, value);
-}
-
-/**
- * e1000_update_mc_addr_list - Update Multicast addresses
- * @hw: pointer to the HW structure
- * @mc_addr_list: array of multicast addresses to program
- * @mc_addr_count: number of multicast addresses to program
- *
- * Updates the Multicast Table Array.
- * The caller must have a packed mc_addr_list of multicast addresses.
- **/
-void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count)
-{
- if (hw->mac.ops.update_mc_addr_list)
- hw->mac.ops.update_mc_addr_list(hw, mc_addr_list,
- mc_addr_count);
-}
-
-/**
- * e1000_force_mac_fc - Force MAC flow control
- * @hw: pointer to the HW structure
- *
- * Force the MAC's flow control settings. Currently no func pointer exists
- * and all implementations are handled in the generic version of this
- * function.
- **/
-s32 e1000_force_mac_fc(struct e1000_hw *hw)
-{
- return e1000_force_mac_fc_generic(hw);
-}
-
-/**
- * e1000_check_for_link - Check/Store link connection
- * @hw: pointer to the HW structure
- *
- * This checks the link condition of the adapter and stores the
- * results in the hw->mac structure. This is a function pointer entry
- * point called by drivers.
- **/
-s32 e1000_check_for_link(struct e1000_hw *hw)
-{
- if (hw->mac.ops.check_for_link)
- return hw->mac.ops.check_for_link(hw);
-
- return -E1000_ERR_CONFIG;
-}
-
-/**
- * e1000_check_mng_mode - Check management mode
- * @hw: pointer to the HW structure
- *
- * This checks if the adapter has manageability enabled.
- * This is a function pointer entry point called by drivers.
- **/
-bool e1000_check_mng_mode(struct e1000_hw *hw)
-{
- if (hw->mac.ops.check_mng_mode)
- return hw->mac.ops.check_mng_mode(hw);
-
- return false;
-}
-
-/**
- * e1000_mng_write_dhcp_info - Writes DHCP info to host interface
- * @hw: pointer to the HW structure
- * @buffer: pointer to the host interface
- * @length: size of the buffer
- *
- * Writes the DHCP information to the host interface.
- **/
-s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
-{
- return e1000_mng_write_dhcp_info_generic(hw, buffer, length);
-}
-
-/**
- * e1000_reset_hw - Reset hardware
- * @hw: pointer to the HW structure
- *
- * This resets the hardware into a known state. This is a function pointer
- * entry point called by drivers.
- **/
-s32 e1000_reset_hw(struct e1000_hw *hw)
-{
- if (hw->mac.ops.reset_hw)
- return hw->mac.ops.reset_hw(hw);
-
- return -E1000_ERR_CONFIG;
-}
-
-/**
- * e1000_init_hw - Initialize hardware
- * @hw: pointer to the HW structure
- *
- * This inits the hardware readying it for operation. This is a function
- * pointer entry point called by drivers.
- **/
-s32 e1000_init_hw(struct e1000_hw *hw)
-{
- if (hw->mac.ops.init_hw)
- return hw->mac.ops.init_hw(hw);
-
- return -E1000_ERR_CONFIG;
-}
-
-/**
- * e1000_setup_link - Configures link and flow control
- * @hw: pointer to the HW structure
- *
- * This configures link and flow control settings for the adapter. This
- * is a function pointer entry point called by drivers. While modules can
- * also call this, they probably call their own version of this function.
- **/
-s32 e1000_setup_link(struct e1000_hw *hw)
-{
- if (hw->mac.ops.setup_link)
- return hw->mac.ops.setup_link(hw);
-
- return -E1000_ERR_CONFIG;
-}
-
-/**
- * e1000_get_speed_and_duplex - Returns current speed and duplex
- * @hw: pointer to the HW structure
- * @speed: pointer to a 16-bit value to store the speed
- * @duplex: pointer to a 16-bit value to store the duplex.
- *
- * This returns the speed and duplex of the adapter in the two 'out'
- * variables passed in. This is a function pointer entry point called
- * by drivers.
- **/
-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
-{
- if (hw->mac.ops.get_link_up_info)
- return hw->mac.ops.get_link_up_info(hw, speed, duplex);
-
- return -E1000_ERR_CONFIG;
-}
-
-/**
- * e1000_setup_led - Configures SW controllable LED
- * @hw: pointer to the HW structure
- *
- * This prepares the SW controllable LED for use and saves the current state
- * of the LED so it can be later restored. This is a function pointer entry
- * point called by drivers.
- **/
-s32 e1000_setup_led(struct e1000_hw *hw)
-{
- if (hw->mac.ops.setup_led)
- return hw->mac.ops.setup_led(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_cleanup_led - Restores SW controllable LED
- * @hw: pointer to the HW structure
- *
- * This restores the SW controllable LED to the value saved off by
- * e1000_setup_led. This is a function pointer entry point called by drivers.
- **/
-s32 e1000_cleanup_led(struct e1000_hw *hw)
-{
- if (hw->mac.ops.cleanup_led)
- return hw->mac.ops.cleanup_led(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_blink_led - Blink SW controllable LED
- * @hw: pointer to the HW structure
- *
- * This starts the adapter LED blinking. Request the LED to be setup first
- * and cleaned up after. This is a function pointer entry point called by
- * drivers.
- **/
-s32 e1000_blink_led(struct e1000_hw *hw)
-{
- if (hw->mac.ops.blink_led)
- return hw->mac.ops.blink_led(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_id_led_init - store LED configurations in SW
- * @hw: pointer to the HW structure
- *
- * Initializes the LED config in SW. This is a function pointer entry point
- * called by drivers.
- **/
-s32 e1000_id_led_init(struct e1000_hw *hw)
-{
- if (hw->mac.ops.id_led_init)
- return hw->mac.ops.id_led_init(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_led_on - Turn on SW controllable LED
- * @hw: pointer to the HW structure
- *
- * Turns the SW defined LED on. This is a function pointer entry point
- * called by drivers.
- **/
-s32 e1000_led_on(struct e1000_hw *hw)
-{
- if (hw->mac.ops.led_on)
- return hw->mac.ops.led_on(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_led_off - Turn off SW controllable LED
- * @hw: pointer to the HW structure
- *
- * Turns the SW defined LED off. This is a function pointer entry point
- * called by drivers.
- **/
-s32 e1000_led_off(struct e1000_hw *hw)
-{
- if (hw->mac.ops.led_off)
- return hw->mac.ops.led_off(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_reset_adaptive - Reset adaptive IFS
- * @hw: pointer to the HW structure
- *
- * Resets the adaptive IFS. Currently no func pointer exists and all
- * implementations are handled in the generic version of this function.
- **/
-void e1000_reset_adaptive(struct e1000_hw *hw)
-{
- e1000_reset_adaptive_generic(hw);
-}
-
-/**
- * e1000_update_adaptive - Update adaptive IFS
- * @hw: pointer to the HW structure
- *
- * Updates adapter IFS. Currently no func pointer exists and all
- * implementations are handled in the generic version of this function.
- **/
-void e1000_update_adaptive(struct e1000_hw *hw)
-{
- e1000_update_adaptive_generic(hw);
-}
-
-/**
- * e1000_disable_pcie_master - Disable PCI-Express master access
- * @hw: pointer to the HW structure
- *
- * Disables PCI-Express master access and verifies there are no pending
- * requests. Currently no func pointer exists and all implementations are
- * handled in the generic version of this function.
- **/
-s32 e1000_disable_pcie_master(struct e1000_hw *hw)
-{
- return e1000_disable_pcie_master_generic(hw);
-}
-
-/**
- * e1000_config_collision_dist - Configure collision distance
- * @hw: pointer to the HW structure
- *
- * Configures the collision distance to the default value and is used
- * during link setup.
- **/
-void e1000_config_collision_dist(struct e1000_hw *hw)
-{
- if (hw->mac.ops.config_collision_dist)
- hw->mac.ops.config_collision_dist(hw);
-}
-
-/**
- * e1000_rar_set - Sets a receive address register
- * @hw: pointer to the HW structure
- * @addr: address to set the RAR to
- * @index: the RAR to set
- *
- * Sets a Receive Address Register (RAR) to the specified address.
- **/
-void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
-{
- if (hw->mac.ops.rar_set)
- hw->mac.ops.rar_set(hw, addr, index);
-}
-
-/**
- * e1000_validate_mdi_setting - Ensures valid MDI/MDIX SW state
- * @hw: pointer to the HW structure
- *
- * Ensures that the MDI/MDIX SW state is valid.
- **/
-s32 e1000_validate_mdi_setting(struct e1000_hw *hw)
-{
- if (hw->mac.ops.validate_mdi_setting)
- return hw->mac.ops.validate_mdi_setting(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_hash_mc_addr - Determines address location in multicast table
- * @hw: pointer to the HW structure
- * @mc_addr: Multicast address to hash.
- *
- * This hashes an address to determine its location in the multicast
- * table. Currently no func pointer exists and all implementations
- * are handled in the generic version of this function.
- **/
-u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
-{
- return e1000_hash_mc_addr_generic(hw, mc_addr);
-}
-
-/**
- * e1000_enable_tx_pkt_filtering - Enable packet filtering on TX
- * @hw: pointer to the HW structure
- *
- * Enables packet filtering on transmit packets if manageability is enabled
- * and host interface is enabled.
- * Currently no func pointer exists and all implementations are handled in the
- * generic version of this function.
- **/
-bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
-{
- return e1000_enable_tx_pkt_filtering_generic(hw);
-}
-
-/**
- * e1000_mng_host_if_write - Writes to the manageability host interface
- * @hw: pointer to the HW structure
- * @buffer: pointer to the host interface buffer
- * @length: size of the buffer
- * @offset: location in the buffer to write to
- * @sum: sum of the data (not checksum)
- *
- * This function writes the buffer content at the offset given on the host if.
- * It also does alignment considerations to do the writes in most efficient
- * way. Also fills up the sum of the buffer in *buffer parameter.
- **/
-s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
- u16 offset, u8 *sum)
-{
- return e1000_mng_host_if_write_generic(hw, buffer, length, offset, sum);
-}
-
-/**
- * e1000_mng_write_cmd_header - Writes manageability command header
- * @hw: pointer to the HW structure
- * @hdr: pointer to the host interface command header
- *
- * Writes the command header after does the checksum calculation.
- **/
-s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
- struct e1000_host_mng_command_header *hdr)
-{
- return e1000_mng_write_cmd_header_generic(hw, hdr);
-}
-
-/**
- * e1000_mng_enable_host_if - Checks host interface is enabled
- * @hw: pointer to the HW structure
- *
- * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
- *
- * This function checks whether the HOST IF is enabled for command operation
- * and also checks whether the previous command is completed. It busy waits
- * in case of previous command is not completed.
- **/
-s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
-{
- return e1000_mng_enable_host_if_generic(hw);
-}
-
-/**
- * e1000_check_reset_block - Verifies PHY can be reset
- * @hw: pointer to the HW structure
- *
- * Checks if the PHY is in a state that can be reset or if manageability
- * has it tied up. This is a function pointer entry point called by drivers.
- **/
-s32 e1000_check_reset_block(struct e1000_hw *hw)
-{
- if (hw->phy.ops.check_reset_block)
- return hw->phy.ops.check_reset_block(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_phy_reg - Reads PHY register
- * @hw: pointer to the HW structure
- * @offset: the register to read
- * @data: the buffer to store the 16-bit read.
- *
- * Reads the PHY register and returns the value in data.
- * This is a function pointer entry point called by drivers.
- **/
-s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- if (hw->phy.ops.read_reg)
- return hw->phy.ops.read_reg(hw, offset, data);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_phy_reg - Writes PHY register
- * @hw: pointer to the HW structure
- * @offset: the register to write
- * @data: the value to write.
- *
- * Writes the PHY register at offset with the value in data.
- * This is a function pointer entry point called by drivers.
- **/
-s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data)
-{
- if (hw->phy.ops.write_reg)
- return hw->phy.ops.write_reg(hw, offset, data);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_release_phy - Generic release PHY
- * @hw: pointer to the HW structure
- *
- * Return if silicon family does not require a semaphore when accessing the
- * PHY.
- **/
-void e1000_release_phy(struct e1000_hw *hw)
-{
- if (hw->phy.ops.release)
- hw->phy.ops.release(hw);
-}
-
-/**
- * e1000_acquire_phy - Generic acquire PHY
- * @hw: pointer to the HW structure
- *
- * Return success if silicon family does not require a semaphore when
- * accessing the PHY.
- **/
-s32 e1000_acquire_phy(struct e1000_hw *hw)
-{
- if (hw->phy.ops.acquire)
- return hw->phy.ops.acquire(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_kmrn_reg - Reads register using Kumeran interface
- * @hw: pointer to the HW structure
- * @offset: the register to read
- * @data: the location to store the 16-bit value read.
- *
- * Reads a register out of the Kumeran interface. Currently no func pointer
- * exists and all implementations are handled in the generic version of
- * this function.
- **/
-s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- return e1000_read_kmrn_reg_generic(hw, offset, data);
-}
-
-/**
- * e1000_write_kmrn_reg - Writes register using Kumeran interface
- * @hw: pointer to the HW structure
- * @offset: the register to write
- * @data: the value to write.
- *
- * Writes a register to the Kumeran interface. Currently no func pointer
- * exists and all implementations are handled in the generic version of
- * this function.
- **/
-s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
-{
- return e1000_write_kmrn_reg_generic(hw, offset, data);
-}
-
-/**
- * e1000_get_cable_length - Retrieves cable length estimation
- * @hw: pointer to the HW structure
- *
- * This function estimates the cable length and stores them in
- * hw->phy.min_length and hw->phy.max_length. This is a function pointer
- * entry point called by drivers.
- **/
-s32 e1000_get_cable_length(struct e1000_hw *hw)
-{
- if (hw->phy.ops.get_cable_length)
- return hw->phy.ops.get_cable_length(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_get_phy_info - Retrieves PHY information from registers
- * @hw: pointer to the HW structure
- *
- * This function gets some information from various PHY registers and
- * populates hw->phy values with it. This is a function pointer entry
- * point called by drivers.
- **/
-s32 e1000_get_phy_info(struct e1000_hw *hw)
-{
- if (hw->phy.ops.get_info)
- return hw->phy.ops.get_info(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_phy_hw_reset - Hard PHY reset
- * @hw: pointer to the HW structure
- *
- * Performs a hard PHY reset. This is a function pointer entry point called
- * by drivers.
- **/
-s32 e1000_phy_hw_reset(struct e1000_hw *hw)
-{
- if (hw->phy.ops.reset)
- return hw->phy.ops.reset(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_phy_commit - Soft PHY reset
- * @hw: pointer to the HW structure
- *
- * Performs a soft PHY reset on those that apply. This is a function pointer
- * entry point called by drivers.
- **/
-s32 e1000_phy_commit(struct e1000_hw *hw)
-{
- if (hw->phy.ops.commit)
- return hw->phy.ops.commit(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_set_d0_lplu_state - Sets low power link up state for D0
- * @hw: pointer to the HW structure
- * @active: boolean used to enable/disable lplu
- *
- * Success returns 0, Failure returns 1
- *
- * The low power link up (lplu) state is set to the power management level D0
- * and SmartSpeed is disabled when active is true, else clear lplu for D0
- * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
- * is used during Dx states where the power conservation is most important.
- * During driver activity, SmartSpeed should be enabled so performance is
- * maintained. This is a function pointer entry point called by drivers.
- **/
-s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
-{
- if (hw->phy.ops.set_d0_lplu_state)
- return hw->phy.ops.set_d0_lplu_state(hw, active);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_set_d3_lplu_state - Sets low power link up state for D3
- * @hw: pointer to the HW structure
- * @active: boolean used to enable/disable lplu
- *
- * Success returns 0, Failure returns 1
- *
- * The low power link up (lplu) state is set to the power management level D3
- * and SmartSpeed is disabled when active is true, else clear lplu for D3
- * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
- * is used during Dx states where the power conservation is most important.
- * During driver activity, SmartSpeed should be enabled so performance is
- * maintained. This is a function pointer entry point called by drivers.
- **/
-s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
-{
- if (hw->phy.ops.set_d3_lplu_state)
- return hw->phy.ops.set_d3_lplu_state(hw, active);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_mac_addr - Reads MAC address
- * @hw: pointer to the HW structure
- *
- * Reads the MAC address out of the adapter and stores it in the HW structure.
- * Currently no func pointer exists and all implementations are handled in the
- * generic version of this function.
- **/
-s32 e1000_read_mac_addr(struct e1000_hw *hw)
-{
- if (hw->mac.ops.read_mac_addr)
- return hw->mac.ops.read_mac_addr(hw);
-
- return e1000_read_mac_addr_generic(hw);
-}
-
-/**
- * e1000_read_pba_string - Read device part number string
- * @hw: pointer to the HW structure
- * @pba_num: pointer to device part number
- * @pba_num_size: size of part number buffer
- *
- * Reads the product board assembly (PBA) number from the EEPROM and stores
- * the value in pba_num.
- * Currently no func pointer exists and all implementations are handled in the
- * generic version of this function.
- **/
-s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size)
-{
- return e1000_read_pba_string_generic(hw, pba_num, pba_num_size);
-}
-
-/**
- * e1000_read_pba_length - Read device part number string length
- * @hw: pointer to the HW structure
- * @pba_num_size: size of part number buffer
- *
- * Reads the product board assembly (PBA) number length from the EEPROM and
- * stores the value in pba_num.
- * Currently no func pointer exists and all implementations are handled in the
- * generic version of this function.
- **/
-s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size)
-{
- return e1000_read_pba_length_generic(hw, pba_num_size);
-}
-
-/**
- * e1000_validate_nvm_checksum - Verifies NVM (EEPROM) checksum
- * @hw: pointer to the HW structure
- *
- * Validates the NVM checksum is correct. This is a function pointer entry
- * point called by drivers.
- **/
-s32 e1000_validate_nvm_checksum(struct e1000_hw *hw)
-{
- if (hw->nvm.ops.validate)
- return hw->nvm.ops.validate(hw);
-
- return -E1000_ERR_CONFIG;
-}
-
-/**
- * e1000_update_nvm_checksum - Updates NVM (EEPROM) checksum
- * @hw: pointer to the HW structure
- *
- * Updates the NVM checksum. Currently no func pointer exists and all
- * implementations are handled in the generic version of this function.
- **/
-s32 e1000_update_nvm_checksum(struct e1000_hw *hw)
-{
- if (hw->nvm.ops.update)
- return hw->nvm.ops.update(hw);
-
- return -E1000_ERR_CONFIG;
-}
-
-/**
- * e1000_reload_nvm - Reloads EEPROM
- * @hw: pointer to the HW structure
- *
- * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
- * extended control register.
- **/
-void e1000_reload_nvm(struct e1000_hw *hw)
-{
- if (hw->nvm.ops.reload)
- hw->nvm.ops.reload(hw);
-}
-
-/**
- * e1000_read_nvm - Reads NVM (EEPROM)
- * @hw: pointer to the HW structure
- * @offset: the word offset to read
- * @words: number of 16-bit words to read
- * @data: pointer to the properly sized buffer for the data.
- *
- * Reads 16-bit chunks of data from the NVM (EEPROM). This is a function
- * pointer entry point called by drivers.
- **/
-s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- if (hw->nvm.ops.read)
- return hw->nvm.ops.read(hw, offset, words, data);
-
- return -E1000_ERR_CONFIG;
-}
-
-/**
- * e1000_write_nvm - Writes to NVM (EEPROM)
- * @hw: pointer to the HW structure
- * @offset: the word offset to read
- * @words: number of 16-bit words to write
- * @data: pointer to the properly sized buffer for the data.
- *
- * Writes 16-bit chunks of data to the NVM (EEPROM). This is a function
- * pointer entry point called by drivers.
- **/
-s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- if (hw->nvm.ops.write)
- return hw->nvm.ops.write(hw, offset, words, data);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_8bit_ctrl_reg - Writes 8bit Control register
- * @hw: pointer to the HW structure
- * @reg: 32bit register offset
- * @offset: the register to write
- * @data: the value to write.
- *
- * Writes the PHY register at offset with the value in data.
- * This is a function pointer entry point called by drivers.
- **/
-s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset,
- u8 data)
-{
- return e1000_write_8bit_ctrl_reg_generic(hw, reg, offset, data);
-}
-
-/**
- * e1000_power_up_phy - Restores link in case of PHY power down
- * @hw: pointer to the HW structure
- *
- * The phy may be powered down to save power, to turn off link when the
- * driver is unloaded, or wake on lan is not enabled (among others).
- **/
-void e1000_power_up_phy(struct e1000_hw *hw)
-{
- if (hw->phy.ops.power_up)
- hw->phy.ops.power_up(hw);
-
- e1000_setup_link(hw);
-}
-
-/**
- * e1000_power_down_phy - Power down PHY
- * @hw: pointer to the HW structure
- *
- * The phy may be powered down to save power, to turn off link when the
- * driver is unloaded, or wake on lan is not enabled (among others).
- **/
-void e1000_power_down_phy(struct e1000_hw *hw)
-{
- if (hw->phy.ops.power_down)
- hw->phy.ops.power_down(hw);
-}
-
-/**
- * e1000_power_up_fiber_serdes_link - Power up serdes link
- * @hw: pointer to the HW structure
- *
- * Power on the optics and PCS.
- **/
-void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw)
-{
- if (hw->mac.ops.power_up_serdes)
- hw->mac.ops.power_up_serdes(hw);
-}
-
-/**
- * e1000_shutdown_fiber_serdes_link - Remove link during power down
- * @hw: pointer to the HW structure
- *
- * Shutdown the optics and PCS on driver unload.
- **/
-void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw)
-{
- if (hw->mac.ops.shutdown_serdes)
- hw->mac.ops.shutdown_serdes(hw);
-}
-
-/**
- * e1000_get_thermal_sensor_data - Gathers thermal sensor data
- * @hw: pointer to hardware structure
- *
- * Updates the temperatures in mac.thermal_sensor_data
- **/
-s32 e1000_get_thermal_sensor_data(struct e1000_hw *hw)
-{
- if (hw->mac.ops.get_thermal_sensor_data)
- return hw->mac.ops.get_thermal_sensor_data(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_init_thermal_sensor_thresh - Sets thermal sensor thresholds
- * @hw: pointer to hardware structure
- *
- * Sets the thermal sensor thresholds according to the NVM map
- **/
-s32 e1000_init_thermal_sensor_thresh(struct e1000_hw *hw)
-{
- if (hw->mac.ops.init_thermal_sensor_thresh)
- return hw->mac.ops.init_thermal_sensor_thresh(hw);
-
- return E1000_SUCCESS;
-}
diff --git a/kernel/linux/kni/ethtool/igb/e1000_api.h b/kernel/linux/kni/ethtool/igb/e1000_api.h
deleted file mode 100644
index 0bc00acdf..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_api.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_API_H_
-#define _E1000_API_H_
-
-#include "e1000_hw.h"
-
-extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
-extern void e1000_rx_fifo_flush_82575(struct e1000_hw *hw);
-extern void e1000_init_function_pointers_vf(struct e1000_hw *hw);
-extern void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw);
-extern void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw);
-extern void e1000_init_function_pointers_i210(struct e1000_hw *hw);
-
-s32 e1000_set_obff_timer(struct e1000_hw *hw, u32 itr);
-s32 e1000_set_mac_type(struct e1000_hw *hw);
-s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
-s32 e1000_init_mac_params(struct e1000_hw *hw);
-s32 e1000_init_nvm_params(struct e1000_hw *hw);
-s32 e1000_init_phy_params(struct e1000_hw *hw);
-s32 e1000_init_mbx_params(struct e1000_hw *hw);
-s32 e1000_get_bus_info(struct e1000_hw *hw);
-void e1000_clear_vfta(struct e1000_hw *hw);
-void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
-s32 e1000_force_mac_fc(struct e1000_hw *hw);
-s32 e1000_check_for_link(struct e1000_hw *hw);
-s32 e1000_reset_hw(struct e1000_hw *hw);
-s32 e1000_init_hw(struct e1000_hw *hw);
-s32 e1000_setup_link(struct e1000_hw *hw);
-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);
-s32 e1000_disable_pcie_master(struct e1000_hw *hw);
-void e1000_config_collision_dist(struct e1000_hw *hw);
-void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
-u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
-void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count);
-s32 e1000_setup_led(struct e1000_hw *hw);
-s32 e1000_cleanup_led(struct e1000_hw *hw);
-s32 e1000_check_reset_block(struct e1000_hw *hw);
-s32 e1000_blink_led(struct e1000_hw *hw);
-s32 e1000_led_on(struct e1000_hw *hw);
-s32 e1000_led_off(struct e1000_hw *hw);
-s32 e1000_id_led_init(struct e1000_hw *hw);
-void e1000_reset_adaptive(struct e1000_hw *hw);
-void e1000_update_adaptive(struct e1000_hw *hw);
-s32 e1000_get_cable_length(struct e1000_hw *hw);
-s32 e1000_validate_mdi_setting(struct e1000_hw *hw);
-s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset,
- u8 data);
-s32 e1000_get_phy_info(struct e1000_hw *hw);
-void e1000_release_phy(struct e1000_hw *hw);
-s32 e1000_acquire_phy(struct e1000_hw *hw);
-s32 e1000_phy_hw_reset(struct e1000_hw *hw);
-s32 e1000_phy_commit(struct e1000_hw *hw);
-void e1000_power_up_phy(struct e1000_hw *hw);
-void e1000_power_down_phy(struct e1000_hw *hw);
-s32 e1000_read_mac_addr(struct e1000_hw *hw);
-s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size);
-s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size);
-void e1000_reload_nvm(struct e1000_hw *hw);
-s32 e1000_update_nvm_checksum(struct e1000_hw *hw);
-s32 e1000_validate_nvm_checksum(struct e1000_hw *hw);
-s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
-s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
-s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
-s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
-bool e1000_check_mng_mode(struct e1000_hw *hw);
-bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
-s32 e1000_mng_enable_host_if(struct e1000_hw *hw);
-s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
- u16 offset, u8 *sum);
-s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
- struct e1000_host_mng_command_header *hdr);
-s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length);
-s32 e1000_get_thermal_sensor_data(struct e1000_hw *hw);
-s32 e1000_init_thermal_sensor_thresh(struct e1000_hw *hw);
-
-
-
-/*
- * TBI_ACCEPT macro definition:
- *
- * This macro requires:
- * adapter = a pointer to struct e1000_hw
- * status = the 8 bit status field of the Rx descriptor with EOP set
- * error = the 8 bit error field of the Rx descriptor with EOP set
- * length = the sum of all the length fields of the Rx descriptors that
- * make up the current frame
- * last_byte = the last byte of the frame DMAed by the hardware
- * max_frame_length = the maximum frame length we want to accept.
- * min_frame_length = the minimum frame length we want to accept.
- *
- * This macro is a conditional that should be used in the interrupt
- * handler's Rx processing routine when RxErrors have been detected.
- *
- * Typical use:
- * ...
- * if (TBI_ACCEPT) {
- * accept_frame = true;
- * e1000_tbi_adjust_stats(adapter, MacAddress);
- * frame_length--;
- * } else {
- * accept_frame = false;
- * }
- * ...
- */
-
-/* The carrier extension symbol, as received by the NIC. */
-#define CARRIER_EXTENSION 0x0F
-
-#define TBI_ACCEPT(a, status, errors, length, last_byte, \
- min_frame_size, max_frame_size) \
- (e1000_tbi_sbp_enabled_82543(a) && \
- (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
- ((last_byte) == CARRIER_EXTENSION) && \
- (((status) & E1000_RXD_STAT_VP) ? \
- (((length) > (min_frame_size - VLAN_TAG_SIZE)) && \
- ((length) <= (max_frame_size + 1))) : \
- (((length) > min_frame_size) && \
- ((length) <= (max_frame_size + VLAN_TAG_SIZE + 1)))))
-
-#ifndef E1000_MAX
-#define E1000_MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef E1000_DIVIDE_ROUND_UP
-#define E1000_DIVIDE_ROUND_UP(a, b) (((a) + (b) - 1) / (b)) /* ceil(a/b) */
-#endif
-#endif /* _E1000_API_H_ */
diff --git a/kernel/linux/kni/ethtool/igb/e1000_defines.h b/kernel/linux/kni/ethtool/igb/e1000_defines.h
deleted file mode 100644
index b39aaf80a..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_defines.h
+++ /dev/null
@@ -1,1365 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_DEFINES_H_
-#define _E1000_DEFINES_H_
-
-/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
-#define REQ_TX_DESCRIPTOR_MULTIPLE 8
-#define REQ_RX_DESCRIPTOR_MULTIPLE 8
-
-/* Definitions for power management and wakeup registers */
-/* Wake Up Control */
-#define E1000_WUC_APME 0x00000001 /* APM Enable */
-#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
-#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
-#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
-#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */
-
-/* Wake Up Filter Control */
-#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
-#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
-#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
-#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
-#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
-#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
-#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
-#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
-
-/* Wake Up Status */
-#define E1000_WUS_LNKC E1000_WUFC_LNKC
-#define E1000_WUS_MAG E1000_WUFC_MAG
-#define E1000_WUS_EX E1000_WUFC_EX
-#define E1000_WUS_MC E1000_WUFC_MC
-#define E1000_WUS_BC E1000_WUFC_BC
-
-/* Extended Device Control */
-#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* SW Definable Pin 4 data */
-#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* SW Definable Pin 6 data */
-#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* SW Definable Pin 3 data */
-#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */
-#define E1000_CTRL_EXT_SDP3_DIR 0x00000800 /* Direction of SDP3 0=in 1=out */
-#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
-/* Physical Func Reset Done Indication */
-#define E1000_CTRL_EXT_PFRSTD 0x00004000
-#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
-#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
-#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clk Gating */
-#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
-/* Offset of the link mode field in Ctrl Ext register */
-#define E1000_CTRL_EXT_LINK_MODE_OFFSET 22
-#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000
-#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
-#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
-#define E1000_CTRL_EXT_EIAME 0x01000000
-#define E1000_CTRL_EXT_IRCA 0x00000001
-#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Drv loaded bit for FW */
-#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */
-#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
-#define E1000_I2CCMD_REG_ADDR_SHIFT 16
-#define E1000_I2CCMD_PHY_ADDR_SHIFT 24
-#define E1000_I2CCMD_OPCODE_READ 0x08000000
-#define E1000_I2CCMD_OPCODE_WRITE 0x00000000
-#define E1000_I2CCMD_READY 0x20000000
-#define E1000_I2CCMD_ERROR 0x80000000
-#define E1000_I2CCMD_SFP_DATA_ADDR(a) (0x0000 + (a))
-#define E1000_I2CCMD_SFP_DIAG_ADDR(a) (0x0100 + (a))
-#define E1000_MAX_SGMII_PHY_REG_ADDR 255
-#define E1000_I2CCMD_PHY_TIMEOUT 200
-#define E1000_IVAR_VALID 0x80
-#define E1000_GPIE_NSICR 0x00000001
-#define E1000_GPIE_MSIX_MODE 0x00000010
-#define E1000_GPIE_EIAME 0x40000000
-#define E1000_GPIE_PBA 0x80000000
-
-/* Receive Descriptor bit definitions */
-#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
-#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
-#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
-#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
-#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
-#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
-#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
-#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */
-#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
-#define E1000_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
-#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
-#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
-#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
-#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
-#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
-#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
-#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
-#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
-
-#define E1000_RXDEXT_STATERR_TST 0x00000100 /* Time Stamp taken */
-#define E1000_RXDEXT_STATERR_LB 0x00040000
-#define E1000_RXDEXT_STATERR_CE 0x01000000
-#define E1000_RXDEXT_STATERR_SE 0x02000000
-#define E1000_RXDEXT_STATERR_SEQ 0x04000000
-#define E1000_RXDEXT_STATERR_CXE 0x10000000
-#define E1000_RXDEXT_STATERR_TCPE 0x20000000
-#define E1000_RXDEXT_STATERR_IPE 0x40000000
-#define E1000_RXDEXT_STATERR_RXE 0x80000000
-
-/* mask to determine if packets should be dropped due to frame errors */
-#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
- E1000_RXD_ERR_CE | \
- E1000_RXD_ERR_SE | \
- E1000_RXD_ERR_SEQ | \
- E1000_RXD_ERR_CXE | \
- E1000_RXD_ERR_RXE)
-
-/* Same mask, but for extended and packet split descriptors */
-#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
- E1000_RXDEXT_STATERR_CE | \
- E1000_RXDEXT_STATERR_SE | \
- E1000_RXDEXT_STATERR_SEQ | \
- E1000_RXDEXT_STATERR_CXE | \
- E1000_RXDEXT_STATERR_RXE)
-
-#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
-#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
-#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
-#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
-#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
-#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000
-
-#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
-
-/* Management Control */
-#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
-#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
-#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
-#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
-#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
-/* Enable MAC address filtering */
-#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000
-/* Enable MNG packets to host memory */
-#define E1000_MANC_EN_MNG2HOST 0x00200000
-
-#define E1000_MANC2H_PORT_623 0x00000020 /* Port 0x26f */
-#define E1000_MANC2H_PORT_664 0x00000040 /* Port 0x298 */
-#define E1000_MDEF_PORT_623 0x00000800 /* Port 0x26f */
-#define E1000_MDEF_PORT_664 0x00000400 /* Port 0x298 */
-
-/* Receive Control */
-#define E1000_RCTL_RST 0x00000001 /* Software reset */
-#define E1000_RCTL_EN 0x00000002 /* enable */
-#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
-#define E1000_RCTL_UPE 0x00000008 /* unicast promisc enable */
-#define E1000_RCTL_MPE 0x00000010 /* multicast promisc enable */
-#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
-#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
-#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
-#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
-#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
-#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min thresh size */
-#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
-#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
-#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
-#define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024 0x00010000 /* Rx buffer size 1024 */
-#define E1000_RCTL_SZ_512 0x00020000 /* Rx buffer size 512 */
-#define E1000_RCTL_SZ_256 0x00030000 /* Rx buffer size 256 */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
-#define E1000_RCTL_SZ_16384 0x00010000 /* Rx buffer size 16384 */
-#define E1000_RCTL_SZ_8192 0x00020000 /* Rx buffer size 8192 */
-#define E1000_RCTL_SZ_4096 0x00030000 /* Rx buffer size 4096 */
-#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
-#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
-#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
-#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
-#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
-#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
-#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
-
-/* Use byte values for the following shift parameters
- * Usage:
- * psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
- * E1000_PSRCTL_BSIZE0_MASK) |
- * ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
- * E1000_PSRCTL_BSIZE1_MASK) |
- * ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
- * E1000_PSRCTL_BSIZE2_MASK) |
- * ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
- * E1000_PSRCTL_BSIZE3_MASK))
- * where value0 = [128..16256], default=256
- * value1 = [1024..64512], default=4096
- * value2 = [0..64512], default=4096
- * value3 = [0..64512], default=0
- */
-
-#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F
-#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00
-#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000
-#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000
-
-#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */
-#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */
-#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */
-#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */
-
-/* SWFW_SYNC Definitions */
-#define E1000_SWFW_EEP_SM 0x01
-#define E1000_SWFW_PHY0_SM 0x02
-#define E1000_SWFW_PHY1_SM 0x04
-#define E1000_SWFW_CSR_SM 0x08
-#define E1000_SWFW_PHY2_SM 0x20
-#define E1000_SWFW_PHY3_SM 0x40
-#define E1000_SWFW_SW_MNG_SM 0x400
-
-/* Device Control */
-#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
-#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
-#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master reqs */
-#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
-#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
-#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
-#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
-#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
-#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
-#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
-#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
-#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
-#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
-#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
-#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
-#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
-#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */
-#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
-#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
-#define E1000_CTRL_RST 0x04000000 /* Global reset */
-#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
-#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
-#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
-#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
-#define E1000_CTRL_I2C_ENA 0x02000000 /* I2C enable */
-
-
-#define E1000_CONNSW_ENRGSRC 0x4
-#define E1000_CONNSW_PHYSD 0x400
-#define E1000_CONNSW_PHY_PDN 0x800
-#define E1000_CONNSW_SERDESD 0x200
-#define E1000_CONNSW_AUTOSENSE_CONF 0x2
-#define E1000_CONNSW_AUTOSENSE_EN 0x1
-#define E1000_PCS_CFG_PCS_EN 8
-#define E1000_PCS_LCTL_FLV_LINK_UP 1
-#define E1000_PCS_LCTL_FSV_10 0
-#define E1000_PCS_LCTL_FSV_100 2
-#define E1000_PCS_LCTL_FSV_1000 4
-#define E1000_PCS_LCTL_FDV_FULL 8
-#define E1000_PCS_LCTL_FSD 0x10
-#define E1000_PCS_LCTL_FORCE_LINK 0x20
-#define E1000_PCS_LCTL_FORCE_FCTRL 0x80
-#define E1000_PCS_LCTL_AN_ENABLE 0x10000
-#define E1000_PCS_LCTL_AN_RESTART 0x20000
-#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000
-#define E1000_ENABLE_SERDES_LOOPBACK 0x0410
-
-#define E1000_PCS_LSTS_LINK_OK 1
-#define E1000_PCS_LSTS_SPEED_100 2
-#define E1000_PCS_LSTS_SPEED_1000 4
-#define E1000_PCS_LSTS_DUPLEX_FULL 8
-#define E1000_PCS_LSTS_SYNK_OK 0x10
-#define E1000_PCS_LSTS_AN_COMPLETE 0x10000
-
-/* Device Status */
-#define E1000_STATUS_FD 0x00000001 /* Duplex 0=half 1=full */
-#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
-#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
-#define E1000_STATUS_FUNC_SHIFT 2
-#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
-#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
-#define E1000_STATUS_SPEED_MASK 0x000000C0
-#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
-#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
-#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
-#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Compltn by NVM */
-#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */
-#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master request status */
-#define E1000_STATUS_2P5_SKU 0x00001000 /* Val of 2.5GBE SKU strap */
-#define E1000_STATUS_2P5_SKU_OVER 0x00002000 /* Val of 2.5GBE SKU Over */
-
-#define SPEED_10 10
-#define SPEED_100 100
-#define SPEED_1000 1000
-#define SPEED_2500 2500
-#define HALF_DUPLEX 1
-#define FULL_DUPLEX 2
-
-
-#define ADVERTISE_10_HALF 0x0001
-#define ADVERTISE_10_FULL 0x0002
-#define ADVERTISE_100_HALF 0x0004
-#define ADVERTISE_100_FULL 0x0008
-#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */
-#define ADVERTISE_1000_FULL 0x0020
-
-/* 1000/H is not supported, nor spec-compliant. */
-#define E1000_ALL_SPEED_DUPLEX ( \
- ADVERTISE_10_HALF | ADVERTISE_10_FULL | ADVERTISE_100_HALF | \
- ADVERTISE_100_FULL | ADVERTISE_1000_FULL)
-#define E1000_ALL_NOT_GIG ( \
- ADVERTISE_10_HALF | ADVERTISE_10_FULL | ADVERTISE_100_HALF | \
- ADVERTISE_100_FULL)
-#define E1000_ALL_100_SPEED (ADVERTISE_100_HALF | ADVERTISE_100_FULL)
-#define E1000_ALL_10_SPEED (ADVERTISE_10_HALF | ADVERTISE_10_FULL)
-#define E1000_ALL_HALF_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_100_HALF)
-
-#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
-
-/* LED Control */
-#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
-#define E1000_LEDCTL_LED0_MODE_SHIFT 0
-#define E1000_LEDCTL_LED0_IVRT 0x00000040
-#define E1000_LEDCTL_LED0_BLINK 0x00000080
-
-#define E1000_LEDCTL_MODE_LED_ON 0xE
-#define E1000_LEDCTL_MODE_LED_OFF 0xF
-
-/* Transmit Descriptor bit definitions */
-#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
-#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
-#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
-#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
-#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
-#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
-#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
-#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
-#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
-#define E1000_TXD_CMD_DEXT 0x20000000 /* Desc extension (0 = legacy) */
-#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
-#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
-#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
-#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
-#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
-#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
-#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
-#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
-#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
-#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
-#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */
-
-/* Transmit Control */
-#define E1000_TCTL_EN 0x00000002 /* enable Tx */
-#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
-#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
-#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
-#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
-#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
-
-/* Transmit Arbitration Count */
-#define E1000_TARC0_ENABLE 0x00000400 /* Enable Tx Queue 0 */
-
-/* SerDes Control */
-#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
-#define E1000_SCTL_ENABLE_SERDES_LOOPBACK 0x0410
-
-/* Receive Checksum Control */
-#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */
-#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
-#define E1000_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */
-#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
-#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
-
-/* Header split receive */
-#define E1000_RFCTL_NFSW_DIS 0x00000040
-#define E1000_RFCTL_NFSR_DIS 0x00000080
-#define E1000_RFCTL_ACK_DIS 0x00001000
-#define E1000_RFCTL_EXTEN 0x00008000
-#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
-#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
-#define E1000_RFCTL_LEF 0x00040000
-
-/* Collision related configuration parameters */
-#define E1000_COLLISION_THRESHOLD 15
-#define E1000_CT_SHIFT 4
-#define E1000_COLLISION_DISTANCE 63
-#define E1000_COLD_SHIFT 12
-
-/* Default values for the transmit IPG register */
-#define DEFAULT_82543_TIPG_IPGT_FIBER 9
-#define DEFAULT_82543_TIPG_IPGT_COPPER 8
-
-#define E1000_TIPG_IPGT_MASK 0x000003FF
-
-#define DEFAULT_82543_TIPG_IPGR1 8
-#define E1000_TIPG_IPGR1_SHIFT 10
-
-#define DEFAULT_82543_TIPG_IPGR2 6
-#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7
-#define E1000_TIPG_IPGR2_SHIFT 20
-
-/* Ethertype field values */
-#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */
-
-#define ETHERNET_FCS_SIZE 4
-#define MAX_JUMBO_FRAME_SIZE 0x3F00
-
-/* Extended Configuration Control and Size */
-#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
-#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
-#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008
-#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
-#define E1000_EXTCNF_CTRL_GATE_PHY_CFG 0x00000080
-#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000
-#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16
-#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK 0x0FFF0000
-#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT 16
-
-#define E1000_PHY_CTRL_D0A_LPLU 0x00000002
-#define E1000_PHY_CTRL_NOND0A_LPLU 0x00000004
-#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE 0x00000008
-#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040
-
-#define E1000_KABGTXD_BGSQLBIAS 0x00050000
-
-/* PBA constants */
-#define E1000_PBA_8K 0x0008 /* 8KB */
-#define E1000_PBA_10K 0x000A /* 10KB */
-#define E1000_PBA_12K 0x000C /* 12KB */
-#define E1000_PBA_14K 0x000E /* 14KB */
-#define E1000_PBA_16K 0x0010 /* 16KB */
-#define E1000_PBA_18K 0x0012
-#define E1000_PBA_20K 0x0014
-#define E1000_PBA_22K 0x0016
-#define E1000_PBA_24K 0x0018
-#define E1000_PBA_26K 0x001A
-#define E1000_PBA_30K 0x001E
-#define E1000_PBA_32K 0x0020
-#define E1000_PBA_34K 0x0022
-#define E1000_PBA_35K 0x0023
-#define E1000_PBA_38K 0x0026
-#define E1000_PBA_40K 0x0028
-#define E1000_PBA_48K 0x0030 /* 48KB */
-#define E1000_PBA_64K 0x0040 /* 64KB */
-
-#define E1000_PBA_RXA_MASK 0xFFFF
-
-#define E1000_PBS_16K E1000_PBA_16K
-
-#define IFS_MAX 80
-#define IFS_MIN 40
-#define IFS_RATIO 4
-#define IFS_STEP 10
-#define MIN_NUM_XMITS 1000
-
-/* SW Semaphore Register */
-#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
-#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
-#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
-
-#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
-
-/* Interrupt Cause Read */
-#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
-#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
-#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
-#define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */
-#define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */
-#define E1000_ICR_RXO 0x00000040 /* Rx overrun */
-#define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */
-#define E1000_ICR_VMMB 0x00000100 /* VM MB event */
-#define E1000_ICR_RXCFG 0x00000400 /* Rx /c/ ordered set */
-#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
-#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
-#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
-#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
-#define E1000_ICR_TXD_LOW 0x00008000
-#define E1000_ICR_MNG 0x00040000 /* Manageability event */
-#define E1000_ICR_TS 0x00080000 /* Time Sync Interrupt */
-#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */
-/* If this bit asserted, the driver should claim the interrupt */
-#define E1000_ICR_INT_ASSERTED 0x80000000
-#define E1000_ICR_DOUTSYNC 0x10000000 /* NIC DMA out of sync */
-#define E1000_ICR_FER 0x00400000 /* Fatal Error */
-
-#define E1000_ICR_THS 0x00800000 /* ICR.THS: Thermal Sensor Event*/
-#define E1000_ICR_MDDET 0x10000000 /* Malicious Driver Detect */
-
-
-/* Extended Interrupt Cause Read */
-#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */
-#define E1000_EICR_RX_QUEUE1 0x00000002 /* Rx Queue 1 Interrupt */
-#define E1000_EICR_RX_QUEUE2 0x00000004 /* Rx Queue 2 Interrupt */
-#define E1000_EICR_RX_QUEUE3 0x00000008 /* Rx Queue 3 Interrupt */
-#define E1000_EICR_TX_QUEUE0 0x00000100 /* Tx Queue 0 Interrupt */
-#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */
-#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */
-#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */
-#define E1000_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
-#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */
-/* TCP Timer */
-#define E1000_TCPTIMER_KS 0x00000100 /* KickStart */
-#define E1000_TCPTIMER_COUNT_ENABLE 0x00000200 /* Count Enable */
-#define E1000_TCPTIMER_COUNT_FINISH 0x00000400 /* Count finish */
-#define E1000_TCPTIMER_LOOP 0x00000800 /* Loop */
-
-/* This defines the bits that are set in the Interrupt Mask
- * Set/Read Register. Each bit is documented below:
- * o RXT0 = Receiver Timer Interrupt (ring 0)
- * o TXDW = Transmit Descriptor Written Back
- * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
- * o RXSEQ = Receive Sequence Error
- * o LSC = Link Status Change
- */
-#define IMS_ENABLE_MASK ( \
- E1000_IMS_RXT0 | \
- E1000_IMS_TXDW | \
- E1000_IMS_RXDMT0 | \
- E1000_IMS_RXSEQ | \
- E1000_IMS_LSC)
-
-/* Interrupt Mask Set */
-#define E1000_IMS_TXDW E1000_ICR_TXDW /* Tx desc written back */
-#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */
-#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */
-#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */
-#define E1000_IMS_RXO E1000_ICR_RXO /* Rx overrun */
-#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */
-#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMS_TS E1000_ICR_TS /* Time Sync Interrupt */
-#define E1000_IMS_DRSTA E1000_ICR_DRSTA /* Device Reset Asserted */
-#define E1000_IMS_DOUTSYNC E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
-#define E1000_IMS_FER E1000_ICR_FER /* Fatal Error */
-
-#define E1000_IMS_THS E1000_ICR_THS /* ICR.TS: Thermal Sensor Event*/
-#define E1000_IMS_MDDET E1000_ICR_MDDET /* Malicious Driver Detect */
-/* Extended Interrupt Mask Set */
-#define E1000_EIMS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */
-#define E1000_EIMS_RX_QUEUE1 E1000_EICR_RX_QUEUE1 /* Rx Queue 1 Interrupt */
-#define E1000_EIMS_RX_QUEUE2 E1000_EICR_RX_QUEUE2 /* Rx Queue 2 Interrupt */
-#define E1000_EIMS_RX_QUEUE3 E1000_EICR_RX_QUEUE3 /* Rx Queue 3 Interrupt */
-#define E1000_EIMS_TX_QUEUE0 E1000_EICR_TX_QUEUE0 /* Tx Queue 0 Interrupt */
-#define E1000_EIMS_TX_QUEUE1 E1000_EICR_TX_QUEUE1 /* Tx Queue 1 Interrupt */
-#define E1000_EIMS_TX_QUEUE2 E1000_EICR_TX_QUEUE2 /* Tx Queue 2 Interrupt */
-#define E1000_EIMS_TX_QUEUE3 E1000_EICR_TX_QUEUE3 /* Tx Queue 3 Interrupt */
-#define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */
-#define E1000_EIMS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */
-
-/* Interrupt Cause Set */
-#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */
-#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */
-
-/* Extended Interrupt Cause Set */
-#define E1000_EICS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */
-#define E1000_EICS_RX_QUEUE1 E1000_EICR_RX_QUEUE1 /* Rx Queue 1 Interrupt */
-#define E1000_EICS_RX_QUEUE2 E1000_EICR_RX_QUEUE2 /* Rx Queue 2 Interrupt */
-#define E1000_EICS_RX_QUEUE3 E1000_EICR_RX_QUEUE3 /* Rx Queue 3 Interrupt */
-#define E1000_EICS_TX_QUEUE0 E1000_EICR_TX_QUEUE0 /* Tx Queue 0 Interrupt */
-#define E1000_EICS_TX_QUEUE1 E1000_EICR_TX_QUEUE1 /* Tx Queue 1 Interrupt */
-#define E1000_EICS_TX_QUEUE2 E1000_EICR_TX_QUEUE2 /* Tx Queue 2 Interrupt */
-#define E1000_EICS_TX_QUEUE3 E1000_EICR_TX_QUEUE3 /* Tx Queue 3 Interrupt */
-#define E1000_EICS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */
-#define E1000_EICS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */
-
-#define E1000_EITR_ITR_INT_MASK 0x0000FFFF
-/* E1000_EITR_CNT_IGNR is only for 82576 and newer */
-#define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on write */
-#define E1000_EITR_INTERVAL 0x00007FFC
-
-/* Transmit Descriptor Control */
-#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
-#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */
-#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */
-#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
-#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
-#define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */
-/* Enable the counting of descriptors still to be processed. */
-#define E1000_TXDCTL_COUNT_DESC 0x00400000
-
-/* Flow Control Constants */
-#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
-#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
-#define FLOW_CONTROL_TYPE 0x8808
-
-/* 802.1q VLAN Packet Size */
-#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMA'd) */
-#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
-
-/* Receive Address
- * Number of high/low register pairs in the RAR. The RAR (Receive Address
- * Registers) holds the directed and multicast addresses that we monitor.
- * Technically, we have 16 spots. However, we reserve one of these spots
- * (RAR[15]) for our directed address used by controllers with
- * manageability enabled, allowing us room for 15 multicast addresses.
- */
-#define E1000_RAR_ENTRIES 15
-#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
-#define E1000_RAL_MAC_ADDR_LEN 4
-#define E1000_RAH_MAC_ADDR_LEN 2
-#define E1000_RAH_QUEUE_MASK_82575 0x000C0000
-#define E1000_RAH_POOL_1 0x00040000
-
-/* Error Codes */
-#define E1000_SUCCESS 0
-#define E1000_ERR_NVM 1
-#define E1000_ERR_PHY 2
-#define E1000_ERR_CONFIG 3
-#define E1000_ERR_PARAM 4
-#define E1000_ERR_MAC_INIT 5
-#define E1000_ERR_PHY_TYPE 6
-#define E1000_ERR_RESET 9
-#define E1000_ERR_MASTER_REQUESTS_PENDING 10
-#define E1000_ERR_HOST_INTERFACE_COMMAND 11
-#define E1000_BLK_PHY_RESET 12
-#define E1000_ERR_SWFW_SYNC 13
-#define E1000_NOT_IMPLEMENTED 14
-#define E1000_ERR_MBX 15
-#define E1000_ERR_INVALID_ARGUMENT 16
-#define E1000_ERR_NO_SPACE 17
-#define E1000_ERR_NVM_PBA_SECTION 18
-#define E1000_ERR_I2C 19
-#define E1000_ERR_INVM_VALUE_NOT_FOUND 20
-
-/* Loop limit on how long we wait for auto-negotiation to complete */
-#define FIBER_LINK_UP_LIMIT 50
-#define COPPER_LINK_UP_LIMIT 10
-#define PHY_AUTO_NEG_LIMIT 45
-#define PHY_FORCE_LIMIT 20
-/* Number of 100 microseconds we wait for PCI Express master disable */
-#define MASTER_DISABLE_TIMEOUT 800
-/* Number of milliseconds we wait for PHY configuration done after MAC reset */
-#define PHY_CFG_TIMEOUT 100
-/* Number of 2 milliseconds we wait for acquiring MDIO ownership. */
-#define MDIO_OWNERSHIP_TIMEOUT 10
-/* Number of milliseconds for NVM auto read done after MAC reset. */
-#define AUTO_READ_DONE_TIMEOUT 10
-
-/* Flow Control */
-#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */
-#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
-#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
-
-/* Transmit Configuration Word */
-#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
-#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */
-#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */
-#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */
-#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
-
-/* Receive Configuration Word */
-#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */
-#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */
-#define E1000_RXCW_C 0x20000000 /* Receive config */
-#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */
-
-#define E1000_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
-#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */
-
-#define E1000_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
-#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
-#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00
-#define E1000_TSYNCRXCTL_TYPE_L4_V1 0x02
-#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
-#define E1000_TSYNCRXCTL_TYPE_ALL 0x08
-#define E1000_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
-#define E1000_TSYNCRXCTL_ENABLED 0x00000010 /* enable Rx timestamping */
-#define E1000_TSYNCRXCTL_SYSCFI 0x00000020 /* Sys clock frequency */
-
-#define E1000_TSYNCRXCFG_PTP_V1_CTRLT_MASK 0x000000FF
-#define E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE 0x00
-#define E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE 0x01
-#define E1000_TSYNCRXCFG_PTP_V1_FOLLOWUP_MESSAGE 0x02
-#define E1000_TSYNCRXCFG_PTP_V1_DELAY_RESP_MESSAGE 0x03
-#define E1000_TSYNCRXCFG_PTP_V1_MANAGEMENT_MESSAGE 0x04
-
-#define E1000_TSYNCRXCFG_PTP_V2_MSGID_MASK 0x00000F00
-#define E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE 0x0000
-#define E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE 0x0100
-#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_REQ_MESSAGE 0x0200
-#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_RESP_MESSAGE 0x0300
-#define E1000_TSYNCRXCFG_PTP_V2_FOLLOWUP_MESSAGE 0x0800
-#define E1000_TSYNCRXCFG_PTP_V2_DELAY_RESP_MESSAGE 0x0900
-#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_FOLLOWUP_MESSAGE 0x0A00
-#define E1000_TSYNCRXCFG_PTP_V2_ANNOUNCE_MESSAGE 0x0B00
-#define E1000_TSYNCRXCFG_PTP_V2_SIGNALLING_MESSAGE 0x0C00
-#define E1000_TSYNCRXCFG_PTP_V2_MANAGEMENT_MESSAGE 0x0D00
-
-#define E1000_TIMINCA_16NS_SHIFT 24
-#define E1000_TIMINCA_INCPERIOD_SHIFT 24
-#define E1000_TIMINCA_INCVALUE_MASK 0x00FFFFFF
-
-#define E1000_TSICR_TXTS 0x00000002
-#define E1000_TSIM_TXTS 0x00000002
-/* TUPLE Filtering Configuration */
-#define E1000_TTQF_DISABLE_MASK 0xF0008000 /* TTQF Disable Mask */
-#define E1000_TTQF_QUEUE_ENABLE 0x100 /* TTQF Queue Enable Bit */
-#define E1000_TTQF_PROTOCOL_MASK 0xFF /* TTQF Protocol Mask */
-/* TTQF TCP Bit, shift with E1000_TTQF_PROTOCOL SHIFT */
-#define E1000_TTQF_PROTOCOL_TCP 0x0
-/* TTQF UDP Bit, shift with E1000_TTQF_PROTOCOL_SHIFT */
-#define E1000_TTQF_PROTOCOL_UDP 0x1
-/* TTQF SCTP Bit, shift with E1000_TTQF_PROTOCOL_SHIFT */
-#define E1000_TTQF_PROTOCOL_SCTP 0x2
-#define E1000_TTQF_PROTOCOL_SHIFT 5 /* TTQF Protocol Shift */
-#define E1000_TTQF_QUEUE_SHIFT 16 /* TTQF Queue Shfit */
-#define E1000_TTQF_RX_QUEUE_MASK 0x70000 /* TTQF Queue Mask */
-#define E1000_TTQF_MASK_ENABLE 0x10000000 /* TTQF Mask Enable Bit */
-#define E1000_IMIR_CLEAR_MASK 0xF001FFFF /* IMIR Reg Clear Mask */
-#define E1000_IMIR_PORT_BYPASS 0x20000 /* IMIR Port Bypass Bit */
-#define E1000_IMIR_PRIORITY_SHIFT 29 /* IMIR Priority Shift */
-#define E1000_IMIREXT_CLEAR_MASK 0x7FFFF /* IMIREXT Reg Clear Mask */
-
-#define E1000_MDICNFG_EXT_MDIO 0x80000000 /* MDI ext/int destination */
-#define E1000_MDICNFG_COM_MDIO 0x40000000 /* MDI shared w/ lan 0 */
-#define E1000_MDICNFG_PHY_MASK 0x03E00000
-#define E1000_MDICNFG_PHY_SHIFT 21
-
-#define E1000_MEDIA_PORT_COPPER 1
-#define E1000_MEDIA_PORT_OTHER 2
-#define E1000_M88E1112_AUTO_COPPER_SGMII 0x2
-#define E1000_M88E1112_AUTO_COPPER_BASEX 0x3
-#define E1000_M88E1112_STATUS_LINK 0x0004 /* Interface Link Bit */
-#define E1000_M88E1112_MAC_CTRL_1 0x10
-#define E1000_M88E1112_MAC_CTRL_1_MODE_MASK 0x0380 /* Mode Select */
-#define E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT 7
-#define E1000_M88E1112_PAGE_ADDR 0x16
-#define E1000_M88E1112_STATUS 0x01
-
-#define E1000_THSTAT_LOW_EVENT 0x20000000 /* Low thermal threshold */
-#define E1000_THSTAT_MID_EVENT 0x00200000 /* Mid thermal threshold */
-#define E1000_THSTAT_HIGH_EVENT 0x00002000 /* High thermal threshold */
-#define E1000_THSTAT_PWR_DOWN 0x00000001 /* Power Down Event */
-#define E1000_THSTAT_LINK_THROTTLE 0x00000002 /* Link Spd Throttle Event */
-
-/* I350 EEE defines */
-#define E1000_IPCNFG_EEE_1G_AN 0x00000008 /* IPCNFG EEE Ena 1G AN */
-#define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* IPCNFG EEE Ena 100M AN */
-#define E1000_EEER_TX_LPI_EN 0x00010000 /* EEER Tx LPI Enable */
-#define E1000_EEER_RX_LPI_EN 0x00020000 /* EEER Rx LPI Enable */
-#define E1000_EEER_LPI_FC 0x00040000 /* EEER Ena on Flow Cntrl */
-/* EEE status */
-#define E1000_EEER_EEE_NEG 0x20000000 /* EEE capability nego */
-#define E1000_EEER_RX_LPI_STATUS 0x40000000 /* Rx in LPI state */
-#define E1000_EEER_TX_LPI_STATUS 0x80000000 /* Tx in LPI state */
-#define E1000_EEE_LP_ADV_ADDR_I350 0x040F /* EEE LP Advertisement */
-#define E1000_M88E1543_PAGE_ADDR 0x16 /* Page Offset Register */
-#define E1000_M88E1543_EEE_CTRL_1 0x0
-#define E1000_M88E1543_EEE_CTRL_1_MS 0x0001 /* EEE Master/Slave */
-#define E1000_EEE_ADV_DEV_I354 7
-#define E1000_EEE_ADV_ADDR_I354 60
-#define E1000_EEE_ADV_100_SUPPORTED (1 << 1) /* 100BaseTx EEE Supported */
-#define E1000_EEE_ADV_1000_SUPPORTED (1 << 2) /* 1000BaseT EEE Supported */
-#define E1000_PCS_STATUS_DEV_I354 3
-#define E1000_PCS_STATUS_ADDR_I354 1
-#define E1000_PCS_STATUS_RX_LPI_RCVD 0x0400
-#define E1000_PCS_STATUS_TX_LPI_RCVD 0x0800
-#define E1000_EEE_SU_LPI_CLK_STP 0x00800000 /* EEE LPI Clock Stop */
-#define E1000_EEE_LP_ADV_DEV_I210 7 /* EEE LP Adv Device */
-#define E1000_EEE_LP_ADV_ADDR_I210 61 /* EEE LP Adv Register */
-/* PCI Express Control */
-#define E1000_GCR_RXD_NO_SNOOP 0x00000001
-#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002
-#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004
-#define E1000_GCR_TXD_NO_SNOOP 0x00000008
-#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010
-#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020
-#define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000
-#define E1000_GCR_CMPL_TMOUT_10ms 0x00001000
-#define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000
-#define E1000_GCR_CAP_VER2 0x00040000
-
-#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \
- E1000_GCR_RXDSCW_NO_SNOOP | \
- E1000_GCR_RXDSCR_NO_SNOOP | \
- E1000_GCR_TXD_NO_SNOOP | \
- E1000_GCR_TXDSCW_NO_SNOOP | \
- E1000_GCR_TXDSCR_NO_SNOOP)
-
-#define E1000_MMDAC_FUNC_DATA 0x4000 /* Data, no post increment */
-
-/* mPHY address control and data registers */
-#define E1000_MPHY_ADDR_CTL 0x0024 /* Address Control Reg */
-#define E1000_MPHY_ADDR_CTL_OFFSET_MASK 0xFFFF0000
-#define E1000_MPHY_DATA 0x0E10 /* Data Register */
-
-/* AFE CSR Offset for PCS CLK */
-#define E1000_MPHY_PCS_CLK_REG_OFFSET 0x0004
-/* Override for near end digital loopback. */
-#define E1000_MPHY_PCS_CLK_REG_DIGINELBEN 0x10
-
-/* PHY Control Register */
-#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
-#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
-#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
-#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
-#define MII_CR_POWER_DOWN 0x0800 /* Power down */
-#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
-#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
-#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
-#define MII_CR_SPEED_1000 0x0040
-#define MII_CR_SPEED_100 0x2000
-#define MII_CR_SPEED_10 0x0000
-
-/* PHY Status Register */
-#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
-#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
-#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
-#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
-#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
-#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
-#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
-#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
-#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
-#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
-#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
-#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
-#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
-#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
-#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
-
-/* Autoneg Advertisement Register */
-#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */
-#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
-#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
-#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
-#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
-#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */
-#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */
-#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */
-#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */
-#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */
-
-/* Link Partner Ability Register (Base Page) */
-#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */
-#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP 10T Half Dplx Capable */
-#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP 10T Full Dplx Capable */
-#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP 100TX Half Dplx Capable */
-#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP 100TX Full Dplx Capable */
-#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */
-#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */
-#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asym Pause Direction bit */
-#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP detected Remote Fault */
-#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP rx'd link code word */
-#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */
-
-/* Autoneg Expansion Register */
-#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */
-#define NWAY_ER_PAGE_RXD 0x0002 /* LP 10T Half Dplx Capable */
-#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP 10T Full Dplx Capable */
-#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP 100TX Half Dplx Capable */
-#define NWAY_ER_PAR_DETECT_FAULT 0x0010 /* LP 100TX Full Dplx Capable */
-
-/* 1000BASE-T Control Register */
-#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */
-#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
-#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
-/* 1=Repeater/switch device port 0=DTE device */
-#define CR_1000T_REPEATER_DTE 0x0400
-/* 1=Configure PHY as Master 0=Configure PHY as Slave */
-#define CR_1000T_MS_VALUE 0x0800
-/* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
-#define CR_1000T_MS_ENABLE 0x1000
-#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
-#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
-#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
-#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
-#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
-
-/* 1000BASE-T Status Register */
-#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle err since last rd */
-#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asym pause direction bit */
-#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
-#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
-#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
-#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
-#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local Tx Master, 0=Slave */
-#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */
-
-#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5
-
-/* PHY 1000 MII Register/Bit Definitions */
-/* PHY Registers defined by IEEE */
-#define PHY_CONTROL 0x00 /* Control Register */
-#define PHY_STATUS 0x01 /* Status Register */
-#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
-#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
-#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
-#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
-#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */
-#define PHY_NEXT_PAGE_TX 0x07 /* Next Page Tx */
-#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
-#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */
-#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
-#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
-
-#define PHY_CONTROL_LB 0x4000 /* PHY Loopback bit */
-
-/* NVM Control */
-#define E1000_EECD_SK 0x00000001 /* NVM Clock */
-#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */
-#define E1000_EECD_DI 0x00000004 /* NVM Data In */
-#define E1000_EECD_DO 0x00000008 /* NVM Data Out */
-#define E1000_EECD_REQ 0x00000040 /* NVM Access Request */
-#define E1000_EECD_GNT 0x00000080 /* NVM Access Grant */
-#define E1000_EECD_PRES 0x00000100 /* NVM Present */
-#define E1000_EECD_SIZE 0x00000200 /* NVM Size (0=64 word 1=256 word) */
-#define E1000_EECD_BLOCKED 0x00008000 /* Bit banging access blocked flag */
-#define E1000_EECD_ABORT 0x00010000 /* NVM operation aborted flag */
-#define E1000_EECD_TIMEOUT 0x00020000 /* NVM read operation timeout flag */
-#define E1000_EECD_ERROR_CLR 0x00040000 /* NVM error status clear bit */
-/* NVM Addressing bits based on type 0=small, 1=large */
-#define E1000_EECD_ADDR_BITS 0x00000400
-#define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */
-#define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */
-#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */
-#define E1000_EECD_SIZE_EX_SHIFT 11
-#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
-#define E1000_EECD_AUPDEN 0x00100000 /* Ena Auto FLASH update */
-#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
-#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES)
-#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */
-#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done */
-#define E1000_EECD_FLASH_DETECTED_I210 0x00080000 /* FLASH detected */
-#define E1000_EECD_SEC1VAL_I210 0x02000000 /* Sector One Valid */
-#define E1000_FLUDONE_ATTEMPTS 20000
-#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */
-#define E1000_I210_FIFO_SEL_RX 0x00
-#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i))
-#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0)
-#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06
-#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01
-
-#define E1000_I210_FLASH_SECTOR_SIZE 0x1000 /* 4KB FLASH sector unit size */
-/* Secure FLASH mode requires removing MSb */
-#define E1000_I210_FW_PTR_MASK 0x7FFF
-/* Firmware code revision field word offset*/
-#define E1000_I210_FW_VER_OFFSET 328
-
-#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write regs */
-#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
-#define E1000_NVM_RW_REG_START 1 /* Start operation */
-#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
-#define E1000_NVM_POLL_WRITE 1 /* Flag for polling for write complete */
-#define E1000_NVM_POLL_READ 0 /* Flag for polling for read complete */
-#define E1000_FLASH_UPDATES 2000
-
-/* NVM Word Offsets */
-#define NVM_COMPAT 0x0003
-#define NVM_ID_LED_SETTINGS 0x0004
-#define NVM_VERSION 0x0005
-#define E1000_I210_NVM_FW_MODULE_PTR 0x0010
-#define E1000_I350_NVM_FW_MODULE_PTR 0x0051
-#define NVM_FUTURE_INIT_WORD1 0x0019
-#define NVM_ETRACK_WORD 0x0042
-#define NVM_ETRACK_HIWORD 0x0043
-#define NVM_COMB_VER_OFF 0x0083
-#define NVM_COMB_VER_PTR 0x003d
-
-/* NVM version defines */
-#define NVM_MAJOR_MASK 0xF000
-#define NVM_MINOR_MASK 0x0FF0
-#define NVM_IMAGE_ID_MASK 0x000F
-#define NVM_COMB_VER_MASK 0x00FF
-#define NVM_MAJOR_SHIFT 12
-#define NVM_MINOR_SHIFT 4
-#define NVM_COMB_VER_SHFT 8
-#define NVM_VER_INVALID 0xFFFF
-#define NVM_ETRACK_SHIFT 16
-#define NVM_ETRACK_VALID 0x8000
-#define NVM_NEW_DEC_MASK 0x0F00
-#define NVM_HEX_CONV 16
-#define NVM_HEX_TENS 10
-
-/* FW version defines */
-/* Offset of "Loader patch ptr" in Firmware Header */
-#define E1000_I350_NVM_FW_LOADER_PATCH_PTR_OFFSET 0x01
-/* Patch generation hour & minutes */
-#define E1000_I350_NVM_FW_VER_WORD1_OFFSET 0x04
-/* Patch generation month & day */
-#define E1000_I350_NVM_FW_VER_WORD2_OFFSET 0x05
-/* Patch generation year */
-#define E1000_I350_NVM_FW_VER_WORD3_OFFSET 0x06
-/* Patch major & minor numbers */
-#define E1000_I350_NVM_FW_VER_WORD4_OFFSET 0x07
-
-#define NVM_MAC_ADDR 0x0000
-#define NVM_SUB_DEV_ID 0x000B
-#define NVM_SUB_VEN_ID 0x000C
-#define NVM_DEV_ID 0x000D
-#define NVM_VEN_ID 0x000E
-#define NVM_INIT_CTRL_2 0x000F
-#define NVM_INIT_CTRL_4 0x0013
-#define NVM_LED_1_CFG 0x001C
-#define NVM_LED_0_2_CFG 0x001F
-
-#define NVM_COMPAT_VALID_CSUM 0x0001
-#define NVM_FUTURE_INIT_WORD1_VALID_CSUM 0x0040
-
-#define NVM_ETS_CFG 0x003E
-#define NVM_ETS_LTHRES_DELTA_MASK 0x07C0
-#define NVM_ETS_LTHRES_DELTA_SHIFT 6
-#define NVM_ETS_TYPE_MASK 0x0038
-#define NVM_ETS_TYPE_SHIFT 3
-#define NVM_ETS_TYPE_EMC 0x000
-#define NVM_ETS_NUM_SENSORS_MASK 0x0007
-#define NVM_ETS_DATA_LOC_MASK 0x3C00
-#define NVM_ETS_DATA_LOC_SHIFT 10
-#define NVM_ETS_DATA_INDEX_MASK 0x0300
-#define NVM_ETS_DATA_INDEX_SHIFT 8
-#define NVM_ETS_DATA_HTHRESH_MASK 0x00FF
-#define NVM_INIT_CONTROL2_REG 0x000F
-#define NVM_INIT_CONTROL3_PORT_B 0x0014
-#define NVM_INIT_3GIO_3 0x001A
-#define NVM_SWDEF_PINS_CTRL_PORT_0 0x0020
-#define NVM_INIT_CONTROL3_PORT_A 0x0024
-#define NVM_CFG 0x0012
-#define NVM_ALT_MAC_ADDR_PTR 0x0037
-#define NVM_CHECKSUM_REG 0x003F
-#define NVM_COMPATIBILITY_REG_3 0x0003
-#define NVM_COMPATIBILITY_BIT_MASK 0x8000
-
-#define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */
-#define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */
-#define E1000_NVM_CFG_DONE_PORT_2 0x100000 /* ...for third port */
-#define E1000_NVM_CFG_DONE_PORT_3 0x200000 /* ...for fourth port */
-
-#define NVM_82580_LAN_FUNC_OFFSET(a) ((a) ? (0x40 + (0x40 * (a))) : 0)
-
-/* Mask bits for fields in Word 0x24 of the NVM */
-#define NVM_WORD24_COM_MDIO 0x0008 /* MDIO interface shared */
-#define NVM_WORD24_EXT_MDIO 0x0004 /* MDIO accesses routed extrnl */
-/* Offset of Link Mode bits for 82575/82576 */
-#define NVM_WORD24_LNK_MODE_OFFSET 8
-/* Offset of Link Mode bits for 82580 up */
-#define NVM_WORD24_82580_LNK_MODE_OFFSET 4
-
-
-/* Mask bits for fields in Word 0x0f of the NVM */
-#define NVM_WORD0F_PAUSE_MASK 0x3000
-#define NVM_WORD0F_PAUSE 0x1000
-#define NVM_WORD0F_ASM_DIR 0x2000
-
-/* Mask bits for fields in Word 0x1a of the NVM */
-#define NVM_WORD1A_ASPM_MASK 0x000C
-
-/* Mask bits for fields in Word 0x03 of the EEPROM */
-#define NVM_COMPAT_LOM 0x0800
-
-/* length of string needed to store PBA number */
-#define E1000_PBANUM_LENGTH 11
-
-/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
-#define NVM_SUM 0xBABA
-
-/* PBA (printed board assembly) number words */
-#define NVM_PBA_OFFSET_0 8
-#define NVM_PBA_OFFSET_1 9
-#define NVM_PBA_PTR_GUARD 0xFAFA
-#define NVM_RESERVED_WORD 0xFFFF
-#define NVM_WORD_SIZE_BASE_SHIFT 6
-
-/* NVM Commands - SPI */
-#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
-#define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */
-#define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */
-#define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */
-#define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */
-#define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */
-
-/* SPI NVM Status Register */
-#define NVM_STATUS_RDY_SPI 0x01
-
-/* Word definitions for ID LED Settings */
-#define ID_LED_RESERVED_0000 0x0000
-#define ID_LED_RESERVED_FFFF 0xFFFF
-#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \
- (ID_LED_OFF1_OFF2 << 8) | \
- (ID_LED_DEF1_DEF2 << 4) | \
- (ID_LED_DEF1_DEF2))
-#define ID_LED_DEF1_DEF2 0x1
-#define ID_LED_DEF1_ON2 0x2
-#define ID_LED_DEF1_OFF2 0x3
-#define ID_LED_ON1_DEF2 0x4
-#define ID_LED_ON1_ON2 0x5
-#define ID_LED_ON1_OFF2 0x6
-#define ID_LED_OFF1_DEF2 0x7
-#define ID_LED_OFF1_ON2 0x8
-#define ID_LED_OFF1_OFF2 0x9
-
-#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
-#define IGP_ACTIVITY_LED_ENABLE 0x0300
-#define IGP_LED3_MODE 0x07000000
-
-/* PCI/PCI-X/PCI-EX Config space */
-#define PCI_HEADER_TYPE_REGISTER 0x0E
-#define PCIE_LINK_STATUS 0x12
-#define PCIE_DEVICE_CONTROL2 0x28
-
-#define PCI_HEADER_TYPE_MULTIFUNC 0x80
-#define PCIE_LINK_WIDTH_MASK 0x3F0
-#define PCIE_LINK_WIDTH_SHIFT 4
-#define PCIE_LINK_SPEED_MASK 0x0F
-#define PCIE_LINK_SPEED_2500 0x01
-#define PCIE_LINK_SPEED_5000 0x02
-#define PCIE_DEVICE_CONTROL2_16ms 0x0005
-
-#ifndef ETH_ADDR_LEN
-#define ETH_ADDR_LEN 6
-#endif
-
-#define PHY_REVISION_MASK 0xFFFFFFF0
-#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
-#define MAX_PHY_MULTI_PAGE_REG 0xF
-
-/* Bit definitions for valid PHY IDs.
- * I = Integrated
- * E = External
- */
-#define M88E1000_E_PHY_ID 0x01410C50
-#define M88E1000_I_PHY_ID 0x01410C30
-#define M88E1011_I_PHY_ID 0x01410C20
-#define IGP01E1000_I_PHY_ID 0x02A80380
-#define M88E1111_I_PHY_ID 0x01410CC0
-#define M88E1543_E_PHY_ID 0x01410EA0
-#define M88E1112_E_PHY_ID 0x01410C90
-#define I347AT4_E_PHY_ID 0x01410DC0
-#define M88E1340M_E_PHY_ID 0x01410DF0
-#define GG82563_E_PHY_ID 0x01410CA0
-#define IGP03E1000_E_PHY_ID 0x02A80390
-#define IFE_E_PHY_ID 0x02A80330
-#define IFE_PLUS_E_PHY_ID 0x02A80320
-#define IFE_C_E_PHY_ID 0x02A80310
-#define I82580_I_PHY_ID 0x015403A0
-#define I350_I_PHY_ID 0x015403B0
-#define I210_I_PHY_ID 0x01410C00
-#define IGP04E1000_E_PHY_ID 0x02A80391
-#define M88_VENDOR 0x0141
-
-/* M88E1000 Specific Registers */
-#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Reg */
-#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Reg */
-#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Cntrl */
-#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
-
-#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for pg number setting */
-#define M88E1000_PHY_GEN_CONTROL 0x1E /* meaning depends on reg 29 */
-
-/* M88E1000 PHY Specific Control Register */
-#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reverse enabled */
-/* MDI Crossover Mode bits 6:5 Manual MDI configuration */
-#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000
-#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
-/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
-#define M88E1000_PSCR_AUTO_X_1000T 0x0040
-/* Auto crossover enabled all speeds */
-#define M88E1000_PSCR_AUTO_X_MODE 0x0060
-#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Tx */
-
-/* M88E1000 PHY Specific Status Register */
-#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
-#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */
-#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
-/* 0 = <50M
- * 1 = 50-80M
- * 2 = 80-110M
- * 3 = 110-140M
- * 4 = >140M
- */
-#define M88E1000_PSSR_CABLE_LENGTH 0x0380
-#define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */
-#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
-#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
-#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
-
-#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
-
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the master
- */
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the slave
- */
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100
-#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
-
-/* Intel I347AT4 Registers */
-#define I347AT4_PCDL 0x10 /* PHY Cable Diagnostics Length */
-#define I347AT4_PCDC 0x15 /* PHY Cable Diagnostics Control */
-#define I347AT4_PAGE_SELECT 0x16
-
-/* I347AT4 Extended PHY Specific Control Register */
-
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the master
- */
-#define I347AT4_PSCR_DOWNSHIFT_ENABLE 0x0800
-#define I347AT4_PSCR_DOWNSHIFT_MASK 0x7000
-#define I347AT4_PSCR_DOWNSHIFT_1X 0x0000
-#define I347AT4_PSCR_DOWNSHIFT_2X 0x1000
-#define I347AT4_PSCR_DOWNSHIFT_3X 0x2000
-#define I347AT4_PSCR_DOWNSHIFT_4X 0x3000
-#define I347AT4_PSCR_DOWNSHIFT_5X 0x4000
-#define I347AT4_PSCR_DOWNSHIFT_6X 0x5000
-#define I347AT4_PSCR_DOWNSHIFT_7X 0x6000
-#define I347AT4_PSCR_DOWNSHIFT_8X 0x7000
-
-/* I347AT4 PHY Cable Diagnostics Control */
-#define I347AT4_PCDC_CABLE_LENGTH_UNIT 0x0400 /* 0=cm 1=meters */
-
-/* M88E1112 only registers */
-#define M88E1112_VCT_DSP_DISTANCE 0x001A
-
-/* M88EC018 Rev 2 specific DownShift settings */
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
-
-/* Bits...
- * 15-5: page
- * 4-0: register offset
- */
-#define GG82563_PAGE_SHIFT 5
-#define GG82563_REG(page, reg) \
- (((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))
-#define GG82563_MIN_ALT_REG 30
-
-/* GG82563 Specific Registers */
-#define GG82563_PHY_SPEC_CTRL GG82563_REG(0, 16) /* PHY Spec Cntrl */
-#define GG82563_PHY_PAGE_SELECT GG82563_REG(0, 22) /* Page Select */
-#define GG82563_PHY_SPEC_CTRL_2 GG82563_REG(0, 26) /* PHY Spec Cntrl2 */
-#define GG82563_PHY_PAGE_SELECT_ALT GG82563_REG(0, 29) /* Alt Page Select */
-
-/* MAC Specific Control Register */
-#define GG82563_PHY_MAC_SPEC_CTRL GG82563_REG(2, 21)
-
-#define GG82563_PHY_DSP_DISTANCE GG82563_REG(5, 26) /* DSP Distance */
-
-/* Page 193 - Port Control Registers */
-/* Kumeran Mode Control */
-#define GG82563_PHY_KMRN_MODE_CTRL GG82563_REG(193, 16)
-#define GG82563_PHY_PWR_MGMT_CTRL GG82563_REG(193, 20) /* Pwr Mgt Ctrl */
-
-/* Page 194 - KMRN Registers */
-#define GG82563_PHY_INBAND_CTRL GG82563_REG(194, 18) /* Inband Ctrl */
-
-/* MDI Control */
-#define E1000_MDIC_REG_MASK 0x001F0000
-#define E1000_MDIC_REG_SHIFT 16
-#define E1000_MDIC_PHY_MASK 0x03E00000
-#define E1000_MDIC_PHY_SHIFT 21
-#define E1000_MDIC_OP_WRITE 0x04000000
-#define E1000_MDIC_OP_READ 0x08000000
-#define E1000_MDIC_READY 0x10000000
-#define E1000_MDIC_ERROR 0x40000000
-#define E1000_MDIC_DEST 0x80000000
-
-/* SerDes Control */
-#define E1000_GEN_CTL_READY 0x80000000
-#define E1000_GEN_CTL_ADDRESS_SHIFT 8
-#define E1000_GEN_POLL_TIMEOUT 640
-
-/* LinkSec register fields */
-#define E1000_LSECTXCAP_SUM_MASK 0x00FF0000
-#define E1000_LSECTXCAP_SUM_SHIFT 16
-#define E1000_LSECRXCAP_SUM_MASK 0x00FF0000
-#define E1000_LSECRXCAP_SUM_SHIFT 16
-
-#define E1000_LSECTXCTRL_EN_MASK 0x00000003
-#define E1000_LSECTXCTRL_DISABLE 0x0
-#define E1000_LSECTXCTRL_AUTH 0x1
-#define E1000_LSECTXCTRL_AUTH_ENCRYPT 0x2
-#define E1000_LSECTXCTRL_AISCI 0x00000020
-#define E1000_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00
-#define E1000_LSECTXCTRL_RSV_MASK 0x000000D8
-
-#define E1000_LSECRXCTRL_EN_MASK 0x0000000C
-#define E1000_LSECRXCTRL_EN_SHIFT 2
-#define E1000_LSECRXCTRL_DISABLE 0x0
-#define E1000_LSECRXCTRL_CHECK 0x1
-#define E1000_LSECRXCTRL_STRICT 0x2
-#define E1000_LSECRXCTRL_DROP 0x3
-#define E1000_LSECRXCTRL_PLSH 0x00000040
-#define E1000_LSECRXCTRL_RP 0x00000080
-#define E1000_LSECRXCTRL_RSV_MASK 0xFFFFFF33
-
-/* Tx Rate-Scheduler Config fields */
-#define E1000_RTTBCNRC_RS_ENA 0x80000000
-#define E1000_RTTBCNRC_RF_DEC_MASK 0x00003FFF
-#define E1000_RTTBCNRC_RF_INT_SHIFT 14
-#define E1000_RTTBCNRC_RF_INT_MASK \
- (E1000_RTTBCNRC_RF_DEC_MASK << E1000_RTTBCNRC_RF_INT_SHIFT)
-
-/* DMA Coalescing register fields */
-/* DMA Coalescing Watchdog Timer */
-#define E1000_DMACR_DMACWT_MASK 0x00003FFF
-/* DMA Coalescing Rx Threshold */
-#define E1000_DMACR_DMACTHR_MASK 0x00FF0000
-#define E1000_DMACR_DMACTHR_SHIFT 16
-/* Lx when no PCIe transactions */
-#define E1000_DMACR_DMAC_LX_MASK 0x30000000
-#define E1000_DMACR_DMAC_LX_SHIFT 28
-#define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */
-/* DMA Coalescing BMC-to-OS Watchdog Enable */
-#define E1000_DMACR_DC_BMC2OSW_EN 0x00008000
-
-/* DMA Coalescing Transmit Threshold */
-#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF
-
-#define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */
-
-/* Rx Traffic Rate Threshold */
-#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF
-/* Rx packet rate in current window */
-#define E1000_DMCRTRH_LRPRCW 0x80000000
-
-/* DMA Coal Rx Traffic Current Count */
-#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF
-
-/* Flow ctrl Rx Threshold High val */
-#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0
-#define E1000_FCRTC_RTH_COAL_SHIFT 4
-/* Lx power decision based on DMA coal */
-#define E1000_PCIEMISC_LX_DECISION 0x00000080
-
-#define E1000_RXPBS_CFG_TS_EN 0x80000000 /* Timestamp in Rx buffer */
-#define E1000_RXPBS_SIZE_I210_MASK 0x0000003F /* Rx packet buffer size */
-#define E1000_TXPB0S_SIZE_I210_MASK 0x0000003F /* Tx packet buffer 0 size */
-
-/* Proxy Filter Control */
-#define E1000_PROXYFC_D0 0x00000001 /* Enable offload in D0 */
-#define E1000_PROXYFC_EX 0x00000004 /* Directed exact proxy */
-#define E1000_PROXYFC_MC 0x00000008 /* Directed MC Proxy */
-#define E1000_PROXYFC_BC 0x00000010 /* Broadcast Proxy Enable */
-#define E1000_PROXYFC_ARP_DIRECTED 0x00000020 /* Directed ARP Proxy Ena */
-#define E1000_PROXYFC_IPV4 0x00000040 /* Directed IPv4 Enable */
-#define E1000_PROXYFC_IPV6 0x00000080 /* Directed IPv6 Enable */
-#define E1000_PROXYFC_NS 0x00000200 /* IPv6 Neighbor Solicitation */
-#define E1000_PROXYFC_ARP 0x00000800 /* ARP Request Proxy Ena */
-/* Proxy Status */
-#define E1000_PROXYS_CLEAR 0xFFFFFFFF /* Clear */
-
-/* Firmware Status */
-#define E1000_FWSTS_FWRI 0x80000000 /* FW Reset Indication */
-/* VF Control */
-#define E1000_VTCTRL_RST 0x04000000 /* Reset VF */
-
-#define E1000_STATUS_LAN_ID_MASK 0x00000000C /* Mask for Lan ID field */
-/* Lan ID bit field offset in status register */
-#define E1000_STATUS_LAN_ID_OFFSET 2
-#define E1000_VFTA_ENTRIES 128
-#ifndef E1000_UNUSEDARG
-#define E1000_UNUSEDARG
-#endif /* E1000_UNUSEDARG */
-#endif /* _E1000_DEFINES_H_ */
diff --git a/kernel/linux/kni/ethtool/igb/e1000_hw.h b/kernel/linux/kni/ethtool/igb/e1000_hw.h
deleted file mode 100644
index ed43ef5a1..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_hw.h
+++ /dev/null
@@ -1,778 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_HW_H_
-#define _E1000_HW_H_
-
-#include "e1000_osdep.h"
-#include "e1000_regs.h"
-#include "e1000_defines.h"
-
-struct e1000_hw;
-
-#define E1000_DEV_ID_82576 0x10C9
-#define E1000_DEV_ID_82576_FIBER 0x10E6
-#define E1000_DEV_ID_82576_SERDES 0x10E7
-#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
-#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526
-#define E1000_DEV_ID_82576_NS 0x150A
-#define E1000_DEV_ID_82576_NS_SERDES 0x1518
-#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
-#define E1000_DEV_ID_82575EB_COPPER 0x10A7
-#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
-#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
-#define E1000_DEV_ID_82580_COPPER 0x150E
-#define E1000_DEV_ID_82580_FIBER 0x150F
-#define E1000_DEV_ID_82580_SERDES 0x1510
-#define E1000_DEV_ID_82580_SGMII 0x1511
-#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516
-#define E1000_DEV_ID_82580_QUAD_FIBER 0x1527
-#define E1000_DEV_ID_I350_COPPER 0x1521
-#define E1000_DEV_ID_I350_FIBER 0x1522
-#define E1000_DEV_ID_I350_SERDES 0x1523
-#define E1000_DEV_ID_I350_SGMII 0x1524
-#define E1000_DEV_ID_I350_DA4 0x1546
-#define E1000_DEV_ID_I210_COPPER 0x1533
-#define E1000_DEV_ID_I210_COPPER_OEM1 0x1534
-#define E1000_DEV_ID_I210_COPPER_IT 0x1535
-#define E1000_DEV_ID_I210_FIBER 0x1536
-#define E1000_DEV_ID_I210_SERDES 0x1537
-#define E1000_DEV_ID_I210_SGMII 0x1538
-#define E1000_DEV_ID_I210_COPPER_FLASHLESS 0x157B
-#define E1000_DEV_ID_I210_SERDES_FLASHLESS 0x157C
-#define E1000_DEV_ID_I211_COPPER 0x1539
-#define E1000_DEV_ID_I354_BACKPLANE_1GBPS 0x1F40
-#define E1000_DEV_ID_I354_SGMII 0x1F41
-#define E1000_DEV_ID_I354_BACKPLANE_2_5GBPS 0x1F45
-#define E1000_DEV_ID_DH89XXCC_SGMII 0x0438
-#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A
-#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C
-#define E1000_DEV_ID_DH89XXCC_SFP 0x0440
-
-#define E1000_REVISION_0 0
-#define E1000_REVISION_1 1
-#define E1000_REVISION_2 2
-#define E1000_REVISION_3 3
-#define E1000_REVISION_4 4
-
-#define E1000_FUNC_0 0
-#define E1000_FUNC_1 1
-#define E1000_FUNC_2 2
-#define E1000_FUNC_3 3
-
-#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0
-#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3
-#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN2 6
-#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN3 9
-
-enum e1000_mac_type {
- e1000_undefined = 0,
- e1000_82575,
- e1000_82576,
- e1000_82580,
- e1000_i350,
- e1000_i354,
- e1000_i210,
- e1000_i211,
- e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
-};
-
-enum e1000_media_type {
- e1000_media_type_unknown = 0,
- e1000_media_type_copper = 1,
- e1000_media_type_fiber = 2,
- e1000_media_type_internal_serdes = 3,
- e1000_num_media_types
-};
-
-enum e1000_nvm_type {
- e1000_nvm_unknown = 0,
- e1000_nvm_none,
- e1000_nvm_eeprom_spi,
- e1000_nvm_flash_hw,
- e1000_nvm_invm,
- e1000_nvm_flash_sw
-};
-
-enum e1000_nvm_override {
- e1000_nvm_override_none = 0,
- e1000_nvm_override_spi_small,
- e1000_nvm_override_spi_large,
-};
-
-enum e1000_phy_type {
- e1000_phy_unknown = 0,
- e1000_phy_none,
- e1000_phy_m88,
- e1000_phy_igp,
- e1000_phy_igp_2,
- e1000_phy_gg82563,
- e1000_phy_igp_3,
- e1000_phy_ife,
- e1000_phy_82580,
- e1000_phy_vf,
- e1000_phy_i210,
-};
-
-enum e1000_bus_type {
- e1000_bus_type_unknown = 0,
- e1000_bus_type_pci,
- e1000_bus_type_pcix,
- e1000_bus_type_pci_express,
- e1000_bus_type_reserved
-};
-
-enum e1000_bus_speed {
- e1000_bus_speed_unknown = 0,
- e1000_bus_speed_33,
- e1000_bus_speed_66,
- e1000_bus_speed_100,
- e1000_bus_speed_120,
- e1000_bus_speed_133,
- e1000_bus_speed_2500,
- e1000_bus_speed_5000,
- e1000_bus_speed_reserved
-};
-
-enum e1000_bus_width {
- e1000_bus_width_unknown = 0,
- e1000_bus_width_pcie_x1,
- e1000_bus_width_pcie_x2,
- e1000_bus_width_pcie_x4 = 4,
- e1000_bus_width_pcie_x8 = 8,
- e1000_bus_width_32,
- e1000_bus_width_64,
- e1000_bus_width_reserved
-};
-
-enum e1000_1000t_rx_status {
- e1000_1000t_rx_status_not_ok = 0,
- e1000_1000t_rx_status_ok,
- e1000_1000t_rx_status_undefined = 0xFF
-};
-
-enum e1000_rev_polarity {
- e1000_rev_polarity_normal = 0,
- e1000_rev_polarity_reversed,
- e1000_rev_polarity_undefined = 0xFF
-};
-
-enum e1000_fc_mode {
- e1000_fc_none = 0,
- e1000_fc_rx_pause,
- e1000_fc_tx_pause,
- e1000_fc_full,
- e1000_fc_default = 0xFF
-};
-
-enum e1000_ms_type {
- e1000_ms_hw_default = 0,
- e1000_ms_force_master,
- e1000_ms_force_slave,
- e1000_ms_auto
-};
-
-enum e1000_smart_speed {
- e1000_smart_speed_default = 0,
- e1000_smart_speed_on,
- e1000_smart_speed_off
-};
-
-enum e1000_serdes_link_state {
- e1000_serdes_link_down = 0,
- e1000_serdes_link_autoneg_progress,
- e1000_serdes_link_autoneg_complete,
- e1000_serdes_link_forced_up
-};
-
-#ifndef __le16
-#define __le16 u16
-#endif
-#ifndef __le32
-#define __le32 u32
-#endif
-#ifndef __le64
-#define __le64 u64
-#endif
-/* Receive Descriptor */
-struct e1000_rx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- __le16 length; /* Length of data DMAed into data buffer */
- __le16 csum; /* Packet checksum */
- u8 status; /* Descriptor status */
- u8 errors; /* Descriptor Errors */
- __le16 special;
-};
-
-/* Receive Descriptor - Extended */
-union e1000_rx_desc_extended {
- struct {
- __le64 buffer_addr;
- __le64 reserved;
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length;
- __le16 vlan; /* VLAN tag */
- } upper;
- } wb; /* writeback */
-};
-
-#define MAX_PS_BUFFERS 4
-
-/* Number of packet split data buffers (not including the header buffer) */
-#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
-
-/* Receive Descriptor - Packet Split */
-union e1000_rx_desc_packet_split {
- struct {
- /* one buffer for protocol header(s), three data buffers */
- __le64 buffer_addr[MAX_PS_BUFFERS];
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length0; /* length of buffer 0 */
- __le16 vlan; /* VLAN tag */
- } middle;
- struct {
- __le16 header_status;
- /* length of buffers 1-3 */
- __le16 length[PS_PAGE_BUFFERS];
- } upper;
- __le64 reserved;
- } wb; /* writeback */
-};
-
-/* Transmit Descriptor */
-struct e1000_tx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 cso; /* Checksum offset */
- u8 cmd; /* Descriptor control */
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 css; /* Checksum start */
- __le16 special;
- } fields;
- } upper;
-};
-
-/* Offload Context Descriptor */
-struct e1000_context_desc {
- union {
- __le32 ip_config;
- struct {
- u8 ipcss; /* IP checksum start */
- u8 ipcso; /* IP checksum offset */
- __le16 ipcse; /* IP checksum end */
- } ip_fields;
- } lower_setup;
- union {
- __le32 tcp_config;
- struct {
- u8 tucss; /* TCP checksum start */
- u8 tucso; /* TCP checksum offset */
- __le16 tucse; /* TCP checksum end */
- } tcp_fields;
- } upper_setup;
- __le32 cmd_and_length;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 hdr_len; /* Header length */
- __le16 mss; /* Maximum segment size */
- } fields;
- } tcp_seg_setup;
-};
-
-/* Offload data descriptor */
-struct e1000_data_desc {
- __le64 buffer_addr; /* Address of the descriptor's buffer address */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 typ_len_ext;
- u8 cmd;
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 popts; /* Packet Options */
- __le16 special;
- } fields;
- } upper;
-};
-
-/* Statistics counters collected by the MAC */
-struct e1000_hw_stats {
- u64 crcerrs;
- u64 algnerrc;
- u64 symerrs;
- u64 rxerrc;
- u64 mpc;
- u64 scc;
- u64 ecol;
- u64 mcc;
- u64 latecol;
- u64 colc;
- u64 dc;
- u64 tncrs;
- u64 sec;
- u64 cexterr;
- u64 rlec;
- u64 xonrxc;
- u64 xontxc;
- u64 xoffrxc;
- u64 xofftxc;
- u64 fcruc;
- u64 prc64;
- u64 prc127;
- u64 prc255;
- u64 prc511;
- u64 prc1023;
- u64 prc1522;
- u64 gprc;
- u64 bprc;
- u64 mprc;
- u64 gptc;
- u64 gorc;
- u64 gotc;
- u64 rnbc;
- u64 ruc;
- u64 rfc;
- u64 roc;
- u64 rjc;
- u64 mgprc;
- u64 mgpdc;
- u64 mgptc;
- u64 tor;
- u64 tot;
- u64 tpr;
- u64 tpt;
- u64 ptc64;
- u64 ptc127;
- u64 ptc255;
- u64 ptc511;
- u64 ptc1023;
- u64 ptc1522;
- u64 mptc;
- u64 bptc;
- u64 tsctc;
- u64 tsctfc;
- u64 iac;
- u64 icrxptc;
- u64 icrxatc;
- u64 ictxptc;
- u64 ictxatc;
- u64 ictxqec;
- u64 ictxqmtc;
- u64 icrxdmtc;
- u64 icrxoc;
- u64 cbtmpc;
- u64 htdpmc;
- u64 cbrdpc;
- u64 cbrmpc;
- u64 rpthc;
- u64 hgptc;
- u64 htcbdpc;
- u64 hgorc;
- u64 hgotc;
- u64 lenerrs;
- u64 scvpc;
- u64 hrmpc;
- u64 doosync;
- u64 o2bgptc;
- u64 o2bspc;
- u64 b2ospc;
- u64 b2ogprc;
-};
-
-
-struct e1000_phy_stats {
- u32 idle_errors;
- u32 receive_errors;
-};
-
-struct e1000_host_mng_dhcp_cookie {
- u32 signature;
- u8 status;
- u8 reserved0;
- u16 vlan_id;
- u32 reserved1;
- u16 reserved2;
- u8 reserved3;
- u8 checksum;
-};
-
-/* Host Interface "Rev 1" */
-struct e1000_host_command_header {
- u8 command_id;
- u8 command_length;
- u8 command_options;
- u8 checksum;
-};
-
-#define E1000_HI_MAX_DATA_LENGTH 252
-struct e1000_host_command_info {
- struct e1000_host_command_header command_header;
- u8 command_data[E1000_HI_MAX_DATA_LENGTH];
-};
-
-/* Host Interface "Rev 2" */
-struct e1000_host_mng_command_header {
- u8 command_id;
- u8 checksum;
- u16 reserved1;
- u16 reserved2;
- u16 command_length;
-};
-
-#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
-struct e1000_host_mng_command_info {
- struct e1000_host_mng_command_header command_header;
- u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
-};
-
-#include "e1000_mac.h"
-#include "e1000_phy.h"
-#include "e1000_nvm.h"
-#include "e1000_manage.h"
-#include "e1000_mbx.h"
-
-/* Function pointers for the MAC. */
-struct e1000_mac_operations {
- s32 (*init_params)(struct e1000_hw *);
- s32 (*id_led_init)(struct e1000_hw *);
- s32 (*blink_led)(struct e1000_hw *);
- bool (*check_mng_mode)(struct e1000_hw *);
- s32 (*check_for_link)(struct e1000_hw *);
- s32 (*cleanup_led)(struct e1000_hw *);
- void (*clear_hw_cntrs)(struct e1000_hw *);
- void (*clear_vfta)(struct e1000_hw *);
- s32 (*get_bus_info)(struct e1000_hw *);
- void (*set_lan_id)(struct e1000_hw *);
- s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
- s32 (*led_on)(struct e1000_hw *);
- s32 (*led_off)(struct e1000_hw *);
- void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32);
- s32 (*reset_hw)(struct e1000_hw *);
- s32 (*init_hw)(struct e1000_hw *);
- void (*shutdown_serdes)(struct e1000_hw *);
- void (*power_up_serdes)(struct e1000_hw *);
- s32 (*setup_link)(struct e1000_hw *);
- s32 (*setup_physical_interface)(struct e1000_hw *);
- s32 (*setup_led)(struct e1000_hw *);
- void (*write_vfta)(struct e1000_hw *, u32, u32);
- void (*config_collision_dist)(struct e1000_hw *);
- void (*rar_set)(struct e1000_hw *, u8*, u32);
- s32 (*read_mac_addr)(struct e1000_hw *);
- s32 (*validate_mdi_setting)(struct e1000_hw *);
- s32 (*get_thermal_sensor_data)(struct e1000_hw *);
- s32 (*init_thermal_sensor_thresh)(struct e1000_hw *);
- s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
- void (*release_swfw_sync)(struct e1000_hw *, u16);
-};
-
-/* When to use various PHY register access functions:
- *
- * Func Caller
- * Function Does Does When to use
- * ~~~~~~~~~~~~ ~~~~~ ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * X_reg L,P,A n/a for simple PHY reg accesses
- * X_reg_locked P,A L for multiple accesses of different regs
- * on different pages
- * X_reg_page A L,P for multiple accesses of different regs
- * on the same page
- *
- * Where X=[read|write], L=locking, P=sets page, A=register access
- *
- */
-struct e1000_phy_operations {
- s32 (*init_params)(struct e1000_hw *);
- s32 (*acquire)(struct e1000_hw *);
- s32 (*check_polarity)(struct e1000_hw *);
- s32 (*check_reset_block)(struct e1000_hw *);
- s32 (*commit)(struct e1000_hw *);
- s32 (*force_speed_duplex)(struct e1000_hw *);
- s32 (*get_cfg_done)(struct e1000_hw *hw);
- s32 (*get_cable_length)(struct e1000_hw *);
- s32 (*get_info)(struct e1000_hw *);
- s32 (*set_page)(struct e1000_hw *, u16);
- s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
- s32 (*read_reg_locked)(struct e1000_hw *, u32, u16 *);
- s32 (*read_reg_page)(struct e1000_hw *, u32, u16 *);
- void (*release)(struct e1000_hw *);
- s32 (*reset)(struct e1000_hw *);
- s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
- s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
- s32 (*write_reg)(struct e1000_hw *, u32, u16);
- s32 (*write_reg_locked)(struct e1000_hw *, u32, u16);
- s32 (*write_reg_page)(struct e1000_hw *, u32, u16);
- void (*power_up)(struct e1000_hw *);
- void (*power_down)(struct e1000_hw *);
- s32 (*read_i2c_byte)(struct e1000_hw *, u8, u8, u8 *);
- s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8);
-};
-
-/* Function pointers for the NVM. */
-struct e1000_nvm_operations {
- s32 (*init_params)(struct e1000_hw *);
- s32 (*acquire)(struct e1000_hw *);
- s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
- void (*release)(struct e1000_hw *);
- void (*reload)(struct e1000_hw *);
- s32 (*update)(struct e1000_hw *);
- s32 (*valid_led_default)(struct e1000_hw *, u16 *);
- s32 (*validate)(struct e1000_hw *);
- s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
-};
-
-#define E1000_MAX_SENSORS 3
-
-struct e1000_thermal_diode_data {
- u8 location;
- u8 temp;
- u8 caution_thresh;
- u8 max_op_thresh;
-};
-
-struct e1000_thermal_sensor_data {
- struct e1000_thermal_diode_data sensor[E1000_MAX_SENSORS];
-};
-
-struct e1000_mac_info {
- struct e1000_mac_operations ops;
- u8 addr[ETH_ADDR_LEN];
- u8 perm_addr[ETH_ADDR_LEN];
-
- enum e1000_mac_type type;
-
- u32 collision_delta;
- u32 ledctl_default;
- u32 ledctl_mode1;
- u32 ledctl_mode2;
- u32 mc_filter_type;
- u32 tx_packet_delta;
- u32 txcw;
-
- u16 current_ifs_val;
- u16 ifs_max_val;
- u16 ifs_min_val;
- u16 ifs_ratio;
- u16 ifs_step_size;
- u16 mta_reg_count;
- u16 uta_reg_count;
-
- /* Maximum size of the MTA register table in all supported adapters */
- #define MAX_MTA_REG 128
- u32 mta_shadow[MAX_MTA_REG];
- u16 rar_entry_count;
-
- u8 forced_speed_duplex;
-
- bool adaptive_ifs;
- bool has_fwsm;
- bool arc_subsystem_valid;
- bool asf_firmware_present;
- bool autoneg;
- bool autoneg_failed;
- bool get_link_status;
- bool in_ifs_mode;
- enum e1000_serdes_link_state serdes_link_state;
- bool serdes_has_link;
- bool tx_pkt_filtering;
- struct e1000_thermal_sensor_data thermal_sensor_data;
-};
-
-struct e1000_phy_info {
- struct e1000_phy_operations ops;
- enum e1000_phy_type type;
-
- enum e1000_1000t_rx_status local_rx;
- enum e1000_1000t_rx_status remote_rx;
- enum e1000_ms_type ms_type;
- enum e1000_ms_type original_ms_type;
- enum e1000_rev_polarity cable_polarity;
- enum e1000_smart_speed smart_speed;
-
- u32 addr;
- u32 id;
- u32 reset_delay_us; /* in usec */
- u32 revision;
-
- enum e1000_media_type media_type;
-
- u16 autoneg_advertised;
- u16 autoneg_mask;
- u16 cable_length;
- u16 max_cable_length;
- u16 min_cable_length;
-
- u8 mdix;
-
- bool disable_polarity_correction;
- bool is_mdix;
- bool polarity_correction;
- bool reset_disable;
- bool speed_downgraded;
- bool autoneg_wait_to_complete;
-};
-
-struct e1000_nvm_info {
- struct e1000_nvm_operations ops;
- enum e1000_nvm_type type;
- enum e1000_nvm_override override;
-
- u32 flash_bank_size;
- u32 flash_base_addr;
-
- u16 word_size;
- u16 delay_usec;
- u16 address_bits;
- u16 opcode_bits;
- u16 page_size;
-};
-
-struct e1000_bus_info {
- enum e1000_bus_type type;
- enum e1000_bus_speed speed;
- enum e1000_bus_width width;
-
- u16 func;
- u16 pci_cmd_word;
-};
-
-struct e1000_fc_info {
- u32 high_water; /* Flow control high-water mark */
- u32 low_water; /* Flow control low-water mark */
- u16 pause_time; /* Flow control pause timer */
- u16 refresh_time; /* Flow control refresh timer */
- bool send_xon; /* Flow control send XON */
- bool strict_ieee; /* Strict IEEE mode */
- enum e1000_fc_mode current_mode; /* FC mode in effect */
- enum e1000_fc_mode requested_mode; /* FC mode requested by caller */
-};
-
-struct e1000_mbx_operations {
- s32 (*init_params)(struct e1000_hw *hw);
- s32 (*read)(struct e1000_hw *, u32 *, u16, u16);
- s32 (*write)(struct e1000_hw *, u32 *, u16, u16);
- s32 (*read_posted)(struct e1000_hw *, u32 *, u16, u16);
- s32 (*write_posted)(struct e1000_hw *, u32 *, u16, u16);
- s32 (*check_for_msg)(struct e1000_hw *, u16);
- s32 (*check_for_ack)(struct e1000_hw *, u16);
- s32 (*check_for_rst)(struct e1000_hw *, u16);
-};
-
-struct e1000_mbx_stats {
- u32 msgs_tx;
- u32 msgs_rx;
-
- u32 acks;
- u32 reqs;
- u32 rsts;
-};
-
-struct e1000_mbx_info {
- struct e1000_mbx_operations ops;
- struct e1000_mbx_stats stats;
- u32 timeout;
- u32 usec_delay;
- u16 size;
-};
-
-struct e1000_dev_spec_82575 {
- bool sgmii_active;
- bool global_device_reset;
- bool eee_disable;
- bool module_plugged;
- bool clear_semaphore_once;
- u32 mtu;
- struct sfp_e1000_flags eth_flags;
- u8 media_port;
- bool media_changed;
-};
-
-struct e1000_dev_spec_vf {
- u32 vf_number;
- u32 v2p_mailbox;
-};
-
-struct e1000_hw {
- void *back;
-
- u8 __iomem *hw_addr;
- u8 __iomem *flash_address;
- unsigned long io_base;
-
- struct e1000_mac_info mac;
- struct e1000_fc_info fc;
- struct e1000_phy_info phy;
- struct e1000_nvm_info nvm;
- struct e1000_bus_info bus;
- struct e1000_mbx_info mbx;
- struct e1000_host_mng_dhcp_cookie mng_cookie;
-
- union {
- struct e1000_dev_spec_82575 _82575;
- struct e1000_dev_spec_vf vf;
- } dev_spec;
-
- u16 device_id;
- u16 subsystem_vendor_id;
- u16 subsystem_device_id;
- u16 vendor_id;
-
- u8 revision_id;
-};
-
-#include "e1000_82575.h"
-#include "e1000_i210.h"
-
-/* These functions must be implemented by drivers */
-s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
-s32 e1000_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
-
-#endif
diff --git a/kernel/linux/kni/ethtool/igb/e1000_i210.c b/kernel/linux/kni/ethtool/igb/e1000_i210.c
deleted file mode 100644
index a4fabc3aa..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_i210.c
+++ /dev/null
@@ -1,894 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "e1000_api.h"
-
-
-static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw);
-static void e1000_release_nvm_i210(struct e1000_hw *hw);
-static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw);
-static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data);
-static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw);
-static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
-
-/**
- * e1000_acquire_nvm_i210 - Request for access to EEPROM
- * @hw: pointer to the HW structure
- *
- * Acquire the necessary semaphores for exclusive access to the EEPROM.
- * Set the EEPROM access request bit and wait for EEPROM access grant bit.
- * Return successful if access grant bit set, else clear the request for
- * EEPROM access and return -E1000_ERR_NVM (-1).
- **/
-static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_acquire_nvm_i210");
-
- ret_val = e1000_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
-
- return ret_val;
-}
-
-/**
- * e1000_release_nvm_i210 - Release exclusive access to EEPROM
- * @hw: pointer to the HW structure
- *
- * Stop any current commands to the EEPROM and clear the EEPROM request bit,
- * then release the semaphores acquired.
- **/
-static void e1000_release_nvm_i210(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_release_nvm_i210");
-
- e1000_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
-}
-
-/**
- * e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
- * will also specify which port we're acquiring the lock for.
- **/
-s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
- u32 swmask = mask;
- u32 fwmask = mask << 16;
- s32 ret_val = E1000_SUCCESS;
- s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
-
- DEBUGFUNC("e1000_acquire_swfw_sync_i210");
-
- while (i < timeout) {
- if (e1000_get_hw_semaphore_i210(hw)) {
- ret_val = -E1000_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- if (!(swfw_sync & (fwmask | swmask)))
- break;
-
- /*
- * Firmware currently using resource (fwmask)
- * or other software thread using resource (swmask)
- */
- e1000_put_hw_semaphore_generic(hw);
- msec_delay_irq(5);
- i++;
- }
-
- if (i == timeout) {
- DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
- ret_val = -E1000_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync |= swmask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_release_swfw_sync_i210 - Release SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Release the SW/FW semaphore used to access the PHY or NVM. The mask
- * will also specify which port we're releasing the lock for.
- **/
-void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
-
- DEBUGFUNC("e1000_release_swfw_sync_i210");
-
- while (e1000_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
- ; /* Empty */
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- swfw_sync &= ~mask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
-}
-
-/**
- * e1000_get_hw_semaphore_i210 - Acquire hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Acquire the HW semaphore to access the PHY or NVM
- **/
-static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
-{
- u32 swsm;
- s32 timeout = hw->nvm.word_size + 1;
- s32 i = 0;
-
- DEBUGFUNC("e1000_get_hw_semaphore_i210");
-
- /* Get the SW semaphore */
- while (i < timeout) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- if (!(swsm & E1000_SWSM_SMBI))
- break;
-
- usec_delay(50);
- i++;
- }
-
- if (i == timeout) {
- /* In rare circumstances, the SW semaphore may already be held
- * unintentionally. Clear the semaphore once before giving up.
- */
- if (hw->dev_spec._82575.clear_semaphore_once) {
- hw->dev_spec._82575.clear_semaphore_once = false;
- e1000_put_hw_semaphore_generic(hw);
- for (i = 0; i < timeout; i++) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- if (!(swsm & E1000_SWSM_SMBI))
- break;
-
- usec_delay(50);
- }
- }
-
- /* If we do not have the semaphore here, we have to give up. */
- if (i == timeout) {
- DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
- return -E1000_ERR_NVM;
- }
- }
-
- /* Get the FW semaphore. */
- for (i = 0; i < timeout; i++) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
-
- /* Semaphore acquired if bit latched */
- if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
- break;
-
- usec_delay(50);
- }
-
- if (i == timeout) {
- /* Release semaphores */
- e1000_put_hw_semaphore_generic(hw);
- DEBUGOUT("Driver can't access the NVM\n");
- return -E1000_ERR_NVM;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
- * @hw: pointer to the HW structure
- * @offset: offset of word in the Shadow Ram to read
- * @words: number of words to read
- * @data: word read from the Shadow Ram
- *
- * Reads a 16 bit word from the Shadow Ram using the EERD register.
- * Uses necessary synchronization semaphores.
- **/
-s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- s32 status = E1000_SUCCESS;
- u16 i, count;
-
- DEBUGFUNC("e1000_read_nvm_srrd_i210");
-
- /* We cannot hold synchronization semaphores for too long,
- * because of forceful takeover procedure. However it is more efficient
- * to read in bursts than synchronizing access for each word. */
- for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
- count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
- E1000_EERD_EEWR_MAX_COUNT : (words - i);
- if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
- status = e1000_read_nvm_eerd(hw, offset, count,
- data + i);
- hw->nvm.ops.release(hw);
- } else {
- status = E1000_ERR_SWFW_SYNC;
- }
-
- if (status != E1000_SUCCESS)
- break;
- }
-
- return status;
-}
-
-/**
- * e1000_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
- * @hw: pointer to the HW structure
- * @offset: offset within the Shadow RAM to be written to
- * @words: number of words to write
- * @data: 16 bit word(s) to be written to the Shadow RAM
- *
- * Writes data to Shadow RAM at offset using EEWR register.
- *
- * If e1000_update_nvm_checksum is not called after this function , the
- * data will not be committed to FLASH and also Shadow RAM will most likely
- * contain an invalid checksum.
- *
- * If error code is returned, data and Shadow RAM may be inconsistent - buffer
- * partially written.
- **/
-s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- s32 status = E1000_SUCCESS;
- u16 i, count;
-
- DEBUGFUNC("e1000_write_nvm_srwr_i210");
-
- /* We cannot hold synchronization semaphores for too long,
- * because of forceful takeover procedure. However it is more efficient
- * to write in bursts than synchronizing access for each word. */
- for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
- count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
- E1000_EERD_EEWR_MAX_COUNT : (words - i);
- if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
- status = e1000_write_nvm_srwr(hw, offset, count,
- data + i);
- hw->nvm.ops.release(hw);
- } else {
- status = E1000_ERR_SWFW_SYNC;
- }
-
- if (status != E1000_SUCCESS)
- break;
- }
-
- return status;
-}
-
-/**
- * e1000_write_nvm_srwr - Write to Shadow Ram using EEWR
- * @hw: pointer to the HW structure
- * @offset: offset within the Shadow Ram to be written to
- * @words: number of words to write
- * @data: 16 bit word(s) to be written to the Shadow Ram
- *
- * Writes data to Shadow Ram at offset using EEWR register.
- *
- * If e1000_update_nvm_checksum is not called after this function , the
- * Shadow Ram will most likely contain an invalid checksum.
- **/
-static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 i, k, eewr = 0;
- u32 attempts = 100000;
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_write_nvm_srwr");
-
- /*
- * A check for invalid values: offset too large, too many words,
- * too many words for the offset, and not enough words.
- */
- if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
- (words == 0)) {
- DEBUGOUT("nvm parameter(s) out of bounds\n");
- ret_val = -E1000_ERR_NVM;
- goto out;
- }
-
- for (i = 0; i < words; i++) {
- eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
- (data[i] << E1000_NVM_RW_REG_DATA) |
- E1000_NVM_RW_REG_START;
-
- E1000_WRITE_REG(hw, E1000_SRWR, eewr);
-
- for (k = 0; k < attempts; k++) {
- if (E1000_NVM_RW_REG_DONE &
- E1000_READ_REG(hw, E1000_SRWR)) {
- ret_val = E1000_SUCCESS;
- break;
- }
- usec_delay(5);
- }
-
- if (ret_val != E1000_SUCCESS) {
- DEBUGOUT("Shadow RAM write EEWR timed out\n");
- break;
- }
- }
-
-out:
- return ret_val;
-}
-
-/** e1000_read_invm_word_i210 - Reads OTP
- * @hw: pointer to the HW structure
- * @address: the word address (aka eeprom offset) to read
- * @data: pointer to the data read
- *
- * Reads 16-bit words from the OTP. Return error when the word is not
- * stored in OTP.
- **/
-static s32 e1000_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
-{
- s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
- u32 invm_dword;
- u16 i;
- u8 record_type, word_address;
-
- DEBUGFUNC("e1000_read_invm_word_i210");
-
- for (i = 0; i < E1000_INVM_SIZE; i++) {
- invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
- /* Get record type */
- record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
- if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
- break;
- if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
- i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
- if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
- i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
- if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
- word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
- if (word_address == address) {
- *data = INVM_DWORD_TO_WORD_DATA(invm_dword);
- DEBUGOUT2("Read INVM Word 0x%02x = %x",
- address, *data);
- status = E1000_SUCCESS;
- break;
- }
- }
- }
- if (status != E1000_SUCCESS)
- DEBUGOUT1("Requested word 0x%02x not found in OTP\n", address);
- return status;
-}
-
-/** e1000_read_invm_i210 - Read invm wrapper function for I210/I211
- * @hw: pointer to the HW structure
- * @address: the word address (aka eeprom offset) to read
- * @data: pointer to the data read
- *
- * Wrapper function to return data formerly found in the NVM.
- **/
-static s32 e1000_read_invm_i210(struct e1000_hw *hw, u16 offset,
- u16 E1000_UNUSEDARG words, u16 *data)
-{
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_read_invm_i210");
-
- /* Only the MAC addr is required to be present in the iNVM */
- switch (offset) {
- case NVM_MAC_ADDR:
- ret_val = e1000_read_invm_word_i210(hw, (u8)offset, &data[0]);
- ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+1,
- &data[1]);
- ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+2,
- &data[2]);
- if (ret_val != E1000_SUCCESS)
- DEBUGOUT("MAC Addr not found in iNVM\n");
- break;
- case NVM_INIT_CTRL_2:
- ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
- if (ret_val != E1000_SUCCESS) {
- *data = NVM_INIT_CTRL_2_DEFAULT_I211;
- ret_val = E1000_SUCCESS;
- }
- break;
- case NVM_INIT_CTRL_4:
- ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
- if (ret_val != E1000_SUCCESS) {
- *data = NVM_INIT_CTRL_4_DEFAULT_I211;
- ret_val = E1000_SUCCESS;
- }
- break;
- case NVM_LED_1_CFG:
- ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
- if (ret_val != E1000_SUCCESS) {
- *data = NVM_LED_1_CFG_DEFAULT_I211;
- ret_val = E1000_SUCCESS;
- }
- break;
- case NVM_LED_0_2_CFG:
- ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
- if (ret_val != E1000_SUCCESS) {
- *data = NVM_LED_0_2_CFG_DEFAULT_I211;
- ret_val = E1000_SUCCESS;
- }
- break;
- case NVM_ID_LED_SETTINGS:
- ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
- if (ret_val != E1000_SUCCESS) {
- *data = ID_LED_RESERVED_FFFF;
- ret_val = E1000_SUCCESS;
- }
- break;
- case NVM_SUB_DEV_ID:
- *data = hw->subsystem_device_id;
- break;
- case NVM_SUB_VEN_ID:
- *data = hw->subsystem_vendor_id;
- break;
- case NVM_DEV_ID:
- *data = hw->device_id;
- break;
- case NVM_VEN_ID:
- *data = hw->vendor_id;
- break;
- default:
- DEBUGOUT1("NVM word 0x%02x is not mapped.\n", offset);
- *data = NVM_RESERVED_WORD;
- break;
- }
- return ret_val;
-}
-
-/**
- * e1000_read_invm_version - Reads iNVM version and image type
- * @hw: pointer to the HW structure
- * @invm_ver: version structure for the version read
- *
- * Reads iNVM version and image type.
- **/
-s32 e1000_read_invm_version(struct e1000_hw *hw,
- struct e1000_fw_version *invm_ver)
-{
- u32 *record = NULL;
- u32 *next_record = NULL;
- u32 i = 0;
- u32 invm_dword = 0;
- u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
- E1000_INVM_RECORD_SIZE_IN_BYTES);
- u32 buffer[E1000_INVM_SIZE];
- s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
- u16 version = 0;
-
- DEBUGFUNC("e1000_read_invm_version");
-
- /* Read iNVM memory */
- for (i = 0; i < E1000_INVM_SIZE; i++) {
- invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
- buffer[i] = invm_dword;
- }
-
- /* Read version number */
- for (i = 1; i < invm_blocks; i++) {
- record = &buffer[invm_blocks - i];
- next_record = &buffer[invm_blocks - i + 1];
-
- /* Check if we have first version location used */
- if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
- version = 0;
- status = E1000_SUCCESS;
- break;
- }
- /* Check if we have second version location used */
- else if ((i == 1) &&
- ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
- version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
- status = E1000_SUCCESS;
- break;
- }
- /*
- * Check if we have odd version location
- * used and it is the last one used
- */
- else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
- ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
- (i != 1))) {
- version = (*next_record & E1000_INVM_VER_FIELD_TWO)
- >> 13;
- status = E1000_SUCCESS;
- break;
- }
- /*
- * Check if we have even version location
- * used and it is the last one used
- */
- else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
- ((*record & 0x3) == 0)) {
- version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
- status = E1000_SUCCESS;
- break;
- }
- }
-
- if (status == E1000_SUCCESS) {
- invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
- >> E1000_INVM_MAJOR_SHIFT;
- invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
- }
- /* Read Image Type */
- for (i = 1; i < invm_blocks; i++) {
- record = &buffer[invm_blocks - i];
- next_record = &buffer[invm_blocks - i + 1];
-
- /* Check if we have image type in first location used */
- if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
- invm_ver->invm_img_type = 0;
- status = E1000_SUCCESS;
- break;
- }
- /* Check if we have image type in first location used */
- else if ((((*record & 0x3) == 0) &&
- ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
- ((((*record & 0x3) != 0) && (i != 1)))) {
- invm_ver->invm_img_type =
- (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
- status = E1000_SUCCESS;
- break;
- }
- }
- return status;
-}
-
-/**
- * e1000_validate_nvm_checksum_i210 - Validate EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
- * and then verifies that the sum of the EEPROM is equal to 0xBABA.
- **/
-s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw)
-{
- s32 status = E1000_SUCCESS;
- s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
-
- DEBUGFUNC("e1000_validate_nvm_checksum_i210");
-
- if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
-
- /*
- * Replace the read function with semaphore grabbing with
- * the one that skips this for a while.
- * We have semaphore taken already here.
- */
- read_op_ptr = hw->nvm.ops.read;
- hw->nvm.ops.read = e1000_read_nvm_eerd;
-
- status = e1000_validate_nvm_checksum_generic(hw);
-
- /* Revert original read operation. */
- hw->nvm.ops.read = read_op_ptr;
-
- hw->nvm.ops.release(hw);
- } else {
- status = E1000_ERR_SWFW_SYNC;
- }
-
- return status;
-}
-
-
-/**
- * e1000_update_nvm_checksum_i210 - Update EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Updates the EEPROM checksum by reading/adding each word of the EEPROM
- * up to the checksum. Then calculates the EEPROM checksum and writes the
- * value to the EEPROM. Next commit EEPROM data onto the Flash.
- **/
-s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u16 checksum = 0;
- u16 i, nvm_data;
-
- DEBUGFUNC("e1000_update_nvm_checksum_i210");
-
- /*
- * Read the first word from the EEPROM. If this times out or fails, do
- * not continue or we could be in for a very long wait while every
- * EEPROM read fails
- */
- ret_val = e1000_read_nvm_eerd(hw, 0, 1, &nvm_data);
- if (ret_val != E1000_SUCCESS) {
- DEBUGOUT("EEPROM read failed\n");
- goto out;
- }
-
- if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
- /*
- * Do not use hw->nvm.ops.write, hw->nvm.ops.read
- * because we do not want to take the synchronization
- * semaphores twice here.
- */
-
- for (i = 0; i < NVM_CHECKSUM_REG; i++) {
- ret_val = e1000_read_nvm_eerd(hw, i, 1, &nvm_data);
- if (ret_val) {
- hw->nvm.ops.release(hw);
- DEBUGOUT("NVM Read Error while updating checksum.\n");
- goto out;
- }
- checksum += nvm_data;
- }
- checksum = (u16) NVM_SUM - checksum;
- ret_val = e1000_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
- &checksum);
- if (ret_val != E1000_SUCCESS) {
- hw->nvm.ops.release(hw);
- DEBUGOUT("NVM Write Error while updating checksum.\n");
- goto out;
- }
-
- hw->nvm.ops.release(hw);
-
- ret_val = e1000_update_flash_i210(hw);
- } else {
- ret_val = E1000_ERR_SWFW_SYNC;
- }
-out:
- return ret_val;
-}
-
-/**
- * e1000_get_flash_presence_i210 - Check if flash device is detected.
- * @hw: pointer to the HW structure
- *
- **/
-bool e1000_get_flash_presence_i210(struct e1000_hw *hw)
-{
- u32 eec = 0;
- bool ret_val = false;
-
- DEBUGFUNC("e1000_get_flash_presence_i210");
-
- eec = E1000_READ_REG(hw, E1000_EECD);
-
- if (eec & E1000_EECD_FLASH_DETECTED_I210)
- ret_val = true;
-
- return ret_val;
-}
-
-/**
- * e1000_update_flash_i210 - Commit EEPROM to the flash
- * @hw: pointer to the HW structure
- *
- **/
-s32 e1000_update_flash_i210(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u32 flup;
-
- DEBUGFUNC("e1000_update_flash_i210");
-
- ret_val = e1000_pool_flash_update_done_i210(hw);
- if (ret_val == -E1000_ERR_NVM) {
- DEBUGOUT("Flash update time out\n");
- goto out;
- }
-
- flup = E1000_READ_REG(hw, E1000_EECD) | E1000_EECD_FLUPD_I210;
- E1000_WRITE_REG(hw, E1000_EECD, flup);
-
- ret_val = e1000_pool_flash_update_done_i210(hw);
- if (ret_val == E1000_SUCCESS)
- DEBUGOUT("Flash update complete\n");
- else
- DEBUGOUT("Flash update time out\n");
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_pool_flash_update_done_i210 - Pool FLUDONE status.
- * @hw: pointer to the HW structure
- *
- **/
-s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw)
-{
- s32 ret_val = -E1000_ERR_NVM;
- u32 i, reg;
-
- DEBUGFUNC("e1000_pool_flash_update_done_i210");
-
- for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
- reg = E1000_READ_REG(hw, E1000_EECD);
- if (reg & E1000_EECD_FLUDONE_I210) {
- ret_val = E1000_SUCCESS;
- break;
- }
- usec_delay(5);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_init_nvm_params_i210 - Initialize i210 NVM function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize the i210/i211 NVM parameters and function pointers.
- **/
-static s32 e1000_init_nvm_params_i210(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- struct e1000_nvm_info *nvm = &hw->nvm;
-
- DEBUGFUNC("e1000_init_nvm_params_i210");
-
- ret_val = e1000_init_nvm_params_82575(hw);
- nvm->ops.acquire = e1000_acquire_nvm_i210;
- nvm->ops.release = e1000_release_nvm_i210;
- nvm->ops.valid_led_default = e1000_valid_led_default_i210;
- if (e1000_get_flash_presence_i210(hw)) {
- hw->nvm.type = e1000_nvm_flash_hw;
- nvm->ops.read = e1000_read_nvm_srrd_i210;
- nvm->ops.write = e1000_write_nvm_srwr_i210;
- nvm->ops.validate = e1000_validate_nvm_checksum_i210;
- nvm->ops.update = e1000_update_nvm_checksum_i210;
- } else {
- hw->nvm.type = e1000_nvm_invm;
- nvm->ops.read = e1000_read_invm_i210;
- nvm->ops.write = e1000_null_write_nvm;
- nvm->ops.validate = e1000_null_ops_generic;
- nvm->ops.update = e1000_null_ops_generic;
- }
- return ret_val;
-}
-
-/**
- * e1000_init_function_pointers_i210 - Init func ptrs.
- * @hw: pointer to the HW structure
- *
- * Called to initialize all function pointers and parameters.
- **/
-void e1000_init_function_pointers_i210(struct e1000_hw *hw)
-{
- e1000_init_function_pointers_82575(hw);
- hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
-
- return;
-}
-
-/**
- * e1000_valid_led_default_i210 - Verify a valid default LED config
- * @hw: pointer to the HW structure
- * @data: pointer to the NVM (EEPROM)
- *
- * Read the EEPROM for the current default LED configuration. If the
- * LED configuration is not valid, set to a valid LED configuration.
- **/
-static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_valid_led_default_i210");
-
- ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- goto out;
- }
-
- if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
- switch (hw->phy.media_type) {
- case e1000_media_type_internal_serdes:
- *data = ID_LED_DEFAULT_I210_SERDES;
- break;
- case e1000_media_type_copper:
- default:
- *data = ID_LED_DEFAULT_I210;
- break;
- }
- }
-out:
- return ret_val;
-}
-
-/**
- * __e1000_access_xmdio_reg - Read/write XMDIO register
- * @hw: pointer to the HW structure
- * @address: XMDIO address to program
- * @dev_addr: device address to program
- * @data: pointer to value to read/write from/to the XMDIO address
- * @read: boolean flag to indicate read or write
- **/
-static s32 __e1000_access_xmdio_reg(struct e1000_hw *hw, u16 address,
- u8 dev_addr, u16 *data, bool read)
-{
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("__e1000_access_xmdio_reg");
-
- ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr);
- if (ret_val)
- return ret_val;
-
- ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address);
- if (ret_val)
- return ret_val;
-
- ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA |
- dev_addr);
- if (ret_val)
- return ret_val;
-
- if (read)
- ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data);
- else
- ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data);
- if (ret_val)
- return ret_val;
-
- /* Recalibrate the device back to 0 */
- ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0);
- if (ret_val)
- return ret_val;
-
- return ret_val;
-}
-
-/**
- * e1000_read_xmdio_reg - Read XMDIO register
- * @hw: pointer to the HW structure
- * @addr: XMDIO address to program
- * @dev_addr: device address to program
- * @data: value to be read from the EMI address
- **/
-s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data)
-{
- DEBUGFUNC("e1000_read_xmdio_reg");
-
- return __e1000_access_xmdio_reg(hw, addr, dev_addr, data, true);
-}
-
-/**
- * e1000_write_xmdio_reg - Write XMDIO register
- * @hw: pointer to the HW structure
- * @addr: XMDIO address to program
- * @dev_addr: device address to program
- * @data: value to be written to the XMDIO address
- **/
-s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
-{
- DEBUGFUNC("e1000_read_xmdio_reg");
-
- return __e1000_access_xmdio_reg(hw, addr, dev_addr, &data, false);
-}
diff --git a/kernel/linux/kni/ethtool/igb/e1000_i210.h b/kernel/linux/kni/ethtool/igb/e1000_i210.h
deleted file mode 100644
index 9df7c203c..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_i210.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_I210_H_
-#define _E1000_I210_H_
-
-bool e1000_get_flash_presence_i210(struct e1000_hw *hw);
-s32 e1000_update_flash_i210(struct e1000_hw *hw);
-s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw);
-s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw);
-s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset,
- u16 words, u16 *data);
-s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
- u16 words, u16 *data);
-s32 e1000_read_invm_version(struct e1000_hw *hw,
- struct e1000_fw_version *invm_ver);
-s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
-void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
-s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
- u16 *data);
-s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
- u16 data);
-
-#define E1000_STM_OPCODE 0xDB00
-#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
-
-#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \
- (u8)((invm_dword) & 0x7)
-#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \
- (u8)(((invm_dword) & 0x0000FE00) >> 9)
-#define INVM_DWORD_TO_WORD_DATA(invm_dword) \
- (u16)(((invm_dword) & 0xFFFF0000) >> 16)
-
-enum E1000_INVM_STRUCTURE_TYPE {
- E1000_INVM_UNINITIALIZED_STRUCTURE = 0x00,
- E1000_INVM_WORD_AUTOLOAD_STRUCTURE = 0x01,
- E1000_INVM_CSR_AUTOLOAD_STRUCTURE = 0x02,
- E1000_INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE = 0x03,
- E1000_INVM_RSA_KEY_SHA256_STRUCTURE = 0x04,
- E1000_INVM_INVALIDATED_STRUCTURE = 0x0F,
-};
-
-#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
-#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
-#define E1000_INVM_ULT_BYTES_SIZE 8
-#define E1000_INVM_RECORD_SIZE_IN_BYTES 4
-#define E1000_INVM_VER_FIELD_ONE 0x1FF8
-#define E1000_INVM_VER_FIELD_TWO 0x7FE000
-#define E1000_INVM_IMGTYPE_FIELD 0x1F800000
-
-#define E1000_INVM_MAJOR_MASK 0x3F0
-#define E1000_INVM_MINOR_MASK 0xF
-#define E1000_INVM_MAJOR_SHIFT 4
-
-#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
- (ID_LED_DEF1_DEF2 << 4) | \
- (ID_LED_OFF1_OFF2))
-#define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \
- (ID_LED_DEF1_DEF2 << 4) | \
- (ID_LED_OFF1_ON2))
-
-/* NVM offset defaults for I211 devices */
-#define NVM_INIT_CTRL_2_DEFAULT_I211 0X7243
-#define NVM_INIT_CTRL_4_DEFAULT_I211 0x00C1
-#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
-#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
-#endif
diff --git a/kernel/linux/kni/ethtool/igb/e1000_mac.c b/kernel/linux/kni/ethtool/igb/e1000_mac.c
deleted file mode 100644
index 13a42267c..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_mac.c
+++ /dev/null
@@ -1,2081 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "e1000_api.h"
-
-static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw);
-static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw);
-static void e1000_config_collision_dist_generic(struct e1000_hw *hw);
-static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
-
-/**
- * e1000_init_mac_ops_generic - Initialize MAC function pointers
- * @hw: pointer to the HW structure
- *
- * Setups up the function pointers to no-op functions
- **/
-void e1000_init_mac_ops_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- DEBUGFUNC("e1000_init_mac_ops_generic");
-
- /* General Setup */
- mac->ops.init_params = e1000_null_ops_generic;
- mac->ops.init_hw = e1000_null_ops_generic;
- mac->ops.reset_hw = e1000_null_ops_generic;
- mac->ops.setup_physical_interface = e1000_null_ops_generic;
- mac->ops.get_bus_info = e1000_null_ops_generic;
- mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pcie;
- mac->ops.read_mac_addr = e1000_read_mac_addr_generic;
- mac->ops.config_collision_dist = e1000_config_collision_dist_generic;
- mac->ops.clear_hw_cntrs = e1000_null_mac_generic;
- /* LED */
- mac->ops.cleanup_led = e1000_null_ops_generic;
- mac->ops.setup_led = e1000_null_ops_generic;
- mac->ops.blink_led = e1000_null_ops_generic;
- mac->ops.led_on = e1000_null_ops_generic;
- mac->ops.led_off = e1000_null_ops_generic;
- /* LINK */
- mac->ops.setup_link = e1000_null_ops_generic;
- mac->ops.get_link_up_info = e1000_null_link_info;
- mac->ops.check_for_link = e1000_null_ops_generic;
- /* Management */
- mac->ops.check_mng_mode = e1000_null_mng_mode;
- /* VLAN, MC, etc. */
- mac->ops.update_mc_addr_list = e1000_null_update_mc;
- mac->ops.clear_vfta = e1000_null_mac_generic;
- mac->ops.write_vfta = e1000_null_write_vfta;
- mac->ops.rar_set = e1000_rar_set_generic;
- mac->ops.validate_mdi_setting = e1000_validate_mdi_setting_generic;
-}
-
-/**
- * e1000_null_ops_generic - No-op function, returns 0
- * @hw: pointer to the HW structure
- **/
-s32 e1000_null_ops_generic(struct e1000_hw E1000_UNUSEDARG *hw)
-{
- DEBUGFUNC("e1000_null_ops_generic");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_null_mac_generic - No-op function, return void
- * @hw: pointer to the HW structure
- **/
-void e1000_null_mac_generic(struct e1000_hw E1000_UNUSEDARG *hw)
-{
- DEBUGFUNC("e1000_null_mac_generic");
- return;
-}
-
-/**
- * e1000_null_link_info - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-s32 e1000_null_link_info(struct e1000_hw E1000_UNUSEDARG *hw,
- u16 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d)
-{
- DEBUGFUNC("e1000_null_link_info");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_null_mng_mode - No-op function, return false
- * @hw: pointer to the HW structure
- **/
-bool e1000_null_mng_mode(struct e1000_hw E1000_UNUSEDARG *hw)
-{
- DEBUGFUNC("e1000_null_mng_mode");
- return false;
-}
-
-/**
- * e1000_null_update_mc - No-op function, return void
- * @hw: pointer to the HW structure
- **/
-void e1000_null_update_mc(struct e1000_hw E1000_UNUSEDARG *hw,
- u8 E1000_UNUSEDARG *h, u32 E1000_UNUSEDARG a)
-{
- DEBUGFUNC("e1000_null_update_mc");
- return;
-}
-
-/**
- * e1000_null_write_vfta - No-op function, return void
- * @hw: pointer to the HW structure
- **/
-void e1000_null_write_vfta(struct e1000_hw E1000_UNUSEDARG *hw,
- u32 E1000_UNUSEDARG a, u32 E1000_UNUSEDARG b)
-{
- DEBUGFUNC("e1000_null_write_vfta");
- return;
-}
-
-/**
- * e1000_null_rar_set - No-op function, return void
- * @hw: pointer to the HW structure
- **/
-void e1000_null_rar_set(struct e1000_hw E1000_UNUSEDARG *hw,
- u8 E1000_UNUSEDARG *h, u32 E1000_UNUSEDARG a)
-{
- DEBUGFUNC("e1000_null_rar_set");
- return;
-}
-
-/**
- * e1000_get_bus_info_pcie_generic - Get PCIe bus information
- * @hw: pointer to the HW structure
- *
- * Determines and stores the system bus information for a particular
- * network interface. The following bus information is determined and stored:
- * bus speed, bus width, type (PCIe), and PCIe function.
- **/
-s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- struct e1000_bus_info *bus = &hw->bus;
- s32 ret_val;
- u16 pcie_link_status;
-
- DEBUGFUNC("e1000_get_bus_info_pcie_generic");
-
- bus->type = e1000_bus_type_pci_express;
-
- ret_val = e1000_read_pcie_cap_reg(hw, PCIE_LINK_STATUS,
- &pcie_link_status);
- if (ret_val) {
- bus->width = e1000_bus_width_unknown;
- bus->speed = e1000_bus_speed_unknown;
- } else {
- switch (pcie_link_status & PCIE_LINK_SPEED_MASK) {
- case PCIE_LINK_SPEED_2500:
- bus->speed = e1000_bus_speed_2500;
- break;
- case PCIE_LINK_SPEED_5000:
- bus->speed = e1000_bus_speed_5000;
- break;
- default:
- bus->speed = e1000_bus_speed_unknown;
- break;
- }
-
- bus->width = (enum e1000_bus_width)((pcie_link_status &
- PCIE_LINK_WIDTH_MASK) >> PCIE_LINK_WIDTH_SHIFT);
- }
-
- mac->ops.set_lan_id(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
- *
- * @hw: pointer to the HW structure
- *
- * Determines the LAN function id by reading memory-mapped registers
- * and swaps the port value if requested.
- **/
-static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
-{
- struct e1000_bus_info *bus = &hw->bus;
- u32 reg;
-
- /* The status register reports the correct function number
- * for the device regardless of function swap state.
- */
- reg = E1000_READ_REG(hw, E1000_STATUS);
- bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT;
-}
-
-/**
- * e1000_set_lan_id_single_port - Set LAN id for a single port device
- * @hw: pointer to the HW structure
- *
- * Sets the LAN function id to zero for a single port device.
- **/
-void e1000_set_lan_id_single_port(struct e1000_hw *hw)
-{
- struct e1000_bus_info *bus = &hw->bus;
-
- bus->func = 0;
-}
-
-/**
- * e1000_clear_vfta_generic - Clear VLAN filter table
- * @hw: pointer to the HW structure
- *
- * Clears the register array which contains the VLAN filter table by
- * setting all the values to 0.
- **/
-void e1000_clear_vfta_generic(struct e1000_hw *hw)
-{
- u32 offset;
-
- DEBUGFUNC("e1000_clear_vfta_generic");
-
- for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
- E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
- E1000_WRITE_FLUSH(hw);
- }
-}
-
-/**
- * e1000_write_vfta_generic - Write value to VLAN filter table
- * @hw: pointer to the HW structure
- * @offset: register offset in VLAN filter table
- * @value: register value written to VLAN filter table
- *
- * Writes value at the given offset in the register array which stores
- * the VLAN filter table.
- **/
-void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
-{
- DEBUGFUNC("e1000_write_vfta_generic");
-
- E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
- E1000_WRITE_FLUSH(hw);
-}
-
-/**
- * e1000_init_rx_addrs_generic - Initialize receive address's
- * @hw: pointer to the HW structure
- * @rar_count: receive address registers
- *
- * Setup the receive address registers by setting the base receive address
- * register to the devices MAC address and clearing all the other receive
- * address registers to 0.
- **/
-void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count)
-{
- u32 i;
- u8 mac_addr[ETH_ADDR_LEN] = {0};
-
- DEBUGFUNC("e1000_init_rx_addrs_generic");
-
- /* Setup the receive address */
- DEBUGOUT("Programming MAC Address into RAR[0]\n");
-
- hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
-
- /* Zero out the other (rar_entry_count - 1) receive addresses */
- DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count-1);
- for (i = 1; i < rar_count; i++)
- hw->mac.ops.rar_set(hw, mac_addr, i);
-}
-
-/**
- * e1000_check_alt_mac_addr_generic - Check for alternate MAC addr
- * @hw: pointer to the HW structure
- *
- * Checks the nvm for an alternate MAC address. An alternate MAC address
- * can be setup by pre-boot software and must be treated like a permanent
- * address and must override the actual permanent MAC address. If an
- * alternate MAC address is found it is programmed into RAR0, replacing
- * the permanent address that was installed into RAR0 by the Si on reset.
- * This function will return SUCCESS unless it encounters an error while
- * reading the EEPROM.
- **/
-s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
-{
- u32 i;
- s32 ret_val;
- u16 offset, nvm_alt_mac_addr_offset, nvm_data;
- u8 alt_mac_addr[ETH_ADDR_LEN];
-
- DEBUGFUNC("e1000_check_alt_mac_addr_generic");
-
- ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &nvm_data);
- if (ret_val)
- return ret_val;
-
-
- /* Alternate MAC address is handled by the option ROM for 82580
- * and newer. SW support not required.
- */
- if (hw->mac.type >= e1000_82580)
- return E1000_SUCCESS;
-
- ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1,
- &nvm_alt_mac_addr_offset);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- if ((nvm_alt_mac_addr_offset == 0xFFFF) ||
- (nvm_alt_mac_addr_offset == 0x0000))
- /* There is no Alternate MAC Address */
- return E1000_SUCCESS;
-
- if (hw->bus.func == E1000_FUNC_1)
- nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
- if (hw->bus.func == E1000_FUNC_2)
- nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN2;
-
- if (hw->bus.func == E1000_FUNC_3)
- nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN3;
- for (i = 0; i < ETH_ADDR_LEN; i += 2) {
- offset = nvm_alt_mac_addr_offset + (i >> 1);
- ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- alt_mac_addr[i] = (u8)(nvm_data & 0xFF);
- alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);
- }
-
- /* if multicast bit is set, the alternate address will not be used */
- if (alt_mac_addr[0] & 0x01) {
- DEBUGOUT("Ignoring Alternate Mac Address with MC bit set\n");
- return E1000_SUCCESS;
- }
-
- /* We have a valid alternate MAC address, and we want to treat it the
- * same as the normal permanent MAC address stored by the HW into the
- * RAR. Do this by mapping this address into RAR0.
- */
- hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_rar_set_generic - Set receive address register
- * @hw: pointer to the HW structure
- * @addr: pointer to the receive address
- * @index: receive address array register
- *
- * Sets the receive address array register at index to the address passed
- * in by addr.
- **/
-static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
-{
- u32 rar_low, rar_high;
-
- DEBUGFUNC("e1000_rar_set_generic");
-
- /* HW expects these in little endian so we reverse the byte order
- * from network order (big endian) to little endian
- */
- rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
- ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
-
- rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
-
- /* If MAC address zero, no need to set the AV bit */
- if (rar_low || rar_high)
- rar_high |= E1000_RAH_AV;
-
- /* Some bridges will combine consecutive 32-bit writes into
- * a single burst write, which will malfunction on some parts.
- * The flushes avoid this.
- */
- E1000_WRITE_REG(hw, E1000_RAL(index), rar_low);
- E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG(hw, E1000_RAH(index), rar_high);
- E1000_WRITE_FLUSH(hw);
-}
-
-/**
- * e1000_hash_mc_addr_generic - Generate a multicast hash value
- * @hw: pointer to the HW structure
- * @mc_addr: pointer to a multicast address
- *
- * Generates a multicast address hash value which is used to determine
- * the multicast filter table array address and new table value.
- **/
-u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr)
-{
- u32 hash_value, hash_mask;
- u8 bit_shift = 0;
-
- DEBUGFUNC("e1000_hash_mc_addr_generic");
-
- /* Register count multiplied by bits per register */
- hash_mask = (hw->mac.mta_reg_count * 32) - 1;
-
- /* For a mc_filter_type of 0, bit_shift is the number of left-shifts
- * where 0xFF would still fall within the hash mask.
- */
- while (hash_mask >> bit_shift != 0xFF)
- bit_shift++;
-
- /* The portion of the address that is used for the hash table
- * is determined by the mc_filter_type setting.
- * The algorithm is such that there is a total of 8 bits of shifting.
- * The bit_shift for a mc_filter_type of 0 represents the number of
- * left-shifts where the MSB of mc_addr[5] would still fall within
- * the hash_mask. Case 0 does this exactly. Since there are a total
- * of 8 bits of shifting, then mc_addr[4] will shift right the
- * remaining number of bits. Thus 8 - bit_shift. The rest of the
- * cases are a variation of this algorithm...essentially raising the
- * number of bits to shift mc_addr[5] left, while still keeping the
- * 8-bit shifting total.
- *
- * For example, given the following Destination MAC Address and an
- * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
- * we can see that the bit_shift for case 0 is 4. These are the hash
- * values resulting from each mc_filter_type...
- * [0] [1] [2] [3] [4] [5]
- * 01 AA 00 12 34 56
- * LSB MSB
- *
- * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563
- * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6
- * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163
- * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634
- */
- switch (hw->mac.mc_filter_type) {
- default:
- case 0:
- break;
- case 1:
- bit_shift += 1;
- break;
- case 2:
- bit_shift += 2;
- break;
- case 3:
- bit_shift += 4;
- break;
- }
-
- hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
- (((u16) mc_addr[5]) << bit_shift)));
-
- return hash_value;
-}
-
-/**
- * e1000_update_mc_addr_list_generic - Update Multicast addresses
- * @hw: pointer to the HW structure
- * @mc_addr_list: array of multicast addresses to program
- * @mc_addr_count: number of multicast addresses to program
- *
- * Updates entire Multicast Table Array.
- * The caller must have a packed mc_addr_list of multicast addresses.
- **/
-void e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
- u8 *mc_addr_list, u32 mc_addr_count)
-{
- u32 hash_value, hash_bit, hash_reg;
- int i;
-
- DEBUGFUNC("e1000_update_mc_addr_list_generic");
-
- /* clear mta_shadow */
- memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
-
- /* update mta_shadow from mc_addr_list */
- for (i = 0; (u32) i < mc_addr_count; i++) {
- hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list);
-
- hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
- hash_bit = hash_value & 0x1F;
-
- hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
- mc_addr_list += (ETH_ADDR_LEN);
- }
-
- /* replace the entire MTA table */
- for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
- E1000_WRITE_FLUSH(hw);
-}
-
-/**
- * e1000_clear_hw_cntrs_base_generic - Clear base hardware counters
- * @hw: pointer to the HW structure
- *
- * Clears the base hardware counters by reading the counter registers.
- **/
-void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_clear_hw_cntrs_base_generic");
-
- E1000_READ_REG(hw, E1000_CRCERRS);
- E1000_READ_REG(hw, E1000_SYMERRS);
- E1000_READ_REG(hw, E1000_MPC);
- E1000_READ_REG(hw, E1000_SCC);
- E1000_READ_REG(hw, E1000_ECOL);
- E1000_READ_REG(hw, E1000_MCC);
- E1000_READ_REG(hw, E1000_LATECOL);
- E1000_READ_REG(hw, E1000_COLC);
- E1000_READ_REG(hw, E1000_DC);
- E1000_READ_REG(hw, E1000_SEC);
- E1000_READ_REG(hw, E1000_RLEC);
- E1000_READ_REG(hw, E1000_XONRXC);
- E1000_READ_REG(hw, E1000_XONTXC);
- E1000_READ_REG(hw, E1000_XOFFRXC);
- E1000_READ_REG(hw, E1000_XOFFTXC);
- E1000_READ_REG(hw, E1000_FCRUC);
- E1000_READ_REG(hw, E1000_GPRC);
- E1000_READ_REG(hw, E1000_BPRC);
- E1000_READ_REG(hw, E1000_MPRC);
- E1000_READ_REG(hw, E1000_GPTC);
- E1000_READ_REG(hw, E1000_GORCL);
- E1000_READ_REG(hw, E1000_GORCH);
- E1000_READ_REG(hw, E1000_GOTCL);
- E1000_READ_REG(hw, E1000_GOTCH);
- E1000_READ_REG(hw, E1000_RNBC);
- E1000_READ_REG(hw, E1000_RUC);
- E1000_READ_REG(hw, E1000_RFC);
- E1000_READ_REG(hw, E1000_ROC);
- E1000_READ_REG(hw, E1000_RJC);
- E1000_READ_REG(hw, E1000_TORL);
- E1000_READ_REG(hw, E1000_TORH);
- E1000_READ_REG(hw, E1000_TOTL);
- E1000_READ_REG(hw, E1000_TOTH);
- E1000_READ_REG(hw, E1000_TPR);
- E1000_READ_REG(hw, E1000_TPT);
- E1000_READ_REG(hw, E1000_MPTC);
- E1000_READ_REG(hw, E1000_BPTC);
-}
-
-/**
- * e1000_check_for_copper_link_generic - Check for link (Copper)
- * @hw: pointer to the HW structure
- *
- * Checks to see of the link status of the hardware has changed. If a
- * change in link status has been detected, then we read the PHY registers
- * to get the current speed/duplex if link exists.
- **/
-s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val;
- bool link;
-
- DEBUGFUNC("e1000_check_for_copper_link");
-
- /* We only want to go out to the PHY registers to see if Auto-Neg
- * has completed and/or if our link status has changed. The
- * get_link_status flag is set upon receiving a Link Status
- * Change or Rx Sequence Error interrupt.
- */
- if (!mac->get_link_status)
- return E1000_SUCCESS;
-
- /* First we want to see if the MII Status Register reports
- * link. If so, then we want to get the current speed/duplex
- * of the PHY.
- */
- ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- return ret_val;
-
- if (!link)
- return E1000_SUCCESS; /* No link detected */
-
- mac->get_link_status = false;
-
- /* Check if there was DownShift, must be checked
- * immediately after link-up
- */
- e1000_check_downshift_generic(hw);
-
- /* If we are forcing speed/duplex, then we simply return since
- * we have already determined whether we have link or not.
- */
- if (!mac->autoneg)
- return -E1000_ERR_CONFIG;
-
- /* Auto-Neg is enabled. Auto Speed Detection takes care
- * of MAC speed/duplex configuration. So we only need to
- * configure Collision Distance in the MAC.
- */
- mac->ops.config_collision_dist(hw);
-
- /* Configure Flow Control now that Auto-Neg has completed.
- * First, we need to restore the desired flow control
- * settings because we may have had to re-autoneg with a
- * different link partner.
- */
- ret_val = e1000_config_fc_after_link_up_generic(hw);
- if (ret_val)
- DEBUGOUT("Error configuring flow control\n");
-
- return ret_val;
-}
-
-/**
- * e1000_check_for_fiber_link_generic - Check for link (Fiber)
- * @hw: pointer to the HW structure
- *
- * Checks for link up on the hardware. If link is not up and we have
- * a signal, then we need to force link up.
- **/
-s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 rxcw;
- u32 ctrl;
- u32 status;
- s32 ret_val;
-
- DEBUGFUNC("e1000_check_for_fiber_link_generic");
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- status = E1000_READ_REG(hw, E1000_STATUS);
- rxcw = E1000_READ_REG(hw, E1000_RXCW);
-
- /* If we don't have link (auto-negotiation failed or link partner
- * cannot auto-negotiate), the cable is plugged in (we have signal),
- * and our link partner is not trying to auto-negotiate with us (we
- * are receiving idles or data), we need to force link up. We also
- * need to give auto-negotiation time to complete, in case the cable
- * was just plugged in. The autoneg_failed flag does this.
- */
- /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
- if ((ctrl & E1000_CTRL_SWDPIN1) && !(status & E1000_STATUS_LU) &&
- !(rxcw & E1000_RXCW_C)) {
- if (!mac->autoneg_failed) {
- mac->autoneg_failed = true;
- return E1000_SUCCESS;
- }
- DEBUGOUT("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
-
- /* Disable auto-negotiation in the TXCW register */
- E1000_WRITE_REG(hw, E1000_TXCW, (mac->txcw & ~E1000_TXCW_ANE));
-
- /* Force link-up and also force full-duplex. */
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-
- /* Configure Flow Control after forcing link up. */
- ret_val = e1000_config_fc_after_link_up_generic(hw);
- if (ret_val) {
- DEBUGOUT("Error configuring flow control\n");
- return ret_val;
- }
- } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
- /* If we are forcing link and we are receiving /C/ ordered
- * sets, re-enable auto-negotiation in the TXCW register
- * and disable forced link in the Device Control register
- * in an attempt to auto-negotiate with our link partner.
- */
- DEBUGOUT("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
- E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
- E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU));
-
- mac->serdes_has_link = true;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_check_for_serdes_link_generic - Check for link (Serdes)
- * @hw: pointer to the HW structure
- *
- * Checks for link up on the hardware. If link is not up and we have
- * a signal, then we need to force link up.
- **/
-s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 rxcw;
- u32 ctrl;
- u32 status;
- s32 ret_val;
-
- DEBUGFUNC("e1000_check_for_serdes_link_generic");
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- status = E1000_READ_REG(hw, E1000_STATUS);
- rxcw = E1000_READ_REG(hw, E1000_RXCW);
-
- /* If we don't have link (auto-negotiation failed or link partner
- * cannot auto-negotiate), and our link partner is not trying to
- * auto-negotiate with us (we are receiving idles or data),
- * we need to force link up. We also need to give auto-negotiation
- * time to complete.
- */
- /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
- if (!(status & E1000_STATUS_LU) && !(rxcw & E1000_RXCW_C)) {
- if (!mac->autoneg_failed) {
- mac->autoneg_failed = true;
- return E1000_SUCCESS;
- }
- DEBUGOUT("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
-
- /* Disable auto-negotiation in the TXCW register */
- E1000_WRITE_REG(hw, E1000_TXCW, (mac->txcw & ~E1000_TXCW_ANE));
-
- /* Force link-up and also force full-duplex. */
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-
- /* Configure Flow Control after forcing link up. */
- ret_val = e1000_config_fc_after_link_up_generic(hw);
- if (ret_val) {
- DEBUGOUT("Error configuring flow control\n");
- return ret_val;
- }
- } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
- /* If we are forcing link and we are receiving /C/ ordered
- * sets, re-enable auto-negotiation in the TXCW register
- * and disable forced link in the Device Control register
- * in an attempt to auto-negotiate with our link partner.
- */
- DEBUGOUT("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
- E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
- E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU));
-
- mac->serdes_has_link = true;
- } else if (!(E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW))) {
- /* If we force link for non-auto-negotiation switch, check
- * link status based on MAC synchronization for internal
- * serdes media type.
- */
- /* SYNCH bit and IV bit are sticky. */
- usec_delay(10);
- rxcw = E1000_READ_REG(hw, E1000_RXCW);
- if (rxcw & E1000_RXCW_SYNCH) {
- if (!(rxcw & E1000_RXCW_IV)) {
- mac->serdes_has_link = true;
- DEBUGOUT("SERDES: Link up - forced.\n");
- }
- } else {
- mac->serdes_has_link = false;
- DEBUGOUT("SERDES: Link down - force failed.\n");
- }
- }
-
- if (E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW)) {
- status = E1000_READ_REG(hw, E1000_STATUS);
- if (status & E1000_STATUS_LU) {
- /* SYNCH bit and IV bit are sticky, so reread rxcw. */
- usec_delay(10);
- rxcw = E1000_READ_REG(hw, E1000_RXCW);
- if (rxcw & E1000_RXCW_SYNCH) {
- if (!(rxcw & E1000_RXCW_IV)) {
- mac->serdes_has_link = true;
- DEBUGOUT("SERDES: Link up - autoneg completed successfully.\n");
- } else {
- mac->serdes_has_link = false;
- DEBUGOUT("SERDES: Link down - invalid codewords detected in autoneg.\n");
- }
- } else {
- mac->serdes_has_link = false;
- DEBUGOUT("SERDES: Link down - no sync.\n");
- }
- } else {
- mac->serdes_has_link = false;
- DEBUGOUT("SERDES: Link down - autoneg failed\n");
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_set_default_fc_generic - Set flow control default values
- * @hw: pointer to the HW structure
- *
- * Read the EEPROM for the default values for flow control and store the
- * values.
- **/
-static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 nvm_data;
-
- DEBUGFUNC("e1000_set_default_fc_generic");
-
- /* Read and store word 0x0F of the EEPROM. This word contains bits
- * that determine the hardware's default PAUSE (flow control) mode,
- * a bit that determines whether the HW defaults to enabling or
- * disabling auto-negotiation, and the direction of the
- * SW defined pins. If there is no SW over-ride of the flow
- * control setting, then the variable hw->fc will
- * be initialized based on a value in the EEPROM.
- */
- ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
-
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- if (!(nvm_data & NVM_WORD0F_PAUSE_MASK))
- hw->fc.requested_mode = e1000_fc_none;
- else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
- NVM_WORD0F_ASM_DIR)
- hw->fc.requested_mode = e1000_fc_tx_pause;
- else
- hw->fc.requested_mode = e1000_fc_full;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_setup_link_generic - Setup flow control and link settings
- * @hw: pointer to the HW structure
- *
- * Determines which flow control settings to use, then configures flow
- * control. Calls the appropriate media-specific link configuration
- * function. Assuming the adapter has a valid link partner, a valid link
- * should be established. Assumes the hardware has previously been reset
- * and the transmitter and receiver are not enabled.
- **/
-s32 e1000_setup_link_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_setup_link_generic");
-
- /* In the case of the phy reset being blocked, we already have a link.
- * We do not need to set it up again.
- */
- if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
- return E1000_SUCCESS;
-
- /* If requested flow control is set to default, set flow control
- * based on the EEPROM flow control settings.
- */
- if (hw->fc.requested_mode == e1000_fc_default) {
- ret_val = e1000_set_default_fc_generic(hw);
- if (ret_val)
- return ret_val;
- }
-
- /* Save off the requested flow control mode for use later. Depending
- * on the link partner's capabilities, we may or may not use this mode.
- */
- hw->fc.current_mode = hw->fc.requested_mode;
-
- DEBUGOUT1("After fix-ups FlowControl is now = %x\n",
- hw->fc.current_mode);
-
- /* Call the necessary media_type subroutine to configure the link. */
- ret_val = hw->mac.ops.setup_physical_interface(hw);
- if (ret_val)
- return ret_val;
-
- /* Initialize the flow control address, type, and PAUSE timer
- * registers to their default values. This is done even if flow
- * control is disabled, because it does not hurt anything to
- * initialize these registers.
- */
- DEBUGOUT("Initializing the Flow Control address, type and timer regs\n");
- E1000_WRITE_REG(hw, E1000_FCT, FLOW_CONTROL_TYPE);
- E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
- E1000_WRITE_REG(hw, E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW);
-
- E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time);
-
- return e1000_set_fc_watermarks_generic(hw);
-}
-
-/**
- * e1000_commit_fc_settings_generic - Configure flow control
- * @hw: pointer to the HW structure
- *
- * Write the flow control settings to the Transmit Config Word Register (TXCW)
- * base on the flow control settings in e1000_mac_info.
- **/
-static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 txcw;
-
- DEBUGFUNC("e1000_commit_fc_settings_generic");
-
- /* Check for a software override of the flow control settings, and
- * setup the device accordingly. If auto-negotiation is enabled, then
- * software will have to set the "PAUSE" bits to the correct value in
- * the Transmit Config Word Register (TXCW) and re-start auto-
- * negotiation. However, if auto-negotiation is disabled, then
- * software will have to manually configure the two flow control enable
- * bits in the CTRL register.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames,
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but we
- * do not support receiving pause frames).
- * 3: Both Rx and Tx flow control (symmetric) are enabled.
- */
- switch (hw->fc.current_mode) {
- case e1000_fc_none:
- /* Flow control completely disabled by a software over-ride. */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
- break;
- case e1000_fc_rx_pause:
- /* Rx Flow control is enabled and Tx Flow control is disabled
- * by a software over-ride. Since there really isn't a way to
- * advertise that we are capable of Rx Pause ONLY, we will
- * advertise that we support both symmetric and asymmetric Rx
- * PAUSE. Later, we will disable the adapter's ability to send
- * PAUSE frames.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
- break;
- case e1000_fc_tx_pause:
- /* Tx Flow control is enabled, and Rx Flow control is disabled,
- * by a software over-ride.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
- break;
- case e1000_fc_full:
- /* Flow control (both Rx and Tx) is enabled by a software
- * over-ride.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
- break;
- default:
- DEBUGOUT("Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- break;
- }
-
- E1000_WRITE_REG(hw, E1000_TXCW, txcw);
- mac->txcw = txcw;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_poll_fiber_serdes_link_generic - Poll for link up
- * @hw: pointer to the HW structure
- *
- * Polls for link up by reading the status register, if link fails to come
- * up with auto-negotiation, then the link is forced if a signal is detected.
- **/
-static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 i, status;
- s32 ret_val;
-
- DEBUGFUNC("e1000_poll_fiber_serdes_link_generic");
-
- /* If we have a signal (the cable is plugged in, or assumed true for
- * serdes media) then poll for a "Link-Up" indication in the Device
- * Status Register. Time-out if a link isn't seen in 500 milliseconds
- * seconds (Auto-negotiation should complete in less than 500
- * milliseconds even if the other end is doing it in SW).
- */
- for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
- msec_delay(10);
- status = E1000_READ_REG(hw, E1000_STATUS);
- if (status & E1000_STATUS_LU)
- break;
- }
- if (i == FIBER_LINK_UP_LIMIT) {
- DEBUGOUT("Never got a valid link from auto-neg!!!\n");
- mac->autoneg_failed = true;
- /* AutoNeg failed to achieve a link, so we'll call
- * mac->check_for_link. This routine will force the
- * link up if we detect a signal. This will allow us to
- * communicate with non-autonegotiating link partners.
- */
- ret_val = mac->ops.check_for_link(hw);
- if (ret_val) {
- DEBUGOUT("Error while checking for link\n");
- return ret_val;
- }
- mac->autoneg_failed = false;
- } else {
- mac->autoneg_failed = false;
- DEBUGOUT("Valid Link Found\n");
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_setup_fiber_serdes_link_generic - Setup link for fiber/serdes
- * @hw: pointer to the HW structure
- *
- * Configures collision distance and flow control for fiber and serdes
- * links. Upon successful setup, poll for link.
- **/
-s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 ret_val;
-
- DEBUGFUNC("e1000_setup_fiber_serdes_link_generic");
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
-
- /* Take the link out of reset */
- ctrl &= ~E1000_CTRL_LRST;
-
- hw->mac.ops.config_collision_dist(hw);
-
- ret_val = e1000_commit_fc_settings_generic(hw);
- if (ret_val)
- return ret_val;
-
- /* Since auto-negotiation is enabled, take the link out of reset (the
- * link will be in reset, because we previously reset the chip). This
- * will restart auto-negotiation. If auto-negotiation is successful
- * then the link-up status bit will be set and the flow control enable
- * bits (RFCE and TFCE) will be set according to their negotiated value.
- */
- DEBUGOUT("Auto-negotiation enabled\n");
-
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
- msec_delay(1);
-
- /* For these adapters, the SW definable pin 1 is set when the optics
- * detect a signal. If we have a signal, then poll for a "Link-Up"
- * indication.
- */
- if (hw->phy.media_type == e1000_media_type_internal_serdes ||
- (E1000_READ_REG(hw, E1000_CTRL) & E1000_CTRL_SWDPIN1)) {
- ret_val = e1000_poll_fiber_serdes_link_generic(hw);
- } else {
- DEBUGOUT("No signal detected\n");
- }
-
- return ret_val;
-}
-
-/**
- * e1000_config_collision_dist_generic - Configure collision distance
- * @hw: pointer to the HW structure
- *
- * Configures the collision distance to the default value and is used
- * during link setup.
- **/
-static void e1000_config_collision_dist_generic(struct e1000_hw *hw)
-{
- u32 tctl;
-
- DEBUGFUNC("e1000_config_collision_dist_generic");
-
- tctl = E1000_READ_REG(hw, E1000_TCTL);
-
- tctl &= ~E1000_TCTL_COLD;
- tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
-
- E1000_WRITE_REG(hw, E1000_TCTL, tctl);
- E1000_WRITE_FLUSH(hw);
-}
-
-/**
- * e1000_set_fc_watermarks_generic - Set flow control high/low watermarks
- * @hw: pointer to the HW structure
- *
- * Sets the flow control high/low threshold (watermark) registers. If
- * flow control XON frame transmission is enabled, then set XON frame
- * transmission as well.
- **/
-s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw)
-{
- u32 fcrtl = 0, fcrth = 0;
-
- DEBUGFUNC("e1000_set_fc_watermarks_generic");
-
- /* Set the flow control receive threshold registers. Normally,
- * these registers will be set to a default threshold that may be
- * adjusted later by the driver's runtime code. However, if the
- * ability to transmit pause frames is not enabled, then these
- * registers will be set to 0.
- */
- if (hw->fc.current_mode & e1000_fc_tx_pause) {
- /* We need to set up the Receive Threshold high and low water
- * marks as well as (optionally) enabling the transmission of
- * XON frames.
- */
- fcrtl = hw->fc.low_water;
- if (hw->fc.send_xon)
- fcrtl |= E1000_FCRTL_XONE;
-
- fcrth = hw->fc.high_water;
- }
- E1000_WRITE_REG(hw, E1000_FCRTL, fcrtl);
- E1000_WRITE_REG(hw, E1000_FCRTH, fcrth);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_force_mac_fc_generic - Force the MAC's flow control settings
- * @hw: pointer to the HW structure
- *
- * Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the
- * device control register to reflect the adapter settings. TFCE and RFCE
- * need to be explicitly set by software when a copper PHY is used because
- * autonegotiation is managed by the PHY rather than the MAC. Software must
- * also configure these bits when link is forced on a fiber connection.
- **/
-s32 e1000_force_mac_fc_generic(struct e1000_hw *hw)
-{
- u32 ctrl;
-
- DEBUGFUNC("e1000_force_mac_fc_generic");
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
-
- /* Because we didn't get link via the internal auto-negotiation
- * mechanism (we either forced link or we got link via PHY
- * auto-neg), we have to manually enable/disable transmit an
- * receive flow control.
- *
- * The "Case" statement below enables/disable flow control
- * according to the "hw->fc.current_mode" parameter.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause
- * frames but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames
- * frames but we do not receive pause frames).
- * 3: Both Rx and Tx flow control (symmetric) is enabled.
- * other: No other values should be possible at this point.
- */
- DEBUGOUT1("hw->fc.current_mode = %u\n", hw->fc.current_mode);
-
- switch (hw->fc.current_mode) {
- case e1000_fc_none:
- ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
- break;
- case e1000_fc_rx_pause:
- ctrl &= (~E1000_CTRL_TFCE);
- ctrl |= E1000_CTRL_RFCE;
- break;
- case e1000_fc_tx_pause:
- ctrl &= (~E1000_CTRL_RFCE);
- ctrl |= E1000_CTRL_TFCE;
- break;
- case e1000_fc_full:
- ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
- break;
- default:
- DEBUGOUT("Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- }
-
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_config_fc_after_link_up_generic - Configures flow control after link
- * @hw: pointer to the HW structure
- *
- * Checks the status of auto-negotiation after link up to ensure that the
- * speed and duplex were not forced. If the link needed to be forced, then
- * flow control needs to be forced also. If auto-negotiation is enabled
- * and did not fail, then we configure flow control based on our link
- * partner.
- **/
-s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val = E1000_SUCCESS;
- u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
- u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
- u16 speed, duplex;
-
- DEBUGFUNC("e1000_config_fc_after_link_up_generic");
-
- /* Check for the case where we have fiber media and auto-neg failed
- * so we had to force link. In this case, we need to force the
- * configuration of the MAC to match the "fc" parameter.
- */
- if (mac->autoneg_failed) {
- if (hw->phy.media_type == e1000_media_type_fiber ||
- hw->phy.media_type == e1000_media_type_internal_serdes)
- ret_val = e1000_force_mac_fc_generic(hw);
- } else {
- if (hw->phy.media_type == e1000_media_type_copper)
- ret_val = e1000_force_mac_fc_generic(hw);
- }
-
- if (ret_val) {
- DEBUGOUT("Error forcing flow control settings\n");
- return ret_val;
- }
-
- /* Check for the case where we have copper media and auto-neg is
- * enabled. In this case, we need to check and see if Auto-Neg
- * has completed, and if so, how the PHY and link partner has
- * flow control configured.
- */
- if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
- /* Read the MII Status Register and check to see if AutoNeg
- * has completed. We read this twice because this reg has
- * some "sticky" (latched) bits.
- */
- ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
- ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
- DEBUGOUT("Copper PHY and Auto Neg has not completed.\n");
- return ret_val;
- }
-
- /* The AutoNeg process has completed, so we now need to
- * read both the Auto Negotiation Advertisement
- * Register (Address 4) and the Auto_Negotiation Base
- * Page Ability Register (Address 5) to determine how
- * flow control was negotiated.
- */
- ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
- &mii_nway_adv_reg);
- if (ret_val)
- return ret_val;
- ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
- &mii_nway_lp_ability_reg);
- if (ret_val)
- return ret_val;
-
- /* Two bits in the Auto Negotiation Advertisement Register
- * (Address 4) and two bits in the Auto Negotiation Base
- * Page Ability Register (Address 5) determine flow control
- * for both the PHY and the link partner. The following
- * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
- * 1999, describes these PAUSE resolution bits and how flow
- * control is determined based upon these settings.
- * NOTE: DC = Don't Care
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
- *-------|---------|-------|---------|--------------------
- * 0 | 0 | DC | DC | e1000_fc_none
- * 0 | 1 | 0 | DC | e1000_fc_none
- * 0 | 1 | 1 | 0 | e1000_fc_none
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
- * 1 | 0 | 0 | DC | e1000_fc_none
- * 1 | DC | 1 | DC | e1000_fc_full
- * 1 | 1 | 0 | 0 | e1000_fc_none
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
- *
- * Are both PAUSE bits set to 1? If so, this implies
- * Symmetric Flow Control is enabled at both ends. The
- * ASM_DIR bits are irrelevant per the spec.
- *
- * For Symmetric Flow Control:
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | DC | 1 | DC | E1000_fc_full
- *
- */
- if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
- /* Now we need to check if the user selected Rx ONLY
- * of pause frames. In this case, we had to advertise
- * FULL flow control because we could not advertise Rx
- * ONLY. Hence, we must now check to see if we need to
- * turn OFF the TRANSMISSION of PAUSE frames.
- */
- if (hw->fc.requested_mode == e1000_fc_full) {
- hw->fc.current_mode = e1000_fc_full;
- DEBUGOUT("Flow Control = FULL.\n");
- } else {
- hw->fc.current_mode = e1000_fc_rx_pause;
- DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
- }
- }
- /* For receiving PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
- */
- else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc.current_mode = e1000_fc_tx_pause;
- DEBUGOUT("Flow Control = Tx PAUSE frames only.\n");
- }
- /* For transmitting PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
- */
- else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
- !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc.current_mode = e1000_fc_rx_pause;
- DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
- } else {
- /* Per the IEEE spec, at this point flow control
- * should be disabled.
- */
- hw->fc.current_mode = e1000_fc_none;
- DEBUGOUT("Flow Control = NONE.\n");
- }
-
- /* Now we need to do one last check... If we auto-
- * negotiated to HALF DUPLEX, flow control should not be
- * enabled per IEEE 802.3 spec.
- */
- ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
- if (ret_val) {
- DEBUGOUT("Error getting link speed and duplex\n");
- return ret_val;
- }
-
- if (duplex == HALF_DUPLEX)
- hw->fc.current_mode = e1000_fc_none;
-
- /* Now we call a subroutine to actually force the MAC
- * controller to use the correct flow control settings.
- */
- ret_val = e1000_force_mac_fc_generic(hw);
- if (ret_val) {
- DEBUGOUT("Error forcing flow control settings\n");
- return ret_val;
- }
- }
-
- /* Check for the case where we have SerDes media and auto-neg is
- * enabled. In this case, we need to check and see if Auto-Neg
- * has completed, and if so, how the PHY and link partner has
- * flow control configured.
- */
- if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
- mac->autoneg) {
- /* Read the PCS_LSTS and check to see if AutoNeg
- * has completed.
- */
- pcs_status_reg = E1000_READ_REG(hw, E1000_PCS_LSTAT);
-
- if (!(pcs_status_reg & E1000_PCS_LSTS_AN_COMPLETE)) {
- DEBUGOUT("PCS Auto Neg has not completed.\n");
- return ret_val;
- }
-
- /* The AutoNeg process has completed, so we now need to
- * read both the Auto Negotiation Advertisement
- * Register (PCS_ANADV) and the Auto_Negotiation Base
- * Page Ability Register (PCS_LPAB) to determine how
- * flow control was negotiated.
- */
- pcs_adv_reg = E1000_READ_REG(hw, E1000_PCS_ANADV);
- pcs_lp_ability_reg = E1000_READ_REG(hw, E1000_PCS_LPAB);
-
- /* Two bits in the Auto Negotiation Advertisement Register
- * (PCS_ANADV) and two bits in the Auto Negotiation Base
- * Page Ability Register (PCS_LPAB) determine flow control
- * for both the PHY and the link partner. The following
- * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
- * 1999, describes these PAUSE resolution bits and how flow
- * control is determined based upon these settings.
- * NOTE: DC = Don't Care
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
- *-------|---------|-------|---------|--------------------
- * 0 | 0 | DC | DC | e1000_fc_none
- * 0 | 1 | 0 | DC | e1000_fc_none
- * 0 | 1 | 1 | 0 | e1000_fc_none
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
- * 1 | 0 | 0 | DC | e1000_fc_none
- * 1 | DC | 1 | DC | e1000_fc_full
- * 1 | 1 | 0 | 0 | e1000_fc_none
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
- *
- * Are both PAUSE bits set to 1? If so, this implies
- * Symmetric Flow Control is enabled at both ends. The
- * ASM_DIR bits are irrelevant per the spec.
- *
- * For Symmetric Flow Control:
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | DC | 1 | DC | e1000_fc_full
- *
- */
- if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
- (pcs_lp_ability_reg & E1000_TXCW_PAUSE)) {
- /* Now we need to check if the user selected Rx ONLY
- * of pause frames. In this case, we had to advertise
- * FULL flow control because we could not advertise Rx
- * ONLY. Hence, we must now check to see if we need to
- * turn OFF the TRANSMISSION of PAUSE frames.
- */
- if (hw->fc.requested_mode == e1000_fc_full) {
- hw->fc.current_mode = e1000_fc_full;
- DEBUGOUT("Flow Control = FULL.\n");
- } else {
- hw->fc.current_mode = e1000_fc_rx_pause;
- DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
- }
- }
- /* For receiving PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
- */
- else if (!(pcs_adv_reg & E1000_TXCW_PAUSE) &&
- (pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
- (pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
- (pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
- hw->fc.current_mode = e1000_fc_tx_pause;
- DEBUGOUT("Flow Control = Tx PAUSE frames only.\n");
- }
- /* For transmitting PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
- */
- else if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
- (pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
- !(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
- (pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
- hw->fc.current_mode = e1000_fc_rx_pause;
- DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
- } else {
- /* Per the IEEE spec, at this point flow control
- * should be disabled.
- */
- hw->fc.current_mode = e1000_fc_none;
- DEBUGOUT("Flow Control = NONE.\n");
- }
-
- /* Now we call a subroutine to actually force the MAC
- * controller to use the correct flow control settings.
- */
- pcs_ctrl_reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
- pcs_ctrl_reg |= E1000_PCS_LCTL_FORCE_FCTRL;
- E1000_WRITE_REG(hw, E1000_PCS_LCTL, pcs_ctrl_reg);
-
- ret_val = e1000_force_mac_fc_generic(hw);
- if (ret_val) {
- DEBUGOUT("Error forcing flow control settings\n");
- return ret_val;
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_get_speed_and_duplex_copper_generic - Retrieve current speed/duplex
- * @hw: pointer to the HW structure
- * @speed: stores the current speed
- * @duplex: stores the current duplex
- *
- * Read the status register for the current speed/duplex and store the current
- * speed and duplex for copper connections.
- **/
-s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
- u16 *duplex)
-{
- u32 status;
-
- DEBUGFUNC("e1000_get_speed_and_duplex_copper_generic");
-
- status = E1000_READ_REG(hw, E1000_STATUS);
- if (status & E1000_STATUS_SPEED_1000) {
- *speed = SPEED_1000;
- DEBUGOUT("1000 Mbs, ");
- } else if (status & E1000_STATUS_SPEED_100) {
- *speed = SPEED_100;
- DEBUGOUT("100 Mbs, ");
- } else {
- *speed = SPEED_10;
- DEBUGOUT("10 Mbs, ");
- }
-
- if (status & E1000_STATUS_FD) {
- *duplex = FULL_DUPLEX;
- DEBUGOUT("Full Duplex\n");
- } else {
- *duplex = HALF_DUPLEX;
- DEBUGOUT("Half Duplex\n");
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_get_speed_and_duplex_fiber_generic - Retrieve current speed/duplex
- * @hw: pointer to the HW structure
- * @speed: stores the current speed
- * @duplex: stores the current duplex
- *
- * Sets the speed and duplex to gigabit full duplex (the only possible option)
- * for fiber/serdes links.
- **/
-s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSEDARG *hw,
- u16 *speed, u16 *duplex)
-{
- DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic");
-
- *speed = SPEED_1000;
- *duplex = FULL_DUPLEX;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_get_hw_semaphore_generic - Acquire hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Acquire the HW semaphore to access the PHY or NVM
- **/
-s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw)
-{
- u32 swsm;
- s32 timeout = hw->nvm.word_size + 1;
- s32 i = 0;
-
- DEBUGFUNC("e1000_get_hw_semaphore_generic");
-
- /* Get the SW semaphore */
- while (i < timeout) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- if (!(swsm & E1000_SWSM_SMBI))
- break;
-
- usec_delay(50);
- i++;
- }
-
- if (i == timeout) {
- DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
- return -E1000_ERR_NVM;
- }
-
- /* Get the FW semaphore. */
- for (i = 0; i < timeout; i++) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
-
- /* Semaphore acquired if bit latched */
- if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
- break;
-
- usec_delay(50);
- }
-
- if (i == timeout) {
- /* Release semaphores */
- e1000_put_hw_semaphore_generic(hw);
- DEBUGOUT("Driver can't access the NVM\n");
- return -E1000_ERR_NVM;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_put_hw_semaphore_generic - Release hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Release hardware semaphore used to access the PHY or NVM
- **/
-void e1000_put_hw_semaphore_generic(struct e1000_hw *hw)
-{
- u32 swsm;
-
- DEBUGFUNC("e1000_put_hw_semaphore_generic");
-
- swsm = E1000_READ_REG(hw, E1000_SWSM);
-
- swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
-
- E1000_WRITE_REG(hw, E1000_SWSM, swsm);
-}
-
-/**
- * e1000_get_auto_rd_done_generic - Check for auto read completion
- * @hw: pointer to the HW structure
- *
- * Check EEPROM for Auto Read done bit.
- **/
-s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw)
-{
- s32 i = 0;
-
- DEBUGFUNC("e1000_get_auto_rd_done_generic");
-
- while (i < AUTO_READ_DONE_TIMEOUT) {
- if (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_AUTO_RD)
- break;
- msec_delay(1);
- i++;
- }
-
- if (i == AUTO_READ_DONE_TIMEOUT) {
- DEBUGOUT("Auto read by HW from NVM has not completed.\n");
- return -E1000_ERR_RESET;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_valid_led_default_generic - Verify a valid default LED config
- * @hw: pointer to the HW structure
- * @data: pointer to the NVM (EEPROM)
- *
- * Read the EEPROM for the current default LED configuration. If the
- * LED configuration is not valid, set to a valid LED configuration.
- **/
-s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_valid_led_default_generic");
-
- ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
- *data = ID_LED_DEFAULT;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_id_led_init_generic -
- * @hw: pointer to the HW structure
- *
- **/
-s32 e1000_id_led_init_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val;
- const u32 ledctl_mask = 0x000000FF;
- const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
- const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
- u16 data, i, temp;
- const u16 led_mask = 0x0F;
-
- DEBUGFUNC("e1000_id_led_init_generic");
-
- ret_val = hw->nvm.ops.valid_led_default(hw, &data);
- if (ret_val)
- return ret_val;
-
- mac->ledctl_default = E1000_READ_REG(hw, E1000_LEDCTL);
- mac->ledctl_mode1 = mac->ledctl_default;
- mac->ledctl_mode2 = mac->ledctl_default;
-
- for (i = 0; i < 4; i++) {
- temp = (data >> (i << 2)) & led_mask;
- switch (temp) {
- case ID_LED_ON1_DEF2:
- case ID_LED_ON1_ON2:
- case ID_LED_ON1_OFF2:
- mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
- mac->ledctl_mode1 |= ledctl_on << (i << 3);
- break;
- case ID_LED_OFF1_DEF2:
- case ID_LED_OFF1_ON2:
- case ID_LED_OFF1_OFF2:
- mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
- mac->ledctl_mode1 |= ledctl_off << (i << 3);
- break;
- default:
- /* Do nothing */
- break;
- }
- switch (temp) {
- case ID_LED_DEF1_ON2:
- case ID_LED_ON1_ON2:
- case ID_LED_OFF1_ON2:
- mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
- mac->ledctl_mode2 |= ledctl_on << (i << 3);
- break;
- case ID_LED_DEF1_OFF2:
- case ID_LED_ON1_OFF2:
- case ID_LED_OFF1_OFF2:
- mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
- mac->ledctl_mode2 |= ledctl_off << (i << 3);
- break;
- default:
- /* Do nothing */
- break;
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_setup_led_generic - Configures SW controllable LED
- * @hw: pointer to the HW structure
- *
- * This prepares the SW controllable LED for use and saves the current state
- * of the LED so it can be later restored.
- **/
-s32 e1000_setup_led_generic(struct e1000_hw *hw)
-{
- u32 ledctl;
-
- DEBUGFUNC("e1000_setup_led_generic");
-
- if (hw->mac.ops.setup_led != e1000_setup_led_generic)
- return -E1000_ERR_CONFIG;
-
- if (hw->phy.media_type == e1000_media_type_fiber) {
- ledctl = E1000_READ_REG(hw, E1000_LEDCTL);
- hw->mac.ledctl_default = ledctl;
- /* Turn off LED0 */
- ledctl &= ~(E1000_LEDCTL_LED0_IVRT | E1000_LEDCTL_LED0_BLINK |
- E1000_LEDCTL_LED0_MODE_MASK);
- ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
- E1000_LEDCTL_LED0_MODE_SHIFT);
- E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl);
- } else if (hw->phy.media_type == e1000_media_type_copper) {
- E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1);
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_cleanup_led_generic - Set LED config to default operation
- * @hw: pointer to the HW structure
- *
- * Remove the current LED configuration and set the LED configuration
- * to the default value, saved from the EEPROM.
- **/
-s32 e1000_cleanup_led_generic(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_cleanup_led_generic");
-
- E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default);
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_blink_led_generic - Blink LED
- * @hw: pointer to the HW structure
- *
- * Blink the LEDs which are set to be on.
- **/
-s32 e1000_blink_led_generic(struct e1000_hw *hw)
-{
- u32 ledctl_blink = 0;
- u32 i;
-
- DEBUGFUNC("e1000_blink_led_generic");
-
- if (hw->phy.media_type == e1000_media_type_fiber) {
- /* always blink LED0 for PCI-E fiber */
- ledctl_blink = E1000_LEDCTL_LED0_BLINK |
- (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
- } else {
- /* Set the blink bit for each LED that's "on" (0x0E)
- * (or "off" if inverted) in ledctl_mode2. The blink
- * logic in hardware only works when mode is set to "on"
- * so it must be changed accordingly when the mode is
- * "off" and inverted.
- */
- ledctl_blink = hw->mac.ledctl_mode2;
- for (i = 0; i < 32; i += 8) {
- u32 mode = (hw->mac.ledctl_mode2 >> i) &
- E1000_LEDCTL_LED0_MODE_MASK;
- u32 led_default = hw->mac.ledctl_default >> i;
-
- if ((!(led_default & E1000_LEDCTL_LED0_IVRT) &&
- (mode == E1000_LEDCTL_MODE_LED_ON)) ||
- ((led_default & E1000_LEDCTL_LED0_IVRT) &&
- (mode == E1000_LEDCTL_MODE_LED_OFF))) {
- ledctl_blink &=
- ~(E1000_LEDCTL_LED0_MODE_MASK << i);
- ledctl_blink |= (E1000_LEDCTL_LED0_BLINK |
- E1000_LEDCTL_MODE_LED_ON) << i;
- }
- }
- }
-
- E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl_blink);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_led_on_generic - Turn LED on
- * @hw: pointer to the HW structure
- *
- * Turn LED on.
- **/
-s32 e1000_led_on_generic(struct e1000_hw *hw)
-{
- u32 ctrl;
-
- DEBUGFUNC("e1000_led_on_generic");
-
- switch (hw->phy.media_type) {
- case e1000_media_type_fiber:
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
- break;
- case e1000_media_type_copper:
- E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode2);
- break;
- default:
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_led_off_generic - Turn LED off
- * @hw: pointer to the HW structure
- *
- * Turn LED off.
- **/
-s32 e1000_led_off_generic(struct e1000_hw *hw)
-{
- u32 ctrl;
-
- DEBUGFUNC("e1000_led_off_generic");
-
- switch (hw->phy.media_type) {
- case e1000_media_type_fiber:
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
- break;
- case e1000_media_type_copper:
- E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1);
- break;
- default:
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_set_pcie_no_snoop_generic - Set PCI-express capabilities
- * @hw: pointer to the HW structure
- * @no_snoop: bitmap of snoop events
- *
- * Set the PCI-express register to snoop for events enabled in 'no_snoop'.
- **/
-void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop)
-{
- u32 gcr;
-
- DEBUGFUNC("e1000_set_pcie_no_snoop_generic");
-
- if (no_snoop) {
- gcr = E1000_READ_REG(hw, E1000_GCR);
- gcr &= ~(PCIE_NO_SNOOP_ALL);
- gcr |= no_snoop;
- E1000_WRITE_REG(hw, E1000_GCR, gcr);
- }
-}
-
-/**
- * e1000_disable_pcie_master_generic - Disables PCI-express master access
- * @hw: pointer to the HW structure
- *
- * Returns E1000_SUCCESS if successful, else returns -10
- * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
- * the master requests to be disabled.
- *
- * Disables PCI-Express master access and verifies there are no pending
- * requests.
- **/
-s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 timeout = MASTER_DISABLE_TIMEOUT;
-
- DEBUGFUNC("e1000_disable_pcie_master_generic");
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-
- while (timeout) {
- if (!(E1000_READ_REG(hw, E1000_STATUS) &
- E1000_STATUS_GIO_MASTER_ENABLE))
- break;
- usec_delay(100);
- timeout--;
- }
-
- if (!timeout) {
- DEBUGOUT("Master requests are pending.\n");
- return -E1000_ERR_MASTER_REQUESTS_PENDING;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_reset_adaptive_generic - Reset Adaptive Interframe Spacing
- * @hw: pointer to the HW structure
- *
- * Reset the Adaptive Interframe Spacing throttle to default values.
- **/
-void e1000_reset_adaptive_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
-
- DEBUGFUNC("e1000_reset_adaptive_generic");
-
- if (!mac->adaptive_ifs) {
- DEBUGOUT("Not in Adaptive IFS mode!\n");
- return;
- }
-
- mac->current_ifs_val = 0;
- mac->ifs_min_val = IFS_MIN;
- mac->ifs_max_val = IFS_MAX;
- mac->ifs_step_size = IFS_STEP;
- mac->ifs_ratio = IFS_RATIO;
-
- mac->in_ifs_mode = false;
- E1000_WRITE_REG(hw, E1000_AIT, 0);
-}
-
-/**
- * e1000_update_adaptive_generic - Update Adaptive Interframe Spacing
- * @hw: pointer to the HW structure
- *
- * Update the Adaptive Interframe Spacing Throttle value based on the
- * time between transmitted packets and time between collisions.
- **/
-void e1000_update_adaptive_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
-
- DEBUGFUNC("e1000_update_adaptive_generic");
-
- if (!mac->adaptive_ifs) {
- DEBUGOUT("Not in Adaptive IFS mode!\n");
- return;
- }
-
- if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
- if (mac->tx_packet_delta > MIN_NUM_XMITS) {
- mac->in_ifs_mode = true;
- if (mac->current_ifs_val < mac->ifs_max_val) {
- if (!mac->current_ifs_val)
- mac->current_ifs_val = mac->ifs_min_val;
- else
- mac->current_ifs_val +=
- mac->ifs_step_size;
- E1000_WRITE_REG(hw, E1000_AIT,
- mac->current_ifs_val);
- }
- }
- } else {
- if (mac->in_ifs_mode &&
- (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
- mac->current_ifs_val = 0;
- mac->in_ifs_mode = false;
- E1000_WRITE_REG(hw, E1000_AIT, 0);
- }
- }
-}
-
-/**
- * e1000_validate_mdi_setting_generic - Verify MDI/MDIx settings
- * @hw: pointer to the HW structure
- *
- * Verify that when not using auto-negotiation that MDI/MDIx is correctly
- * set, which is forced to MDI mode only.
- **/
-static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_validate_mdi_setting_generic");
-
- if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) {
- DEBUGOUT("Invalid MDI setting detected\n");
- hw->phy.mdix = 1;
- return -E1000_ERR_CONFIG;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_validate_mdi_setting_crossover_generic - Verify MDI/MDIx settings
- * @hw: pointer to the HW structure
- *
- * Validate the MDI/MDIx setting, allowing for auto-crossover during forced
- * operation.
- **/
-s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw E1000_UNUSEDARG *hw)
-{
- DEBUGFUNC("e1000_validate_mdi_setting_crossover_generic");
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_8bit_ctrl_reg_generic - Write a 8bit CTRL register
- * @hw: pointer to the HW structure
- * @reg: 32bit register offset such as E1000_SCTL
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Writes an address/data control type register. There are several of these
- * and they all have the format address << 8 | data and bit 31 is polled for
- * completion.
- **/
-s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
- u32 offset, u8 data)
-{
- u32 i, regvalue = 0;
-
- DEBUGFUNC("e1000_write_8bit_ctrl_reg_generic");
-
- /* Set up the address and data */
- regvalue = ((u32)data) | (offset << E1000_GEN_CTL_ADDRESS_SHIFT);
- E1000_WRITE_REG(hw, reg, regvalue);
-
- /* Poll the ready bit to see if the MDI read completed */
- for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) {
- usec_delay(5);
- regvalue = E1000_READ_REG(hw, reg);
- if (regvalue & E1000_GEN_CTL_READY)
- break;
- }
- if (!(regvalue & E1000_GEN_CTL_READY)) {
- DEBUGOUT1("Reg %08x did not indicate ready\n", reg);
- return -E1000_ERR_PHY;
- }
-
- return E1000_SUCCESS;
-}
diff --git a/kernel/linux/kni/ethtool/igb/e1000_mac.h b/kernel/linux/kni/ethtool/igb/e1000_mac.h
deleted file mode 100644
index a3e784982..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_mac.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_MAC_H_
-#define _E1000_MAC_H_
-
-void e1000_init_mac_ops_generic(struct e1000_hw *hw);
-void e1000_null_mac_generic(struct e1000_hw *hw);
-s32 e1000_null_ops_generic(struct e1000_hw *hw);
-s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
-bool e1000_null_mng_mode(struct e1000_hw *hw);
-void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a);
-void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
-void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a);
-s32 e1000_blink_led_generic(struct e1000_hw *hw);
-s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw);
-s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw);
-s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw);
-s32 e1000_cleanup_led_generic(struct e1000_hw *hw);
-s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw);
-s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw);
-s32 e1000_force_mac_fc_generic(struct e1000_hw *hw);
-s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw);
-s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw);
-void e1000_set_lan_id_single_port(struct e1000_hw *hw);
-s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
-s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
- u16 *duplex);
-s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
- u16 *speed, u16 *duplex);
-s32 e1000_id_led_init_generic(struct e1000_hw *hw);
-s32 e1000_led_on_generic(struct e1000_hw *hw);
-s32 e1000_led_off_generic(struct e1000_hw *hw);
-void e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
- u8 *mc_addr_list, u32 mc_addr_count);
-s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw);
-s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw);
-s32 e1000_setup_led_generic(struct e1000_hw *hw);
-s32 e1000_setup_link_generic(struct e1000_hw *hw);
-s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw *hw);
-s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
- u32 offset, u8 data);
-
-u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr);
-
-void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw);
-void e1000_clear_vfta_generic(struct e1000_hw *hw);
-void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count);
-void e1000_put_hw_semaphore_generic(struct e1000_hw *hw);
-s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
-void e1000_reset_adaptive_generic(struct e1000_hw *hw);
-void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop);
-void e1000_update_adaptive_generic(struct e1000_hw *hw);
-void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
-
-#endif
diff --git a/kernel/linux/kni/ethtool/igb/e1000_manage.c b/kernel/linux/kni/ethtool/igb/e1000_manage.c
deleted file mode 100644
index 2f75bc357..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_manage.c
+++ /dev/null
@@ -1,539 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "e1000_api.h"
-
-/**
- * e1000_calculate_checksum - Calculate checksum for buffer
- * @buffer: pointer to EEPROM
- * @length: size of EEPROM to calculate a checksum for
- *
- * Calculates the checksum for some buffer on a specified length. The
- * checksum calculated is returned.
- **/
-u8 e1000_calculate_checksum(u8 *buffer, u32 length)
-{
- u32 i;
- u8 sum = 0;
-
- DEBUGFUNC("e1000_calculate_checksum");
-
- if (!buffer)
- return 0;
-
- for (i = 0; i < length; i++)
- sum += buffer[i];
-
- return (u8) (0 - sum);
-}
-
-/**
- * e1000_mng_enable_host_if_generic - Checks host interface is enabled
- * @hw: pointer to the HW structure
- *
- * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
- *
- * This function checks whether the HOST IF is enabled for command operation
- * and also checks whether the previous command is completed. It busy waits
- * in case of previous command is not completed.
- **/
-s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
-{
- u32 hicr;
- u8 i;
-
- DEBUGFUNC("e1000_mng_enable_host_if_generic");
-
- if (!hw->mac.arc_subsystem_valid) {
- DEBUGOUT("ARC subsystem not valid.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
-
- /* Check that the host interface is enabled. */
- hicr = E1000_READ_REG(hw, E1000_HICR);
- if (!(hicr & E1000_HICR_EN)) {
- DEBUGOUT("E1000_HOST_EN bit disabled.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
- /* check the previous command is completed */
- for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
- hicr = E1000_READ_REG(hw, E1000_HICR);
- if (!(hicr & E1000_HICR_C))
- break;
- msec_delay_irq(1);
- }
-
- if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
- DEBUGOUT("Previous command timeout failed .\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_check_mng_mode_generic - Generic check management mode
- * @hw: pointer to the HW structure
- *
- * Reads the firmware semaphore register and returns true (>0) if
- * manageability is enabled, else false (0).
- **/
-bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
-{
- u32 fwsm = E1000_READ_REG(hw, E1000_FWSM);
-
- DEBUGFUNC("e1000_check_mng_mode_generic");
-
-
- return (fwsm & E1000_FWSM_MODE_MASK) ==
- (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
-}
-
-/**
- * e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on Tx
- * @hw: pointer to the HW structure
- *
- * Enables packet filtering on transmit packets if manageability is enabled
- * and host interface is enabled.
- **/
-bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
-{
- struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
- u32 *buffer = (u32 *)&hw->mng_cookie;
- u32 offset;
- s32 ret_val, hdr_csum, csum;
- u8 i, len;
-
- DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
-
- hw->mac.tx_pkt_filtering = true;
-
- /* No manageability, no filtering */
- if (!hw->mac.ops.check_mng_mode(hw)) {
- hw->mac.tx_pkt_filtering = false;
- return hw->mac.tx_pkt_filtering;
- }
-
- /* If we can't read from the host interface for whatever
- * reason, disable filtering.
- */
- ret_val = e1000_mng_enable_host_if_generic(hw);
- if (ret_val != E1000_SUCCESS) {
- hw->mac.tx_pkt_filtering = false;
- return hw->mac.tx_pkt_filtering;
- }
-
- /* Read in the header. Length and offset are in dwords. */
- len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
- offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
- for (i = 0; i < len; i++)
- *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
- offset + i);
- hdr_csum = hdr->checksum;
- hdr->checksum = 0;
- csum = e1000_calculate_checksum((u8 *)hdr,
- E1000_MNG_DHCP_COOKIE_LENGTH);
- /* If either the checksums or signature don't match, then
- * the cookie area isn't considered valid, in which case we
- * take the safe route of assuming Tx filtering is enabled.
- */
- if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
- hw->mac.tx_pkt_filtering = true;
- return hw->mac.tx_pkt_filtering;
- }
-
- /* Cookie area is valid, make the final check for filtering. */
- if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
- hw->mac.tx_pkt_filtering = false;
-
- return hw->mac.tx_pkt_filtering;
-}
-
-/**
- * e1000_mng_write_cmd_header_generic - Writes manageability command header
- * @hw: pointer to the HW structure
- * @hdr: pointer to the host interface command header
- *
- * Writes the command header after does the checksum calculation.
- **/
-s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
- struct e1000_host_mng_command_header *hdr)
-{
- u16 i, length = sizeof(struct e1000_host_mng_command_header);
-
- DEBUGFUNC("e1000_mng_write_cmd_header_generic");
-
- /* Write the whole command header structure with new checksum. */
-
- hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
-
- length >>= 2;
- /* Write the relevant command block into the ram area. */
- for (i = 0; i < length; i++) {
- E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
- *((u32 *) hdr + i));
- E1000_WRITE_FLUSH(hw);
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_mng_host_if_write_generic - Write to the manageability host interface
- * @hw: pointer to the HW structure
- * @buffer: pointer to the host interface buffer
- * @length: size of the buffer
- * @offset: location in the buffer to write to
- * @sum: sum of the data (not checksum)
- *
- * This function writes the buffer content at the offset given on the host if.
- * It also does alignment considerations to do the writes in most efficient
- * way. Also fills up the sum of the buffer in *buffer parameter.
- **/
-s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
- u16 length, u16 offset, u8 *sum)
-{
- u8 *tmp;
- u8 *bufptr = buffer;
- u32 data = 0;
- u16 remaining, i, j, prev_bytes;
-
- DEBUGFUNC("e1000_mng_host_if_write_generic");
-
- /* sum = only sum of the data and it is not checksum */
-
- if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
- return -E1000_ERR_PARAM;
-
- tmp = (u8 *)&data;
- prev_bytes = offset & 0x3;
- offset >>= 2;
-
- if (prev_bytes) {
- data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
- for (j = prev_bytes; j < sizeof(u32); j++) {
- *(tmp + j) = *bufptr++;
- *sum += *(tmp + j);
- }
- E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
- length -= j - prev_bytes;
- offset++;
- }
-
- remaining = length & 0x3;
- length -= remaining;
-
- /* Calculate length in DWORDs */
- length >>= 2;
-
- /* The device driver writes the relevant command block into the
- * ram area.
- */
- for (i = 0; i < length; i++) {
- for (j = 0; j < sizeof(u32); j++) {
- *(tmp + j) = *bufptr++;
- *sum += *(tmp + j);
- }
-
- E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
- data);
- }
- if (remaining) {
- for (j = 0; j < sizeof(u32); j++) {
- if (j < remaining)
- *(tmp + j) = *bufptr++;
- else
- *(tmp + j) = 0;
-
- *sum += *(tmp + j);
- }
- E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
- data);
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
- * @hw: pointer to the HW structure
- * @buffer: pointer to the host interface
- * @length: size of the buffer
- *
- * Writes the DHCP information to the host interface.
- **/
-s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
- u16 length)
-{
- struct e1000_host_mng_command_header hdr;
- s32 ret_val;
- u32 hicr;
-
- DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
-
- hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
- hdr.command_length = length;
- hdr.reserved1 = 0;
- hdr.reserved2 = 0;
- hdr.checksum = 0;
-
- /* Enable the host interface */
- ret_val = e1000_mng_enable_host_if_generic(hw);
- if (ret_val)
- return ret_val;
-
- /* Populate the host interface with the contents of "buffer". */
- ret_val = e1000_mng_host_if_write_generic(hw, buffer, length,
- sizeof(hdr), &(hdr.checksum));
- if (ret_val)
- return ret_val;
-
- /* Write the manageability command header */
- ret_val = e1000_mng_write_cmd_header_generic(hw, &hdr);
- if (ret_val)
- return ret_val;
-
- /* Tell the ARC a new command is pending. */
- hicr = E1000_READ_REG(hw, E1000_HICR);
- E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_enable_mng_pass_thru - Check if management passthrough is needed
- * @hw: pointer to the HW structure
- *
- * Verifies the hardware needs to leave interface enabled so that frames can
- * be directed to and from the management interface.
- **/
-bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
-{
- u32 manc;
- u32 fwsm, factps;
-
- DEBUGFUNC("e1000_enable_mng_pass_thru");
-
- if (!hw->mac.asf_firmware_present)
- return false;
-
- manc = E1000_READ_REG(hw, E1000_MANC);
-
- if (!(manc & E1000_MANC_RCV_TCO_EN))
- return false;
-
- if (hw->mac.has_fwsm) {
- fwsm = E1000_READ_REG(hw, E1000_FWSM);
- factps = E1000_READ_REG(hw, E1000_FACTPS);
-
- if (!(factps & E1000_FACTPS_MNGCG) &&
- ((fwsm & E1000_FWSM_MODE_MASK) ==
- (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
- return true;
- } else if ((manc & E1000_MANC_SMBUS_EN) &&
- !(manc & E1000_MANC_ASF_EN)) {
- return true;
- }
-
- return false;
-}
-
-/**
- * e1000_host_interface_command - Writes buffer to host interface
- * @hw: pointer to the HW structure
- * @buffer: contains a command to write
- * @length: the byte length of the buffer, must be multiple of 4 bytes
- *
- * Writes a buffer to the Host Interface. Upon success, returns E1000_SUCCESS
- * else returns E1000_ERR_HOST_INTERFACE_COMMAND.
- **/
-s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
-{
- u32 hicr, i;
-
- DEBUGFUNC("e1000_host_interface_command");
-
- if (!(hw->mac.arc_subsystem_valid)) {
- DEBUGOUT("Hardware doesn't support host interface command.\n");
- return E1000_SUCCESS;
- }
-
- if (!hw->mac.asf_firmware_present) {
- DEBUGOUT("Firmware is not present.\n");
- return E1000_SUCCESS;
- }
-
- if (length == 0 || length & 0x3 ||
- length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) {
- DEBUGOUT("Buffer length failure.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
-
- /* Check that the host interface is enabled. */
- hicr = E1000_READ_REG(hw, E1000_HICR);
- if (!(hicr & E1000_HICR_EN)) {
- DEBUGOUT("E1000_HOST_EN bit disabled.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
-
- /* Calculate length in DWORDs */
- length >>= 2;
-
- /* The device driver writes the relevant command block
- * into the ram area.
- */
- for (i = 0; i < length; i++)
- E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
- *((u32 *)buffer + i));
-
- /* Setting this bit tells the ARC that a new command is pending. */
- E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
-
- for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
- hicr = E1000_READ_REG(hw, E1000_HICR);
- if (!(hicr & E1000_HICR_C))
- break;
- msec_delay(1);
- }
-
- /* Check command successful completion. */
- if (i == E1000_HI_COMMAND_TIMEOUT ||
- (!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) {
- DEBUGOUT("Command has failed with no status valid.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
-
- for (i = 0; i < length; i++)
- *((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
- E1000_HOST_IF,
- i);
-
- return E1000_SUCCESS;
-}
-/**
- * e1000_load_firmware - Writes proxy FW code buffer to host interface
- * and execute.
- * @hw: pointer to the HW structure
- * @buffer: contains a firmware to write
- * @length: the byte length of the buffer, must be multiple of 4 bytes
- *
- * Upon success returns E1000_SUCCESS, returns E1000_ERR_CONFIG if not enabled
- * in HW else returns E1000_ERR_HOST_INTERFACE_COMMAND.
- **/
-s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
-{
- u32 hicr, hibba, fwsm, icr, i;
-
- DEBUGFUNC("e1000_load_firmware");
-
- if (hw->mac.type < e1000_i210) {
- DEBUGOUT("Hardware doesn't support loading FW by the driver\n");
- return -E1000_ERR_CONFIG;
- }
-
- /* Check that the host interface is enabled. */
- hicr = E1000_READ_REG(hw, E1000_HICR);
- if (!(hicr & E1000_HICR_EN)) {
- DEBUGOUT("E1000_HOST_EN bit disabled.\n");
- return -E1000_ERR_CONFIG;
- }
- if (!(hicr & E1000_HICR_MEMORY_BASE_EN)) {
- DEBUGOUT("E1000_HICR_MEMORY_BASE_EN bit disabled.\n");
- return -E1000_ERR_CONFIG;
- }
-
- if (length == 0 || length & 0x3 || length > E1000_HI_FW_MAX_LENGTH) {
- DEBUGOUT("Buffer length failure.\n");
- return -E1000_ERR_INVALID_ARGUMENT;
- }
-
- /* Clear notification from ROM-FW by reading ICR register */
- icr = E1000_READ_REG(hw, E1000_ICR_V2);
-
- /* Reset ROM-FW */
- hicr = E1000_READ_REG(hw, E1000_HICR);
- hicr |= E1000_HICR_FW_RESET_ENABLE;
- E1000_WRITE_REG(hw, E1000_HICR, hicr);
- hicr |= E1000_HICR_FW_RESET;
- E1000_WRITE_REG(hw, E1000_HICR, hicr);
- E1000_WRITE_FLUSH(hw);
-
- /* Wait till MAC notifies about its readiness after ROM-FW reset */
- for (i = 0; i < (E1000_HI_COMMAND_TIMEOUT * 2); i++) {
- icr = E1000_READ_REG(hw, E1000_ICR_V2);
- if (icr & E1000_ICR_MNG)
- break;
- msec_delay(1);
- }
-
- /* Check for timeout */
- if (i == E1000_HI_COMMAND_TIMEOUT) {
- DEBUGOUT("FW reset failed.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
-
- /* Wait till MAC is ready to accept new FW code */
- for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
- fwsm = E1000_READ_REG(hw, E1000_FWSM);
- if ((fwsm & E1000_FWSM_FW_VALID) &&
- ((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT ==
- E1000_FWSM_HI_EN_ONLY_MODE))
- break;
- msec_delay(1);
- }
-
- /* Check for timeout */
- if (i == E1000_HI_COMMAND_TIMEOUT) {
- DEBUGOUT("FW reset failed.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
-
- /* Calculate length in DWORDs */
- length >>= 2;
-
- /* The device driver writes the relevant FW code block
- * into the ram area in DWORDs via 1kB ram addressing window.
- */
- for (i = 0; i < length; i++) {
- if (!(i % E1000_HI_FW_BLOCK_DWORD_LENGTH)) {
- /* Point to correct 1kB ram window */
- hibba = E1000_HI_FW_BASE_ADDRESS +
- ((E1000_HI_FW_BLOCK_DWORD_LENGTH << 2) *
- (i / E1000_HI_FW_BLOCK_DWORD_LENGTH));
-
- E1000_WRITE_REG(hw, E1000_HIBBA, hibba);
- }
-
- E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
- i % E1000_HI_FW_BLOCK_DWORD_LENGTH,
- *((u32 *)buffer + i));
- }
-
- /* Setting this bit tells the ARC that a new FW is ready to execute. */
- hicr = E1000_READ_REG(hw, E1000_HICR);
- E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
-
- for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
- hicr = E1000_READ_REG(hw, E1000_HICR);
- if (!(hicr & E1000_HICR_C))
- break;
- msec_delay(1);
- }
-
- /* Check for successful FW start. */
- if (i == E1000_HI_COMMAND_TIMEOUT) {
- DEBUGOUT("New FW did not start within timeout period.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
-
- return E1000_SUCCESS;
-}
diff --git a/kernel/linux/kni/ethtool/igb/e1000_manage.h b/kernel/linux/kni/ethtool/igb/e1000_manage.h
deleted file mode 100644
index 9f27b9343..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_manage.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_MANAGE_H_
-#define _E1000_MANAGE_H_
-
-bool e1000_check_mng_mode_generic(struct e1000_hw *hw);
-bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw);
-s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw);
-s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
- u16 length, u16 offset, u8 *sum);
-s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
- struct e1000_host_mng_command_header *hdr);
-s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw,
- u8 *buffer, u16 length);
-bool e1000_enable_mng_pass_thru(struct e1000_hw *hw);
-u8 e1000_calculate_checksum(u8 *buffer, u32 length);
-s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length);
-s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length);
-
-enum e1000_mng_mode {
- e1000_mng_mode_none = 0,
- e1000_mng_mode_asf,
- e1000_mng_mode_pt,
- e1000_mng_mode_ipmi,
- e1000_mng_mode_host_if_only
-};
-
-#define E1000_FACTPS_MNGCG 0x20000000
-
-#define E1000_FWSM_MODE_MASK 0xE
-#define E1000_FWSM_MODE_SHIFT 1
-#define E1000_FWSM_FW_VALID 0x00008000
-#define E1000_FWSM_HI_EN_ONLY_MODE 0x4
-
-#define E1000_MNG_IAMT_MODE 0x3
-#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
-#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0
-#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
-#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
-#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1
-#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
-
-#define E1000_VFTA_ENTRY_SHIFT 5
-#define E1000_VFTA_ENTRY_MASK 0x7F
-#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
-
-#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */
-#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */
-#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI cmd limit */
-#define E1000_HI_FW_BASE_ADDRESS 0x10000
-#define E1000_HI_FW_MAX_LENGTH (64 * 1024) /* Num of bytes */
-#define E1000_HI_FW_BLOCK_DWORD_LENGTH 256 /* Num of DWORDs per page */
-#define E1000_HICR_MEMORY_BASE_EN 0x200 /* MB Enable bit - RO */
-#define E1000_HICR_EN 0x01 /* Enable bit - RO */
-/* Driver sets this bit when done to put command in RAM */
-#define E1000_HICR_C 0x02
-#define E1000_HICR_SV 0x04 /* Status Validity */
-#define E1000_HICR_FW_RESET_ENABLE 0x40
-#define E1000_HICR_FW_RESET 0x80
-
-/* Intel(R) Active Management Technology signature */
-#define E1000_IAMT_SIGNATURE 0x544D4149
-
-#endif
diff --git a/kernel/linux/kni/ethtool/igb/e1000_mbx.c b/kernel/linux/kni/ethtool/igb/e1000_mbx.c
deleted file mode 100644
index 1be443491..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_mbx.c
+++ /dev/null
@@ -1,510 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "e1000_mbx.h"
-
-/**
- * e1000_null_mbx_check_for_flag - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-static s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw,
- u16 E1000_UNUSEDARG mbx_id)
-{
- DEBUGFUNC("e1000_null_mbx_check_flag");
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_null_mbx_transact - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw,
- u32 E1000_UNUSEDARG *msg,
- u16 E1000_UNUSEDARG size,
- u16 E1000_UNUSEDARG mbx_id)
-{
- DEBUGFUNC("e1000_null_mbx_rw_msg");
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_mbx - Reads a message from the mailbox
- * @hw: pointer to the HW structure
- * @msg: The message buffer
- * @size: Length of buffer
- * @mbx_id: id of mailbox to read
- *
- * returns SUCCESS if it successfully read message from buffer
- **/
-s32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- s32 ret_val = -E1000_ERR_MBX;
-
- DEBUGFUNC("e1000_read_mbx");
-
- /* limit read to size of mailbox */
- if (size > mbx->size)
- size = mbx->size;
-
- if (mbx->ops.read)
- ret_val = mbx->ops.read(hw, msg, size, mbx_id);
-
- return ret_val;
-}
-
-/**
- * e1000_write_mbx - Write a message to the mailbox
- * @hw: pointer to the HW structure
- * @msg: The message buffer
- * @size: Length of buffer
- * @mbx_id: id of mailbox to write
- *
- * returns SUCCESS if it successfully copied message into the buffer
- **/
-s32 e1000_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_write_mbx");
-
- if (size > mbx->size)
- ret_val = -E1000_ERR_MBX;
-
- else if (mbx->ops.write)
- ret_val = mbx->ops.write(hw, msg, size, mbx_id);
-
- return ret_val;
-}
-
-/**
- * e1000_check_for_msg - checks to see if someone sent us mail
- * @hw: pointer to the HW structure
- * @mbx_id: id of mailbox to check
- *
- * returns SUCCESS if the Status bit was found or else ERR_MBX
- **/
-s32 e1000_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- s32 ret_val = -E1000_ERR_MBX;
-
- DEBUGFUNC("e1000_check_for_msg");
-
- if (mbx->ops.check_for_msg)
- ret_val = mbx->ops.check_for_msg(hw, mbx_id);
-
- return ret_val;
-}
-
-/**
- * e1000_check_for_ack - checks to see if someone sent us ACK
- * @hw: pointer to the HW structure
- * @mbx_id: id of mailbox to check
- *
- * returns SUCCESS if the Status bit was found or else ERR_MBX
- **/
-s32 e1000_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- s32 ret_val = -E1000_ERR_MBX;
-
- DEBUGFUNC("e1000_check_for_ack");
-
- if (mbx->ops.check_for_ack)
- ret_val = mbx->ops.check_for_ack(hw, mbx_id);
-
- return ret_val;
-}
-
-/**
- * e1000_check_for_rst - checks to see if other side has reset
- * @hw: pointer to the HW structure
- * @mbx_id: id of mailbox to check
- *
- * returns SUCCESS if the Status bit was found or else ERR_MBX
- **/
-s32 e1000_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- s32 ret_val = -E1000_ERR_MBX;
-
- DEBUGFUNC("e1000_check_for_rst");
-
- if (mbx->ops.check_for_rst)
- ret_val = mbx->ops.check_for_rst(hw, mbx_id);
-
- return ret_val;
-}
-
-/**
- * e1000_poll_for_msg - Wait for message notification
- * @hw: pointer to the HW structure
- * @mbx_id: id of mailbox to write
- *
- * returns SUCCESS if it successfully received a message notification
- **/
-static s32 e1000_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- int countdown = mbx->timeout;
-
- DEBUGFUNC("e1000_poll_for_msg");
-
- if (!countdown || !mbx->ops.check_for_msg)
- goto out;
-
- while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
- countdown--;
- if (!countdown)
- break;
- usec_delay(mbx->usec_delay);
- }
-
- /* if we failed, all future posted messages fail until reset */
- if (!countdown)
- mbx->timeout = 0;
-out:
- return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
-}
-
-/**
- * e1000_poll_for_ack - Wait for message acknowledgement
- * @hw: pointer to the HW structure
- * @mbx_id: id of mailbox to write
- *
- * returns SUCCESS if it successfully received a message acknowledgement
- **/
-static s32 e1000_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- int countdown = mbx->timeout;
-
- DEBUGFUNC("e1000_poll_for_ack");
-
- if (!countdown || !mbx->ops.check_for_ack)
- goto out;
-
- while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
- countdown--;
- if (!countdown)
- break;
- usec_delay(mbx->usec_delay);
- }
-
- /* if we failed, all future posted messages fail until reset */
- if (!countdown)
- mbx->timeout = 0;
-out:
- return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
-}
-
-/**
- * e1000_read_posted_mbx - Wait for message notification and receive message
- * @hw: pointer to the HW structure
- * @msg: The message buffer
- * @size: Length of buffer
- * @mbx_id: id of mailbox to write
- *
- * returns SUCCESS if it successfully received a message notification and
- * copied it into the receive buffer.
- **/
-s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- s32 ret_val = -E1000_ERR_MBX;
-
- DEBUGFUNC("e1000_read_posted_mbx");
-
- if (!mbx->ops.read)
- goto out;
-
- ret_val = e1000_poll_for_msg(hw, mbx_id);
-
- /* if ack received read message, otherwise we timed out */
- if (!ret_val)
- ret_val = mbx->ops.read(hw, msg, size, mbx_id);
-out:
- return ret_val;
-}
-
-/**
- * e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
- * @hw: pointer to the HW structure
- * @msg: The message buffer
- * @size: Length of buffer
- * @mbx_id: id of mailbox to write
- *
- * returns SUCCESS if it successfully copied message into the buffer and
- * received an ack to that message within delay * timeout period
- **/
-s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- s32 ret_val = -E1000_ERR_MBX;
-
- DEBUGFUNC("e1000_write_posted_mbx");
-
- /* exit if either we can't write or there isn't a defined timeout */
- if (!mbx->ops.write || !mbx->timeout)
- goto out;
-
- /* send msg */
- ret_val = mbx->ops.write(hw, msg, size, mbx_id);
-
- /* if msg sent wait until we receive an ack */
- if (!ret_val)
- ret_val = e1000_poll_for_ack(hw, mbx_id);
-out:
- return ret_val;
-}
-
-/**
- * e1000_init_mbx_ops_generic - Initialize mbx function pointers
- * @hw: pointer to the HW structure
- *
- * Sets the function pointers to no-op functions
- **/
-void e1000_init_mbx_ops_generic(struct e1000_hw *hw)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
- mbx->ops.init_params = e1000_null_ops_generic;
- mbx->ops.read = e1000_null_mbx_transact;
- mbx->ops.write = e1000_null_mbx_transact;
- mbx->ops.check_for_msg = e1000_null_mbx_check_for_flag;
- mbx->ops.check_for_ack = e1000_null_mbx_check_for_flag;
- mbx->ops.check_for_rst = e1000_null_mbx_check_for_flag;
- mbx->ops.read_posted = e1000_read_posted_mbx;
- mbx->ops.write_posted = e1000_write_posted_mbx;
-}
-
-static s32 e1000_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
-{
- u32 mbvficr = E1000_READ_REG(hw, E1000_MBVFICR);
- s32 ret_val = -E1000_ERR_MBX;
-
- if (mbvficr & mask) {
- ret_val = E1000_SUCCESS;
- E1000_WRITE_REG(hw, E1000_MBVFICR, mask);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_check_for_msg_pf - checks to see if the VF has sent mail
- * @hw: pointer to the HW structure
- * @vf_number: the VF index
- *
- * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
- **/
-static s32 e1000_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
-{
- s32 ret_val = -E1000_ERR_MBX;
-
- DEBUGFUNC("e1000_check_for_msg_pf");
-
- if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
- ret_val = E1000_SUCCESS;
- hw->mbx.stats.reqs++;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_check_for_ack_pf - checks to see if the VF has ACKed
- * @hw: pointer to the HW structure
- * @vf_number: the VF index
- *
- * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
- **/
-static s32 e1000_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
-{
- s32 ret_val = -E1000_ERR_MBX;
-
- DEBUGFUNC("e1000_check_for_ack_pf");
-
- if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
- ret_val = E1000_SUCCESS;
- hw->mbx.stats.acks++;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_check_for_rst_pf - checks to see if the VF has reset
- * @hw: pointer to the HW structure
- * @vf_number: the VF index
- *
- * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
- **/
-static s32 e1000_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
-{
- u32 vflre = E1000_READ_REG(hw, E1000_VFLRE);
- s32 ret_val = -E1000_ERR_MBX;
-
- DEBUGFUNC("e1000_check_for_rst_pf");
-
- if (vflre & (1 << vf_number)) {
- ret_val = E1000_SUCCESS;
- E1000_WRITE_REG(hw, E1000_VFLRE, (1 << vf_number));
- hw->mbx.stats.rsts++;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_obtain_mbx_lock_pf - obtain mailbox lock
- * @hw: pointer to the HW structure
- * @vf_number: the VF index
- *
- * return SUCCESS if we obtained the mailbox lock
- **/
-static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
-{
- s32 ret_val = -E1000_ERR_MBX;
- u32 p2v_mailbox;
-
- DEBUGFUNC("e1000_obtain_mbx_lock_pf");
-
- /* Take ownership of the buffer */
- E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
-
- /* reserve mailbox for vf use */
- p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
- if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
- ret_val = E1000_SUCCESS;
-
- return ret_val;
-}
-
-/**
- * e1000_write_mbx_pf - Places a message in the mailbox
- * @hw: pointer to the HW structure
- * @msg: The message buffer
- * @size: Length of buffer
- * @vf_number: the VF index
- *
- * returns SUCCESS if it successfully copied message into the buffer
- **/
-static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
- u16 vf_number)
-{
- s32 ret_val;
- u16 i;
-
- DEBUGFUNC("e1000_write_mbx_pf");
-
- /* lock the mailbox to prevent pf/vf race condition */
- ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
- if (ret_val)
- goto out_no_write;
-
- /* flush msg and acks as we are overwriting the message buffer */
- e1000_check_for_msg_pf(hw, vf_number);
- e1000_check_for_ack_pf(hw, vf_number);
-
- /* copy the caller specified message to the mailbox memory buffer */
- for (i = 0; i < size; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i, msg[i]);
-
- /* Interrupt VF to tell it a message has been sent and release buffer*/
- E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
-
- /* update stats */
- hw->mbx.stats.msgs_tx++;
-
-out_no_write:
- return ret_val;
-
-}
-
-/**
- * e1000_read_mbx_pf - Read a message from the mailbox
- * @hw: pointer to the HW structure
- * @msg: The message buffer
- * @size: Length of buffer
- * @vf_number: the VF index
- *
- * This function copies a message from the mailbox buffer to the caller's
- * memory buffer. The presumption is that the caller knows that there was
- * a message due to a VF request so no polling for message is needed.
- **/
-static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
- u16 vf_number)
-{
- s32 ret_val;
- u16 i;
-
- DEBUGFUNC("e1000_read_mbx_pf");
-
- /* lock the mailbox to prevent pf/vf race condition */
- ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number);
- if (ret_val)
- goto out_no_read;
-
- /* copy the message to the mailbox memory buffer */
- for (i = 0; i < size; i++)
- msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i);
-
- /* Acknowledge the message and release buffer */
- E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
-
- /* update stats */
- hw->mbx.stats.msgs_rx++;
-
-out_no_read:
- return ret_val;
-}
-
-/**
- * e1000_init_mbx_params_pf - set initial values for pf mailbox
- * @hw: pointer to the HW structure
- *
- * Initializes the hw->mbx struct to correct values for pf mailbox
- */
-s32 e1000_init_mbx_params_pf(struct e1000_hw *hw)
-{
- struct e1000_mbx_info *mbx = &hw->mbx;
-
- switch (hw->mac.type) {
- case e1000_82576:
- case e1000_i350:
- case e1000_i354:
- mbx->timeout = 0;
- mbx->usec_delay = 0;
-
- mbx->size = E1000_VFMAILBOX_SIZE;
-
- mbx->ops.read = e1000_read_mbx_pf;
- mbx->ops.write = e1000_write_mbx_pf;
- mbx->ops.read_posted = e1000_read_posted_mbx;
- mbx->ops.write_posted = e1000_write_posted_mbx;
- mbx->ops.check_for_msg = e1000_check_for_msg_pf;
- mbx->ops.check_for_ack = e1000_check_for_ack_pf;
- mbx->ops.check_for_rst = e1000_check_for_rst_pf;
-
- mbx->stats.msgs_tx = 0;
- mbx->stats.msgs_rx = 0;
- mbx->stats.reqs = 0;
- mbx->stats.acks = 0;
- mbx->stats.rsts = 0;
- default:
- return E1000_SUCCESS;
- }
-}
diff --git a/kernel/linux/kni/ethtool/igb/e1000_mbx.h b/kernel/linux/kni/ethtool/igb/e1000_mbx.h
deleted file mode 100644
index 5951f18fb..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_mbx.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_MBX_H_
-#define _E1000_MBX_H_
-
-#include "e1000_api.h"
-
-#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */
-#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
-#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
-#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
-#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */
-
-#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */
-#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */
-#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */
-#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */
-
-#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
-
-/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
- * PF. The reverse is true if it is E1000_PF_*.
- * Message ACK's are the value or'd with 0xF0000000
- */
-/* Msgs below or'd with this are the ACK */
-#define E1000_VT_MSGTYPE_ACK 0x80000000
-/* Msgs below or'd with this are the NACK */
-#define E1000_VT_MSGTYPE_NACK 0x40000000
-/* Indicates that VF is still clear to send requests */
-#define E1000_VT_MSGTYPE_CTS 0x20000000
-#define E1000_VT_MSGINFO_SHIFT 16
-/* bits 23:16 are used for extra info for certain messages */
-#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
-
-#define E1000_VF_RESET 0x01 /* VF requests reset */
-#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests to set MAC addr */
-#define E1000_VF_SET_MULTICAST 0x03 /* VF requests to set MC addr */
-#define E1000_VF_SET_MULTICAST_COUNT_MASK (0x1F << E1000_VT_MSGINFO_SHIFT)
-#define E1000_VF_SET_MULTICAST_OVERFLOW (0x80 << E1000_VT_MSGINFO_SHIFT)
-#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */
-#define E1000_VF_SET_VLAN_ADD (0x01 << E1000_VT_MSGINFO_SHIFT)
-#define E1000_VF_SET_LPE 0x05 /* reqs to set VMOLR.LPE */
-#define E1000_VF_SET_PROMISC 0x06 /* reqs to clear VMOLR.ROPE/MPME*/
-#define E1000_VF_SET_PROMISC_UNICAST (0x01 << E1000_VT_MSGINFO_SHIFT)
-#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT)
-
-#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */
-
-#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
-#define E1000_VF_MBX_INIT_DELAY 500 /* microseconds between retries */
-
-s32 e1000_read_mbx(struct e1000_hw *, u32 *, u16, u16);
-s32 e1000_write_mbx(struct e1000_hw *, u32 *, u16, u16);
-s32 e1000_read_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
-s32 e1000_write_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
-s32 e1000_check_for_msg(struct e1000_hw *, u16);
-s32 e1000_check_for_ack(struct e1000_hw *, u16);
-s32 e1000_check_for_rst(struct e1000_hw *, u16);
-void e1000_init_mbx_ops_generic(struct e1000_hw *hw);
-s32 e1000_init_mbx_params_pf(struct e1000_hw *);
-
-#endif /* _E1000_MBX_H_ */
diff --git a/kernel/linux/kni/ethtool/igb/e1000_nvm.c b/kernel/linux/kni/ethtool/igb/e1000_nvm.c
deleted file mode 100644
index 78c3fc0ed..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_nvm.c
+++ /dev/null
@@ -1,950 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "e1000_api.h"
-
-static void e1000_reload_nvm_generic(struct e1000_hw *hw);
-
-/**
- * e1000_init_nvm_ops_generic - Initialize NVM function pointers
- * @hw: pointer to the HW structure
- *
- * Setups up the function pointers to no-op functions
- **/
-void e1000_init_nvm_ops_generic(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- DEBUGFUNC("e1000_init_nvm_ops_generic");
-
- /* Initialize function pointers */
- nvm->ops.init_params = e1000_null_ops_generic;
- nvm->ops.acquire = e1000_null_ops_generic;
- nvm->ops.read = e1000_null_read_nvm;
- nvm->ops.release = e1000_null_nvm_generic;
- nvm->ops.reload = e1000_reload_nvm_generic;
- nvm->ops.update = e1000_null_ops_generic;
- nvm->ops.valid_led_default = e1000_null_led_default;
- nvm->ops.validate = e1000_null_ops_generic;
- nvm->ops.write = e1000_null_write_nvm;
-}
-
-/**
- * e1000_null_nvm_read - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-s32 e1000_null_read_nvm(struct e1000_hw E1000_UNUSEDARG *hw,
- u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b,
- u16 E1000_UNUSEDARG *c)
-{
- DEBUGFUNC("e1000_null_read_nvm");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_null_nvm_generic - No-op function, return void
- * @hw: pointer to the HW structure
- **/
-void e1000_null_nvm_generic(struct e1000_hw E1000_UNUSEDARG *hw)
-{
- DEBUGFUNC("e1000_null_nvm_generic");
- return;
-}
-
-/**
- * e1000_null_led_default - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-s32 e1000_null_led_default(struct e1000_hw E1000_UNUSEDARG *hw,
- u16 E1000_UNUSEDARG *data)
-{
- DEBUGFUNC("e1000_null_led_default");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_null_write_nvm - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-s32 e1000_null_write_nvm(struct e1000_hw E1000_UNUSEDARG *hw,
- u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b,
- u16 E1000_UNUSEDARG *c)
-{
- DEBUGFUNC("e1000_null_write_nvm");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_raise_eec_clk - Raise EEPROM clock
- * @hw: pointer to the HW structure
- * @eecd: pointer to the EEPROM
- *
- * Enable/Raise the EEPROM clock bit.
- **/
-static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
-{
- *eecd = *eecd | E1000_EECD_SK;
- E1000_WRITE_REG(hw, E1000_EECD, *eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(hw->nvm.delay_usec);
-}
-
-/**
- * e1000_lower_eec_clk - Lower EEPROM clock
- * @hw: pointer to the HW structure
- * @eecd: pointer to the EEPROM
- *
- * Clear/Lower the EEPROM clock bit.
- **/
-static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
-{
- *eecd = *eecd & ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, E1000_EECD, *eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(hw->nvm.delay_usec);
-}
-
-/**
- * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
- * @hw: pointer to the HW structure
- * @data: data to send to the EEPROM
- * @count: number of bits to shift out
- *
- * We need to shift 'count' bits out to the EEPROM. So, the value in the
- * "data" parameter will be shifted out to the EEPROM one bit at a time.
- * In order to do this, "data" must be broken down into bits.
- **/
-static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 eecd = E1000_READ_REG(hw, E1000_EECD);
- u32 mask;
-
- DEBUGFUNC("e1000_shift_out_eec_bits");
-
- mask = 0x01 << (count - 1);
- if (nvm->type == e1000_nvm_eeprom_spi)
- eecd |= E1000_EECD_DO;
-
- do {
- eecd &= ~E1000_EECD_DI;
-
- if (data & mask)
- eecd |= E1000_EECD_DI;
-
- E1000_WRITE_REG(hw, E1000_EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-
- usec_delay(nvm->delay_usec);
-
- e1000_raise_eec_clk(hw, &eecd);
- e1000_lower_eec_clk(hw, &eecd);
-
- mask >>= 1;
- } while (mask);
-
- eecd &= ~E1000_EECD_DI;
- E1000_WRITE_REG(hw, E1000_EECD, eecd);
-}
-
-/**
- * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
- * @hw: pointer to the HW structure
- * @count: number of bits to shift in
- *
- * In order to read a register from the EEPROM, we need to shift 'count' bits
- * in from the EEPROM. Bits are "shifted in" by raising the clock input to
- * the EEPROM (setting the SK bit), and then reading the value of the data out
- * "DO" bit. During this "shifting in" process the data in "DI" bit should
- * always be clear.
- **/
-static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
-{
- u32 eecd;
- u32 i;
- u16 data;
-
- DEBUGFUNC("e1000_shift_in_eec_bits");
-
- eecd = E1000_READ_REG(hw, E1000_EECD);
-
- eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
- data = 0;
-
- for (i = 0; i < count; i++) {
- data <<= 1;
- e1000_raise_eec_clk(hw, &eecd);
-
- eecd = E1000_READ_REG(hw, E1000_EECD);
-
- eecd &= ~E1000_EECD_DI;
- if (eecd & E1000_EECD_DO)
- data |= 1;
-
- e1000_lower_eec_clk(hw, &eecd);
- }
-
- return data;
-}
-
-/**
- * e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion
- * @hw: pointer to the HW structure
- * @ee_reg: EEPROM flag for polling
- *
- * Polls the EEPROM status bit for either read or write completion based
- * upon the value of 'ee_reg'.
- **/
-s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
-{
- u32 attempts = 100000;
- u32 i, reg = 0;
-
- DEBUGFUNC("e1000_poll_eerd_eewr_done");
-
- for (i = 0; i < attempts; i++) {
- if (ee_reg == E1000_NVM_POLL_READ)
- reg = E1000_READ_REG(hw, E1000_EERD);
- else
- reg = E1000_READ_REG(hw, E1000_EEWR);
-
- if (reg & E1000_NVM_RW_REG_DONE)
- return E1000_SUCCESS;
-
- usec_delay(5);
- }
-
- return -E1000_ERR_NVM;
-}
-
-/**
- * e1000_acquire_nvm_generic - Generic request for access to EEPROM
- * @hw: pointer to the HW structure
- *
- * Set the EEPROM access request bit and wait for EEPROM access grant bit.
- * Return successful if access grant bit set, else clear the request for
- * EEPROM access and return -E1000_ERR_NVM (-1).
- **/
-s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
-{
- u32 eecd = E1000_READ_REG(hw, E1000_EECD);
- s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
-
- DEBUGFUNC("e1000_acquire_nvm_generic");
-
- E1000_WRITE_REG(hw, E1000_EECD, eecd | E1000_EECD_REQ);
- eecd = E1000_READ_REG(hw, E1000_EECD);
-
- while (timeout) {
- if (eecd & E1000_EECD_GNT)
- break;
- usec_delay(5);
- eecd = E1000_READ_REG(hw, E1000_EECD);
- timeout--;
- }
-
- if (!timeout) {
- eecd &= ~E1000_EECD_REQ;
- E1000_WRITE_REG(hw, E1000_EECD, eecd);
- DEBUGOUT("Could not acquire NVM grant\n");
- return -E1000_ERR_NVM;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_standby_nvm - Return EEPROM to standby state
- * @hw: pointer to the HW structure
- *
- * Return the EEPROM to a standby state.
- **/
-static void e1000_standby_nvm(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 eecd = E1000_READ_REG(hw, E1000_EECD);
-
- DEBUGFUNC("e1000_standby_nvm");
-
- if (nvm->type == e1000_nvm_eeprom_spi) {
- /* Toggle CS to flush commands */
- eecd |= E1000_EECD_CS;
- E1000_WRITE_REG(hw, E1000_EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(nvm->delay_usec);
- eecd &= ~E1000_EECD_CS;
- E1000_WRITE_REG(hw, E1000_EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(nvm->delay_usec);
- }
-}
-
-/**
- * e1000_stop_nvm - Terminate EEPROM command
- * @hw: pointer to the HW structure
- *
- * Terminates the current command by inverting the EEPROM's chip select pin.
- **/
-static void e1000_stop_nvm(struct e1000_hw *hw)
-{
- u32 eecd;
-
- DEBUGFUNC("e1000_stop_nvm");
-
- eecd = E1000_READ_REG(hw, E1000_EECD);
- if (hw->nvm.type == e1000_nvm_eeprom_spi) {
- /* Pull CS high */
- eecd |= E1000_EECD_CS;
- e1000_lower_eec_clk(hw, &eecd);
- }
-}
-
-/**
- * e1000_release_nvm_generic - Release exclusive access to EEPROM
- * @hw: pointer to the HW structure
- *
- * Stop any current commands to the EEPROM and clear the EEPROM request bit.
- **/
-void e1000_release_nvm_generic(struct e1000_hw *hw)
-{
- u32 eecd;
-
- DEBUGFUNC("e1000_release_nvm_generic");
-
- e1000_stop_nvm(hw);
-
- eecd = E1000_READ_REG(hw, E1000_EECD);
- eecd &= ~E1000_EECD_REQ;
- E1000_WRITE_REG(hw, E1000_EECD, eecd);
-}
-
-/**
- * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
- * @hw: pointer to the HW structure
- *
- * Setups the EEPROM for reading and writing.
- **/
-static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 eecd = E1000_READ_REG(hw, E1000_EECD);
- u8 spi_stat_reg;
-
- DEBUGFUNC("e1000_ready_nvm_eeprom");
-
- if (nvm->type == e1000_nvm_eeprom_spi) {
- u16 timeout = NVM_MAX_RETRY_SPI;
-
- /* Clear SK and CS */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- E1000_WRITE_REG(hw, E1000_EECD, eecd);
- E1000_WRITE_FLUSH(hw);
- usec_delay(1);
-
- /* Read "Status Register" repeatedly until the LSB is cleared.
- * The EEPROM will signal that the command has been completed
- * by clearing bit 0 of the internal status register. If it's
- * not cleared within 'timeout', then error out.
- */
- while (timeout) {
- e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
- hw->nvm.opcode_bits);
- spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
- if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
- break;
-
- usec_delay(5);
- e1000_standby_nvm(hw);
- timeout--;
- }
-
- if (!timeout) {
- DEBUGOUT("SPI NVM Status error\n");
- return -E1000_ERR_NVM;
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_nvm_spi - Read EEPROM's using SPI
- * @hw: pointer to the HW structure
- * @offset: offset of word in the EEPROM to read
- * @words: number of words to read
- * @data: word read from the EEPROM
- *
- * Reads a 16 bit word from the EEPROM.
- **/
-s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 i = 0;
- s32 ret_val;
- u16 word_in;
- u8 read_opcode = NVM_READ_OPCODE_SPI;
-
- DEBUGFUNC("e1000_read_nvm_spi");
-
- /* A check for invalid values: offset too large, too many words,
- * and not enough words.
- */
- if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
- (words == 0)) {
- DEBUGOUT("nvm parameter(s) out of bounds\n");
- return -E1000_ERR_NVM;
- }
-
- ret_val = nvm->ops.acquire(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_ready_nvm_eeprom(hw);
- if (ret_val)
- goto release;
-
- e1000_standby_nvm(hw);
-
- if ((nvm->address_bits == 8) && (offset >= 128))
- read_opcode |= NVM_A8_OPCODE_SPI;
-
- /* Send the READ command (opcode + addr) */
- e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
- e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
-
- /* Read the data. SPI NVMs increment the address with each byte
- * read and will roll over if reading beyond the end. This allows
- * us to read the whole NVM from any offset
- */
- for (i = 0; i < words; i++) {
- word_in = e1000_shift_in_eec_bits(hw, 16);
- data[i] = (word_in >> 8) | (word_in << 8);
- }
-
-release:
- nvm->ops.release(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_read_nvm_eerd - Reads EEPROM using EERD register
- * @hw: pointer to the HW structure
- * @offset: offset of word in the EEPROM to read
- * @words: number of words to read
- * @data: word read from the EEPROM
- *
- * Reads a 16 bit word from the EEPROM using the EERD register.
- **/
-s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 i, eerd = 0;
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_read_nvm_eerd");
-
- /* A check for invalid values: offset too large, too many words,
- * too many words for the offset, and not enough words.
- */
- if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
- (words == 0)) {
- DEBUGOUT("nvm parameter(s) out of bounds\n");
- return -E1000_ERR_NVM;
- }
-
- for (i = 0; i < words; i++) {
- eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
- E1000_NVM_RW_REG_START;
-
- E1000_WRITE_REG(hw, E1000_EERD, eerd);
- ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
- if (ret_val)
- break;
-
- data[i] = (E1000_READ_REG(hw, E1000_EERD) >>
- E1000_NVM_RW_REG_DATA);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_write_nvm_spi - Write to EEPROM using SPI
- * @hw: pointer to the HW structure
- * @offset: offset within the EEPROM to be written to
- * @words: number of words to write
- * @data: 16 bit word(s) to be written to the EEPROM
- *
- * Writes data to EEPROM at offset using SPI interface.
- *
- * If e1000_update_nvm_checksum is not called after this function , the
- * EEPROM will most likely contain an invalid checksum.
- **/
-s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- s32 ret_val = -E1000_ERR_NVM;
- u16 widx = 0;
-
- DEBUGFUNC("e1000_write_nvm_spi");
-
- /* A check for invalid values: offset too large, too many words,
- * and not enough words.
- */
- if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
- (words == 0)) {
- DEBUGOUT("nvm parameter(s) out of bounds\n");
- return -E1000_ERR_NVM;
- }
-
- while (widx < words) {
- u8 write_opcode = NVM_WRITE_OPCODE_SPI;
-
- ret_val = nvm->ops.acquire(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_ready_nvm_eeprom(hw);
- if (ret_val) {
- nvm->ops.release(hw);
- return ret_val;
- }
-
- e1000_standby_nvm(hw);
-
- /* Send the WRITE ENABLE command (8 bit opcode) */
- e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
- nvm->opcode_bits);
-
- e1000_standby_nvm(hw);
-
- /* Some SPI eeproms use the 8th address bit embedded in the
- * opcode
- */
- if ((nvm->address_bits == 8) && (offset >= 128))
- write_opcode |= NVM_A8_OPCODE_SPI;
-
- /* Send the Write command (8-bit opcode + addr) */
- e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
- e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
- nvm->address_bits);
-
- /* Loop to allow for up to whole page write of eeprom */
- while (widx < words) {
- u16 word_out = data[widx];
- word_out = (word_out >> 8) | (word_out << 8);
- e1000_shift_out_eec_bits(hw, word_out, 16);
- widx++;
-
- if ((((offset + widx) * 2) % nvm->page_size) == 0) {
- e1000_standby_nvm(hw);
- break;
- }
- }
- msec_delay(10);
- nvm->ops.release(hw);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_read_pba_string_generic - Read device part number
- * @hw: pointer to the HW structure
- * @pba_num: pointer to device part number
- * @pba_num_size: size of part number buffer
- *
- * Reads the product board assembly (PBA) number from the EEPROM and stores
- * the value in pba_num.
- **/
-s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
- u32 pba_num_size)
-{
- s32 ret_val;
- u16 nvm_data;
- u16 pba_ptr;
- u16 offset;
- u16 length;
-
- DEBUGFUNC("e1000_read_pba_string_generic");
-
- if (pba_num == NULL) {
- DEBUGOUT("PBA string buffer was null\n");
- return -E1000_ERR_INVALID_ARGUMENT;
- }
-
- ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- /* if nvm_data is not ptr guard the PBA must be in legacy format which
- * means pba_ptr is actually our second data word for the PBA number
- * and we can decode it into an ascii string
- */
- if (nvm_data != NVM_PBA_PTR_GUARD) {
- DEBUGOUT("NVM PBA number is not stored as string\n");
-
- /* make sure callers buffer is big enough to store the PBA */
- if (pba_num_size < E1000_PBANUM_LENGTH) {
- DEBUGOUT("PBA string buffer too small\n");
- return E1000_ERR_NO_SPACE;
- }
-
- /* extract hex string from data and pba_ptr */
- pba_num[0] = (nvm_data >> 12) & 0xF;
- pba_num[1] = (nvm_data >> 8) & 0xF;
- pba_num[2] = (nvm_data >> 4) & 0xF;
- pba_num[3] = nvm_data & 0xF;
- pba_num[4] = (pba_ptr >> 12) & 0xF;
- pba_num[5] = (pba_ptr >> 8) & 0xF;
- pba_num[6] = '-';
- pba_num[7] = 0;
- pba_num[8] = (pba_ptr >> 4) & 0xF;
- pba_num[9] = pba_ptr & 0xF;
-
- /* put a null character on the end of our string */
- pba_num[10] = '\0';
-
- /* switch all the data but the '-' to hex char */
- for (offset = 0; offset < 10; offset++) {
- if (pba_num[offset] < 0xA)
- pba_num[offset] += '0';
- else if (pba_num[offset] < 0x10)
- pba_num[offset] += 'A' - 0xA;
- }
-
- return E1000_SUCCESS;
- }
-
- ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- if (length == 0xFFFF || length == 0) {
- DEBUGOUT("NVM PBA number section invalid length\n");
- return -E1000_ERR_NVM_PBA_SECTION;
- }
- /* check if pba_num buffer is big enough */
- if (pba_num_size < (((u32)length * 2) - 1)) {
- DEBUGOUT("PBA string buffer too small\n");
- return -E1000_ERR_NO_SPACE;
- }
-
- /* trim pba length from start of string */
- pba_ptr++;
- length--;
-
- for (offset = 0; offset < length; offset++) {
- ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
- pba_num[offset * 2] = (u8)(nvm_data >> 8);
- pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
- }
- pba_num[offset * 2] = '\0';
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_pba_length_generic - Read device part number length
- * @hw: pointer to the HW structure
- * @pba_num_size: size of part number buffer
- *
- * Reads the product board assembly (PBA) number length from the EEPROM and
- * stores the value in pba_num_size.
- **/
-s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
-{
- s32 ret_val;
- u16 nvm_data;
- u16 pba_ptr;
- u16 length;
-
- DEBUGFUNC("e1000_read_pba_length_generic");
-
- if (pba_num_size == NULL) {
- DEBUGOUT("PBA buffer size was null\n");
- return -E1000_ERR_INVALID_ARGUMENT;
- }
-
- ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- /* if data is not ptr guard the PBA must be in legacy format */
- if (nvm_data != NVM_PBA_PTR_GUARD) {
- *pba_num_size = E1000_PBANUM_LENGTH;
- return E1000_SUCCESS;
- }
-
- ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
-
- if (length == 0xFFFF || length == 0) {
- DEBUGOUT("NVM PBA number section invalid length\n");
- return -E1000_ERR_NVM_PBA_SECTION;
- }
-
- /* Convert from length in u16 values to u8 chars, add 1 for NULL,
- * and subtract 2 because length field is included in length.
- */
- *pba_num_size = ((u32)length * 2) - 1;
-
- return E1000_SUCCESS;
-}
-
-
-
-
-
-/**
- * e1000_read_mac_addr_generic - Read device MAC address
- * @hw: pointer to the HW structure
- *
- * Reads the device MAC address from the EEPROM and stores the value.
- * Since devices with two ports use the same EEPROM, we increment the
- * last bit in the MAC address for the second port.
- **/
-s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
-{
- u32 rar_high;
- u32 rar_low;
- u16 i;
-
- rar_high = E1000_READ_REG(hw, E1000_RAH(0));
- rar_low = E1000_READ_REG(hw, E1000_RAL(0));
-
- for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
- hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
-
- for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
- hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
-
- for (i = 0; i < ETH_ADDR_LEN; i++)
- hw->mac.addr[i] = hw->mac.perm_addr[i];
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_validate_nvm_checksum_generic - Validate EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
- * and then verifies that the sum of the EEPROM is equal to 0xBABA.
- **/
-s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 checksum = 0;
- u16 i, nvm_data;
-
- DEBUGFUNC("e1000_validate_nvm_checksum_generic");
-
- for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
- ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error\n");
- return ret_val;
- }
- checksum += nvm_data;
- }
-
- if (checksum != (u16) NVM_SUM) {
- DEBUGOUT("NVM Checksum Invalid\n");
- return -E1000_ERR_NVM;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_update_nvm_checksum_generic - Update EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Updates the EEPROM checksum by reading/adding each word of the EEPROM
- * up to the checksum. Then calculates the EEPROM checksum and writes the
- * value to the EEPROM.
- **/
-s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 checksum = 0;
- u16 i, nvm_data;
-
- DEBUGFUNC("e1000_update_nvm_checksum");
-
- for (i = 0; i < NVM_CHECKSUM_REG; i++) {
- ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
- if (ret_val) {
- DEBUGOUT("NVM Read Error while updating checksum.\n");
- return ret_val;
- }
- checksum += nvm_data;
- }
- checksum = (u16) NVM_SUM - checksum;
- ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
- if (ret_val)
- DEBUGOUT("NVM Write Error while updating checksum.\n");
-
- return ret_val;
-}
-
-/**
- * e1000_reload_nvm_generic - Reloads EEPROM
- * @hw: pointer to the HW structure
- *
- * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
- * extended control register.
- **/
-static void e1000_reload_nvm_generic(struct e1000_hw *hw)
-{
- u32 ctrl_ext;
-
- DEBUGFUNC("e1000_reload_nvm_generic");
-
- usec_delay(10);
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH(hw);
-}
-
-/**
- * e1000_get_fw_version - Get firmware version information
- * @hw: pointer to the HW structure
- * @fw_vers: pointer to output version structure
- *
- * unsupported/not present features return 0 in version structure
- **/
-void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
-{
- u16 eeprom_verh, eeprom_verl, etrack_test, fw_version;
- u8 q, hval, rem, result;
- u16 comb_verh, comb_verl, comb_offset;
-
- memset(fw_vers, 0, sizeof(struct e1000_fw_version));
-
- /* basic eeprom version numbers, bits used vary by part and by tool
- * used to create the nvm images */
- /* Check which data format we have */
- hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
- switch (hw->mac.type) {
- case e1000_i211:
- e1000_read_invm_version(hw, fw_vers);
- return;
- case e1000_82575:
- case e1000_82576:
- case e1000_82580:
- /* Use this format, unless EETRACK ID exists,
- * then use alternate format
- */
- if ((etrack_test & NVM_MAJOR_MASK) != NVM_ETRACK_VALID) {
- hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
- fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
- >> NVM_MAJOR_SHIFT;
- fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK)
- >> NVM_MINOR_SHIFT;
- fw_vers->eep_build = (fw_version & NVM_IMAGE_ID_MASK);
- goto etrack_id;
- }
- break;
- case e1000_i210:
- if (!(e1000_get_flash_presence_i210(hw))) {
- e1000_read_invm_version(hw, fw_vers);
- return;
- }
- /* fall through */
- case e1000_i350:
- case e1000_i354:
- /* find combo image version */
- hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
- if ((comb_offset != 0x0) &&
- (comb_offset != NVM_VER_INVALID)) {
-
- hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset
- + 1), 1, &comb_verh);
- hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset),
- 1, &comb_verl);
-
- /* get Option Rom version if it exists and is valid */
- if ((comb_verh && comb_verl) &&
- ((comb_verh != NVM_VER_INVALID) &&
- (comb_verl != NVM_VER_INVALID))) {
-
- fw_vers->or_valid = true;
- fw_vers->or_major =
- comb_verl >> NVM_COMB_VER_SHFT;
- fw_vers->or_build =
- (comb_verl << NVM_COMB_VER_SHFT)
- | (comb_verh >> NVM_COMB_VER_SHFT);
- fw_vers->or_patch =
- comb_verh & NVM_COMB_VER_MASK;
- }
- }
- break;
- default:
- return;
- }
- hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
- fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
- >> NVM_MAJOR_SHIFT;
-
- /* check for old style version format in newer images*/
- if ((fw_version & NVM_NEW_DEC_MASK) == 0x0) {
- eeprom_verl = (fw_version & NVM_COMB_VER_MASK);
- } else {
- eeprom_verl = (fw_version & NVM_MINOR_MASK)
- >> NVM_MINOR_SHIFT;
- }
- /* Convert minor value to hex before assigning to output struct
- * Val to be converted will not be higher than 99, per tool output
- */
- q = eeprom_verl / NVM_HEX_CONV;
- hval = q * NVM_HEX_TENS;
- rem = eeprom_verl % NVM_HEX_CONV;
- result = hval + rem;
- fw_vers->eep_minor = result;
-
-etrack_id:
- if ((etrack_test & NVM_MAJOR_MASK) == NVM_ETRACK_VALID) {
- hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl);
- hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
- fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT)
- | eeprom_verl;
- }
- return;
-}
diff --git a/kernel/linux/kni/ethtool/igb/e1000_nvm.h b/kernel/linux/kni/ethtool/igb/e1000_nvm.h
deleted file mode 100644
index e27b1c0ad..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_nvm.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_NVM_H_
-#define _E1000_NVM_H_
-
-
-struct e1000_fw_version {
- u32 etrack_id;
- u16 eep_major;
- u16 eep_minor;
- u16 eep_build;
-
- u8 invm_major;
- u8 invm_minor;
- u8 invm_img_type;
-
- bool or_valid;
- u16 or_major;
- u16 or_build;
- u16 or_patch;
-};
-
-
-void e1000_init_nvm_ops_generic(struct e1000_hw *hw);
-s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c);
-void e1000_null_nvm_generic(struct e1000_hw *hw);
-s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data);
-s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c);
-s32 e1000_acquire_nvm_generic(struct e1000_hw *hw);
-
-s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
-s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
-s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
- u32 pba_num_size);
-s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size);
-s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
-s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data);
-s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data);
-s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw);
-s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data);
-s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw);
-void e1000_release_nvm_generic(struct e1000_hw *hw);
-void e1000_get_fw_version(struct e1000_hw *hw,
- struct e1000_fw_version *fw_vers);
-
-#define E1000_STM_OPCODE 0xDB00
-
-#endif
diff --git a/kernel/linux/kni/ethtool/igb/e1000_osdep.h b/kernel/linux/kni/ethtool/igb/e1000_osdep.h
deleted file mode 100644
index 3228100e5..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_osdep.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-
-/* glue for the OS independent part of e1000
- * includes register access macros
- */
-
-#ifndef _E1000_OSDEP_H_
-#define _E1000_OSDEP_H_
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/sched.h>
-#include "kcompat.h"
-
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wunused-function"
-#endif
-
-#define usec_delay(x) udelay(x)
-#define usec_delay_irq(x) udelay(x)
-#ifndef msec_delay
-#define msec_delay(x) do { \
- /* Don't mdelay in interrupt context! */ \
- if (in_interrupt()) \
- BUG(); \
- else \
- msleep(x); \
-} while (0)
-
-/* Some workarounds require millisecond delays and are run during interrupt
- * context. Most notably, when establishing link, the phy may need tweaking
- * but cannot process phy register reads/writes faster than millisecond
- * intervals...and we establish link due to a "link status change" interrupt.
- */
-#define msec_delay_irq(x) mdelay(x)
-#endif
-
-#define PCI_COMMAND_REGISTER PCI_COMMAND
-#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
-#define ETH_ADDR_LEN ETH_ALEN
-
-#ifdef __BIG_ENDIAN
-#define E1000_BIG_ENDIAN __BIG_ENDIAN
-#endif
-
-
-#ifdef DEBUG
-#define DEBUGOUT(S) printk(KERN_DEBUG S)
-#define DEBUGOUT1(S, A...) printk(KERN_DEBUG S, ## A)
-#else
-#define DEBUGOUT(S)
-#define DEBUGOUT1(S, A...)
-#endif
-
-#ifdef DEBUG_FUNC
-#define DEBUGFUNC(F) DEBUGOUT(F "\n")
-#else
-#define DEBUGFUNC(F)
-#endif
-#define DEBUGOUT2 DEBUGOUT1
-#define DEBUGOUT3 DEBUGOUT2
-#define DEBUGOUT7 DEBUGOUT3
-
-#define E1000_REGISTER(a, reg) reg
-
-#define E1000_WRITE_REG(a, reg, value) ( \
- writel((value), ((a)->hw_addr + E1000_REGISTER(a, reg))))
-
-#define E1000_READ_REG(a, reg) (readl((a)->hw_addr + E1000_REGISTER(a, reg)))
-
-#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
- writel((value), ((a)->hw_addr + E1000_REGISTER(a, reg) + ((offset) << 2))))
-
-#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
- readl((a)->hw_addr + E1000_REGISTER(a, reg) + ((offset) << 2)))
-
-#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
-#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
-
-#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) ( \
- writew((value), ((a)->hw_addr + E1000_REGISTER(a, reg) + ((offset) << 1))))
-
-#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \
- readw((a)->hw_addr + E1000_REGISTER(a, reg) + ((offset) << 1)))
-
-#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \
- writeb((value), ((a)->hw_addr + E1000_REGISTER(a, reg) + (offset))))
-
-#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \
- readb((a)->hw_addr + E1000_REGISTER(a, reg) + (offset)))
-
-#define E1000_WRITE_REG_IO(a, reg, offset) do { \
- outl(reg, ((a)->io_base)); \
- outl(offset, ((a)->io_base + 4)); } while (0)
-
-#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, E1000_STATUS)
-
-#define E1000_WRITE_FLASH_REG(a, reg, value) ( \
- writel((value), ((a)->flash_address + reg)))
-
-#define E1000_WRITE_FLASH_REG16(a, reg, value) ( \
- writew((value), ((a)->flash_address + reg)))
-
-#define E1000_READ_FLASH_REG(a, reg) (readl((a)->flash_address + reg))
-
-#define E1000_READ_FLASH_REG16(a, reg) (readw((a)->flash_address + reg))
-
-#endif /* _E1000_OSDEP_H_ */
diff --git a/kernel/linux/kni/ethtool/igb/e1000_phy.c b/kernel/linux/kni/ethtool/igb/e1000_phy.c
deleted file mode 100644
index 1934a309c..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_phy.c
+++ /dev/null
@@ -1,3392 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "e1000_api.h"
-
-static s32 e1000_wait_autoneg(struct e1000_hw *hw);
-/* Cable length tables */
-static const u16 e1000_m88_cable_length_table[] = {
- 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
-#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
- (sizeof(e1000_m88_cable_length_table) / \
- sizeof(e1000_m88_cable_length_table[0]))
-
-static const u16 e1000_igp_2_cable_length_table[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
- 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22,
- 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40,
- 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61,
- 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82,
- 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95,
- 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
- 124};
-#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
- (sizeof(e1000_igp_2_cable_length_table) / \
- sizeof(e1000_igp_2_cable_length_table[0]))
-
-/**
- * e1000_init_phy_ops_generic - Initialize PHY function pointers
- * @hw: pointer to the HW structure
- *
- * Setups up the function pointers to no-op functions
- **/
-void e1000_init_phy_ops_generic(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- DEBUGFUNC("e1000_init_phy_ops_generic");
-
- /* Initialize function pointers */
- phy->ops.init_params = e1000_null_ops_generic;
- phy->ops.acquire = e1000_null_ops_generic;
- phy->ops.check_polarity = e1000_null_ops_generic;
- phy->ops.check_reset_block = e1000_null_ops_generic;
- phy->ops.commit = e1000_null_ops_generic;
- phy->ops.force_speed_duplex = e1000_null_ops_generic;
- phy->ops.get_cfg_done = e1000_null_ops_generic;
- phy->ops.get_cable_length = e1000_null_ops_generic;
- phy->ops.get_info = e1000_null_ops_generic;
- phy->ops.set_page = e1000_null_set_page;
- phy->ops.read_reg = e1000_null_read_reg;
- phy->ops.read_reg_locked = e1000_null_read_reg;
- phy->ops.read_reg_page = e1000_null_read_reg;
- phy->ops.release = e1000_null_phy_generic;
- phy->ops.reset = e1000_null_ops_generic;
- phy->ops.set_d0_lplu_state = e1000_null_lplu_state;
- phy->ops.set_d3_lplu_state = e1000_null_lplu_state;
- phy->ops.write_reg = e1000_null_write_reg;
- phy->ops.write_reg_locked = e1000_null_write_reg;
- phy->ops.write_reg_page = e1000_null_write_reg;
- phy->ops.power_up = e1000_null_phy_generic;
- phy->ops.power_down = e1000_null_phy_generic;
- phy->ops.read_i2c_byte = e1000_read_i2c_byte_null;
- phy->ops.write_i2c_byte = e1000_write_i2c_byte_null;
-}
-
-/**
- * e1000_null_set_page - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-s32 e1000_null_set_page(struct e1000_hw E1000_UNUSEDARG *hw,
- u16 E1000_UNUSEDARG data)
-{
- DEBUGFUNC("e1000_null_set_page");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_null_read_reg - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-s32 e1000_null_read_reg(struct e1000_hw E1000_UNUSEDARG *hw,
- u32 E1000_UNUSEDARG offset, u16 E1000_UNUSEDARG *data)
-{
- DEBUGFUNC("e1000_null_read_reg");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_null_phy_generic - No-op function, return void
- * @hw: pointer to the HW structure
- **/
-void e1000_null_phy_generic(struct e1000_hw E1000_UNUSEDARG *hw)
-{
- DEBUGFUNC("e1000_null_phy_generic");
- return;
-}
-
-/**
- * e1000_null_lplu_state - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-s32 e1000_null_lplu_state(struct e1000_hw E1000_UNUSEDARG *hw,
- bool E1000_UNUSEDARG active)
-{
- DEBUGFUNC("e1000_null_lplu_state");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_null_write_reg - No-op function, return 0
- * @hw: pointer to the HW structure
- **/
-s32 e1000_null_write_reg(struct e1000_hw E1000_UNUSEDARG *hw,
- u32 E1000_UNUSEDARG offset, u16 E1000_UNUSEDARG data)
-{
- DEBUGFUNC("e1000_null_write_reg");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_i2c_byte_null - No-op function, return 0
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to write
- * @dev_addr: device address
- * @data: data value read
- *
- **/
-s32 e1000_read_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG *hw,
- u8 E1000_UNUSEDARG byte_offset,
- u8 E1000_UNUSEDARG dev_addr,
- u8 E1000_UNUSEDARG *data)
-{
- DEBUGFUNC("e1000_read_i2c_byte_null");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_i2c_byte_null - No-op function, return 0
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to write
- * @dev_addr: device address
- * @data: data value to write
- *
- **/
-s32 e1000_write_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG *hw,
- u8 E1000_UNUSEDARG byte_offset,
- u8 E1000_UNUSEDARG dev_addr,
- u8 E1000_UNUSEDARG data)
-{
- DEBUGFUNC("e1000_write_i2c_byte_null");
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_check_reset_block_generic - Check if PHY reset is blocked
- * @hw: pointer to the HW structure
- *
- * Read the PHY management control register and check whether a PHY reset
- * is blocked. If a reset is not blocked return E1000_SUCCESS, otherwise
- * return E1000_BLK_PHY_RESET (12).
- **/
-s32 e1000_check_reset_block_generic(struct e1000_hw *hw)
-{
- u32 manc;
-
- DEBUGFUNC("e1000_check_reset_block");
-
- manc = E1000_READ_REG(hw, E1000_MANC);
-
- return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
- E1000_BLK_PHY_RESET : E1000_SUCCESS;
-}
-
-/**
- * e1000_get_phy_id - Retrieve the PHY ID and revision
- * @hw: pointer to the HW structure
- *
- * Reads the PHY registers and stores the PHY ID and possibly the PHY
- * revision in the hardware structure.
- **/
-s32 e1000_get_phy_id(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
- u16 phy_id;
-
- DEBUGFUNC("e1000_get_phy_id");
-
- if (!phy->ops.read_reg)
- return E1000_SUCCESS;
-
- ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
- if (ret_val)
- return ret_val;
-
- phy->id = (u32)(phy_id << 16);
- usec_delay(20);
- ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
- if (ret_val)
- return ret_val;
-
- phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
- phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
-
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_phy_reset_dsp_generic - Reset PHY DSP
- * @hw: pointer to the HW structure
- *
- * Reset the digital signal processor.
- **/
-s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_phy_reset_dsp_generic");
-
- if (!hw->phy.ops.write_reg)
- return E1000_SUCCESS;
-
- ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
- if (ret_val)
- return ret_val;
-
- return hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
-}
-
-/**
- * e1000_read_phy_reg_mdic - Read MDI control register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Reads the MDI control register in the PHY at offset and stores the
- * information read to data.
- **/
-s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i, mdic = 0;
-
- DEBUGFUNC("e1000_read_phy_reg_mdic");
-
- if (offset > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", offset);
- return -E1000_ERR_PARAM;
- }
-
- /* Set up Op-code, Phy Address, and register offset in the MDI
- * Control register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- mdic = ((offset << E1000_MDIC_REG_SHIFT) |
- (phy->addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_READ));
-
- E1000_WRITE_REG(hw, E1000_MDIC, mdic);
-
- /* Poll the ready bit to see if the MDI read completed
- * Increasing the time out as testing showed failures with
- * the lower time out
- */
- for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
- usec_delay_irq(50);
- mdic = E1000_READ_REG(hw, E1000_MDIC);
- if (mdic & E1000_MDIC_READY)
- break;
- }
- if (!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Read did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (mdic & E1000_MDIC_ERROR) {
- DEBUGOUT("MDI Error\n");
- return -E1000_ERR_PHY;
- }
- if (((mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT) != offset) {
- DEBUGOUT2("MDI Read offset error - requested %d, returned %d\n",
- offset,
- (mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
- return -E1000_ERR_PHY;
- }
- *data = (u16) mdic;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_phy_reg_mdic - Write MDI control register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write to register at offset
- *
- * Writes data to MDI control register in the PHY at offset.
- **/
-s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i, mdic = 0;
-
- DEBUGFUNC("e1000_write_phy_reg_mdic");
-
- if (offset > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", offset);
- return -E1000_ERR_PARAM;
- }
-
- /* Set up Op-code, Phy Address, and register offset in the MDI
- * Control register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- mdic = (((u32)data) |
- (offset << E1000_MDIC_REG_SHIFT) |
- (phy->addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_WRITE));
-
- E1000_WRITE_REG(hw, E1000_MDIC, mdic);
-
- /* Poll the ready bit to see if the MDI read completed
- * Increasing the time out as testing showed failures with
- * the lower time out
- */
- for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
- usec_delay_irq(50);
- mdic = E1000_READ_REG(hw, E1000_MDIC);
- if (mdic & E1000_MDIC_READY)
- break;
- }
- if (!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Write did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (mdic & E1000_MDIC_ERROR) {
- DEBUGOUT("MDI Error\n");
- return -E1000_ERR_PHY;
- }
- if (((mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT) != offset) {
- DEBUGOUT2("MDI Write offset error - requested %d, returned %d\n",
- offset,
- (mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
- return -E1000_ERR_PHY;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_phy_reg_i2c - Read PHY register using i2c
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Reads the PHY register at offset using the i2c interface and stores the
- * retrieved information in data.
- **/
-s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i, i2ccmd = 0;
-
- DEBUGFUNC("e1000_read_phy_reg_i2c");
-
- /* Set up Op-code, Phy Address, and register address in the I2CCMD
- * register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
- (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
- (E1000_I2CCMD_OPCODE_READ));
-
- E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
-
- /* Poll the ready bit to see if the I2C read completed */
- for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
- usec_delay(50);
- i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
- if (i2ccmd & E1000_I2CCMD_READY)
- break;
- }
- if (!(i2ccmd & E1000_I2CCMD_READY)) {
- DEBUGOUT("I2CCMD Read did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (i2ccmd & E1000_I2CCMD_ERROR) {
- DEBUGOUT("I2CCMD Error bit set\n");
- return -E1000_ERR_PHY;
- }
-
- /* Need to byte-swap the 16-bit value. */
- *data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_phy_reg_i2c - Write PHY register using i2c
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Writes the data to PHY register at the offset using the i2c interface.
- **/
-s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i, i2ccmd = 0;
- u16 phy_data_swapped;
-
- DEBUGFUNC("e1000_write_phy_reg_i2c");
-
- /* Prevent overwritting SFP I2C EEPROM which is at A0 address.*/
- if ((hw->phy.addr == 0) || (hw->phy.addr > 7)) {
- DEBUGOUT1("PHY I2C Address %d is out of range.\n",
- hw->phy.addr);
- return -E1000_ERR_CONFIG;
- }
-
- /* Swap the data bytes for the I2C interface */
- phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
-
- /* Set up Op-code, Phy Address, and register address in the I2CCMD
- * register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
- (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
- E1000_I2CCMD_OPCODE_WRITE |
- phy_data_swapped);
-
- E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
-
- /* Poll the ready bit to see if the I2C read completed */
- for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
- usec_delay(50);
- i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
- if (i2ccmd & E1000_I2CCMD_READY)
- break;
- }
- if (!(i2ccmd & E1000_I2CCMD_READY)) {
- DEBUGOUT("I2CCMD Write did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (i2ccmd & E1000_I2CCMD_ERROR) {
- DEBUGOUT("I2CCMD Error bit set\n");
- return -E1000_ERR_PHY;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_sfp_data_byte - Reads SFP module data.
- * @hw: pointer to the HW structure
- * @offset: byte location offset to be read
- * @data: read data buffer pointer
- *
- * Reads one byte from SFP module data stored
- * in SFP resided EEPROM memory or SFP diagnostic area.
- * Function should be called with
- * E1000_I2CCMD_SFP_DATA_ADDR(<byte offset>) for SFP module database access
- * E1000_I2CCMD_SFP_DIAG_ADDR(<byte offset>) for SFP diagnostics parameters
- * access
- **/
-s32 e1000_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data)
-{
- u32 i = 0;
- u32 i2ccmd = 0;
- u32 data_local = 0;
-
- DEBUGFUNC("e1000_read_sfp_data_byte");
-
- if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) {
- DEBUGOUT("I2CCMD command address exceeds upper limit\n");
- return -E1000_ERR_PHY;
- }
-
- /* Set up Op-code, EEPROM Address,in the I2CCMD
- * register. The MAC will take care of interfacing with the
- * EEPROM to retrieve the desired data.
- */
- i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
- E1000_I2CCMD_OPCODE_READ);
-
- E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
-
- /* Poll the ready bit to see if the I2C read completed */
- for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
- usec_delay(50);
- data_local = E1000_READ_REG(hw, E1000_I2CCMD);
- if (data_local & E1000_I2CCMD_READY)
- break;
- }
- if (!(data_local & E1000_I2CCMD_READY)) {
- DEBUGOUT("I2CCMD Read did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (data_local & E1000_I2CCMD_ERROR) {
- DEBUGOUT("I2CCMD Error bit set\n");
- return -E1000_ERR_PHY;
- }
- *data = (u8) data_local & 0xFF;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_sfp_data_byte - Writes SFP module data.
- * @hw: pointer to the HW structure
- * @offset: byte location offset to write to
- * @data: data to write
- *
- * Writes one byte to SFP module data stored
- * in SFP resided EEPROM memory or SFP diagnostic area.
- * Function should be called with
- * E1000_I2CCMD_SFP_DATA_ADDR(<byte offset>) for SFP module database access
- * E1000_I2CCMD_SFP_DIAG_ADDR(<byte offset>) for SFP diagnostics parameters
- * access
- **/
-s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data)
-{
- u32 i = 0;
- u32 i2ccmd = 0;
- u32 data_local = 0;
-
- DEBUGFUNC("e1000_write_sfp_data_byte");
-
- if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) {
- DEBUGOUT("I2CCMD command address exceeds upper limit\n");
- return -E1000_ERR_PHY;
- }
- /* The programming interface is 16 bits wide
- * so we need to read the whole word first
- * then update appropriate byte lane and write
- * the updated word back.
- */
- /* Set up Op-code, EEPROM Address,in the I2CCMD
- * register. The MAC will take care of interfacing
- * with an EEPROM to write the data given.
- */
- i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
- E1000_I2CCMD_OPCODE_READ);
- /* Set a command to read single word */
- E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
- for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
- usec_delay(50);
- /* Poll the ready bit to see if lastly
- * launched I2C operation completed
- */
- i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
- if (i2ccmd & E1000_I2CCMD_READY) {
- /* Check if this is READ or WRITE phase */
- if ((i2ccmd & E1000_I2CCMD_OPCODE_READ) ==
- E1000_I2CCMD_OPCODE_READ) {
- /* Write the selected byte
- * lane and update whole word
- */
- data_local = i2ccmd & 0xFF00;
- data_local |= data;
- i2ccmd = ((offset <<
- E1000_I2CCMD_REG_ADDR_SHIFT) |
- E1000_I2CCMD_OPCODE_WRITE | data_local);
- E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
- } else {
- break;
- }
- }
- }
- if (!(i2ccmd & E1000_I2CCMD_READY)) {
- DEBUGOUT("I2CCMD Write did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (i2ccmd & E1000_I2CCMD_ERROR) {
- DEBUGOUT("I2CCMD Error bit set\n");
- return -E1000_ERR_PHY;
- }
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_phy_reg_m88 - Read m88 PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
- * semaphores before exiting.
- **/
-s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_read_phy_reg_m88");
-
- if (!hw->phy.ops.acquire)
- return E1000_SUCCESS;
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
-
- hw->phy.ops.release(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_write_phy_reg_m88 - Write m88 PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore, if necessary, then writes the data to PHY register
- * at the offset. Release any acquired semaphores before exiting.
- **/
-s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_write_phy_reg_m88");
-
- if (!hw->phy.ops.acquire)
- return E1000_SUCCESS;
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
-
- hw->phy.ops.release(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_set_page_igp - Set page as on IGP-like PHY(s)
- * @hw: pointer to the HW structure
- * @page: page to set (shifted left when necessary)
- *
- * Sets PHY page required for PHY register access. Assumes semaphore is
- * already acquired. Note, this function sets phy.addr to 1 so the caller
- * must set it appropriately (if necessary) after this function returns.
- **/
-s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page)
-{
- DEBUGFUNC("e1000_set_page_igp");
-
- DEBUGOUT1("Setting page 0x%x\n", page);
-
- hw->phy.addr = 1;
-
- return e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, page);
-}
-
-/**
- * __e1000_read_phy_reg_igp - Read igp PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- * @locked: semaphore has already been acquired or not
- *
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and stores the retrieved information in data. Release any acquired
- * semaphores before exiting.
- **/
-static s32 __e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
- bool locked)
-{
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("__e1000_read_phy_reg_igp");
-
- if (!locked) {
- if (!hw->phy.ops.acquire)
- return E1000_SUCCESS;
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
- }
-
- if (offset > MAX_PHY_MULTI_PAGE_REG)
- ret_val = e1000_write_phy_reg_mdic(hw,
- IGP01E1000_PHY_PAGE_SELECT,
- (u16)offset);
- if (!ret_val)
- ret_val = e1000_read_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
- if (!locked)
- hw->phy.ops.release(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_read_phy_reg_igp - Read igp PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Acquires semaphore then reads the PHY register at offset and stores the
- * retrieved information in data.
- * Release the acquired semaphore before exiting.
- **/
-s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- return __e1000_read_phy_reg_igp(hw, offset, data, false);
-}
-
-/**
- * e1000_read_phy_reg_igp_locked - Read igp PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Reads the PHY register at offset and stores the retrieved information
- * in data. Assumes semaphore already acquired.
- **/
-s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- return __e1000_read_phy_reg_igp(hw, offset, data, true);
-}
-
-/**
- * e1000_write_phy_reg_igp - Write igp PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- * @locked: semaphore has already been acquired or not
- *
- * Acquires semaphore, if necessary, then writes the data to PHY register
- * at the offset. Release any acquired semaphores before exiting.
- **/
-static s32 __e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
- bool locked)
-{
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_write_phy_reg_igp");
-
- if (!locked) {
- if (!hw->phy.ops.acquire)
- return E1000_SUCCESS;
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
- }
-
- if (offset > MAX_PHY_MULTI_PAGE_REG)
- ret_val = e1000_write_phy_reg_mdic(hw,
- IGP01E1000_PHY_PAGE_SELECT,
- (u16)offset);
- if (!ret_val)
- ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS &
- offset,
- data);
- if (!locked)
- hw->phy.ops.release(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_write_phy_reg_igp - Write igp PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore then writes the data to PHY register
- * at the offset. Release any acquired semaphores before exiting.
- **/
-s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
-{
- return __e1000_write_phy_reg_igp(hw, offset, data, false);
-}
-
-/**
- * e1000_write_phy_reg_igp_locked - Write igp PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Writes the data to PHY register at the offset.
- * Assumes semaphore already acquired.
- **/
-s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data)
-{
- return __e1000_write_phy_reg_igp(hw, offset, data, true);
-}
-
-/**
- * __e1000_read_kmrn_reg - Read kumeran register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- * @locked: semaphore has already been acquired or not
- *
- * Acquires semaphore, if necessary. Then reads the PHY register at offset
- * using the kumeran interface. The information retrieved is stored in data.
- * Release any acquired semaphores before exiting.
- **/
-static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
- bool locked)
-{
- u32 kmrnctrlsta;
-
- DEBUGFUNC("__e1000_read_kmrn_reg");
-
- if (!locked) {
- s32 ret_val = E1000_SUCCESS;
-
- if (!hw->phy.ops.acquire)
- return E1000_SUCCESS;
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
- }
-
- kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
- E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
- E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
- E1000_WRITE_FLUSH(hw);
-
- usec_delay(2);
-
- kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA);
- *data = (u16)kmrnctrlsta;
-
- if (!locked)
- hw->phy.ops.release(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_read_kmrn_reg_generic - Read kumeran register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Acquires semaphore then reads the PHY register at offset using the
- * kumeran interface. The information retrieved is stored in data.
- * Release the acquired semaphore before exiting.
- **/
-s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- return __e1000_read_kmrn_reg(hw, offset, data, false);
-}
-
-/**
- * e1000_read_kmrn_reg_locked - Read kumeran register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Reads the PHY register at offset using the kumeran interface. The
- * information retrieved is stored in data.
- * Assumes semaphore already acquired.
- **/
-s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- return __e1000_read_kmrn_reg(hw, offset, data, true);
-}
-
-/**
- * __e1000_write_kmrn_reg - Write kumeran register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- * @locked: semaphore has already been acquired or not
- *
- * Acquires semaphore, if necessary. Then write the data to PHY register
- * at the offset using the kumeran interface. Release any acquired semaphores
- * before exiting.
- **/
-static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
- bool locked)
-{
- u32 kmrnctrlsta;
-
- DEBUGFUNC("e1000_write_kmrn_reg_generic");
-
- if (!locked) {
- s32 ret_val = E1000_SUCCESS;
-
- if (!hw->phy.ops.acquire)
- return E1000_SUCCESS;
-
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
- }
-
- kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
- E1000_KMRNCTRLSTA_OFFSET) | data;
- E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
- E1000_WRITE_FLUSH(hw);
-
- usec_delay(2);
-
- if (!locked)
- hw->phy.ops.release(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_kmrn_reg_generic - Write kumeran register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore then writes the data to the PHY register at the offset
- * using the kumeran interface. Release the acquired semaphore before exiting.
- **/
-s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data)
-{
- return __e1000_write_kmrn_reg(hw, offset, data, false);
-}
-
-/**
- * e1000_write_kmrn_reg_locked - Write kumeran register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Write the data to PHY register at the offset using the kumeran interface.
- * Assumes semaphore already acquired.
- **/
-s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
-{
- return __e1000_write_kmrn_reg(hw, offset, data, true);
-}
-
-/**
- * e1000_set_master_slave_mode - Setup PHY for Master/slave mode
- * @hw: pointer to the HW structure
- *
- * Sets up Master/slave mode
- **/
-static s32 e1000_set_master_slave_mode(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 phy_data;
-
- /* Resolve Master/Slave mode */
- ret_val = hw->phy.ops.read_reg(hw, PHY_1000T_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- /* load defaults for future use */
- hw->phy.original_ms_type = (phy_data & CR_1000T_MS_ENABLE) ?
- ((phy_data & CR_1000T_MS_VALUE) ?
- e1000_ms_force_master :
- e1000_ms_force_slave) : e1000_ms_auto;
-
- switch (hw->phy.ms_type) {
- case e1000_ms_force_master:
- phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
- break;
- case e1000_ms_force_slave:
- phy_data |= CR_1000T_MS_ENABLE;
- phy_data &= ~(CR_1000T_MS_VALUE);
- break;
- case e1000_ms_auto:
- phy_data &= ~CR_1000T_MS_ENABLE;
- /* fall-through */
- default:
- break;
- }
-
- return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data);
-}
-
-/**
- * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
- * @hw: pointer to the HW structure
- *
- * Sets up Carrier-sense on Transmit and downshift values.
- **/
-s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_copper_link_setup_82577");
-
- if (hw->phy.reset_disable)
- return E1000_SUCCESS;
-
- if (hw->phy.type == e1000_phy_82580) {
- ret_val = hw->phy.ops.reset(hw);
- if (ret_val) {
- DEBUGOUT("Error resetting the PHY.\n");
- return ret_val;
- }
- }
-
- /* Enable CRS on Tx. This must be set for half-duplex operation. */
- ret_val = hw->phy.ops.read_reg(hw, I82577_CFG_REG, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
-
- /* Enable downshift */
- phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
-
- ret_val = hw->phy.ops.write_reg(hw, I82577_CFG_REG, phy_data);
- if (ret_val)
- return ret_val;
-
- /* Set MDI/MDIX mode */
- ret_val = hw->phy.ops.read_reg(hw, I82577_PHY_CTRL_2, &phy_data);
- if (ret_val)
- return ret_val;
- phy_data &= ~I82577_PHY_CTRL2_MDIX_CFG_MASK;
- /* Options:
- * 0 - Auto (default)
- * 1 - MDI mode
- * 2 - MDI-X mode
- */
- switch (hw->phy.mdix) {
- case 1:
- break;
- case 2:
- phy_data |= I82577_PHY_CTRL2_MANUAL_MDIX;
- break;
- case 0:
- default:
- phy_data |= I82577_PHY_CTRL2_AUTO_MDI_MDIX;
- break;
- }
- ret_val = hw->phy.ops.write_reg(hw, I82577_PHY_CTRL_2, phy_data);
- if (ret_val)
- return ret_val;
-
- return e1000_set_master_slave_mode(hw);
-}
-
-/**
- * e1000_copper_link_setup_m88 - Setup m88 PHY's for copper link
- * @hw: pointer to the HW structure
- *
- * Sets up MDI/MDI-X and polarity for m88 PHY's. If necessary, transmit clock
- * and downshift values are set also.
- **/
-s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_copper_link_setup_m88");
-
- if (phy->reset_disable)
- return E1000_SUCCESS;
-
- /* Enable CRS on Tx. This must be set for half-duplex operation. */
- ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-
- /* Options:
- * MDI/MDI-X = 0 (default)
- * 0 - Auto for all speeds
- * 1 - MDI mode
- * 2 - MDI-X mode
- * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
- */
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-
- switch (phy->mdix) {
- case 1:
- phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
- break;
- case 2:
- phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
- break;
- case 3:
- phy_data |= M88E1000_PSCR_AUTO_X_1000T;
- break;
- case 0:
- default:
- phy_data |= M88E1000_PSCR_AUTO_X_MODE;
- break;
- }
-
- /* Options:
- * disable_polarity_correction = 0 (default)
- * Automatic Correction for Reversed Cable Polarity
- * 0 - Disabled
- * 1 - Enabled
- */
- phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
- if (phy->disable_polarity_correction)
- phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-
- ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- if (phy->revision < E1000_REVISION_4) {
- /* Force TX_CLK in the Extended PHY Specific Control Register
- * to 25MHz clock.
- */
- ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_EPSCR_TX_CLK_25;
-
- if ((phy->revision == E1000_REVISION_2) &&
- (phy->id == M88E1111_I_PHY_ID)) {
- /* 82573L PHY - set the downshift counter to 5x. */
- phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
- phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
- } else {
- /* Configure Master and Slave downshift values */
- phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
- M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
- phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
- M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
- }
- ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
- phy_data);
- if (ret_val)
- return ret_val;
- }
-
- /* Commit the changes. */
- ret_val = phy->ops.commit(hw);
- if (ret_val) {
- DEBUGOUT("Error committing the PHY changes\n");
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_copper_link_setup_m88_gen2 - Setup m88 PHY's for copper link
- * @hw: pointer to the HW structure
- *
- * Sets up MDI/MDI-X and polarity for i347-AT4, m88e1322 and m88e1112 PHY's.
- * Also enables and sets the downshift parameters.
- **/
-s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_copper_link_setup_m88_gen2");
-
- if (phy->reset_disable)
- return E1000_SUCCESS;
-
- /* Enable CRS on Tx. This must be set for half-duplex operation. */
- ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- /* Options:
- * MDI/MDI-X = 0 (default)
- * 0 - Auto for all speeds
- * 1 - MDI mode
- * 2 - MDI-X mode
- * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
- */
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-
- switch (phy->mdix) {
- case 1:
- phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
- break;
- case 2:
- phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
- break;
- case 3:
- /* M88E1112 does not support this mode) */
- if (phy->id != M88E1112_E_PHY_ID) {
- phy_data |= M88E1000_PSCR_AUTO_X_1000T;
- break;
- }
- case 0:
- default:
- phy_data |= M88E1000_PSCR_AUTO_X_MODE;
- break;
- }
-
- /* Options:
- * disable_polarity_correction = 0 (default)
- * Automatic Correction for Reversed Cable Polarity
- * 0 - Disabled
- * 1 - Enabled
- */
- phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
- if (phy->disable_polarity_correction)
- phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-
- /* Enable downshift and setting it to X6 */
- if (phy->id == M88E1543_E_PHY_ID) {
- phy_data &= ~I347AT4_PSCR_DOWNSHIFT_ENABLE;
- ret_val =
- phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.commit(hw);
- if (ret_val) {
- DEBUGOUT("Error committing the PHY changes\n");
- return ret_val;
- }
- }
-
- phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK;
- phy_data |= I347AT4_PSCR_DOWNSHIFT_6X;
- phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
-
- ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- /* Commit the changes. */
- ret_val = phy->ops.commit(hw);
- if (ret_val) {
- DEBUGOUT("Error committing the PHY changes\n");
- return ret_val;
- }
-
- ret_val = e1000_set_master_slave_mode(hw);
- if (ret_val)
- return ret_val;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_copper_link_setup_igp - Setup igp PHY's for copper link
- * @hw: pointer to the HW structure
- *
- * Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
- * igp PHY's.
- **/
-s32 e1000_copper_link_setup_igp(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
-
- DEBUGFUNC("e1000_copper_link_setup_igp");
-
- if (phy->reset_disable)
- return E1000_SUCCESS;
-
- ret_val = hw->phy.ops.reset(hw);
- if (ret_val) {
- DEBUGOUT("Error resetting the PHY.\n");
- return ret_val;
- }
-
- /* Wait 100ms for MAC to configure PHY from NVM settings, to avoid
- * timeout issues when LFS is enabled.
- */
- msec_delay(100);
-
- /* disable lplu d0 during driver init */
- if (hw->phy.ops.set_d0_lplu_state) {
- ret_val = hw->phy.ops.set_d0_lplu_state(hw, false);
- if (ret_val) {
- DEBUGOUT("Error Disabling LPLU D0\n");
- return ret_val;
- }
- }
- /* Configure mdi-mdix settings */
- ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCR_AUTO_MDIX;
-
- switch (phy->mdix) {
- case 1:
- data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
- break;
- case 2:
- data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
- break;
- case 0:
- default:
- data |= IGP01E1000_PSCR_AUTO_MDIX;
- break;
- }
- ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
- if (ret_val)
- return ret_val;
-
- /* set auto-master slave resolution settings */
- if (hw->mac.autoneg) {
- /* when autonegotiation advertisement is only 1000Mbps then we
- * should disable SmartSpeed and enable Auto MasterSlave
- * resolution as hardware default.
- */
- if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
- /* Disable SmartSpeed */
- ret_val = phy->ops.read_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
-
- /* Set auto Master/Slave resolution process */
- ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
- if (ret_val)
- return ret_val;
-
- data &= ~CR_1000T_MS_ENABLE;
- ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
- if (ret_val)
- return ret_val;
- }
-
- ret_val = e1000_set_master_slave_mode(hw);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_phy_setup_autoneg - Configure PHY for auto-negotiation
- * @hw: pointer to the HW structure
- *
- * Reads the MII auto-neg advertisement register and/or the 1000T control
- * register and if the PHY is already setup for auto-negotiation, then
- * return successful. Otherwise, setup advertisement and flow control to
- * the appropriate values for the wanted auto-negotiation.
- **/
-static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 mii_autoneg_adv_reg;
- u16 mii_1000t_ctrl_reg = 0;
-
- DEBUGFUNC("e1000_phy_setup_autoneg");
-
- phy->autoneg_advertised &= phy->autoneg_mask;
-
- /* Read the MII Auto-Neg Advertisement Register (Address 4). */
- ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
- if (ret_val)
- return ret_val;
-
- if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
- /* Read the MII 1000Base-T Control Register (Address 9). */
- ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
- &mii_1000t_ctrl_reg);
- if (ret_val)
- return ret_val;
- }
-
- /* Need to parse both autoneg_advertised and fc and set up
- * the appropriate PHY registers. First we will parse for
- * autoneg_advertised software override. Since we can advertise
- * a plethora of combinations, we need to check each bit
- * individually.
- */
-
- /* First we clear all the 10/100 mb speed bits in the Auto-Neg
- * Advertisement Register (Address 4) and the 1000 mb speed bits in
- * the 1000Base-T Control Register (Address 9).
- */
- mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
- NWAY_AR_100TX_HD_CAPS |
- NWAY_AR_10T_FD_CAPS |
- NWAY_AR_10T_HD_CAPS);
- mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
-
- DEBUGOUT1("autoneg_advertised %x\n", phy->autoneg_advertised);
-
- /* Do we want to advertise 10 Mb Half Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
- DEBUGOUT("Advertise 10mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
- }
-
- /* Do we want to advertise 10 Mb Full Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
- DEBUGOUT("Advertise 10mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Half Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
- DEBUGOUT("Advertise 100mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Full Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
- DEBUGOUT("Advertise 100mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
- }
-
- /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
- if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
- DEBUGOUT("Advertise 1000mb Half duplex request denied!\n");
-
- /* Do we want to advertise 1000 Mb Full Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
- DEBUGOUT("Advertise 1000mb Full duplex\n");
- mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
- }
-
- /* Check for a software override of the flow control settings, and
- * setup the PHY advertisement registers accordingly. If
- * auto-negotiation is enabled, then software will have to set the
- * "PAUSE" bits to the correct value in the Auto-Negotiation
- * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
- * negotiation.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames
- * but we do not support receiving pause frames).
- * 3: Both Rx and Tx flow control (symmetric) are enabled.
- * other: No software override. The flow control configuration
- * in the EEPROM is used.
- */
- switch (hw->fc.current_mode) {
- case e1000_fc_none:
- /* Flow control (Rx & Tx) is completely disabled by a
- * software over-ride.
- */
- mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- case e1000_fc_rx_pause:
- /* Rx Flow control is enabled, and Tx Flow control is
- * disabled, by a software over-ride.
- *
- * Since there really isn't a way to advertise that we are
- * capable of Rx Pause ONLY, we will advertise that we
- * support both symmetric and asymmetric Rx PAUSE. Later
- * (in e1000_config_fc_after_link_up) we will disable the
- * hw's ability to send PAUSE frames.
- */
- mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- case e1000_fc_tx_pause:
- /* Tx Flow control is enabled, and Rx Flow control is
- * disabled, by a software over-ride.
- */
- mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
- mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
- break;
- case e1000_fc_full:
- /* Flow control (both Rx and Tx) is enabled by a software
- * over-ride.
- */
- mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- default:
- DEBUGOUT("Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
- if (ret_val)
- return ret_val;
-
- DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
-
- if (phy->autoneg_mask & ADVERTISE_1000_FULL)
- ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL,
- mii_1000t_ctrl_reg);
-
- return ret_val;
-}
-
-/**
- * e1000_copper_link_autoneg - Setup/Enable autoneg for copper link
- * @hw: pointer to the HW structure
- *
- * Performs initial bounds checking on autoneg advertisement parameter, then
- * configure to advertise the full capability. Setup the PHY to autoneg
- * and restart the negotiation process between the link partner. If
- * autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
- **/
-static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_ctrl;
-
- DEBUGFUNC("e1000_copper_link_autoneg");
-
- /* Perform some bounds checking on the autoneg advertisement
- * parameter.
- */
- phy->autoneg_advertised &= phy->autoneg_mask;
-
- /* If autoneg_advertised is zero, we assume it was not defaulted
- * by the calling code so we set to advertise full capability.
- */
- if (!phy->autoneg_advertised)
- phy->autoneg_advertised = phy->autoneg_mask;
-
- DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
- ret_val = e1000_phy_setup_autoneg(hw);
- if (ret_val) {
- DEBUGOUT("Error Setting up Auto-Negotiation\n");
- return ret_val;
- }
- DEBUGOUT("Restarting Auto-Neg\n");
-
- /* Restart auto-negotiation by setting the Auto Neg Enable bit and
- * the Auto Neg Restart bit in the PHY control register.
- */
- ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
- if (ret_val)
- return ret_val;
-
- phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
- ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
- if (ret_val)
- return ret_val;
-
- /* Does the user want to wait for Auto-Neg to complete here, or
- * check at a later time (for example, callback routine).
- */
- if (phy->autoneg_wait_to_complete) {
- ret_val = e1000_wait_autoneg(hw);
- if (ret_val) {
- DEBUGOUT("Error while waiting for autoneg to complete\n");
- return ret_val;
- }
- }
-
- hw->mac.get_link_status = true;
-
- return ret_val;
-}
-
-/**
- * e1000_setup_copper_link_generic - Configure copper link settings
- * @hw: pointer to the HW structure
- *
- * Calls the appropriate function to configure the link for auto-neg or forced
- * speed and duplex. Then we check for link, once link is established calls
- * to configure collision distance and flow control are called. If link is
- * not established, we return -E1000_ERR_PHY (-2).
- **/
-s32 e1000_setup_copper_link_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
- bool link;
-
- DEBUGFUNC("e1000_setup_copper_link_generic");
-
- if (hw->mac.autoneg) {
- /* Setup autoneg and flow control advertisement and perform
- * autonegotiation.
- */
- ret_val = e1000_copper_link_autoneg(hw);
- if (ret_val)
- return ret_val;
- } else {
- /* PHY will be set to 10H, 10F, 100H or 100F
- * depending on user settings.
- */
- DEBUGOUT("Forcing Speed and Duplex\n");
- ret_val = hw->phy.ops.force_speed_duplex(hw);
- if (ret_val) {
- DEBUGOUT("Error Forcing Speed and Duplex\n");
- return ret_val;
- }
- }
-
- /* Check link status. Wait up to 100 microseconds for link to become
- * valid.
- */
- ret_val = e1000_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
- &link);
- if (ret_val)
- return ret_val;
-
- if (link) {
- DEBUGOUT("Valid link established!!!\n");
- hw->mac.ops.config_collision_dist(hw);
- ret_val = e1000_config_fc_after_link_up_generic(hw);
- } else {
- DEBUGOUT("Unable to establish link!!!\n");
- }
-
- return ret_val;
-}
-
-/**
- * e1000_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
- * @hw: pointer to the HW structure
- *
- * Calls the PHY setup function to force speed and duplex. Clears the
- * auto-crossover to force MDI manually. Waits for link and returns
- * successful if link up is successful, else -E1000_ERR_PHY (-2).
- **/
-s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
- bool link;
-
- DEBUGFUNC("e1000_phy_force_speed_duplex_igp");
-
- ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- e1000_phy_force_speed_duplex_setup(hw, &phy_data);
-
- ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
- if (ret_val)
- return ret_val;
-
- /* Clear Auto-Crossover to force MDI manually. IGP requires MDI
- * forced whenever speed and duplex are forced.
- */
- ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
- phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
-
- ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- DEBUGOUT1("IGP PSCR: %X\n", phy_data);
-
- usec_delay(1);
-
- if (phy->autoneg_wait_to_complete) {
- DEBUGOUT("Waiting for forced speed/duplex link on IGP phy.\n");
-
- ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- if (ret_val)
- return ret_val;
-
- if (!link)
- DEBUGOUT("Link taking longer than expected.\n");
-
- /* Try once more */
- ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
- * @hw: pointer to the HW structure
- *
- * Calls the PHY setup function to force speed and duplex. Clears the
- * auto-crossover to force MDI manually. Resets the PHY to commit the
- * changes. If time expires while waiting for link up, we reset the DSP.
- * After reset, TX_CLK and CRS on Tx must be set. Return successful upon
- * successful completion, else return corresponding error code.
- **/
-s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
- bool link;
-
- DEBUGFUNC("e1000_phy_force_speed_duplex_m88");
-
- /* I210 and I211 devices support Auto-Crossover in forced operation. */
- if (phy->type != e1000_phy_i210) {
- /* Clear Auto-Crossover to force MDI manually. M88E1000
- * requires MDI forced whenever speed and duplex are forced.
- */
- ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
- ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
- phy_data);
- if (ret_val)
- return ret_val;
- }
-
- DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data);
-
- ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- e1000_phy_force_speed_duplex_setup(hw, &phy_data);
-
- ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
- if (ret_val)
- return ret_val;
-
- /* Reset the phy to commit changes. */
- ret_val = hw->phy.ops.commit(hw);
- if (ret_val)
- return ret_val;
-
- if (phy->autoneg_wait_to_complete) {
- DEBUGOUT("Waiting for forced speed/duplex link on M88 phy.\n");
-
- ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- if (ret_val)
- return ret_val;
-
- if (!link) {
- bool reset_dsp = true;
-
- switch (hw->phy.id) {
- case I347AT4_E_PHY_ID:
- case M88E1340M_E_PHY_ID:
- case M88E1112_E_PHY_ID:
- case M88E1543_E_PHY_ID:
- case I210_I_PHY_ID:
- reset_dsp = false;
- break;
- default:
- if (hw->phy.type != e1000_phy_m88)
- reset_dsp = false;
- break;
- }
-
- if (!reset_dsp) {
- DEBUGOUT("Link taking longer than expected.\n");
- } else {
- /* We didn't get link.
- * Reset the DSP and cross our fingers.
- */
- ret_val = phy->ops.write_reg(hw,
- M88E1000_PHY_PAGE_SELECT,
- 0x001d);
- if (ret_val)
- return ret_val;
- ret_val = e1000_phy_reset_dsp_generic(hw);
- if (ret_val)
- return ret_val;
- }
- }
-
- /* Try once more */
- ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- if (ret_val)
- return ret_val;
- }
-
- if (hw->phy.type != e1000_phy_m88)
- return E1000_SUCCESS;
-
- if (hw->phy.id == I347AT4_E_PHY_ID ||
- hw->phy.id == M88E1340M_E_PHY_ID ||
- hw->phy.id == M88E1112_E_PHY_ID)
- return E1000_SUCCESS;
- if (hw->phy.id == I210_I_PHY_ID)
- return E1000_SUCCESS;
- if ((hw->phy.id == M88E1543_E_PHY_ID))
- return E1000_SUCCESS;
- ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- /* Resetting the phy means we need to re-force TX_CLK in the
- * Extended PHY Specific Control Register to 25MHz clock from
- * the reset value of 2.5MHz.
- */
- phy_data |= M88E1000_EPSCR_TX_CLK_25;
- ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- /* In addition, we must re-enable CRS on Tx for both half and full
- * duplex.
- */
- ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
- ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
-
- return ret_val;
-}
-
-/**
- * e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex
- * @hw: pointer to the HW structure
- *
- * Forces the speed and duplex settings of the PHY.
- * This is a function pointer entry point only called by
- * PHY setup routines.
- **/
-s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
- bool link;
-
- DEBUGFUNC("e1000_phy_force_speed_duplex_ife");
-
- ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data);
- if (ret_val)
- return ret_val;
-
- e1000_phy_force_speed_duplex_setup(hw, &data);
-
- ret_val = phy->ops.write_reg(hw, PHY_CONTROL, data);
- if (ret_val)
- return ret_val;
-
- /* Disable MDI-X support for 10/100 */
- ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IFE_PMC_AUTO_MDIX;
- data &= ~IFE_PMC_FORCE_MDIX;
-
- ret_val = phy->ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, data);
- if (ret_val)
- return ret_val;
-
- DEBUGOUT1("IFE PMC: %X\n", data);
-
- usec_delay(1);
-
- if (phy->autoneg_wait_to_complete) {
- DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n");
-
- ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- if (ret_val)
- return ret_val;
-
- if (!link)
- DEBUGOUT("Link taking longer than expected.\n");
-
- /* Try once more */
- ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- if (ret_val)
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
- * @hw: pointer to the HW structure
- * @phy_ctrl: pointer to current value of PHY_CONTROL
- *
- * Forces speed and duplex on the PHY by doing the following: disable flow
- * control, force speed/duplex on the MAC, disable auto speed detection,
- * disable auto-negotiation, configure duplex, configure speed, configure
- * the collision distance, write configuration to CTRL register. The
- * caller must write to the PHY_CONTROL register for these settings to
- * take affect.
- **/
-void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 ctrl;
-
- DEBUGFUNC("e1000_phy_force_speed_duplex_setup");
-
- /* Turn off flow control when forcing speed/duplex */
- hw->fc.current_mode = e1000_fc_none;
-
- /* Force speed/duplex on the mac */
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- ctrl &= ~E1000_CTRL_SPD_SEL;
-
- /* Disable Auto Speed Detection */
- ctrl &= ~E1000_CTRL_ASDE;
-
- /* Disable autoneg on the phy */
- *phy_ctrl &= ~MII_CR_AUTO_NEG_EN;
-
- /* Forcing Full or Half Duplex? */
- if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
- ctrl &= ~E1000_CTRL_FD;
- *phy_ctrl &= ~MII_CR_FULL_DUPLEX;
- DEBUGOUT("Half Duplex\n");
- } else {
- ctrl |= E1000_CTRL_FD;
- *phy_ctrl |= MII_CR_FULL_DUPLEX;
- DEBUGOUT("Full Duplex\n");
- }
-
- /* Forcing 10mb or 100mb? */
- if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
- ctrl |= E1000_CTRL_SPD_100;
- *phy_ctrl |= MII_CR_SPEED_100;
- *phy_ctrl &= ~MII_CR_SPEED_1000;
- DEBUGOUT("Forcing 100mb\n");
- } else {
- ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
- *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
- DEBUGOUT("Forcing 10mb\n");
- }
-
- hw->mac.ops.config_collision_dist(hw);
-
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-}
-
-/**
- * e1000_set_d3_lplu_state_generic - Sets low power link up state for D3
- * @hw: pointer to the HW structure
- * @active: boolean used to enable/disable lplu
- *
- * Success returns 0, Failure returns 1
- *
- * The low power link up (lplu) state is set to the power management level D3
- * and SmartSpeed is disabled when active is true, else clear lplu for D3
- * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
- * is used during Dx states where the power conservation is most important.
- * During driver activity, SmartSpeed should be enabled so performance is
- * maintained.
- **/
-s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
-
- DEBUGFUNC("e1000_set_d3_lplu_state_generic");
-
- if (!hw->phy.ops.read_reg)
- return E1000_SUCCESS;
-
- ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
- if (ret_val)
- return ret_val;
-
- if (!active) {
- data &= ~IGP02E1000_PM_D3_LPLU;
- ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- data);
- if (ret_val)
- return ret_val;
- /* LPLU and SmartSpeed are mutually exclusive. LPLU is used
- * during Dx states where the power conservation is most
- * important. During driver activity we should enable
- * SmartSpeed, so performance is maintained.
- */
- if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = phy->ops.read_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- } else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = phy->ops.read_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- }
- } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
- (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
- (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
- data |= IGP02E1000_PM_D3_LPLU;
- ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- data);
- if (ret_val)
- return ret_val;
-
- /* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_check_downshift_generic - Checks whether a downshift in speed occurred
- * @hw: pointer to the HW structure
- *
- * Success returns 0, Failure returns 1
- *
- * A downshift is detected by querying the PHY link health.
- **/
-s32 e1000_check_downshift_generic(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, offset, mask;
-
- DEBUGFUNC("e1000_check_downshift_generic");
-
- switch (phy->type) {
- case e1000_phy_i210:
- case e1000_phy_m88:
- case e1000_phy_gg82563:
- offset = M88E1000_PHY_SPEC_STATUS;
- mask = M88E1000_PSSR_DOWNSHIFT;
- break;
- case e1000_phy_igp_2:
- case e1000_phy_igp_3:
- offset = IGP01E1000_PHY_LINK_HEALTH;
- mask = IGP01E1000_PLHR_SS_DOWNGRADE;
- break;
- default:
- /* speed downshift not supported */
- phy->speed_downgraded = false;
- return E1000_SUCCESS;
- }
-
- ret_val = phy->ops.read_reg(hw, offset, &phy_data);
-
- if (!ret_val)
- phy->speed_downgraded = !!(phy_data & mask);
-
- return ret_val;
-}
-
-/**
- * e1000_check_polarity_m88 - Checks the polarity.
- * @hw: pointer to the HW structure
- *
- * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
- *
- * Polarity is determined based on the PHY specific status register.
- **/
-s32 e1000_check_polarity_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
-
- DEBUGFUNC("e1000_check_polarity_m88");
-
- ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
-
- if (!ret_val)
- phy->cable_polarity = ((data & M88E1000_PSSR_REV_POLARITY)
- ? e1000_rev_polarity_reversed
- : e1000_rev_polarity_normal);
-
- return ret_val;
-}
-
-/**
- * e1000_check_polarity_igp - Checks the polarity.
- * @hw: pointer to the HW structure
- *
- * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
- *
- * Polarity is determined based on the PHY port status register, and the
- * current speed (since there is no polarity at 100Mbps).
- **/
-s32 e1000_check_polarity_igp(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data, offset, mask;
-
- DEBUGFUNC("e1000_check_polarity_igp");
-
- /* Polarity is determined based on the speed of
- * our connection.
- */
- ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
- if (ret_val)
- return ret_val;
-
- if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
- offset = IGP01E1000_PHY_PCS_INIT_REG;
- mask = IGP01E1000_PHY_POLARITY_MASK;
- } else {
- /* This really only applies to 10Mbps since
- * there is no polarity for 100Mbps (always 0).
- */
- offset = IGP01E1000_PHY_PORT_STATUS;
- mask = IGP01E1000_PSSR_POLARITY_REVERSED;
- }
-
- ret_val = phy->ops.read_reg(hw, offset, &data);
-
- if (!ret_val)
- phy->cable_polarity = ((data & mask)
- ? e1000_rev_polarity_reversed
- : e1000_rev_polarity_normal);
-
- return ret_val;
-}
-
-/**
- * e1000_check_polarity_ife - Check cable polarity for IFE PHY
- * @hw: pointer to the HW structure
- *
- * Polarity is determined on the polarity reversal feature being enabled.
- **/
-s32 e1000_check_polarity_ife(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, offset, mask;
-
- DEBUGFUNC("e1000_check_polarity_ife");
-
- /* Polarity is determined based on the reversal feature being enabled.
- */
- if (phy->polarity_correction) {
- offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
- mask = IFE_PESC_POLARITY_REVERSED;
- } else {
- offset = IFE_PHY_SPECIAL_CONTROL;
- mask = IFE_PSC_FORCE_POLARITY;
- }
-
- ret_val = phy->ops.read_reg(hw, offset, &phy_data);
-
- if (!ret_val)
- phy->cable_polarity = ((phy_data & mask)
- ? e1000_rev_polarity_reversed
- : e1000_rev_polarity_normal);
-
- return ret_val;
-}
-
-/**
- * e1000_wait_autoneg - Wait for auto-neg completion
- * @hw: pointer to the HW structure
- *
- * Waits for auto-negotiation to complete or for the auto-negotiation time
- * limit to expire, which ever happens first.
- **/
-static s32 e1000_wait_autoneg(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u16 i, phy_status;
-
- DEBUGFUNC("e1000_wait_autoneg");
-
- if (!hw->phy.ops.read_reg)
- return E1000_SUCCESS;
-
- /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
- for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
- ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- break;
- ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- break;
- if (phy_status & MII_SR_AUTONEG_COMPLETE)
- break;
- msec_delay(100);
- }
-
- /* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
- * has completed.
- */
- return ret_val;
-}
-
-/**
- * e1000_phy_has_link_generic - Polls PHY for link
- * @hw: pointer to the HW structure
- * @iterations: number of times to poll for link
- * @usec_interval: delay between polling attempts
- * @success: pointer to whether polling was successful or not
- *
- * Polls the PHY status register for link, 'iterations' number of times.
- **/
-s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
- u32 usec_interval, bool *success)
-{
- s32 ret_val = E1000_SUCCESS;
- u16 i, phy_status;
-
- DEBUGFUNC("e1000_phy_has_link_generic");
-
- if (!hw->phy.ops.read_reg)
- return E1000_SUCCESS;
-
- for (i = 0; i < iterations; i++) {
- /* Some PHYs require the PHY_STATUS register to be read
- * twice due to the link bit being sticky. No harm doing
- * it across the board.
- */
- ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- /* If the first read fails, another entity may have
- * ownership of the resources, wait and try again to
- * see if they have relinquished the resources yet.
- */
- usec_delay(usec_interval);
- ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- break;
- if (phy_status & MII_SR_LINK_STATUS)
- break;
- if (usec_interval >= 1000)
- msec_delay_irq(usec_interval/1000);
- else
- usec_delay(usec_interval);
- }
-
- *success = (i < iterations);
-
- return ret_val;
-}
-
-/**
- * e1000_get_cable_length_m88 - Determine cable length for m88 PHY
- * @hw: pointer to the HW structure
- *
- * Reads the PHY specific status register to retrieve the cable length
- * information. The cable length is determined by averaging the minimum and
- * maximum values to get the "average" cable length. The m88 PHY has four
- * possible cable length values, which are:
- * Register Value Cable Length
- * 0 < 50 meters
- * 1 50 - 80 meters
- * 2 80 - 110 meters
- * 3 110 - 140 meters
- * 4 > 140 meters
- **/
-s32 e1000_get_cable_length_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, index;
-
- DEBUGFUNC("e1000_get_cable_length_m88");
-
- ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- index = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
- M88E1000_PSSR_CABLE_LENGTH_SHIFT);
-
- if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1)
- return -E1000_ERR_PHY;
-
- phy->min_cable_length = e1000_m88_cable_length_table[index];
- phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
-
- phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
-
- return E1000_SUCCESS;
-}
-
-s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, phy_data2, is_cm;
- u16 index, default_page;
-
- DEBUGFUNC("e1000_get_cable_length_m88_gen2");
-
- switch (hw->phy.id) {
- case I210_I_PHY_ID:
- /* Get cable length from PHY Cable Diagnostics Control Reg */
- ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) +
- (I347AT4_PCDL + phy->addr),
- &phy_data);
- if (ret_val)
- return ret_val;
-
- /* Check if the unit of cable length is meters or cm */
- ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) +
- I347AT4_PCDC, &phy_data2);
- if (ret_val)
- return ret_val;
-
- is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT);
-
- /* Populate the phy structure with cable length in meters */
- phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
- phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
- phy->cable_length = phy_data / (is_cm ? 100 : 1);
- break;
- case M88E1543_E_PHY_ID:
- case M88E1340M_E_PHY_ID:
- case I347AT4_E_PHY_ID:
- /* Remember the original page select and set it to 7 */
- ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
- &default_page);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07);
- if (ret_val)
- return ret_val;
-
- /* Get cable length from PHY Cable Diagnostics Control Reg */
- ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr),
- &phy_data);
- if (ret_val)
- return ret_val;
-
- /* Check if the unit of cable length is meters or cm */
- ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2);
- if (ret_val)
- return ret_val;
-
- is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT);
-
- /* Populate the phy structure with cable length in meters */
- phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
- phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
- phy->cable_length = phy_data / (is_cm ? 100 : 1);
-
- /* Reset the page select to its original value */
- ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
- default_page);
- if (ret_val)
- return ret_val;
- break;
-
- case M88E1112_E_PHY_ID:
- /* Remember the original page select and set it to 5 */
- ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
- &default_page);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
- M88E1000_PSSR_CABLE_LENGTH_SHIFT;
-
- if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1)
- return -E1000_ERR_PHY;
-
- phy->min_cable_length = e1000_m88_cable_length_table[index];
- phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
-
- phy->cable_length = (phy->min_cable_length +
- phy->max_cable_length) / 2;
-
- /* Reset the page select to its original value */
- ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
- default_page);
- if (ret_val)
- return ret_val;
-
- break;
- default:
- return -E1000_ERR_PHY;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_get_cable_length_igp_2 - Determine cable length for igp2 PHY
- * @hw: pointer to the HW structure
- *
- * The automatic gain control (agc) normalizes the amplitude of the
- * received signal, adjusting for the attenuation produced by the
- * cable. By reading the AGC registers, which represent the
- * combination of coarse and fine gain value, the value can be put
- * into a lookup table to obtain the approximate cable length
- * for each channel.
- **/
-s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, i, agc_value = 0;
- u16 cur_agc_index, max_agc_index = 0;
- u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
- static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = {
- IGP02E1000_PHY_AGC_A,
- IGP02E1000_PHY_AGC_B,
- IGP02E1000_PHY_AGC_C,
- IGP02E1000_PHY_AGC_D
- };
-
- DEBUGFUNC("e1000_get_cable_length_igp_2");
-
- /* Read the AGC registers for all channels */
- for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data);
- if (ret_val)
- return ret_val;
-
- /* Getting bits 15:9, which represent the combination of
- * coarse and fine gain values. The result is a number
- * that can be put into the lookup table to obtain the
- * approximate cable length.
- */
- cur_agc_index = ((phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
- IGP02E1000_AGC_LENGTH_MASK);
-
- /* Array index bound check. */
- if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
- (cur_agc_index == 0))
- return -E1000_ERR_PHY;
-
- /* Remove min & max AGC values from calculation. */
- if (e1000_igp_2_cable_length_table[min_agc_index] >
- e1000_igp_2_cable_length_table[cur_agc_index])
- min_agc_index = cur_agc_index;
- if (e1000_igp_2_cable_length_table[max_agc_index] <
- e1000_igp_2_cable_length_table[cur_agc_index])
- max_agc_index = cur_agc_index;
-
- agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
- }
-
- agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
- e1000_igp_2_cable_length_table[max_agc_index]);
- agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
-
- /* Calculate cable length with the error range of +/- 10 meters. */
- phy->min_cable_length = (((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
- (agc_value - IGP02E1000_AGC_RANGE) : 0);
- phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
-
- phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_get_phy_info_m88 - Retrieve PHY information
- * @hw: pointer to the HW structure
- *
- * Valid for only copper links. Read the PHY status register (sticky read)
- * to verify that link is up. Read the PHY special control register to
- * determine the polarity and 10base-T extended distance. Read the PHY
- * special status register to determine MDI/MDIx and current speed. If
- * speed is 1000, then determine cable length, local and remote receiver.
- **/
-s32 e1000_get_phy_info_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
- bool link;
-
- DEBUGFUNC("e1000_get_phy_info_m88");
-
- if (phy->media_type != e1000_media_type_copper) {
- DEBUGOUT("Phy info is only valid for copper media\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- return ret_val;
-
- if (!link) {
- DEBUGOUT("Phy info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy->polarity_correction = !!(phy_data &
- M88E1000_PSCR_POLARITY_REVERSAL);
-
- ret_val = e1000_check_polarity_m88(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy->is_mdix = !!(phy_data & M88E1000_PSSR_MDIX);
-
- if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
- ret_val = hw->phy.ops.get_cable_length(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
-
- phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
- } else {
- /* Set values to "undefined" */
- phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
- phy->local_rx = e1000_1000t_rx_status_undefined;
- phy->remote_rx = e1000_1000t_rx_status_undefined;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_get_phy_info_igp - Retrieve igp PHY information
- * @hw: pointer to the HW structure
- *
- * Read PHY status to determine if link is up. If link is up, then
- * set/determine 10base-T extended distance and polarity correction. Read
- * PHY port status to determine MDI/MDIx and speed. Based on the speed,
- * determine on the cable length, local and remote receiver.
- **/
-s32 e1000_get_phy_info_igp(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
- bool link;
-
- DEBUGFUNC("e1000_get_phy_info_igp");
-
- ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- return ret_val;
-
- if (!link) {
- DEBUGOUT("Phy info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
- phy->polarity_correction = true;
-
- ret_val = e1000_check_polarity_igp(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
- if (ret_val)
- return ret_val;
-
- phy->is_mdix = !!(data & IGP01E1000_PSSR_MDIX);
-
- if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
- ret_val = phy->ops.get_cable_length(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
- if (ret_val)
- return ret_val;
-
- phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
-
- phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
- } else {
- phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
- phy->local_rx = e1000_1000t_rx_status_undefined;
- phy->remote_rx = e1000_1000t_rx_status_undefined;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_get_phy_info_ife - Retrieves various IFE PHY states
- * @hw: pointer to the HW structure
- *
- * Populates "phy" structure with various feature states.
- **/
-s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
- bool link;
-
- DEBUGFUNC("e1000_get_phy_info_ife");
-
- ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- return ret_val;
-
- if (!link) {
- DEBUGOUT("Phy info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = phy->ops.read_reg(hw, IFE_PHY_SPECIAL_CONTROL, &data);
- if (ret_val)
- return ret_val;
- phy->polarity_correction = !(data & IFE_PSC_AUTO_POLARITY_DISABLE);
-
- if (phy->polarity_correction) {
- ret_val = e1000_check_polarity_ife(hw);
- if (ret_val)
- return ret_val;
- } else {
- /* Polarity is forced */
- phy->cable_polarity = ((data & IFE_PSC_FORCE_POLARITY)
- ? e1000_rev_polarity_reversed
- : e1000_rev_polarity_normal);
- }
-
- ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
- if (ret_val)
- return ret_val;
-
- phy->is_mdix = !!(data & IFE_PMC_MDIX_STATUS);
-
- /* The following parameters are undefined for 10/100 operation. */
- phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
- phy->local_rx = e1000_1000t_rx_status_undefined;
- phy->remote_rx = e1000_1000t_rx_status_undefined;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_phy_sw_reset_generic - PHY software reset
- * @hw: pointer to the HW structure
- *
- * Does a software reset of the PHY by reading the PHY control register and
- * setting/write the control register reset bit to the PHY.
- **/
-s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 phy_ctrl;
-
- DEBUGFUNC("e1000_phy_sw_reset_generic");
-
- if (!hw->phy.ops.read_reg)
- return E1000_SUCCESS;
-
- ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
- if (ret_val)
- return ret_val;
-
- phy_ctrl |= MII_CR_RESET;
- ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
- if (ret_val)
- return ret_val;
-
- usec_delay(1);
-
- return ret_val;
-}
-
-/**
- * e1000_phy_hw_reset_generic - PHY hardware reset
- * @hw: pointer to the HW structure
- *
- * Verify the reset block is not blocking us from resetting. Acquire
- * semaphore (if necessary) and read/set/write the device control reset
- * bit in the PHY. Wait the appropriate delay time for the device to
- * reset and release the semaphore (if necessary).
- **/
-s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u32 ctrl;
-
- DEBUGFUNC("e1000_phy_hw_reset_generic");
-
- if (phy->ops.check_reset_block) {
- ret_val = phy->ops.check_reset_block(hw);
- if (ret_val)
- return E1000_SUCCESS;
- }
-
- ret_val = phy->ops.acquire(hw);
- if (ret_val)
- return ret_val;
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PHY_RST);
- E1000_WRITE_FLUSH(hw);
-
- usec_delay(phy->reset_delay_us);
-
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
-
- usec_delay(150);
-
- phy->ops.release(hw);
-
- return phy->ops.get_cfg_done(hw);
-}
-
-/**
- * e1000_get_cfg_done_generic - Generic configuration done
- * @hw: pointer to the HW structure
- *
- * Generic function to wait 10 milli-seconds for configuration to complete
- * and return success.
- **/
-s32 e1000_get_cfg_done_generic(struct e1000_hw E1000_UNUSEDARG *hw)
-{
- DEBUGFUNC("e1000_get_cfg_done_generic");
-
- msec_delay_irq(10);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_phy_init_script_igp3 - Inits the IGP3 PHY
- * @hw: pointer to the HW structure
- *
- * Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
- **/
-s32 e1000_phy_init_script_igp3(struct e1000_hw *hw)
-{
- DEBUGOUT("Running IGP 3 PHY init script\n");
-
- /* PHY init IGP 3 */
- /* Enable rise/fall, 10-mode work in class-A */
- hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018);
- /* Remove all caps from Replica path filter */
- hw->phy.ops.write_reg(hw, 0x2F52, 0x0000);
- /* Bias trimming for ADC, AFE and Driver (Default) */
- hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24);
- /* Increase Hybrid poly bias */
- hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0);
- /* Add 4% to Tx amplitude in Gig mode */
- hw->phy.ops.write_reg(hw, 0x2010, 0x10B0);
- /* Disable trimming (TTT) */
- hw->phy.ops.write_reg(hw, 0x2011, 0x0000);
- /* Poly DC correction to 94.6% + 2% for all channels */
- hw->phy.ops.write_reg(hw, 0x20DD, 0x249A);
- /* ABS DC correction to 95.9% */
- hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3);
- /* BG temp curve trim */
- hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE);
- /* Increasing ADC OPAMP stage 1 currents to max */
- hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4);
- /* Force 1000 ( required for enabling PHY regs configuration) */
- hw->phy.ops.write_reg(hw, 0x0000, 0x0140);
- /* Set upd_freq to 6 */
- hw->phy.ops.write_reg(hw, 0x1F30, 0x1606);
- /* Disable NPDFE */
- hw->phy.ops.write_reg(hw, 0x1F31, 0xB814);
- /* Disable adaptive fixed FFE (Default) */
- hw->phy.ops.write_reg(hw, 0x1F35, 0x002A);
- /* Enable FFE hysteresis */
- hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067);
- /* Fixed FFE for short cable lengths */
- hw->phy.ops.write_reg(hw, 0x1F54, 0x0065);
- /* Fixed FFE for medium cable lengths */
- hw->phy.ops.write_reg(hw, 0x1F55, 0x002A);
- /* Fixed FFE for long cable lengths */
- hw->phy.ops.write_reg(hw, 0x1F56, 0x002A);
- /* Enable Adaptive Clip Threshold */
- hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0);
- /* AHT reset limit to 1 */
- hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF);
- /* Set AHT master delay to 127 msec */
- hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC);
- /* Set scan bits for AHT */
- hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF);
- /* Set AHT Preset bits */
- hw->phy.ops.write_reg(hw, 0x1F79, 0x0210);
- /* Change integ_factor of channel A to 3 */
- hw->phy.ops.write_reg(hw, 0x1895, 0x0003);
- /* Change prop_factor of channels BCD to 8 */
- hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
- /* Change cg_icount + enable integbp for channels BCD */
- hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
- /* Change cg_icount + enable integbp + change prop_factor_master
- * to 8 for channel A
- */
- hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
- /* Disable AHT in Slave mode on channel A */
- hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
- /* Enable LPLU and disable AN to 1000 in non-D0a states,
- * Enable SPD+B2B
- */
- hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
- /* Enable restart AN on an1000_dis change */
- hw->phy.ops.write_reg(hw, 0x001B, 0x2080);
- /* Enable wh_fifo read clock in 10/100 modes */
- hw->phy.ops.write_reg(hw, 0x0014, 0x0045);
- /* Restart AN, Speed selection is 1000 */
- hw->phy.ops.write_reg(hw, 0x0000, 0x1340);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_get_phy_type_from_id - Get PHY type from id
- * @phy_id: phy_id read from the phy
- *
- * Returns the phy type from the id.
- **/
-enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
-{
- enum e1000_phy_type phy_type = e1000_phy_unknown;
-
- switch (phy_id) {
- case M88E1000_I_PHY_ID:
- case M88E1000_E_PHY_ID:
- case M88E1111_I_PHY_ID:
- case M88E1011_I_PHY_ID:
- case M88E1543_E_PHY_ID:
- case I347AT4_E_PHY_ID:
- case M88E1112_E_PHY_ID:
- case M88E1340M_E_PHY_ID:
- phy_type = e1000_phy_m88;
- break;
- case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
- phy_type = e1000_phy_igp_2;
- break;
- case GG82563_E_PHY_ID:
- phy_type = e1000_phy_gg82563;
- break;
- case IGP03E1000_E_PHY_ID:
- phy_type = e1000_phy_igp_3;
- break;
- case IFE_E_PHY_ID:
- case IFE_PLUS_E_PHY_ID:
- case IFE_C_E_PHY_ID:
- phy_type = e1000_phy_ife;
- break;
- case I82580_I_PHY_ID:
- phy_type = e1000_phy_82580;
- break;
- case I210_I_PHY_ID:
- phy_type = e1000_phy_i210;
- break;
- default:
- phy_type = e1000_phy_unknown;
- break;
- }
- return phy_type;
-}
-
-/**
- * e1000_determine_phy_address - Determines PHY address.
- * @hw: pointer to the HW structure
- *
- * This uses a trial and error method to loop through possible PHY
- * addresses. It tests each by reading the PHY ID registers and
- * checking for a match.
- **/
-s32 e1000_determine_phy_address(struct e1000_hw *hw)
-{
- u32 phy_addr = 0;
- u32 i;
- enum e1000_phy_type phy_type = e1000_phy_unknown;
-
- hw->phy.id = phy_type;
-
- for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
- hw->phy.addr = phy_addr;
- i = 0;
-
- do {
- e1000_get_phy_id(hw);
- phy_type = e1000_get_phy_type_from_id(hw->phy.id);
-
- /* If phy_type is valid, break - we found our
- * PHY address
- */
- if (phy_type != e1000_phy_unknown)
- return E1000_SUCCESS;
-
- msec_delay(1);
- i++;
- } while (i < 10);
- }
-
- return -E1000_ERR_PHY_TYPE;
-}
-
-/**
- * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
- * @hw: pointer to the HW structure
- *
- * In the case of a PHY power down to save power, or to turn off link during a
- * driver unload, or wake on lan is not enabled, restore the link to previous
- * settings.
- **/
-void e1000_power_up_phy_copper(struct e1000_hw *hw)
-{
- u16 mii_reg = 0;
- u16 power_reg = 0;
-
- /* The PHY will retain its settings across a power down/up cycle */
- hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
- mii_reg &= ~MII_CR_POWER_DOWN;
- if (hw->phy.type == e1000_phy_i210) {
- hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg);
- power_reg &= ~GS40G_CS_POWER_DOWN;
- hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
- }
- hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
-}
-
-/**
- * e1000_power_down_phy_copper - Restore copper link in case of PHY power down
- * @hw: pointer to the HW structure
- *
- * In the case of a PHY power down to save power, or to turn off link during a
- * driver unload, or wake on lan is not enabled, restore the link to previous
- * settings.
- **/
-void e1000_power_down_phy_copper(struct e1000_hw *hw)
-{
- u16 mii_reg = 0;
- u16 power_reg = 0;
-
- /* The PHY will retain its settings across a power down/up cycle */
- hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
- mii_reg |= MII_CR_POWER_DOWN;
- /* i210 Phy requires an additional bit for power up/down */
- if (hw->phy.type == e1000_phy_i210) {
- hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg);
- power_reg |= GS40G_CS_POWER_DOWN;
- hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
- }
- hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
- msec_delay(1);
-}
-
-/**
- * e1000_check_polarity_82577 - Checks the polarity.
- * @hw: pointer to the HW structure
- *
- * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
- *
- * Polarity is determined based on the PHY specific status register.
- **/
-s32 e1000_check_polarity_82577(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
-
- DEBUGFUNC("e1000_check_polarity_82577");
-
- ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
-
- if (!ret_val)
- phy->cable_polarity = ((data & I82577_PHY_STATUS2_REV_POLARITY)
- ? e1000_rev_polarity_reversed
- : e1000_rev_polarity_normal);
-
- return ret_val;
-}
-
-/**
- * e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
- * @hw: pointer to the HW structure
- *
- * Calls the PHY setup function to force speed and duplex.
- **/
-s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
- bool link;
-
- DEBUGFUNC("e1000_phy_force_speed_duplex_82577");
-
- ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- e1000_phy_force_speed_duplex_setup(hw, &phy_data);
-
- ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
- if (ret_val)
- return ret_val;
-
- usec_delay(1);
-
- if (phy->autoneg_wait_to_complete) {
- DEBUGOUT("Waiting for forced speed/duplex link on 82577 phy\n");
-
- ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- if (ret_val)
- return ret_val;
-
- if (!link)
- DEBUGOUT("Link taking longer than expected.\n");
-
- /* Try once more */
- ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_get_phy_info_82577 - Retrieve I82577 PHY information
- * @hw: pointer to the HW structure
- *
- * Read PHY status to determine if link is up. If link is up, then
- * set/determine 10base-T extended distance and polarity correction. Read
- * PHY port status to determine MDI/MDIx and speed. Based on the speed,
- * determine on the cable length, local and remote receiver.
- **/
-s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
- bool link;
-
- DEBUGFUNC("e1000_get_phy_info_82577");
-
- ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- return ret_val;
-
- if (!link) {
- DEBUGOUT("Phy info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
- phy->polarity_correction = true;
-
- ret_val = e1000_check_polarity_82577(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
- if (ret_val)
- return ret_val;
-
- phy->is_mdix = !!(data & I82577_PHY_STATUS2_MDIX);
-
- if ((data & I82577_PHY_STATUS2_SPEED_MASK) ==
- I82577_PHY_STATUS2_SPEED_1000MBPS) {
- ret_val = hw->phy.ops.get_cable_length(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
- if (ret_val)
- return ret_val;
-
- phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
-
- phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
- } else {
- phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
- phy->local_rx = e1000_1000t_rx_status_undefined;
- phy->remote_rx = e1000_1000t_rx_status_undefined;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_get_cable_length_82577 - Determine cable length for 82577 PHY
- * @hw: pointer to the HW structure
- *
- * Reads the diagnostic status register and verifies result is valid before
- * placing it in the phy_cable_length field.
- **/
-s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, length;
-
- DEBUGFUNC("e1000_get_cable_length_82577");
-
- ret_val = phy->ops.read_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- length = ((phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
- I82577_DSTATUS_CABLE_LENGTH_SHIFT);
-
- if (length == E1000_CABLE_LENGTH_UNDEFINED)
- return -E1000_ERR_PHY;
-
- phy->cable_length = length;
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_phy_reg_gs40g - Write GS40G PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore, if necessary, then writes the data to PHY register
- * at the offset. Release any acquired semaphores before exiting.
- **/
-s32 e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data)
-{
- s32 ret_val;
- u16 page = offset >> GS40G_PAGE_SHIFT;
-
- DEBUGFUNC("e1000_write_phy_reg_gs40g");
-
- offset = offset & GS40G_OFFSET_MASK;
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
- if (ret_val)
- goto release;
- ret_val = e1000_write_phy_reg_mdic(hw, offset, data);
-
-release:
- hw->phy.ops.release(hw);
- return ret_val;
-}
-
-/**
- * e1000_read_phy_reg_gs40g - Read GS40G PHY register
- * @hw: pointer to the HW structure
- * @offset: lower half is register offset to read to
- * upper half is page to use.
- * @data: data to read at register offset
- *
- * Acquires semaphore, if necessary, then reads the data in the PHY register
- * at the offset. Release any acquired semaphores before exiting.
- **/
-s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- s32 ret_val;
- u16 page = offset >> GS40G_PAGE_SHIFT;
-
- DEBUGFUNC("e1000_read_phy_reg_gs40g");
-
- offset = offset & GS40G_OFFSET_MASK;
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
- if (ret_val)
- goto release;
- ret_val = e1000_read_phy_reg_mdic(hw, offset, data);
-
-release:
- hw->phy.ops.release(hw);
- return ret_val;
-}
-
-/**
- * e1000_read_phy_reg_mphy - Read mPHY control register
- * @hw: pointer to the HW structure
- * @address: address to be read
- * @data: pointer to the read data
- *
- * Reads the mPHY control register in the PHY at offset and stores the
- * information read to data.
- **/
-s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data)
-{
- u32 mphy_ctrl = 0;
- bool locked = false;
- bool ready = false;
-
- DEBUGFUNC("e1000_read_phy_reg_mphy");
-
- /* Check if mPHY is ready to read/write operations */
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
-
- /* Check if mPHY access is disabled and enable it if so */
- mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL);
- if (mphy_ctrl & E1000_MPHY_DIS_ACCESS) {
- locked = true;
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
- mphy_ctrl |= E1000_MPHY_ENA_ACCESS;
- E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
- }
-
- /* Set the address that we want to read */
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
-
- /* We mask address, because we want to use only current lane */
- mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK &
- ~E1000_MPHY_ADDRESS_FNC_OVERRIDE) |
- (address & E1000_MPHY_ADDRESS_MASK);
- E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
-
- /* Read data from the address */
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
- *data = E1000_READ_REG(hw, E1000_MPHY_DATA);
-
- /* Disable access to mPHY if it was originally disabled */
- if (locked) {
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
- E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL,
- E1000_MPHY_DIS_ACCESS);
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_write_phy_reg_mphy - Write mPHY control register
- * @hw: pointer to the HW structure
- * @address: address to write to
- * @data: data to write to register at offset
- * @line_override: used when we want to use different line than default one
- *
- * Writes data to mPHY control register.
- **/
-s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
- bool line_override)
-{
- u32 mphy_ctrl = 0;
- bool locked = false;
- bool ready = false;
-
- DEBUGFUNC("e1000_write_phy_reg_mphy");
-
- /* Check if mPHY is ready to read/write operations */
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
-
- /* Check if mPHY access is disabled and enable it if so */
- mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL);
- if (mphy_ctrl & E1000_MPHY_DIS_ACCESS) {
- locked = true;
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
- mphy_ctrl |= E1000_MPHY_ENA_ACCESS;
- E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
- }
-
- /* Set the address that we want to read */
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
-
- /* We mask address, because we want to use only current lane */
- if (line_override)
- mphy_ctrl |= E1000_MPHY_ADDRESS_FNC_OVERRIDE;
- else
- mphy_ctrl &= ~E1000_MPHY_ADDRESS_FNC_OVERRIDE;
- mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK) |
- (address & E1000_MPHY_ADDRESS_MASK);
- E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
-
- /* Read data from the address */
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
- E1000_WRITE_REG(hw, E1000_MPHY_DATA, data);
-
- /* Disable access to mPHY if it was originally disabled */
- if (locked) {
- ready = e1000_is_mphy_ready(hw);
- if (!ready)
- return -E1000_ERR_PHY;
- E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL,
- E1000_MPHY_DIS_ACCESS);
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_is_mphy_ready - Check if mPHY control register is not busy
- * @hw: pointer to the HW structure
- *
- * Returns mPHY control register status.
- **/
-bool e1000_is_mphy_ready(struct e1000_hw *hw)
-{
- u16 retry_count = 0;
- u32 mphy_ctrl = 0;
- bool ready = false;
-
- while (retry_count < 2) {
- mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL);
- if (mphy_ctrl & E1000_MPHY_BUSY) {
- usec_delay(20);
- retry_count++;
- continue;
- }
- ready = true;
- break;
- }
-
- if (!ready)
- DEBUGOUT("ERROR READING mPHY control register, phy is busy.\n");
-
- return ready;
-}
diff --git a/kernel/linux/kni/ethtool/igb/e1000_phy.h b/kernel/linux/kni/ethtool/igb/e1000_phy.h
deleted file mode 100644
index 67e9ba777..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_phy.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_PHY_H_
-#define _E1000_PHY_H_
-
-void e1000_init_phy_ops_generic(struct e1000_hw *hw);
-s32 e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data);
-void e1000_null_phy_generic(struct e1000_hw *hw);
-s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active);
-s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_null_set_page(struct e1000_hw *hw, u16 data);
-s32 e1000_read_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data);
-s32 e1000_write_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data);
-s32 e1000_check_downshift_generic(struct e1000_hw *hw);
-s32 e1000_check_polarity_m88(struct e1000_hw *hw);
-s32 e1000_check_polarity_igp(struct e1000_hw *hw);
-s32 e1000_check_polarity_ife(struct e1000_hw *hw);
-s32 e1000_check_reset_block_generic(struct e1000_hw *hw);
-s32 e1000_copper_link_setup_igp(struct e1000_hw *hw);
-s32 e1000_copper_link_setup_m88(struct e1000_hw *hw);
-s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw);
-s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw);
-s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw);
-s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
-s32 e1000_get_cable_length_m88(struct e1000_hw *hw);
-s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw);
-s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw);
-s32 e1000_get_cfg_done_generic(struct e1000_hw *hw);
-s32 e1000_get_phy_id(struct e1000_hw *hw);
-s32 e1000_get_phy_info_igp(struct e1000_hw *hw);
-s32 e1000_get_phy_info_m88(struct e1000_hw *hw);
-s32 e1000_get_phy_info_ife(struct e1000_hw *hw);
-s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw);
-void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
-s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw);
-s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw);
-s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page);
-s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active);
-s32 e1000_setup_copper_link_generic(struct e1000_hw *hw);
-s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
- u32 usec_interval, bool *success);
-s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
-enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
-s32 e1000_determine_phy_address(struct e1000_hw *hw);
-s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
-s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
-void e1000_power_up_phy_copper(struct e1000_hw *hw);
-void e1000_power_down_phy_copper(struct e1000_hw *hw);
-s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data);
-s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data);
-s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
-s32 e1000_check_polarity_82577(struct e1000_hw *hw);
-s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
-s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
-s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
-s32 e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data);
-s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
- bool line_override);
-bool e1000_is_mphy_ready(struct e1000_hw *hw);
-
-#define E1000_MAX_PHY_ADDR 8
-
-/* IGP01E1000 Specific Registers */
-#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
-#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
-#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
-#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
-#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
-#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
-#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
-#define IGP_PAGE_SHIFT 5
-#define PHY_REG_MASK 0x1F
-
-/* GS40G - I210 PHY defines */
-#define GS40G_PAGE_SELECT 0x16
-#define GS40G_PAGE_SHIFT 16
-#define GS40G_OFFSET_MASK 0xFFFF
-#define GS40G_PAGE_2 0x20000
-#define GS40G_MAC_REG2 0x15
-#define GS40G_MAC_LB 0x4140
-#define GS40G_MAC_SPEED_1G 0X0006
-#define GS40G_COPPER_SPEC 0x0010
-#define GS40G_CS_POWER_DOWN 0x0002
-
-#define HV_INTC_FC_PAGE_START 768
-#define I82578_ADDR_REG 29
-#define I82577_ADDR_REG 16
-#define I82577_CFG_REG 22
-#define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15)
-#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift */
-#define I82577_CTRL_REG 23
-
-/* 82577 specific PHY registers */
-#define I82577_PHY_CTRL_2 18
-#define I82577_PHY_LBK_CTRL 19
-#define I82577_PHY_STATUS_2 26
-#define I82577_PHY_DIAG_STATUS 31
-
-/* I82577 PHY Status 2 */
-#define I82577_PHY_STATUS2_REV_POLARITY 0x0400
-#define I82577_PHY_STATUS2_MDIX 0x0800
-#define I82577_PHY_STATUS2_SPEED_MASK 0x0300
-#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
-
-/* I82577 PHY Control 2 */
-#define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200
-#define I82577_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
-#define I82577_PHY_CTRL2_MDIX_CFG_MASK 0x0600
-
-/* I82577 PHY Diagnostics Status */
-#define I82577_DSTATUS_CABLE_LENGTH 0x03FC
-#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2
-
-/* 82580 PHY Power Management */
-#define E1000_82580_PHY_POWER_MGMT 0xE14
-#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */
-#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */
-#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */
-#define E1000_82580_PM_GO_LINKD 0x0020 /* Go Link Disconnect */
-
-#define E1000_MPHY_DIS_ACCESS 0x80000000 /* disable_access bit */
-#define E1000_MPHY_ENA_ACCESS 0x40000000 /* enable_access bit */
-#define E1000_MPHY_BUSY 0x00010000 /* busy bit */
-#define E1000_MPHY_ADDRESS_FNC_OVERRIDE 0x20000000 /* fnc_override bit */
-#define E1000_MPHY_ADDRESS_MASK 0x0000FFFF /* address mask */
-
-#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
-#define IGP01E1000_PHY_POLARITY_MASK 0x0078
-
-#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
-#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
-
-#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
-
-#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
-#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
-#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
-
-#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
-
-#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
-#define IGP01E1000_PSSR_MDIX 0x0800
-#define IGP01E1000_PSSR_SPEED_MASK 0xC000
-#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
-
-#define IGP02E1000_PHY_CHANNEL_NUM 4
-#define IGP02E1000_PHY_AGC_A 0x11B1
-#define IGP02E1000_PHY_AGC_B 0x12B1
-#define IGP02E1000_PHY_AGC_C 0x14B1
-#define IGP02E1000_PHY_AGC_D 0x18B1
-
-#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course=15:13, Fine=12:9 */
-#define IGP02E1000_AGC_LENGTH_MASK 0x7F
-#define IGP02E1000_AGC_RANGE 15
-
-#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
-
-#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
-#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16
-#define E1000_KMRNCTRLSTA_REN 0x00200000
-#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
-#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */
-#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */
-#define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */
-#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
-
-#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
-#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Ctrl */
-#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Ctrl */
-#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */
-
-/* IFE PHY Extended Status Control */
-#define IFE_PESC_POLARITY_REVERSED 0x0100
-
-/* IFE PHY Special Control */
-#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010
-#define IFE_PSC_FORCE_POLARITY 0x0020
-
-/* IFE PHY Special Control and LED Control */
-#define IFE_PSCL_PROBE_MODE 0x0020
-#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
-#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
-
-/* IFE PHY MDIX Control */
-#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
-#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */
-#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto, 0=disable */
-
-/* SFP modules ID memory locations */
-#define E1000_SFF_IDENTIFIER_OFFSET 0x00
-#define E1000_SFF_IDENTIFIER_SFF 0x02
-#define E1000_SFF_IDENTIFIER_SFP 0x03
-
-#define E1000_SFF_ETH_FLAGS_OFFSET 0x06
-/* Flags for SFP modules compatible with ETH up to 1Gb */
-struct sfp_e1000_flags {
- u8 e1000_base_sx:1;
- u8 e1000_base_lx:1;
- u8 e1000_base_cx:1;
- u8 e1000_base_t:1;
- u8 e100_base_lx:1;
- u8 e100_base_fx:1;
- u8 e10_base_bx10:1;
- u8 e10_base_px:1;
-};
-
-/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
-#define E1000_SFF_VENDOR_OUI_TYCO 0x00407600
-#define E1000_SFF_VENDOR_OUI_FTL 0x00906500
-#define E1000_SFF_VENDOR_OUI_AVAGO 0x00176A00
-#define E1000_SFF_VENDOR_OUI_INTEL 0x001B2100
-
-#endif
diff --git a/kernel/linux/kni/ethtool/igb/e1000_regs.h b/kernel/linux/kni/ethtool/igb/e1000_regs.h
deleted file mode 100644
index f5c7e031a..000000000
--- a/kernel/linux/kni/ethtool/igb/e1000_regs.h
+++ /dev/null
@@ -1,631 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_REGS_H_
-#define _E1000_REGS_H_
-
-#define E1000_CTRL 0x00000 /* Device Control - RW */
-#define E1000_STATUS 0x00008 /* Device Status - RO */
-#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
-#define E1000_EERD 0x00014 /* EEPROM Read - RW */
-#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
-#define E1000_FLA 0x0001C /* Flash Access - RW */
-#define E1000_MDIC 0x00020 /* MDI Control - RW */
-#define E1000_MDICNFG 0x00E04 /* MDI Config - RW */
-#define E1000_REGISTER_SET_SIZE 0x20000 /* CSR Size */
-#define E1000_EEPROM_INIT_CTRL_WORD_2 0x0F /* EEPROM Init Ctrl Word 2 */
-#define E1000_EEPROM_PCIE_CTRL_WORD_2 0x28 /* EEPROM PCIe Ctrl Word 2 */
-#define E1000_BARCTRL 0x5BBC /* BAR ctrl reg */
-#define E1000_BARCTRL_FLSIZE 0x0700 /* BAR ctrl Flsize */
-#define E1000_BARCTRL_CSRSIZE 0x2000 /* BAR ctrl CSR size */
-#define E1000_MPHY_ADDR_CTRL 0x0024 /* GbE MPHY Address Control */
-#define E1000_MPHY_DATA 0x0E10 /* GBE MPHY Data */
-#define E1000_MPHY_STAT 0x0E0C /* GBE MPHY Statistics */
-#define E1000_PPHY_CTRL 0x5b48 /* PCIe PHY Control */
-#define E1000_I350_BARCTRL 0x5BFC /* BAR ctrl reg */
-#define E1000_I350_DTXMXPKTSZ 0x355C /* Maximum sent packet size reg*/
-#define E1000_SCTL 0x00024 /* SerDes Control - RW */
-#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
-#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
-#define E1000_FCT 0x00030 /* Flow Control Type - RW */
-#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
-#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
-#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
-#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
-#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
-#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
-#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
-#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
-#define E1000_RCTL 0x00100 /* Rx Control - RW */
-#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
-#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
-#define E1000_RXCW 0x00180 /* Rx Configuration Word - RO */
-#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
-#define E1000_EITR(_n) (0x01680 + (0x4 * (_n)))
-#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
-#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
-#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
-#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
-#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
-#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable - RW */
-#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */
-#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
-#define E1000_TCTL 0x00400 /* Tx Control - RW */
-#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */
-#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */
-#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
-#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
-#define E1000_LEDMUX 0x08130 /* LED MUX Control */
-#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
-#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
-#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
-#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
-#define E1000_PBS 0x01008 /* Packet Buffer Size */
-#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
-#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
-#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
-#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
-#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
-#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */
-#define E1000_I2CBB_EN 0x00000100 /* I2C - Bit Bang Enable */
-#define E1000_I2C_CLK_OUT 0x00000200 /* I2C- Clock */
-#define E1000_I2C_DATA_OUT 0x00000400 /* I2C- Data Out */
-#define E1000_I2C_DATA_OE_N 0x00000800 /* I2C- Data Output Enable */
-#define E1000_I2C_DATA_IN 0x00001000 /* I2C- Data In */
-#define E1000_I2C_CLK_OE_N 0x00002000 /* I2C- Clock Output Enable */
-#define E1000_I2C_CLK_IN 0x00004000 /* I2C- Clock In */
-#define E1000_I2C_CLK_STRETCH_DIS 0x00008000 /* I2C- Dis Clk Stretching */
-#define E1000_WDSTP 0x01040 /* Watchdog Setup - RW */
-#define E1000_SWDSTS 0x01044 /* SW Device Status - RW */
-#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
-#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
-#define E1000_VPDDIAG 0x01060 /* VPD Diagnostic - RO */
-#define E1000_ICR_V2 0x01500 /* Intr Cause - new location - RC */
-#define E1000_ICS_V2 0x01504 /* Intr Cause Set - new location - WO */
-#define E1000_IMS_V2 0x01508 /* Intr Mask Set/Read - new location - RW */
-#define E1000_IMC_V2 0x0150C /* Intr Mask Clear - new location - WO */
-#define E1000_IAM_V2 0x01510 /* Intr Ack Auto Mask - new location - RW */
-#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
-#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
-#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
-#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
-#define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */
-#define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */
-#define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */
-#define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */
-#define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */
-#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */
-#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
-/* Split and Replication Rx Control - RW */
-#define E1000_RDPUMB 0x025CC /* DMA Rx Descriptor uC Mailbox - RW */
-#define E1000_RDPUAD 0x025D0 /* DMA Rx Descriptor uC Addr Command - RW */
-#define E1000_RDPUWD 0x025D4 /* DMA Rx Descriptor uC Data Write - RW */
-#define E1000_RDPURD 0x025D8 /* DMA Rx Descriptor uC Data Read - RW */
-#define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */
-#define E1000_PBDIAG 0x02458 /* Packet Buffer Diagnostic - RW */
-#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
-#define E1000_IRPBS 0x02404 /* Same as RXPBS, renamed for newer Si - RW */
-#define E1000_PBRWAC 0x024E8 /* Rx packet buffer wrap around counter - RO */
-#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
-#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
-#define E1000_EMIADD 0x10 /* Extended Memory Indirect Address */
-#define E1000_EMIDATA 0x11 /* Extended Memory Indirect Data */
-#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */
-#define E1000_I210_FLMNGCTL 0x12038
-#define E1000_I210_FLMNGDATA 0x1203C
-#define E1000_I210_FLMNGCNT 0x12040
-
-#define E1000_I210_FLSWCTL 0x12048
-#define E1000_I210_FLSWDATA 0x1204C
-#define E1000_I210_FLSWCNT 0x12050
-
-#define E1000_I210_FLA 0x1201C
-
-#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n))
-#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */
-
-/* QAV Tx mode control register */
-#define E1000_I210_TQAVCTRL 0x3570
-
-/* QAV Tx mode control register bitfields masks */
-/* QAV enable */
-#define E1000_TQAVCTRL_MODE (1 << 0)
-/* Fetching arbitration type */
-#define E1000_TQAVCTRL_FETCH_ARB (1 << 4)
-/* Fetching timer enable */
-#define E1000_TQAVCTRL_FETCH_TIMER_ENABLE (1 << 5)
-/* Launch arbitration type */
-#define E1000_TQAVCTRL_LAUNCH_ARB (1 << 8)
-/* Launch timer enable */
-#define E1000_TQAVCTRL_LAUNCH_TIMER_ENABLE (1 << 9)
-/* SP waits for SR enable */
-#define E1000_TQAVCTRL_SP_WAIT_SR (1 << 10)
-/* Fetching timer correction */
-#define E1000_TQAVCTRL_FETCH_TIMER_DELTA_OFFSET 16
-#define E1000_TQAVCTRL_FETCH_TIMER_DELTA \
- (0xFFFF << E1000_TQAVCTRL_FETCH_TIMER_DELTA_OFFSET)
-
-/* High credit registers where _n can be 0 or 1. */
-#define E1000_I210_TQAVHC(_n) (0x300C + 0x40 * (_n))
-
-/* Queues fetch arbitration priority control register */
-#define E1000_I210_TQAVARBCTRL 0x3574
-/* Queues priority masks where _n and _p can be 0-3. */
-#define E1000_TQAVARBCTRL_QUEUE_PRI(_n, _p) ((_p) << (2 * _n))
-/* QAV Tx mode control registers where _n can be 0 or 1. */
-#define E1000_I210_TQAVCC(_n) (0x3004 + 0x40 * (_n))
-
-/* QAV Tx mode control register bitfields masks */
-#define E1000_TQAVCC_IDLE_SLOPE 0xFFFF /* Idle slope */
-#define E1000_TQAVCC_KEEP_CREDITS (1 << 30) /* Keep credits opt enable */
-#define E1000_TQAVCC_QUEUE_MODE (1 << 31) /* SP vs. SR Tx mode */
-
-/* Good transmitted packets counter registers */
-#define E1000_PQGPTC(_n) (0x010014 + (0x100 * (_n)))
-
-/* Queues packet buffer size masks where _n can be 0-3 and _s 0-63 [kB] */
-#define E1000_I210_TXPBS_SIZE(_n, _s) ((_s) << (6 * _n))
-
-#define E1000_MMDAC 13 /* MMD Access Control */
-#define E1000_MMDAAD 14 /* MMD Access Address/Data */
-
-/* Convenience macros
- *
- * Note: "_n" is the queue number of the register to be written to.
- *
- * Example usage:
- * E1000_RDBAL_REG(current_rx_queue)
- */
-#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \
- (0x0C000 + ((_n) * 0x40)))
-#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \
- (0x0C004 + ((_n) * 0x40)))
-#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \
- (0x0C008 + ((_n) * 0x40)))
-#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \
- (0x0C00C + ((_n) * 0x40)))
-#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \
- (0x0C010 + ((_n) * 0x40)))
-#define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \
- (0x0C014 + ((_n) * 0x40)))
-#define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n)
-#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \
- (0x0C018 + ((_n) * 0x40)))
-#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \
- (0x0C028 + ((_n) * 0x40)))
-#define E1000_RQDPC(_n) ((_n) < 4 ? (0x02830 + ((_n) * 0x100)) : \
- (0x0C030 + ((_n) * 0x40)))
-#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \
- (0x0E000 + ((_n) * 0x40)))
-#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \
- (0x0E004 + ((_n) * 0x40)))
-#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \
- (0x0E008 + ((_n) * 0x40)))
-#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \
- (0x0E010 + ((_n) * 0x40)))
-#define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \
- (0x0E014 + ((_n) * 0x40)))
-#define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n)
-#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \
- (0x0E018 + ((_n) * 0x40)))
-#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \
- (0x0E028 + ((_n) * 0x40)))
-#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) : \
- (0x0E038 + ((_n) * 0x40)))
-#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) : \
- (0x0E03C + ((_n) * 0x40)))
-#define E1000_TARC(_n) (0x03840 + ((_n) * 0x100))
-#define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */
-#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
-#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
-#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
-#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
- (0x054E0 + ((_i - 16) * 8)))
-#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
- (0x054E4 + ((_i - 16) * 8)))
-#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8))
-#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8))
-#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
-#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
-#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
-#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8))
-#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8))
-#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8))
-#define E1000_PBSLAC 0x03100 /* Pkt Buffer Slave Access Control */
-#define E1000_PBSLAD(_n) (0x03110 + (0x4 * (_n))) /* Pkt Buffer DWORD */
-#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
-/* Same as TXPBS, renamed for newer Si - RW */
-#define E1000_ITPBS 0x03404
-#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */
-#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */
-#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */
-#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */
-#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */
-#define E1000_TDPUMB 0x0357C /* DMA Tx Desc uC Mail Box - RW */
-#define E1000_TDPUAD 0x03580 /* DMA Tx Desc uC Addr Command - RW */
-#define E1000_TDPUWD 0x03584 /* DMA Tx Desc uC Data Write - RW */
-#define E1000_TDPURD 0x03588 /* DMA Tx Desc uC Data Read - RW */
-#define E1000_TDPUCTL 0x0358C /* DMA Tx Desc uC Control - RW */
-#define E1000_DTXCTL 0x03590 /* DMA Tx Control - RW */
-#define E1000_DTXTCPFLGL 0x0359C /* DMA Tx Control flag low - RW */
-#define E1000_DTXTCPFLGH 0x035A0 /* DMA Tx Control flag high - RW */
-/* DMA Tx Max Total Allow Size Reqs - RW */
-#define E1000_DTXMXSZRQ 0x03540
-#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
-#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
-#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
-#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
-#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
-#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
-#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
-#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
-#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
-#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
-#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
-#define E1000_COLC 0x04028 /* Collision Count - R/clr */
-#define E1000_DC 0x04030 /* Defer Count - R/clr */
-#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */
-#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
-#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
-#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
-#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */
-#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */
-#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */
-#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */
-#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */
-#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */
-#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */
-#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */
-#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */
-#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */
-#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */
-#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */
-#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */
-#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */
-#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */
-#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */
-#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */
-#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */
-#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */
-#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */
-#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */
-#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */
-#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */
-#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */
-#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */
-#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
-#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */
-#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */
-#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */
-#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */
-#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */
-#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */
-#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */
-#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */
-#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */
-#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */
-#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */
-#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */
-#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */
-#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */
-#define E1000_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */
-#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
-#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */
-#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
-#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Pkt Timer Expire Count */
-#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Abs Timer Expire Count */
-#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Pkt Timer Expire Count */
-#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Abs Timer Expire Count */
-#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
-#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */
-#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */
-#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
-
-/* Virtualization statistical counters */
-#define E1000_PFVFGPRC(_n) (0x010010 + (0x100 * (_n)))
-#define E1000_PFVFGPTC(_n) (0x010014 + (0x100 * (_n)))
-#define E1000_PFVFGORC(_n) (0x010018 + (0x100 * (_n)))
-#define E1000_PFVFGOTC(_n) (0x010034 + (0x100 * (_n)))
-#define E1000_PFVFMPRC(_n) (0x010038 + (0x100 * (_n)))
-#define E1000_PFVFGPRLBC(_n) (0x010040 + (0x100 * (_n)))
-#define E1000_PFVFGPTLBC(_n) (0x010044 + (0x100 * (_n)))
-#define E1000_PFVFGORLBC(_n) (0x010048 + (0x100 * (_n)))
-#define E1000_PFVFGOTLBC(_n) (0x010050 + (0x100 * (_n)))
-
-/* LinkSec */
-#define E1000_LSECTXUT 0x04300 /* Tx Untagged Pkt Cnt */
-#define E1000_LSECTXPKTE 0x04304 /* Encrypted Tx Pkts Cnt */
-#define E1000_LSECTXPKTP 0x04308 /* Protected Tx Pkt Cnt */
-#define E1000_LSECTXOCTE 0x0430C /* Encrypted Tx Octets Cnt */
-#define E1000_LSECTXOCTP 0x04310 /* Protected Tx Octets Cnt */
-#define E1000_LSECRXUT 0x04314 /* Untagged non-Strict Rx Pkt Cnt */
-#define E1000_LSECRXOCTD 0x0431C /* Rx Octets Decrypted Count */
-#define E1000_LSECRXOCTV 0x04320 /* Rx Octets Validated */
-#define E1000_LSECRXBAD 0x04324 /* Rx Bad Tag */
-#define E1000_LSECRXNOSCI 0x04328 /* Rx Packet No SCI Count */
-#define E1000_LSECRXUNSCI 0x0432C /* Rx Packet Unknown SCI Count */
-#define E1000_LSECRXUNCH 0x04330 /* Rx Unchecked Packets Count */
-#define E1000_LSECRXDELAY 0x04340 /* Rx Delayed Packet Count */
-#define E1000_LSECRXLATE 0x04350 /* Rx Late Packets Count */
-#define E1000_LSECRXOK(_n) (0x04360 + (0x04 * (_n))) /* Rx Pkt OK Cnt */
-#define E1000_LSECRXINV(_n) (0x04380 + (0x04 * (_n))) /* Rx Invalid Cnt */
-#define E1000_LSECRXNV(_n) (0x043A0 + (0x04 * (_n))) /* Rx Not Valid Cnt */
-#define E1000_LSECRXUNSA 0x043C0 /* Rx Unused SA Count */
-#define E1000_LSECRXNUSA 0x043D0 /* Rx Not Using SA Count */
-#define E1000_LSECTXCAP 0x0B000 /* Tx Capabilities Register - RO */
-#define E1000_LSECRXCAP 0x0B300 /* Rx Capabilities Register - RO */
-#define E1000_LSECTXCTRL 0x0B004 /* Tx Control - RW */
-#define E1000_LSECRXCTRL 0x0B304 /* Rx Control - RW */
-#define E1000_LSECTXSCL 0x0B008 /* Tx SCI Low - RW */
-#define E1000_LSECTXSCH 0x0B00C /* Tx SCI High - RW */
-#define E1000_LSECTXSA 0x0B010 /* Tx SA0 - RW */
-#define E1000_LSECTXPN0 0x0B018 /* Tx SA PN 0 - RW */
-#define E1000_LSECTXPN1 0x0B01C /* Tx SA PN 1 - RW */
-#define E1000_LSECRXSCL 0x0B3D0 /* Rx SCI Low - RW */
-#define E1000_LSECRXSCH 0x0B3E0 /* Rx SCI High - RW */
-/* LinkSec Tx 128-bit Key 0 - WO */
-#define E1000_LSECTXKEY0(_n) (0x0B020 + (0x04 * (_n)))
-/* LinkSec Tx 128-bit Key 1 - WO */
-#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n)))
-#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* Rx SAs - RW */
-#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* Rx SAs - RW */
-/* LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
- * key - RW.
- */
-#define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m)))
-
-#define E1000_SSVPC 0x041A0 /* Switch Security Violation Pkt Cnt */
-#define E1000_IPSCTRL 0xB430 /* IpSec Control Register */
-#define E1000_IPSRXCMD 0x0B408 /* IPSec Rx Command Register - RW */
-#define E1000_IPSRXIDX 0x0B400 /* IPSec Rx Index - RW */
-/* IPSec Rx IPv4/v6 Address - RW */
-#define E1000_IPSRXIPADDR(_n) (0x0B420 + (0x04 * (_n)))
-/* IPSec Rx 128-bit Key - RW */
-#define E1000_IPSRXKEY(_n) (0x0B410 + (0x04 * (_n)))
-#define E1000_IPSRXSALT 0x0B404 /* IPSec Rx Salt - RW */
-#define E1000_IPSRXSPI 0x0B40C /* IPSec Rx SPI - RW */
-/* IPSec Tx 128-bit Key - RW */
-#define E1000_IPSTXKEY(_n) (0x0B460 + (0x04 * (_n)))
-#define E1000_IPSTXSALT 0x0B454 /* IPSec Tx Salt - RW */
-#define E1000_IPSTXIDX 0x0B450 /* IPSec Tx SA IDX - RW */
-#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
-#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
-#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
-#define E1000_CBTMPC 0x0402C /* Circuit Breaker Tx Packet Count */
-#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */
-#define E1000_CBRDPC 0x04044 /* Circuit Breaker Rx Dropped Count */
-#define E1000_CBRMPC 0x040FC /* Circuit Breaker Rx Packet Count */
-#define E1000_RPTHC 0x04104 /* Rx Packets To Host */
-#define E1000_HGPTC 0x04118 /* Host Good Packets Tx Count */
-#define E1000_HTCBDPC 0x04124 /* Host Tx Circuit Breaker Dropped Count */
-#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */
-#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */
-#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
-#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
-#define E1000_LENERRS 0x04138 /* Length Errors Count */
-#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */
-#define E1000_HRMPC 0x0A018 /* Header Redirection Missed Packet Count */
-#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
-#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
-#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
-#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Pg - RW */
-#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
-#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */
-#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
-#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
-#define E1000_RA 0x05400 /* Receive Address - RW Array */
-#define E1000_RA2 0x054E0 /* 2nd half of Rx address array - RW Array */
-#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
-#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
-#define E1000_CIAA 0x05B88 /* Config Indirect Access Address - RW */
-#define E1000_CIAD 0x05B8C /* Config Indirect Access Data - RW */
-#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */
-#define E1000_VFQA1 0x0B200 /* VLAN Filter Queue Array 1 - RW Array */
-#define E1000_WUC 0x05800 /* Wakeup Control - RW */
-#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
-#define E1000_WUS 0x05810 /* Wakeup Status - RO */
-#define E1000_MANC 0x05820 /* Management Control - RW */
-#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
-#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
-#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
-#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
-#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
-#define E1000_PBACL 0x05B68 /* MSIx PBA Clear - Read/Write 1's to clear */
-#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
-#define E1000_HOST_IF 0x08800 /* Host Interface */
-#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
-#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
-#define E1000_HIBBA 0x8F40 /* Host Interface Buffer Base Address */
-/* Flexible Host Filter Table */
-#define E1000_FHFT(_n) (0x09000 + ((_n) * 0x100))
-/* Ext Flexible Host Filter Table */
-#define E1000_FHFT_EXT(_n) (0x09A00 + ((_n) * 0x100))
-
-
-#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
-#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
-/* Management Decision Filters */
-#define E1000_MDEF(_n) (0x05890 + (4 * (_n)))
-#define E1000_SW_FW_SYNC 0x05B5C /* SW-FW Synchronization - RW */
-#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
-#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
-#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
-#define E1000_GCR 0x05B00 /* PCI-Ex Control */
-#define E1000_GCR2 0x05B64 /* PCI-Ex Control #2 */
-#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
-#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
-#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
-#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
-#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
-#define E1000_SWSM 0x05B50 /* SW Semaphore */
-#define E1000_FWSM 0x05B54 /* FW Semaphore */
-/* Driver-only SW semaphore (not used by BOOT agents) */
-#define E1000_SWSM2 0x05B58
-#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
-#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
-#define E1000_UFUSE 0x05B78 /* UFUSE - RO */
-#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
-#define E1000_HICR 0x08F00 /* Host Interface Control */
-#define E1000_FWSTS 0x08F0C /* FW Status */
-
-/* RSS registers */
-#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
-#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
-#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
-#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/
-#define E1000_IMIRVP 0x05AC0 /* Immediate INT Rx VLAN Priority -RW */
-#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Alloc Reg -RW */
-#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
-#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
-#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
-#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
-/* VT Registers */
-#define E1000_SWPBS 0x03004 /* Switch Packet Buffer Size - RW */
-#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */
-#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */
-#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */
-#define E1000_VFRE 0x00C8C /* VF Receive Enables */
-#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
-#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
-#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
-#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */
-#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
-#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
-#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
-#define E1000_VMRCTL 0X05D80 /* Virtual Mirror Rule Control */
-#define E1000_VMRVLAN 0x05D90 /* Virtual Mirror Rule VLAN */
-#define E1000_VMRVM 0x05DA0 /* Virtual Mirror Rule VM */
-#define E1000_MDFB 0x03558 /* Malicious Driver free block */
-#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */
-#define E1000_TXSWC 0x05ACC /* Tx Switch Control */
-#define E1000_SCCRL 0x05DB0 /* Storm Control Control */
-#define E1000_BSCTRH 0x05DB8 /* Broadcast Storm Control Threshold */
-#define E1000_MSCTRH 0x05DBC /* Multicast Storm Control Threshold */
-/* These act per VF so an array friendly macro is used */
-#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n)))
-#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
-#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
-#define E1000_VFVMBMEM(_n) (0x00800 + (_n))
-#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
-/* VLAN Virtual Machine Filter - RW */
-#define E1000_VLVF(_n) (0x05D00 + (4 * (_n)))
-#define E1000_VMVIR(_n) (0x03700 + (4 * (_n)))
-#define E1000_DVMOLR(_n) (0x0C038 + (0x40 * (_n))) /* DMA VM offload */
-#define E1000_VTCTRL(_n) (0x10000 + (0x100 * (_n))) /* VT Control */
-#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
-#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
-#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
-#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
-#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
-#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */
-#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */
-#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
-#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
-#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
-#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
-#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
-#define E1000_TIMADJL 0x0B60C /* Time sync time adjustment offset Low - RW */
-#define E1000_TIMADJH 0x0B610 /* Time sync time adjustment offset High - RW */
-#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
-#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */
-#define E1000_TSICR 0x0B66C /* Interrupt Cause Register */
-#define E1000_TSIM 0x0B674 /* Interrupt Mask Register */
-
-/* Filtering Registers */
-#define E1000_SAQF(_n) (0x05980 + (4 * (_n))) /* Source Address Queue Fltr */
-#define E1000_DAQF(_n) (0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */
-#define E1000_SPQF(_n) (0x059C0 + (4 * (_n))) /* Source Port Queue Fltr */
-#define E1000_FTQF(_n) (0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */
-#define E1000_TTQF(_n) (0x059E0 + (4 * (_n))) /* 2-tuple Queue Fltr */
-#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
-#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
-
-#define E1000_RTTDCS 0x3600 /* Reedtown Tx Desc plane control and status */
-#define E1000_RTTPCS 0x3474 /* Reedtown Tx Packet Plane control and status */
-#define E1000_RTRPCS 0x2474 /* Rx packet plane control and status */
-#define E1000_RTRUP2TC 0x05AC4 /* Rx User Priority to Traffic Class */
-#define E1000_RTTUP2TC 0x0418 /* Transmit User Priority to Traffic Class */
-/* Tx Desc plane TC Rate-scheduler config */
-#define E1000_RTTDTCRC(_n) (0x3610 + ((_n) * 4))
-/* Tx Packet plane TC Rate-Scheduler Config */
-#define E1000_RTTPTCRC(_n) (0x3480 + ((_n) * 4))
-/* Rx Packet plane TC Rate-Scheduler Config */
-#define E1000_RTRPTCRC(_n) (0x2480 + ((_n) * 4))
-/* Tx Desc Plane TC Rate-Scheduler Status */
-#define E1000_RTTDTCRS(_n) (0x3630 + ((_n) * 4))
-/* Tx Desc Plane TC Rate-Scheduler MMW */
-#define E1000_RTTDTCRM(_n) (0x3650 + ((_n) * 4))
-/* Tx Packet plane TC Rate-Scheduler Status */
-#define E1000_RTTPTCRS(_n) (0x34A0 + ((_n) * 4))
-/* Tx Packet plane TC Rate-scheduler MMW */
-#define E1000_RTTPTCRM(_n) (0x34C0 + ((_n) * 4))
-/* Rx Packet plane TC Rate-Scheduler Status */
-#define E1000_RTRPTCRS(_n) (0x24A0 + ((_n) * 4))
-/* Rx Packet plane TC Rate-Scheduler MMW */
-#define E1000_RTRPTCRM(_n) (0x24C0 + ((_n) * 4))
-/* Tx Desc plane VM Rate-Scheduler MMW*/
-#define E1000_RTTDVMRM(_n) (0x3670 + ((_n) * 4))
-/* Tx BCN Rate-Scheduler MMW */
-#define E1000_RTTBCNRM(_n) (0x3690 + ((_n) * 4))
-#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select */
-#define E1000_RTTDVMRC 0x3608 /* Tx Desc Plane VM Rate-Scheduler Config */
-#define E1000_RTTDVMRS 0x360C /* Tx Desc Plane VM Rate-Scheduler Status */
-#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config */
-#define E1000_RTTBCNRS 0x36B4 /* Tx BCN Rate-Scheduler Status */
-#define E1000_RTTBCNCR 0xB200 /* Tx BCN Control Register */
-#define E1000_RTTBCNTG 0x35A4 /* Tx BCN Tagging */
-#define E1000_RTTBCNCP 0xB208 /* Tx BCN Congestion point */
-#define E1000_RTRBCNCR 0xB20C /* Rx BCN Control Register */
-#define E1000_RTTBCNRD 0x36B8 /* Tx BCN Rate Drift */
-#define E1000_PFCTOP 0x1080 /* Priority Flow Control Type and Opcode */
-#define E1000_RTTBCNIDX 0xB204 /* Tx BCN Congestion Point */
-#define E1000_RTTBCNACH 0x0B214 /* Tx BCN Control High */
-#define E1000_RTTBCNACL 0x0B210 /* Tx BCN Control Low */
-
-/* DMA Coalescing registers */
-#define E1000_DMACR 0x02508 /* Control Register */
-#define E1000_DMCTXTH 0x03550 /* Transmit Threshold */
-#define E1000_DMCTLX 0x02514 /* Time to Lx Request */
-#define E1000_DMCRTRH 0x05DD0 /* Receive Packet Rate Threshold */
-#define E1000_DMCCNT 0x05DD4 /* Current Rx Count */
-#define E1000_FCRTC 0x02170 /* Flow Control Rx high watermark */
-#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */
-
-/* PCIe Parity Status Register */
-#define E1000_PCIEERRSTS 0x05BA8
-
-#define E1000_PROXYS 0x5F64 /* Proxying Status */
-#define E1000_PROXYFC 0x5F60 /* Proxying Filter Control */
-/* Thermal sensor configuration and status registers */
-#define E1000_THMJT 0x08100 /* Junction Temperature */
-#define E1000_THLOWTC 0x08104 /* Low Threshold Control */
-#define E1000_THMIDTC 0x08108 /* Mid Threshold Control */
-#define E1000_THHIGHTC 0x0810C /* High Threshold Control */
-#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */
-
-/* Energy Efficient Ethernet "EEE" registers */
-#define E1000_IPCNFG 0x0E38 /* Internal PHY Configuration */
-#define E1000_LTRC 0x01A0 /* Latency Tolerance Reporting Control */
-#define E1000_EEER 0x0E30 /* Energy Efficient Ethernet "EEE"*/
-#define E1000_EEE_SU 0x0E34 /* EEE Setup */
-#define E1000_TLPIC 0x4148 /* EEE Tx LPI Count - TLPIC */
-#define E1000_RLPIC 0x414C /* EEE Rx LPI Count - RLPIC */
-
-/* OS2BMC Registers */
-#define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */
-#define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */
-#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
-#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */
-
-
-
-#endif
diff --git a/kernel/linux/kni/ethtool/igb/igb.h b/kernel/linux/kni/ethtool/igb/igb.h
deleted file mode 100644
index 8aa2a3088..000000000
--- a/kernel/linux/kni/ethtool/igb/igb.h
+++ /dev/null
@@ -1,844 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/* Linux PRO/1000 Ethernet Driver main header file */
-
-#ifndef _IGB_H_
-#define _IGB_H_
-
-#include <linux/kobject.h>
-
-#ifndef IGB_NO_LRO
-#include <net/tcp.h>
-#endif
-
-#undef HAVE_HW_TIME_STAMP
-#ifdef HAVE_HW_TIME_STAMP
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/vmalloc.h>
-
-#endif
-#ifdef SIOCETHTOOL
-#include <linux/ethtool.h>
-#endif
-
-struct igb_adapter;
-
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
-//#define IGB_DCA
-#endif
-#ifdef IGB_DCA
-#include <linux/dca.h>
-#endif
-
-#include "kcompat.h"
-
-#ifdef HAVE_SCTP
-#include <linux/sctp.h>
-#endif
-
-#include "e1000_api.h"
-#include "e1000_82575.h"
-#include "e1000_manage.h"
-#include "e1000_mbx.h"
-
-#define IGB_ERR(args...) printk(KERN_ERR "igb: " args)
-
-#define PFX "igb: "
-#define DPRINTK(nlevel, klevel, fmt, args...) \
- (void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
- printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
- __FUNCTION__ , ## args))
-
-#ifdef HAVE_PTP_1588_CLOCK
-#include <linux/clocksource.h>
-#include <linux/net_tstamp.h>
-#include <linux/ptp_clock_kernel.h>
-#endif /* HAVE_PTP_1588_CLOCK */
-
-#ifdef HAVE_I2C_SUPPORT
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#endif /* HAVE_I2C_SUPPORT */
-
-/* Interrupt defines */
-#define IGB_START_ITR 648 /* ~6000 ints/sec */
-#define IGB_4K_ITR 980
-#define IGB_20K_ITR 196
-#define IGB_70K_ITR 56
-
-/* Interrupt modes, as used by the IntMode parameter */
-#define IGB_INT_MODE_LEGACY 0
-#define IGB_INT_MODE_MSI 1
-#define IGB_INT_MODE_MSIX 2
-
-/* TX/RX descriptor defines */
-#define IGB_DEFAULT_TXD 256
-#define IGB_DEFAULT_TX_WORK 128
-#define IGB_MIN_TXD 80
-#define IGB_MAX_TXD 4096
-
-#define IGB_DEFAULT_RXD 256
-#define IGB_MIN_RXD 80
-#define IGB_MAX_RXD 4096
-
-#define IGB_MIN_ITR_USECS 10 /* 100k irq/sec */
-#define IGB_MAX_ITR_USECS 8191 /* 120 irq/sec */
-
-#define NON_Q_VECTORS 1
-#define MAX_Q_VECTORS 10
-
-/* Transmit and receive queues */
-#define IGB_MAX_RX_QUEUES 16
-#define IGB_MAX_TX_QUEUES 16
-
-#define IGB_MAX_VF_MC_ENTRIES 30
-#define IGB_MAX_VF_FUNCTIONS 8
-#define IGB_82576_VF_DEV_ID 0x10CA
-#define IGB_I350_VF_DEV_ID 0x1520
-#define IGB_MAX_UTA_ENTRIES 128
-#define MAX_EMULATION_MAC_ADDRS 16
-#define OUI_LEN 3
-#define IGB_MAX_VMDQ_QUEUES 8
-
-
-struct vf_data_storage {
- unsigned char vf_mac_addresses[ETH_ALEN];
- u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
- u16 num_vf_mc_hashes;
- u16 default_vf_vlan_id;
- u16 vlans_enabled;
- unsigned char em_mac_addresses[MAX_EMULATION_MAC_ADDRS * ETH_ALEN];
- u32 uta_table_copy[IGB_MAX_UTA_ENTRIES];
- u32 flags;
- unsigned long last_nack;
-#ifdef IFLA_VF_MAX
- u16 pf_vlan; /* When set, guest VLAN config not allowed. */
- u16 pf_qos;
- u16 tx_rate;
-#ifdef HAVE_VF_SPOOFCHK_CONFIGURE
- bool spoofchk_enabled;
-#endif
-#endif
-};
-
-#define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */
-#define IGB_VF_FLAG_UNI_PROMISC 0x00000002 /* VF has unicast promisc */
-#define IGB_VF_FLAG_MULTI_PROMISC 0x00000004 /* VF has multicast promisc */
-#define IGB_VF_FLAG_PF_SET_MAC 0x00000008 /* PF has set MAC address */
-
-/* RX descriptor control thresholds.
- * PTHRESH - MAC will consider prefetch if it has fewer than this number of
- * descriptors available in its onboard memory.
- * Setting this to 0 disables RX descriptor prefetch.
- * HTHRESH - MAC will only prefetch if there are at least this many descriptors
- * available in host memory.
- * If PTHRESH is 0, this should also be 0.
- * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
- * descriptors until either it has this many to write back, or the
- * ITR timer expires.
- */
-#define IGB_RX_PTHRESH ((hw->mac.type == e1000_i354) ? 12 : 8)
-#define IGB_RX_HTHRESH 8
-#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8)
-#define IGB_TX_HTHRESH 1
-#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \
- adapter->msix_entries) ? 1 : 4)
-
-/* this is the size past which hardware will drop packets when setting LPE=0 */
-#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
-
-/* NOTE: netdev_alloc_skb reserves 16 bytes, NET_IP_ALIGN means we
- * reserve 2 more, and skb_shared_info adds an additional 384 more,
- * this adds roughly 448 bytes of extra data meaning the smallest
- * allocation we could have is 1K.
- * i.e. RXBUFFER_512 --> size-1024 slab
- */
-/* Supported Rx Buffer Sizes */
-#define IGB_RXBUFFER_256 256
-#define IGB_RXBUFFER_2048 2048
-#define IGB_RXBUFFER_16384 16384
-#define IGB_RX_HDR_LEN IGB_RXBUFFER_256
-#if MAX_SKB_FRAGS < 8
-#define IGB_RX_BUFSZ ALIGN(MAX_JUMBO_FRAME_SIZE / MAX_SKB_FRAGS, 1024)
-#else
-#define IGB_RX_BUFSZ IGB_RXBUFFER_2048
-#endif
-
-
-/* Packet Buffer allocations */
-#define IGB_PBA_BYTES_SHIFT 0xA
-#define IGB_TX_HEAD_ADDR_SHIFT 7
-#define IGB_PBA_TX_MASK 0xFFFF0000
-
-#define IGB_FC_PAUSE_TIME 0x0680 /* 858 usec */
-
-/* How many Rx Buffers do we bundle into one write to the hardware ? */
-#define IGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */
-
-#define IGB_EEPROM_APME 0x0400
-#define AUTO_ALL_MODES 0
-
-#ifndef IGB_MASTER_SLAVE
-/* Switch to override PHY master/slave setting */
-#define IGB_MASTER_SLAVE e1000_ms_hw_default
-#endif
-
-#define IGB_MNG_VLAN_NONE -1
-
-#ifndef IGB_NO_LRO
-#define IGB_LRO_MAX 32 /*Maximum number of LRO descriptors*/
-struct igb_lro_stats {
- u32 flushed;
- u32 coal;
-};
-
-/*
- * igb_lro_header - header format to be aggregated by LRO
- * @iph: IP header without options
- * @tcp: TCP header
- * @ts: Optional TCP timestamp data in TCP options
- *
- * This structure relies on the check above that verifies that the header
- * is IPv4 and does not contain any options.
- */
-struct igb_lrohdr {
- struct iphdr iph;
- struct tcphdr th;
- __be32 ts[0];
-};
-
-struct igb_lro_list {
- struct sk_buff_head active;
- struct igb_lro_stats stats;
-};
-
-#endif /* IGB_NO_LRO */
-struct igb_cb {
-#ifndef IGB_NO_LRO
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- union { /* Union defining head/tail partner */
- struct sk_buff *head;
- struct sk_buff *tail;
- };
-#endif
- __be32 tsecr; /* timestamp echo response */
- u32 tsval; /* timestamp value in host order */
- u32 next_seq; /* next expected sequence number */
- u16 free; /* 65521 minus total size */
- u16 mss; /* size of data portion of packet */
- u16 append_cnt; /* number of skb's appended */
-#endif /* IGB_NO_LRO */
-#ifdef HAVE_VLAN_RX_REGISTER
- u16 vid; /* VLAN tag */
-#endif
-};
-#define IGB_CB(skb) ((struct igb_cb *)(skb)->cb)
-
-enum igb_tx_flags {
- /* cmd_type flags */
- IGB_TX_FLAGS_VLAN = 0x01,
- IGB_TX_FLAGS_TSO = 0x02,
- IGB_TX_FLAGS_TSTAMP = 0x04,
-
- /* olinfo flags */
- IGB_TX_FLAGS_IPV4 = 0x10,
- IGB_TX_FLAGS_CSUM = 0x20,
-};
-
-/* VLAN info */
-#define IGB_TX_FLAGS_VLAN_MASK 0xffff0000
-#define IGB_TX_FLAGS_VLAN_SHIFT 16
-
-/*
- * The largest size we can write to the descriptor is 65535. In order to
- * maintain a power of two alignment we have to limit ourselves to 32K.
- */
-#define IGB_MAX_TXD_PWR 15
-#define IGB_MAX_DATA_PER_TXD (1 << IGB_MAX_TXD_PWR)
-
-/* Tx Descriptors needed, worst case */
-#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IGB_MAX_DATA_PER_TXD)
-#ifndef MAX_SKB_FRAGS
-#define DESC_NEEDED 4
-#elif (MAX_SKB_FRAGS < 16)
-#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4)
-#else
-#define DESC_NEEDED (MAX_SKB_FRAGS + 4)
-#endif
-
-/* wrapper around a pointer to a socket buffer,
- * so a DMA handle can be stored along with the buffer */
-struct igb_tx_buffer {
- union e1000_adv_tx_desc *next_to_watch;
- unsigned long time_stamp;
- struct sk_buff *skb;
- unsigned int bytecount;
- u16 gso_segs;
- __be16 protocol;
- DEFINE_DMA_UNMAP_ADDR(dma);
- DEFINE_DMA_UNMAP_LEN(len);
- u32 tx_flags;
-};
-
-struct igb_rx_buffer {
- dma_addr_t dma;
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- struct sk_buff *skb;
-#else
- struct page *page;
- u32 page_offset;
-#endif
-};
-
-struct igb_tx_queue_stats {
- u64 packets;
- u64 bytes;
- u64 restart_queue;
-};
-
-struct igb_rx_queue_stats {
- u64 packets;
- u64 bytes;
- u64 drops;
- u64 csum_err;
- u64 alloc_failed;
- u64 ipv4_packets; /* IPv4 headers processed */
- u64 ipv4e_packets; /* IPv4E headers with extensions processed */
- u64 ipv6_packets; /* IPv6 headers processed */
- u64 ipv6e_packets; /* IPv6E headers with extensions processed */
- u64 tcp_packets; /* TCP headers processed */
- u64 udp_packets; /* UDP headers processed */
- u64 sctp_packets; /* SCTP headers processed */
- u64 nfs_packets; /* NFS headers processe */
-};
-
-struct igb_ring_container {
- struct igb_ring *ring; /* pointer to linked list of rings */
- unsigned int total_bytes; /* total bytes processed this int */
- unsigned int total_packets; /* total packets processed this int */
- u16 work_limit; /* total work allowed per interrupt */
- u8 count; /* total number of rings in vector */
- u8 itr; /* current ITR setting for ring */
-};
-
-struct igb_ring {
- struct igb_q_vector *q_vector; /* backlink to q_vector */
- struct net_device *netdev; /* back pointer to net_device */
- struct device *dev; /* device for dma mapping */
- union { /* array of buffer info structs */
- struct igb_tx_buffer *tx_buffer_info;
- struct igb_rx_buffer *rx_buffer_info;
- };
-#ifdef HAVE_PTP_1588_CLOCK
- unsigned long last_rx_timestamp;
-#endif /* HAVE_PTP_1588_CLOCK */
- void *desc; /* descriptor ring memory */
- unsigned long flags; /* ring specific flags */
- void __iomem *tail; /* pointer to ring tail register */
- dma_addr_t dma; /* phys address of the ring */
- unsigned int size; /* length of desc. ring in bytes */
-
- u16 count; /* number of desc. in the ring */
- u8 queue_index; /* logical index of the ring*/
- u8 reg_idx; /* physical index of the ring */
-
- /* everything past this point are written often */
- u16 next_to_clean;
- u16 next_to_use;
- u16 next_to_alloc;
-
- union {
- /* TX */
- struct {
- struct igb_tx_queue_stats tx_stats;
- };
- /* RX */
- struct {
- struct igb_rx_queue_stats rx_stats;
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- u16 rx_buffer_len;
-#else
- struct sk_buff *skb;
-#endif
- };
- };
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- struct net_device *vmdq_netdev;
- int vqueue_index; /* queue index for virtual netdev */
-#endif
-} ____cacheline_internodealigned_in_smp;
-
-struct igb_q_vector {
- struct igb_adapter *adapter; /* backlink */
- int cpu; /* CPU for DCA */
- u32 eims_value; /* EIMS mask value */
-
- u16 itr_val;
- u8 set_itr;
- void __iomem *itr_register;
-
- struct igb_ring_container rx, tx;
-
- struct napi_struct napi;
-#ifndef IGB_NO_LRO
- struct igb_lro_list lrolist; /* LRO list for queue vector*/
-#endif
- char name[IFNAMSIZ + 9];
-#ifndef HAVE_NETDEV_NAPI_LIST
- struct net_device poll_dev;
-#endif
-
- /* for dynamic allocation of rings associated with this q_vector */
- struct igb_ring ring[0] ____cacheline_internodealigned_in_smp;
-};
-
-enum e1000_ring_flags_t {
-#ifndef HAVE_NDO_SET_FEATURES
- IGB_RING_FLAG_RX_CSUM,
-#endif
- IGB_RING_FLAG_RX_SCTP_CSUM,
- IGB_RING_FLAG_RX_LB_VLAN_BSWAP,
- IGB_RING_FLAG_TX_CTX_IDX,
- IGB_RING_FLAG_TX_DETECT_HANG,
-};
-
-struct igb_mac_addr {
- u8 addr[ETH_ALEN];
- u16 queue;
- u16 state; /* bitmask */
-};
-#define IGB_MAC_STATE_DEFAULT 0x1
-#define IGB_MAC_STATE_MODIFIED 0x2
-#define IGB_MAC_STATE_IN_USE 0x4
-
-#define IGB_TXD_DCMD (E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS)
-
-#define IGB_RX_DESC(R, i) \
- (&(((union e1000_adv_rx_desc *)((R)->desc))[i]))
-#define IGB_TX_DESC(R, i) \
- (&(((union e1000_adv_tx_desc *)((R)->desc))[i]))
-#define IGB_TX_CTXTDESC(R, i) \
- (&(((struct e1000_adv_tx_context_desc *)((R)->desc))[i]))
-
-#ifdef CONFIG_IGB_VMDQ_NETDEV
-#define netdev_ring(ring) \
- ((ring->vmdq_netdev ? ring->vmdq_netdev : ring->netdev))
-#define ring_queue_index(ring) \
- ((ring->vmdq_netdev ? ring->vqueue_index : ring->queue_index))
-#else
-#define netdev_ring(ring) (ring->netdev)
-#define ring_queue_index(ring) (ring->queue_index)
-#endif /* CONFIG_IGB_VMDQ_NETDEV */
-
-/* igb_test_staterr - tests bits within Rx descriptor status and error fields */
-static inline __le32 igb_test_staterr(union e1000_adv_rx_desc *rx_desc,
- const u32 stat_err_bits)
-{
- return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits);
-}
-
-/* igb_desc_unused - calculate if we have unused descriptors */
-static inline u16 igb_desc_unused(const struct igb_ring *ring)
-{
- u16 ntc = ring->next_to_clean;
- u16 ntu = ring->next_to_use;
-
- return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
-}
-
-#ifdef CONFIG_BQL
-static inline struct netdev_queue *txring_txq(const struct igb_ring *tx_ring)
-{
- return netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
-}
-#endif /* CONFIG_BQL */
-
-// #ifdef EXT_THERMAL_SENSOR_SUPPORT
-// #ifdef IGB_PROCFS
-struct igb_therm_proc_data
-{
- struct e1000_hw *hw;
- struct e1000_thermal_diode_data *sensor_data;
-};
-
-// #endif /* IGB_PROCFS */
-// #endif /* EXT_THERMAL_SENSOR_SUPPORT */
-
-#ifdef IGB_HWMON
-#define IGB_HWMON_TYPE_LOC 0
-#define IGB_HWMON_TYPE_TEMP 1
-#define IGB_HWMON_TYPE_CAUTION 2
-#define IGB_HWMON_TYPE_MAX 3
-
-struct hwmon_attr {
- struct device_attribute dev_attr;
- struct e1000_hw *hw;
- struct e1000_thermal_diode_data *sensor;
- char name[12];
- };
-
-struct hwmon_buff {
- struct device *device;
- struct hwmon_attr *hwmon_list;
- unsigned int n_hwmon;
- };
-#endif /* IGB_HWMON */
-
-/* board specific private data structure */
-struct igb_adapter {
-#ifdef HAVE_VLAN_RX_REGISTER
- /* vlgrp must be first member of structure */
- struct vlan_group *vlgrp;
-#else
- unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
-#endif
- struct net_device *netdev;
-
- unsigned long state;
- unsigned int flags;
-
- unsigned int num_q_vectors;
- struct msix_entry *msix_entries;
-
-
- /* TX */
- u16 tx_work_limit;
- u32 tx_timeout_count;
- int num_tx_queues;
- struct igb_ring *tx_ring[IGB_MAX_TX_QUEUES];
-
- /* RX */
- int num_rx_queues;
- struct igb_ring *rx_ring[IGB_MAX_RX_QUEUES];
-
- struct timer_list watchdog_timer;
- struct timer_list dma_err_timer;
- struct timer_list phy_info_timer;
- u16 mng_vlan_id;
- u32 bd_number;
- u32 wol;
- u32 en_mng_pt;
- u16 link_speed;
- u16 link_duplex;
- u8 port_num;
-
- /* Interrupt Throttle Rate */
- u32 rx_itr_setting;
- u32 tx_itr_setting;
-
- struct work_struct reset_task;
- struct work_struct watchdog_task;
- struct work_struct dma_err_task;
- bool fc_autoneg;
- u8 tx_timeout_factor;
-
-#ifdef DEBUG
- bool tx_hang_detected;
- bool disable_hw_reset;
-#endif
- u32 max_frame_size;
-
- /* OS defined structs */
- struct pci_dev *pdev;
-#ifndef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats net_stats;
-#endif
-#ifndef IGB_NO_LRO
- struct igb_lro_stats lro_stats;
-#endif
-
- /* structs defined in e1000_hw.h */
- struct e1000_hw hw;
- struct e1000_hw_stats stats;
- struct e1000_phy_info phy_info;
- struct e1000_phy_stats phy_stats;
-
-#ifdef ETHTOOL_TEST
- u32 test_icr;
- struct igb_ring test_tx_ring;
- struct igb_ring test_rx_ring;
-#endif
-
- int msg_enable;
-
- struct igb_q_vector *q_vector[MAX_Q_VECTORS];
- u32 eims_enable_mask;
- u32 eims_other;
-
- /* to not mess up cache alignment, always add to the bottom */
- u32 *config_space;
- u16 tx_ring_count;
- u16 rx_ring_count;
- struct vf_data_storage *vf_data;
-#ifdef IFLA_VF_MAX
- int vf_rate_link_speed;
-#endif
- u32 lli_port;
- u32 lli_size;
- unsigned int vfs_allocated_count;
- /* Malicious Driver Detection flag. Valid only when SR-IOV is enabled */
- bool mdd;
- int int_mode;
- u32 rss_queues;
- u32 vmdq_pools;
- char fw_version[43];
- u32 wvbr;
- struct igb_mac_addr *mac_table;
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- struct net_device *vmdq_netdev[IGB_MAX_VMDQ_QUEUES];
-#endif
- int vferr_refcount;
- int dmac;
- u32 *shadow_vfta;
-
- /* External Thermal Sensor support flag */
- bool ets;
-#ifdef IGB_HWMON
- struct hwmon_buff igb_hwmon_buff;
-#else /* IGB_HWMON */
-#ifdef IGB_PROCFS
- struct proc_dir_entry *eth_dir;
- struct proc_dir_entry *info_dir;
- struct proc_dir_entry *therm_dir[E1000_MAX_SENSORS];
- struct igb_therm_proc_data therm_data[E1000_MAX_SENSORS];
- bool old_lsc;
-#endif /* IGB_PROCFS */
-#endif /* IGB_HWMON */
- u32 etrack_id;
-
-#ifdef HAVE_PTP_1588_CLOCK
- struct ptp_clock *ptp_clock;
- struct ptp_clock_info ptp_caps;
- struct delayed_work ptp_overflow_work;
- struct work_struct ptp_tx_work;
- struct sk_buff *ptp_tx_skb;
- unsigned long ptp_tx_start;
- unsigned long last_rx_ptp_check;
- spinlock_t tmreg_lock;
- struct cyclecounter cc;
- struct timecounter tc;
- u32 tx_hwtstamp_timeouts;
- u32 rx_hwtstamp_cleared;
-#endif /* HAVE_PTP_1588_CLOCK */
-
-#ifdef HAVE_I2C_SUPPORT
- struct i2c_algo_bit_data i2c_algo;
- struct i2c_adapter i2c_adap;
- struct i2c_client *i2c_client;
-#endif /* HAVE_I2C_SUPPORT */
- unsigned long link_check_timeout;
-
-
- int devrc;
-
- int copper_tries;
- u16 eee_advert;
-};
-
-#ifdef CONFIG_IGB_VMDQ_NETDEV
-struct igb_vmdq_adapter {
-#ifdef HAVE_VLAN_RX_REGISTER
- /* vlgrp must be first member of structure */
- struct vlan_group *vlgrp;
-#else
- unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
-#endif
- struct igb_adapter *real_adapter;
- struct net_device *vnetdev;
- struct net_device_stats net_stats;
- struct igb_ring *tx_ring;
- struct igb_ring *rx_ring;
-};
-#endif
-
-#define IGB_FLAG_HAS_MSI (1 << 0)
-#define IGB_FLAG_DCA_ENABLED (1 << 1)
-#define IGB_FLAG_LLI_PUSH (1 << 2)
-#define IGB_FLAG_QUAD_PORT_A (1 << 3)
-#define IGB_FLAG_QUEUE_PAIRS (1 << 4)
-#define IGB_FLAG_EEE (1 << 5)
-#define IGB_FLAG_DMAC (1 << 6)
-#define IGB_FLAG_DETECT_BAD_DMA (1 << 7)
-#define IGB_FLAG_PTP (1 << 8)
-#define IGB_FLAG_RSS_FIELD_IPV4_UDP (1 << 9)
-#define IGB_FLAG_RSS_FIELD_IPV6_UDP (1 << 10)
-#define IGB_FLAG_WOL_SUPPORTED (1 << 11)
-#define IGB_FLAG_NEED_LINK_UPDATE (1 << 12)
-#define IGB_FLAG_LOOPBACK_ENABLE (1 << 13)
-#define IGB_FLAG_MEDIA_RESET (1 << 14)
-#define IGB_FLAG_MAS_ENABLE (1 << 15)
-
-/* Media Auto Sense */
-#define IGB_MAS_ENABLE_0 0X0001
-#define IGB_MAS_ENABLE_1 0X0002
-#define IGB_MAS_ENABLE_2 0X0004
-#define IGB_MAS_ENABLE_3 0X0008
-
-#define IGB_MIN_TXPBSIZE 20408
-#define IGB_TX_BUF_4096 4096
-
-#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coal Flush */
-
-/* DMA Coalescing defines */
-#define IGB_DMAC_DISABLE 0
-#define IGB_DMAC_MIN 250
-#define IGB_DMAC_500 500
-#define IGB_DMAC_EN_DEFAULT 1000
-#define IGB_DMAC_2000 2000
-#define IGB_DMAC_3000 3000
-#define IGB_DMAC_4000 4000
-#define IGB_DMAC_5000 5000
-#define IGB_DMAC_6000 6000
-#define IGB_DMAC_7000 7000
-#define IGB_DMAC_8000 8000
-#define IGB_DMAC_9000 9000
-#define IGB_DMAC_MAX 10000
-
-#define IGB_82576_TSYNC_SHIFT 19
-#define IGB_82580_TSYNC_SHIFT 24
-#define IGB_TS_HDR_LEN 16
-
-/* CEM Support */
-#define FW_HDR_LEN 0x4
-#define FW_CMD_DRV_INFO 0xDD
-#define FW_CMD_DRV_INFO_LEN 0x5
-#define FW_CMD_RESERVED 0X0
-#define FW_RESP_SUCCESS 0x1
-#define FW_UNUSED_VER 0x0
-#define FW_MAX_RETRIES 3
-#define FW_STATUS_SUCCESS 0x1
-#define FW_FAMILY_DRV_VER 0Xffffffff
-
-#define IGB_MAX_LINK_TRIES 20
-
-struct e1000_fw_hdr {
- u8 cmd;
- u8 buf_len;
- union
- {
- u8 cmd_resv;
- u8 ret_status;
- } cmd_or_resp;
- u8 checksum;
-};
-
-#pragma pack(push,1)
-struct e1000_fw_drv_info {
- struct e1000_fw_hdr hdr;
- u8 port_num;
- u32 drv_version;
- u16 pad; /* end spacing to ensure length is mult. of dword */
- u8 pad2; /* end spacing to ensure length is mult. of dword2 */
-};
-#pragma pack(pop)
-
-enum e1000_state_t {
- __IGB_TESTING,
- __IGB_RESETTING,
- __IGB_DOWN
-};
-
-extern char igb_driver_name[];
-extern char igb_driver_version[];
-
-extern int igb_up(struct igb_adapter *);
-extern void igb_down(struct igb_adapter *);
-extern void igb_reinit_locked(struct igb_adapter *);
-extern void igb_reset(struct igb_adapter *);
-extern int igb_set_spd_dplx(struct igb_adapter *, u16);
-extern int igb_setup_tx_resources(struct igb_ring *);
-extern int igb_setup_rx_resources(struct igb_ring *);
-extern void igb_free_tx_resources(struct igb_ring *);
-extern void igb_free_rx_resources(struct igb_ring *);
-extern void igb_configure_tx_ring(struct igb_adapter *, struct igb_ring *);
-extern void igb_configure_rx_ring(struct igb_adapter *, struct igb_ring *);
-extern void igb_setup_tctl(struct igb_adapter *);
-extern void igb_setup_rctl(struct igb_adapter *);
-extern netdev_tx_t igb_xmit_frame_ring(struct sk_buff *, struct igb_ring *);
-extern void igb_unmap_and_free_tx_resource(struct igb_ring *,
- struct igb_tx_buffer *);
-extern void igb_alloc_rx_buffers(struct igb_ring *, u16);
-extern void igb_clean_rx_ring(struct igb_ring *);
-extern void igb_update_stats(struct igb_adapter *);
-extern bool igb_has_link(struct igb_adapter *adapter);
-extern void igb_set_ethtool_ops(struct net_device *);
-extern void igb_check_options(struct igb_adapter *);
-extern void igb_power_up_link(struct igb_adapter *);
-#ifdef HAVE_PTP_1588_CLOCK
-extern void igb_ptp_init(struct igb_adapter *adapter);
-extern void igb_ptp_stop(struct igb_adapter *adapter);
-extern void igb_ptp_reset(struct igb_adapter *adapter);
-extern void igb_ptp_tx_work(struct work_struct *work);
-extern void igb_ptp_rx_hang(struct igb_adapter *adapter);
-extern void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter);
-extern void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector,
- struct sk_buff *skb);
-extern void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector,
- unsigned char *va,
- struct sk_buff *skb);
-static inline void igb_ptp_rx_hwtstamp(struct igb_ring *rx_ring,
- union e1000_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
- if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb);
- skb_pull(skb, IGB_TS_HDR_LEN);
-#endif
- return;
- }
-
- if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TS))
- igb_ptp_rx_rgtstamp(rx_ring->q_vector, skb);
-
- /* Update the last_rx_timestamp timer in order to enable watchdog check
- * for error case of latched timestamp on a dropped packet.
- */
- rx_ring->last_rx_timestamp = jiffies;
-}
-
-extern int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
- struct ifreq *ifr, int cmd);
-#endif /* HAVE_PTP_1588_CLOCK */
-#ifdef ETHTOOL_OPS_COMPAT
-extern int ethtool_ioctl(struct ifreq *);
-#endif
-extern int igb_write_mc_addr_list(struct net_device *netdev);
-extern int igb_add_mac_filter(struct igb_adapter *adapter, u8 *addr, u16 queue);
-extern int igb_del_mac_filter(struct igb_adapter *adapter, u8* addr, u16 queue);
-extern int igb_available_rars(struct igb_adapter *adapter);
-extern s32 igb_vlvf_set(struct igb_adapter *, u32, bool, u32);
-extern void igb_configure_vt_default_pool(struct igb_adapter *adapter);
-extern void igb_enable_vlan_tags(struct igb_adapter *adapter);
-#ifndef HAVE_VLAN_RX_REGISTER
-extern void igb_vlan_mode(struct net_device *, u32);
-#endif
-
-#define E1000_PCS_CFG_IGN_SD 1
-
-#ifdef IGB_HWMON
-void igb_sysfs_exit(struct igb_adapter *adapter);
-int igb_sysfs_init(struct igb_adapter *adapter);
-#else
-#ifdef IGB_PROCFS
-int igb_procfs_init(struct igb_adapter* adapter);
-void igb_procfs_exit(struct igb_adapter* adapter);
-int igb_procfs_topdir_init(void);
-void igb_procfs_topdir_exit(void);
-#endif /* IGB_PROCFS */
-#endif /* IGB_HWMON */
-
-
-
-#endif /* _IGB_H_ */
diff --git a/kernel/linux/kni/ethtool/igb/igb_ethtool.c b/kernel/linux/kni/ethtool/igb/igb_ethtool.c
deleted file mode 100644
index b6bddc025..000000000
--- a/kernel/linux/kni/ethtool/igb/igb_ethtool.c
+++ /dev/null
@@ -1,2851 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/* ethtool support for igb */
-
-#include <linux/netdevice.h>
-#include <linux/vmalloc.h>
-
-#ifdef SIOCETHTOOL
-#include <linux/ethtool.h>
-#ifdef CONFIG_PM_RUNTIME
-#include <linux/pm_runtime.h>
-#endif /* CONFIG_PM_RUNTIME */
-#include <linux/highmem.h>
-
-#include "igb.h"
-#include "igb_regtest.h"
-#include <linux/if_vlan.h>
-#ifdef ETHTOOL_GEEE
-#include <linux/mdio.h>
-#endif
-
-#ifdef ETHTOOL_OPS_COMPAT
-#include "kcompat_ethtool.c"
-#endif
-#ifdef ETHTOOL_GSTATS
-struct igb_stats {
- char stat_string[ETH_GSTRING_LEN];
- int sizeof_stat;
- int stat_offset;
-};
-
-#define IGB_STAT(_name, _stat) { \
- .stat_string = _name, \
- .sizeof_stat = FIELD_SIZEOF(struct igb_adapter, _stat), \
- .stat_offset = offsetof(struct igb_adapter, _stat) \
-}
-static const struct igb_stats igb_gstrings_stats[] = {
- IGB_STAT("rx_packets", stats.gprc),
- IGB_STAT("tx_packets", stats.gptc),
- IGB_STAT("rx_bytes", stats.gorc),
- IGB_STAT("tx_bytes", stats.gotc),
- IGB_STAT("rx_broadcast", stats.bprc),
- IGB_STAT("tx_broadcast", stats.bptc),
- IGB_STAT("rx_multicast", stats.mprc),
- IGB_STAT("tx_multicast", stats.mptc),
- IGB_STAT("multicast", stats.mprc),
- IGB_STAT("collisions", stats.colc),
- IGB_STAT("rx_crc_errors", stats.crcerrs),
- IGB_STAT("rx_no_buffer_count", stats.rnbc),
- IGB_STAT("rx_missed_errors", stats.mpc),
- IGB_STAT("tx_aborted_errors", stats.ecol),
- IGB_STAT("tx_carrier_errors", stats.tncrs),
- IGB_STAT("tx_window_errors", stats.latecol),
- IGB_STAT("tx_abort_late_coll", stats.latecol),
- IGB_STAT("tx_deferred_ok", stats.dc),
- IGB_STAT("tx_single_coll_ok", stats.scc),
- IGB_STAT("tx_multi_coll_ok", stats.mcc),
- IGB_STAT("tx_timeout_count", tx_timeout_count),
- IGB_STAT("rx_long_length_errors", stats.roc),
- IGB_STAT("rx_short_length_errors", stats.ruc),
- IGB_STAT("rx_align_errors", stats.algnerrc),
- IGB_STAT("tx_tcp_seg_good", stats.tsctc),
- IGB_STAT("tx_tcp_seg_failed", stats.tsctfc),
- IGB_STAT("rx_flow_control_xon", stats.xonrxc),
- IGB_STAT("rx_flow_control_xoff", stats.xoffrxc),
- IGB_STAT("tx_flow_control_xon", stats.xontxc),
- IGB_STAT("tx_flow_control_xoff", stats.xofftxc),
- IGB_STAT("rx_long_byte_count", stats.gorc),
- IGB_STAT("tx_dma_out_of_sync", stats.doosync),
-#ifndef IGB_NO_LRO
- IGB_STAT("lro_aggregated", lro_stats.coal),
- IGB_STAT("lro_flushed", lro_stats.flushed),
-#endif /* IGB_LRO */
- IGB_STAT("tx_smbus", stats.mgptc),
- IGB_STAT("rx_smbus", stats.mgprc),
- IGB_STAT("dropped_smbus", stats.mgpdc),
- IGB_STAT("os2bmc_rx_by_bmc", stats.o2bgptc),
- IGB_STAT("os2bmc_tx_by_bmc", stats.b2ospc),
- IGB_STAT("os2bmc_tx_by_host", stats.o2bspc),
- IGB_STAT("os2bmc_rx_by_host", stats.b2ogprc),
-#ifdef HAVE_PTP_1588_CLOCK
- IGB_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
- IGB_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
-#endif /* HAVE_PTP_1588_CLOCK */
-};
-
-#define IGB_NETDEV_STAT(_net_stat) { \
- .stat_string = #_net_stat, \
- .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
- .stat_offset = offsetof(struct net_device_stats, _net_stat) \
-}
-static const struct igb_stats igb_gstrings_net_stats[] = {
- IGB_NETDEV_STAT(rx_errors),
- IGB_NETDEV_STAT(tx_errors),
- IGB_NETDEV_STAT(tx_dropped),
- IGB_NETDEV_STAT(rx_length_errors),
- IGB_NETDEV_STAT(rx_over_errors),
- IGB_NETDEV_STAT(rx_frame_errors),
- IGB_NETDEV_STAT(rx_fifo_errors),
- IGB_NETDEV_STAT(tx_fifo_errors),
- IGB_NETDEV_STAT(tx_heartbeat_errors)
-};
-
-#define IGB_GLOBAL_STATS_LEN ARRAY_SIZE(igb_gstrings_stats)
-#define IGB_NETDEV_STATS_LEN ARRAY_SIZE(igb_gstrings_net_stats)
-#define IGB_RX_QUEUE_STATS_LEN \
- (sizeof(struct igb_rx_queue_stats) / sizeof(u64))
-#define IGB_TX_QUEUE_STATS_LEN \
- (sizeof(struct igb_tx_queue_stats) / sizeof(u64))
-#define IGB_QUEUE_STATS_LEN \
- ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \
- IGB_RX_QUEUE_STATS_LEN) + \
- (((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues * \
- IGB_TX_QUEUE_STATS_LEN))
-#define IGB_STATS_LEN \
- (IGB_GLOBAL_STATS_LEN + IGB_NETDEV_STATS_LEN + IGB_QUEUE_STATS_LEN)
-
-#endif /* ETHTOOL_GSTATS */
-#ifdef ETHTOOL_TEST
-static const char igb_gstrings_test[][ETH_GSTRING_LEN] = {
- "Register test (offline)", "Eeprom test (offline)",
- "Interrupt test (offline)", "Loopback test (offline)",
- "Link test (on/offline)"
-};
-#define IGB_TEST_LEN (sizeof(igb_gstrings_test) / ETH_GSTRING_LEN)
-#endif /* ETHTOOL_TEST */
-
-#ifndef ETHTOOL_GLINKSETTINGS
-static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 status;
-
- if (hw->phy.media_type == e1000_media_type_copper) {
-
- ecmd->supported = (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full|
- SUPPORTED_Autoneg |
- SUPPORTED_TP |
- SUPPORTED_Pause);
- ecmd->advertising = ADVERTISED_TP;
-
- if (hw->mac.autoneg == 1) {
- ecmd->advertising |= ADVERTISED_Autoneg;
- /* the e1000 autoneg seems to match ethtool nicely */
- ecmd->advertising |= hw->phy.autoneg_advertised;
- }
-
- ecmd->port = PORT_TP;
- ecmd->phy_address = hw->phy.addr;
- ecmd->transceiver = XCVR_INTERNAL;
-
- } else {
- ecmd->supported = (SUPPORTED_1000baseT_Full |
- SUPPORTED_100baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause);
- if (hw->mac.type == e1000_i354)
- ecmd->supported |= (SUPPORTED_2500baseX_Full);
-
- ecmd->advertising = ADVERTISED_FIBRE;
-
- switch (adapter->link_speed) {
- case SPEED_2500:
- ecmd->advertising = ADVERTISED_2500baseX_Full;
- break;
- case SPEED_1000:
- ecmd->advertising = ADVERTISED_1000baseT_Full;
- break;
- case SPEED_100:
- ecmd->advertising = ADVERTISED_100baseT_Full;
- break;
- default:
- break;
- }
-
- if (hw->mac.autoneg == 1)
- ecmd->advertising |= ADVERTISED_Autoneg;
-
- ecmd->port = PORT_FIBRE;
- ecmd->transceiver = XCVR_EXTERNAL;
- }
-
- if (hw->mac.autoneg != 1)
- ecmd->advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
-
- if (hw->fc.requested_mode == e1000_fc_full)
- ecmd->advertising |= ADVERTISED_Pause;
- else if (hw->fc.requested_mode == e1000_fc_rx_pause)
- ecmd->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- else if (hw->fc.requested_mode == e1000_fc_tx_pause)
- ecmd->advertising |= ADVERTISED_Asym_Pause;
- else
- ecmd->advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
-
- status = E1000_READ_REG(hw, E1000_STATUS);
-
- if (status & E1000_STATUS_LU) {
- if ((hw->mac.type == e1000_i354) &&
- (status & E1000_STATUS_2P5_SKU) &&
- !(status & E1000_STATUS_2P5_SKU_OVER))
- ecmd->speed = SPEED_2500;
- else if (status & E1000_STATUS_SPEED_1000)
- ecmd->speed = SPEED_1000;
- else if (status & E1000_STATUS_SPEED_100)
- ecmd->speed = SPEED_100;
- else
- ecmd->speed = SPEED_10;
-
- if ((status & E1000_STATUS_FD) ||
- hw->phy.media_type != e1000_media_type_copper)
- ecmd->duplex = DUPLEX_FULL;
- else
- ecmd->duplex = DUPLEX_HALF;
-
- } else {
- ecmd->speed = -1;
- ecmd->duplex = -1;
- }
-
- if ((hw->phy.media_type == e1000_media_type_fiber) ||
- hw->mac.autoneg)
- ecmd->autoneg = AUTONEG_ENABLE;
- else
- ecmd->autoneg = AUTONEG_DISABLE;
-#ifdef ETH_TP_MDI_X
-
- /* MDI-X => 2; MDI =>1; Invalid =>0 */
- if (hw->phy.media_type == e1000_media_type_copper)
- ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :
- ETH_TP_MDI;
- else
- ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
-
-#ifdef ETH_TP_MDI_AUTO
- if (hw->phy.mdix == AUTO_ALL_MODES)
- ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
- else
- ecmd->eth_tp_mdix_ctrl = hw->phy.mdix;
-
-#endif
-#endif /* ETH_TP_MDI_X */
- return 0;
-}
-#endif
-
-#ifndef ETHTOOL_SLINKSETTINGS
-static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
- if (ecmd->duplex == DUPLEX_HALF) {
- if (!hw->dev_spec._82575.eee_disable)
- dev_info(pci_dev_to_dev(adapter->pdev), "EEE disabled: not supported with half duplex\n");
- hw->dev_spec._82575.eee_disable = true;
- } else {
- if (hw->dev_spec._82575.eee_disable)
- dev_info(pci_dev_to_dev(adapter->pdev), "EEE enabled\n");
- hw->dev_spec._82575.eee_disable = false;
- }
-
- /* When SoL/IDER sessions are active, autoneg/speed/duplex
- * cannot be changed */
- if (e1000_check_reset_block(hw)) {
- dev_err(pci_dev_to_dev(adapter->pdev), "Cannot change link "
- "characteristics when SoL/IDER is active.\n");
- return -EINVAL;
- }
-
-#ifdef ETH_TP_MDI_AUTO
- /*
- * MDI setting is only allowed when autoneg enabled because
- * some hardware doesn't allow MDI setting when speed or
- * duplex is forced.
- */
- if (ecmd->eth_tp_mdix_ctrl) {
- if (hw->phy.media_type != e1000_media_type_copper)
- return -EOPNOTSUPP;
-
- if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
- (ecmd->autoneg != AUTONEG_ENABLE)) {
- dev_err(&adapter->pdev->dev, "forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
- return -EINVAL;
- }
- }
-
-#endif /* ETH_TP_MDI_AUTO */
- while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- usleep_range(1000, 2000);
-
- if (ecmd->autoneg == AUTONEG_ENABLE) {
- hw->mac.autoneg = 1;
- if (hw->phy.media_type == e1000_media_type_fiber) {
- hw->phy.autoneg_advertised = ecmd->advertising |
- ADVERTISED_FIBRE |
- ADVERTISED_Autoneg;
- switch (adapter->link_speed) {
- case SPEED_2500:
- hw->phy.autoneg_advertised =
- ADVERTISED_2500baseX_Full;
- break;
- case SPEED_1000:
- hw->phy.autoneg_advertised =
- ADVERTISED_1000baseT_Full;
- break;
- case SPEED_100:
- hw->phy.autoneg_advertised =
- ADVERTISED_100baseT_Full;
- break;
- default:
- break;
- }
- } else {
- hw->phy.autoneg_advertised = ecmd->advertising |
- ADVERTISED_TP |
- ADVERTISED_Autoneg;
- }
- ecmd->advertising = hw->phy.autoneg_advertised;
- if (adapter->fc_autoneg)
- hw->fc.requested_mode = e1000_fc_default;
- } else {
- if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
- clear_bit(__IGB_RESETTING, &adapter->state);
- return -EINVAL;
- }
- }
-
-#ifdef ETH_TP_MDI_AUTO
- /* MDI-X => 2; MDI => 1; Auto => 3 */
- if (ecmd->eth_tp_mdix_ctrl) {
- /* fix up the value for auto (3 => 0) as zero is mapped
- * internally to auto
- */
- if (ecmd->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
- hw->phy.mdix = AUTO_ALL_MODES;
- else
- hw->phy.mdix = ecmd->eth_tp_mdix_ctrl;
- }
-
-#endif /* ETH_TP_MDI_AUTO */
- /* reset the link */
- if (netif_running(adapter->netdev)) {
- igb_down(adapter);
- igb_up(adapter);
- } else
- igb_reset(adapter);
-
- clear_bit(__IGB_RESETTING, &adapter->state);
- return 0;
-}
-#endif
-
-static u32 igb_get_link(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_mac_info *mac = &adapter->hw.mac;
-
- /*
- * If the link is not reported up to netdev, interrupts are disabled,
- * and so the physical link state may have changed since we last
- * looked. Set get_link_status to make sure that the true link
- * state is interrogated, rather than pulling a cached and possibly
- * stale link state from the driver.
- */
- if (!netif_carrier_ok(netdev))
- mac->get_link_status = 1;
-
- return igb_has_link(adapter);
-}
-
-static void igb_get_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
- pause->autoneg =
- (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
-
- if (hw->fc.current_mode == e1000_fc_rx_pause)
- pause->rx_pause = 1;
- else if (hw->fc.current_mode == e1000_fc_tx_pause)
- pause->tx_pause = 1;
- else if (hw->fc.current_mode == e1000_fc_full) {
- pause->rx_pause = 1;
- pause->tx_pause = 1;
- }
-}
-
-static int igb_set_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- int retval = 0;
-
- adapter->fc_autoneg = pause->autoneg;
-
- while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- usleep_range(1000, 2000);
-
- if (adapter->fc_autoneg == AUTONEG_ENABLE) {
- hw->fc.requested_mode = e1000_fc_default;
- if (netif_running(adapter->netdev)) {
- igb_down(adapter);
- igb_up(adapter);
- } else {
- igb_reset(adapter);
- }
- } else {
- if (pause->rx_pause && pause->tx_pause)
- hw->fc.requested_mode = e1000_fc_full;
- else if (pause->rx_pause && !pause->tx_pause)
- hw->fc.requested_mode = e1000_fc_rx_pause;
- else if (!pause->rx_pause && pause->tx_pause)
- hw->fc.requested_mode = e1000_fc_tx_pause;
- else if (!pause->rx_pause && !pause->tx_pause)
- hw->fc.requested_mode = e1000_fc_none;
-
- hw->fc.current_mode = hw->fc.requested_mode;
-
- if (hw->phy.media_type == e1000_media_type_fiber) {
- retval = hw->mac.ops.setup_link(hw);
- /* implicit goto out */
- } else {
- retval = e1000_force_mac_fc(hw);
- if (retval)
- goto out;
- e1000_set_fc_watermarks_generic(hw);
- }
- }
-
-out:
- clear_bit(__IGB_RESETTING, &adapter->state);
- return retval;
-}
-
-static u32 igb_get_msglevel(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- return adapter->msg_enable;
-}
-
-static void igb_set_msglevel(struct net_device *netdev, u32 data)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- adapter->msg_enable = data;
-}
-
-static int igb_get_regs_len(struct net_device *netdev)
-{
-#define IGB_REGS_LEN 555
- return IGB_REGS_LEN * sizeof(u32);
-}
-
-static void igb_get_regs(struct net_device *netdev,
- struct ethtool_regs *regs, void *p)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 *regs_buff = p;
- u8 i;
-
- memset(p, 0, IGB_REGS_LEN * sizeof(u32));
-
- regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
-
- /* General Registers */
- regs_buff[0] = E1000_READ_REG(hw, E1000_CTRL);
- regs_buff[1] = E1000_READ_REG(hw, E1000_STATUS);
- regs_buff[2] = E1000_READ_REG(hw, E1000_CTRL_EXT);
- regs_buff[3] = E1000_READ_REG(hw, E1000_MDIC);
- regs_buff[4] = E1000_READ_REG(hw, E1000_SCTL);
- regs_buff[5] = E1000_READ_REG(hw, E1000_CONNSW);
- regs_buff[6] = E1000_READ_REG(hw, E1000_VET);
- regs_buff[7] = E1000_READ_REG(hw, E1000_LEDCTL);
- regs_buff[8] = E1000_READ_REG(hw, E1000_PBA);
- regs_buff[9] = E1000_READ_REG(hw, E1000_PBS);
- regs_buff[10] = E1000_READ_REG(hw, E1000_FRTIMER);
- regs_buff[11] = E1000_READ_REG(hw, E1000_TCPTIMER);
-
- /* NVM Register */
- regs_buff[12] = E1000_READ_REG(hw, E1000_EECD);
-
- /* Interrupt */
- /* Reading EICS for EICR because they read the
- * same but EICS does not clear on read */
- regs_buff[13] = E1000_READ_REG(hw, E1000_EICS);
- regs_buff[14] = E1000_READ_REG(hw, E1000_EICS);
- regs_buff[15] = E1000_READ_REG(hw, E1000_EIMS);
- regs_buff[16] = E1000_READ_REG(hw, E1000_EIMC);
- regs_buff[17] = E1000_READ_REG(hw, E1000_EIAC);
- regs_buff[18] = E1000_READ_REG(hw, E1000_EIAM);
- /* Reading ICS for ICR because they read the
- * same but ICS does not clear on read */
- regs_buff[19] = E1000_READ_REG(hw, E1000_ICS);
- regs_buff[20] = E1000_READ_REG(hw, E1000_ICS);
- regs_buff[21] = E1000_READ_REG(hw, E1000_IMS);
- regs_buff[22] = E1000_READ_REG(hw, E1000_IMC);
- regs_buff[23] = E1000_READ_REG(hw, E1000_IAC);
- regs_buff[24] = E1000_READ_REG(hw, E1000_IAM);
- regs_buff[25] = E1000_READ_REG(hw, E1000_IMIRVP);
-
- /* Flow Control */
- regs_buff[26] = E1000_READ_REG(hw, E1000_FCAL);
- regs_buff[27] = E1000_READ_REG(hw, E1000_FCAH);
- regs_buff[28] = E1000_READ_REG(hw, E1000_FCTTV);
- regs_buff[29] = E1000_READ_REG(hw, E1000_FCRTL);
- regs_buff[30] = E1000_READ_REG(hw, E1000_FCRTH);
- regs_buff[31] = E1000_READ_REG(hw, E1000_FCRTV);
-
- /* Receive */
- regs_buff[32] = E1000_READ_REG(hw, E1000_RCTL);
- regs_buff[33] = E1000_READ_REG(hw, E1000_RXCSUM);
- regs_buff[34] = E1000_READ_REG(hw, E1000_RLPML);
- regs_buff[35] = E1000_READ_REG(hw, E1000_RFCTL);
- regs_buff[36] = E1000_READ_REG(hw, E1000_MRQC);
- regs_buff[37] = E1000_READ_REG(hw, E1000_VT_CTL);
-
- /* Transmit */
- regs_buff[38] = E1000_READ_REG(hw, E1000_TCTL);
- regs_buff[39] = E1000_READ_REG(hw, E1000_TCTL_EXT);
- regs_buff[40] = E1000_READ_REG(hw, E1000_TIPG);
- regs_buff[41] = E1000_READ_REG(hw, E1000_DTXCTL);
-
- /* Wake Up */
- regs_buff[42] = E1000_READ_REG(hw, E1000_WUC);
- regs_buff[43] = E1000_READ_REG(hw, E1000_WUFC);
- regs_buff[44] = E1000_READ_REG(hw, E1000_WUS);
- regs_buff[45] = E1000_READ_REG(hw, E1000_IPAV);
- regs_buff[46] = E1000_READ_REG(hw, E1000_WUPL);
-
- /* MAC */
- regs_buff[47] = E1000_READ_REG(hw, E1000_PCS_CFG0);
- regs_buff[48] = E1000_READ_REG(hw, E1000_PCS_LCTL);
- regs_buff[49] = E1000_READ_REG(hw, E1000_PCS_LSTAT);
- regs_buff[50] = E1000_READ_REG(hw, E1000_PCS_ANADV);
- regs_buff[51] = E1000_READ_REG(hw, E1000_PCS_LPAB);
- regs_buff[52] = E1000_READ_REG(hw, E1000_PCS_NPTX);
- regs_buff[53] = E1000_READ_REG(hw, E1000_PCS_LPABNP);
-
- /* Statistics */
- regs_buff[54] = adapter->stats.crcerrs;
- regs_buff[55] = adapter->stats.algnerrc;
- regs_buff[56] = adapter->stats.symerrs;
- regs_buff[57] = adapter->stats.rxerrc;
- regs_buff[58] = adapter->stats.mpc;
- regs_buff[59] = adapter->stats.scc;
- regs_buff[60] = adapter->stats.ecol;
- regs_buff[61] = adapter->stats.mcc;
- regs_buff[62] = adapter->stats.latecol;
- regs_buff[63] = adapter->stats.colc;
- regs_buff[64] = adapter->stats.dc;
- regs_buff[65] = adapter->stats.tncrs;
- regs_buff[66] = adapter->stats.sec;
- regs_buff[67] = adapter->stats.htdpmc;
- regs_buff[68] = adapter->stats.rlec;
- regs_buff[69] = adapter->stats.xonrxc;
- regs_buff[70] = adapter->stats.xontxc;
- regs_buff[71] = adapter->stats.xoffrxc;
- regs_buff[72] = adapter->stats.xofftxc;
- regs_buff[73] = adapter->stats.fcruc;
- regs_buff[74] = adapter->stats.prc64;
- regs_buff[75] = adapter->stats.prc127;
- regs_buff[76] = adapter->stats.prc255;
- regs_buff[77] = adapter->stats.prc511;
- regs_buff[78] = adapter->stats.prc1023;
- regs_buff[79] = adapter->stats.prc1522;
- regs_buff[80] = adapter->stats.gprc;
- regs_buff[81] = adapter->stats.bprc;
- regs_buff[82] = adapter->stats.mprc;
- regs_buff[83] = adapter->stats.gptc;
- regs_buff[84] = adapter->stats.gorc;
- regs_buff[86] = adapter->stats.gotc;
- regs_buff[88] = adapter->stats.rnbc;
- regs_buff[89] = adapter->stats.ruc;
- regs_buff[90] = adapter->stats.rfc;
- regs_buff[91] = adapter->stats.roc;
- regs_buff[92] = adapter->stats.rjc;
- regs_buff[93] = adapter->stats.mgprc;
- regs_buff[94] = adapter->stats.mgpdc;
- regs_buff[95] = adapter->stats.mgptc;
- regs_buff[96] = adapter->stats.tor;
- regs_buff[98] = adapter->stats.tot;
- regs_buff[100] = adapter->stats.tpr;
- regs_buff[101] = adapter->stats.tpt;
- regs_buff[102] = adapter->stats.ptc64;
- regs_buff[103] = adapter->stats.ptc127;
- regs_buff[104] = adapter->stats.ptc255;
- regs_buff[105] = adapter->stats.ptc511;
- regs_buff[106] = adapter->stats.ptc1023;
- regs_buff[107] = adapter->stats.ptc1522;
- regs_buff[108] = adapter->stats.mptc;
- regs_buff[109] = adapter->stats.bptc;
- regs_buff[110] = adapter->stats.tsctc;
- regs_buff[111] = adapter->stats.iac;
- regs_buff[112] = adapter->stats.rpthc;
- regs_buff[113] = adapter->stats.hgptc;
- regs_buff[114] = adapter->stats.hgorc;
- regs_buff[116] = adapter->stats.hgotc;
- regs_buff[118] = adapter->stats.lenerrs;
- regs_buff[119] = adapter->stats.scvpc;
- regs_buff[120] = adapter->stats.hrmpc;
-
- for (i = 0; i < 4; i++)
- regs_buff[121 + i] = E1000_READ_REG(hw, E1000_SRRCTL(i));
- for (i = 0; i < 4; i++)
- regs_buff[125 + i] = E1000_READ_REG(hw, E1000_PSRTYPE(i));
- for (i = 0; i < 4; i++)
- regs_buff[129 + i] = E1000_READ_REG(hw, E1000_RDBAL(i));
- for (i = 0; i < 4; i++)
- regs_buff[133 + i] = E1000_READ_REG(hw, E1000_RDBAH(i));
- for (i = 0; i < 4; i++)
- regs_buff[137 + i] = E1000_READ_REG(hw, E1000_RDLEN(i));
- for (i = 0; i < 4; i++)
- regs_buff[141 + i] = E1000_READ_REG(hw, E1000_RDH(i));
- for (i = 0; i < 4; i++)
- regs_buff[145 + i] = E1000_READ_REG(hw, E1000_RDT(i));
- for (i = 0; i < 4; i++)
- regs_buff[149 + i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
-
- for (i = 0; i < 10; i++)
- regs_buff[153 + i] = E1000_READ_REG(hw, E1000_EITR(i));
- for (i = 0; i < 8; i++)
- regs_buff[163 + i] = E1000_READ_REG(hw, E1000_IMIR(i));
- for (i = 0; i < 8; i++)
- regs_buff[171 + i] = E1000_READ_REG(hw, E1000_IMIREXT(i));
- for (i = 0; i < 16; i++)
- regs_buff[179 + i] = E1000_READ_REG(hw, E1000_RAL(i));
- for (i = 0; i < 16; i++)
- regs_buff[195 + i] = E1000_READ_REG(hw, E1000_RAH(i));
-
- for (i = 0; i < 4; i++)
- regs_buff[211 + i] = E1000_READ_REG(hw, E1000_TDBAL(i));
- for (i = 0; i < 4; i++)
- regs_buff[215 + i] = E1000_READ_REG(hw, E1000_TDBAH(i));
- for (i = 0; i < 4; i++)
- regs_buff[219 + i] = E1000_READ_REG(hw, E1000_TDLEN(i));
- for (i = 0; i < 4; i++)
- regs_buff[223 + i] = E1000_READ_REG(hw, E1000_TDH(i));
- for (i = 0; i < 4; i++)
- regs_buff[227 + i] = E1000_READ_REG(hw, E1000_TDT(i));
- for (i = 0; i < 4; i++)
- regs_buff[231 + i] = E1000_READ_REG(hw, E1000_TXDCTL(i));
- for (i = 0; i < 4; i++)
- regs_buff[235 + i] = E1000_READ_REG(hw, E1000_TDWBAL(i));
- for (i = 0; i < 4; i++)
- regs_buff[239 + i] = E1000_READ_REG(hw, E1000_TDWBAH(i));
- for (i = 0; i < 4; i++)
- regs_buff[243 + i] = E1000_READ_REG(hw, E1000_DCA_TXCTRL(i));
-
- for (i = 0; i < 4; i++)
- regs_buff[247 + i] = E1000_READ_REG(hw, E1000_IP4AT_REG(i));
- for (i = 0; i < 4; i++)
- regs_buff[251 + i] = E1000_READ_REG(hw, E1000_IP6AT_REG(i));
- for (i = 0; i < 32; i++)
- regs_buff[255 + i] = E1000_READ_REG(hw, E1000_WUPM_REG(i));
- for (i = 0; i < 128; i++)
- regs_buff[287 + i] = E1000_READ_REG(hw, E1000_FFMT_REG(i));
- for (i = 0; i < 128; i++)
- regs_buff[415 + i] = E1000_READ_REG(hw, E1000_FFVT_REG(i));
- for (i = 0; i < 4; i++)
- regs_buff[543 + i] = E1000_READ_REG(hw, E1000_FFLT_REG(i));
-
- regs_buff[547] = E1000_READ_REG(hw, E1000_TDFH);
- regs_buff[548] = E1000_READ_REG(hw, E1000_TDFT);
- regs_buff[549] = E1000_READ_REG(hw, E1000_TDFHS);
- regs_buff[550] = E1000_READ_REG(hw, E1000_TDFPC);
- if (hw->mac.type > e1000_82580) {
- regs_buff[551] = adapter->stats.o2bgptc;
- regs_buff[552] = adapter->stats.b2ospc;
- regs_buff[553] = adapter->stats.o2bspc;
- regs_buff[554] = adapter->stats.b2ogprc;
- }
-}
-
-static int igb_get_eeprom_len(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- return adapter->hw.nvm.word_size * 2;
-}
-
-static int igb_get_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *eeprom, u8 *bytes)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u16 *eeprom_buff;
- int first_word, last_word;
- int ret_val = 0;
- u16 i;
-
- if (eeprom->len == 0)
- return -EINVAL;
-
- eeprom->magic = hw->vendor_id | (hw->device_id << 16);
-
- first_word = eeprom->offset >> 1;
- last_word = (eeprom->offset + eeprom->len - 1) >> 1;
-
- eeprom_buff = kmalloc(sizeof(u16) *
- (last_word - first_word + 1), GFP_KERNEL);
- if (!eeprom_buff)
- return -ENOMEM;
-
- if (hw->nvm.type == e1000_nvm_eeprom_spi)
- ret_val = e1000_read_nvm(hw, first_word,
- last_word - first_word + 1,
- eeprom_buff);
- else {
- for (i = 0; i < last_word - first_word + 1; i++) {
- ret_val = e1000_read_nvm(hw, first_word + i, 1,
- &eeprom_buff[i]);
- if (ret_val)
- break;
- }
- }
-
- /* Device's eeprom is always little-endian, word addressable */
- for (i = 0; i < last_word - first_word + 1; i++)
- eeprom_buff[i] = le16_to_cpu(eeprom_buff[i]);
-
- memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1),
- eeprom->len);
- kfree(eeprom_buff);
-
- return ret_val;
-}
-
-static int igb_set_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *eeprom, u8 *bytes)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u16 *eeprom_buff;
- void *ptr;
- int max_len, first_word, last_word, ret_val = 0;
- u16 i;
-
- if (eeprom->len == 0)
- return -EOPNOTSUPP;
-
- if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
- return -EFAULT;
-
- max_len = hw->nvm.word_size * 2;
-
- first_word = eeprom->offset >> 1;
- last_word = (eeprom->offset + eeprom->len - 1) >> 1;
- eeprom_buff = kmalloc(max_len, GFP_KERNEL);
- if (!eeprom_buff)
- return -ENOMEM;
-
- ptr = (void *)eeprom_buff;
-
- if (eeprom->offset & 1) {
- /* need read/modify/write of first changed EEPROM word */
- /* only the second byte of the word is being modified */
- ret_val = e1000_read_nvm(hw, first_word, 1,
- &eeprom_buff[0]);
- ptr++;
- }
- if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
- /* need read/modify/write of last changed EEPROM word */
- /* only the first byte of the word is being modified */
- ret_val = e1000_read_nvm(hw, last_word, 1,
- &eeprom_buff[last_word - first_word]);
- }
-
- /* Device's eeprom is always little-endian, word addressable */
- for (i = 0; i < last_word - first_word + 1; i++)
- le16_to_cpus(&eeprom_buff[i]);
-
- memcpy(ptr, bytes, eeprom->len);
-
- for (i = 0; i < last_word - first_word + 1; i++)
- cpu_to_le16s(&eeprom_buff[i]);
-
- ret_val = e1000_write_nvm(hw, first_word,
- last_word - first_word + 1, eeprom_buff);
-
- /* Update the checksum if write succeeded.
- * and flush shadow RAM for 82573 controllers */
- if (ret_val == 0)
- e1000_update_nvm_checksum(hw);
-
- kfree(eeprom_buff);
- return ret_val;
-}
-
-static void igb_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- strncpy(drvinfo->driver, igb_driver_name, sizeof(drvinfo->driver) - 1);
- strncpy(drvinfo->version, igb_driver_version, sizeof(drvinfo->version) - 1);
-
- strlcpy(drvinfo->fw_version, adapter->fw_version,
- sizeof(drvinfo->fw_version));
- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
- sizeof(drvinfo->bus_info));
- drvinfo->n_stats = IGB_STATS_LEN;
- drvinfo->testinfo_len = IGB_TEST_LEN;
- drvinfo->regdump_len = igb_get_regs_len(netdev);
- drvinfo->eedump_len = igb_get_eeprom_len(netdev);
-}
-
-static void igb_get_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- ring->rx_max_pending = IGB_MAX_RXD;
- ring->tx_max_pending = IGB_MAX_TXD;
- ring->rx_mini_max_pending = 0;
- ring->rx_jumbo_max_pending = 0;
- ring->rx_pending = adapter->rx_ring_count;
- ring->tx_pending = adapter->tx_ring_count;
- ring->rx_mini_pending = 0;
- ring->rx_jumbo_pending = 0;
-}
-
-static int igb_set_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct igb_ring *temp_ring;
- int i, err = 0;
- u16 new_rx_count, new_tx_count;
-
- if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
- return -EINVAL;
-
- new_rx_count = min(ring->rx_pending, (u32)IGB_MAX_RXD);
- new_rx_count = max(new_rx_count, (u16)IGB_MIN_RXD);
- new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
-
- new_tx_count = min(ring->tx_pending, (u32)IGB_MAX_TXD);
- new_tx_count = max(new_tx_count, (u16)IGB_MIN_TXD);
- new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
-
- if ((new_tx_count == adapter->tx_ring_count) &&
- (new_rx_count == adapter->rx_ring_count)) {
- /* nothing to do */
- return 0;
- }
-
- while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- usleep_range(1000, 2000);
-
- if (!netif_running(adapter->netdev)) {
- for (i = 0; i < adapter->num_tx_queues; i++)
- adapter->tx_ring[i]->count = new_tx_count;
- for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i]->count = new_rx_count;
- adapter->tx_ring_count = new_tx_count;
- adapter->rx_ring_count = new_rx_count;
- goto clear_reset;
- }
-
- if (adapter->num_tx_queues > adapter->num_rx_queues)
- temp_ring = vmalloc(adapter->num_tx_queues * sizeof(struct igb_ring));
- else
- temp_ring = vmalloc(adapter->num_rx_queues * sizeof(struct igb_ring));
-
- if (!temp_ring) {
- err = -ENOMEM;
- goto clear_reset;
- }
-
- igb_down(adapter);
-
- /*
- * We can't just free everything and then setup again,
- * because the ISRs in MSI-X mode get passed pointers
- * to the tx and rx ring structs.
- */
- if (new_tx_count != adapter->tx_ring_count) {
- for (i = 0; i < adapter->num_tx_queues; i++) {
- memcpy(&temp_ring[i], adapter->tx_ring[i],
- sizeof(struct igb_ring));
-
- temp_ring[i].count = new_tx_count;
- err = igb_setup_tx_resources(&temp_ring[i]);
- if (err) {
- while (i) {
- i--;
- igb_free_tx_resources(&temp_ring[i]);
- }
- goto err_setup;
- }
- }
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- igb_free_tx_resources(adapter->tx_ring[i]);
-
- memcpy(adapter->tx_ring[i], &temp_ring[i],
- sizeof(struct igb_ring));
- }
-
- adapter->tx_ring_count = new_tx_count;
- }
-
- if (new_rx_count != adapter->rx_ring_count) {
- for (i = 0; i < adapter->num_rx_queues; i++) {
- memcpy(&temp_ring[i], adapter->rx_ring[i],
- sizeof(struct igb_ring));
-
- temp_ring[i].count = new_rx_count;
- err = igb_setup_rx_resources(&temp_ring[i]);
- if (err) {
- while (i) {
- i--;
- igb_free_rx_resources(&temp_ring[i]);
- }
- goto err_setup;
- }
-
- }
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- igb_free_rx_resources(adapter->rx_ring[i]);
-
- memcpy(adapter->rx_ring[i], &temp_ring[i],
- sizeof(struct igb_ring));
- }
-
- adapter->rx_ring_count = new_rx_count;
- }
-err_setup:
- igb_up(adapter);
- vfree(temp_ring);
-clear_reset:
- clear_bit(__IGB_RESETTING, &adapter->state);
- return err;
-}
-static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
- int reg, u32 mask, u32 write)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 pat, val;
- static const u32 _test[] =
- {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
- for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
- E1000_WRITE_REG(hw, reg, (_test[pat] & write));
- val = E1000_READ_REG(hw, reg) & mask;
- if (val != (_test[pat] & write & mask)) {
- dev_err(pci_dev_to_dev(adapter->pdev), "pattern test reg %04X "
- "failed: got 0x%08X expected 0x%08X\n",
- E1000_REGISTER(hw, reg), val, (_test[pat] & write & mask));
- *data = E1000_REGISTER(hw, reg);
- return 1;
- }
- }
-
- return 0;
-}
-
-static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
- int reg, u32 mask, u32 write)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 val;
- E1000_WRITE_REG(hw, reg, write & mask);
- val = E1000_READ_REG(hw, reg);
- if ((write & mask) != (val & mask)) {
- dev_err(pci_dev_to_dev(adapter->pdev), "set/check reg %04X test failed:"
- " got 0x%08X expected 0x%08X\n", reg,
- (val & mask), (write & mask));
- *data = E1000_REGISTER(hw, reg);
- return 1;
- }
-
- return 0;
-}
-
-#define REG_PATTERN_TEST(reg, mask, write) \
- do { \
- if (reg_pattern_test(adapter, data, reg, mask, write)) \
- return 1; \
- } while (0)
-
-#define REG_SET_AND_CHECK(reg, mask, write) \
- do { \
- if (reg_set_and_check(adapter, data, reg, mask, write)) \
- return 1; \
- } while (0)
-
-static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct igb_reg_test *test;
- u32 value, before, after;
- u32 i, toggle;
-
- switch (adapter->hw.mac.type) {
- case e1000_i350:
- case e1000_i354:
- test = reg_test_i350;
- toggle = 0x7FEFF3FF;
- break;
- case e1000_i210:
- case e1000_i211:
- test = reg_test_i210;
- toggle = 0x7FEFF3FF;
- break;
- case e1000_82580:
- test = reg_test_82580;
- toggle = 0x7FEFF3FF;
- break;
- case e1000_82576:
- test = reg_test_82576;
- toggle = 0x7FFFF3FF;
- break;
- default:
- test = reg_test_82575;
- toggle = 0x7FFFF3FF;
- break;
- }
-
- /* Because the status register is such a special case,
- * we handle it separately from the rest of the register
- * tests. Some bits are read-only, some toggle, and some
- * are writable on newer MACs.
- */
- before = E1000_READ_REG(hw, E1000_STATUS);
- value = (E1000_READ_REG(hw, E1000_STATUS) & toggle);
- E1000_WRITE_REG(hw, E1000_STATUS, toggle);
- after = E1000_READ_REG(hw, E1000_STATUS) & toggle;
- if (value != after) {
- dev_err(pci_dev_to_dev(adapter->pdev), "failed STATUS register test "
- "got: 0x%08X expected: 0x%08X\n", after, value);
- *data = 1;
- return 1;
- }
- /* restore previous status */
- E1000_WRITE_REG(hw, E1000_STATUS, before);
-
- /* Perform the remainder of the register test, looping through
- * the test table until we either fail or reach the null entry.
- */
- while (test->reg) {
- for (i = 0; i < test->array_len; i++) {
- switch (test->test_type) {
- case PATTERN_TEST:
- REG_PATTERN_TEST(test->reg +
- (i * test->reg_offset),
- test->mask,
- test->write);
- break;
- case SET_READ_TEST:
- REG_SET_AND_CHECK(test->reg +
- (i * test->reg_offset),
- test->mask,
- test->write);
- break;
- case WRITE_NO_TEST:
- writel(test->write,
- (adapter->hw.hw_addr + test->reg)
- + (i * test->reg_offset));
- break;
- case TABLE32_TEST:
- REG_PATTERN_TEST(test->reg + (i * 4),
- test->mask,
- test->write);
- break;
- case TABLE64_TEST_LO:
- REG_PATTERN_TEST(test->reg + (i * 8),
- test->mask,
- test->write);
- break;
- case TABLE64_TEST_HI:
- REG_PATTERN_TEST((test->reg + 4) + (i * 8),
- test->mask,
- test->write);
- break;
- }
- }
- test++;
- }
-
- *data = 0;
- return 0;
-}
-
-static int igb_eeprom_test(struct igb_adapter *adapter, u64 *data)
-{
- *data = 0;
-
- /* Validate NVM checksum */
- if (e1000_validate_nvm_checksum(&adapter->hw) < 0)
- *data = 2;
-
- return *data;
-}
-
-static irqreturn_t igb_test_intr(int irq, void *data)
-{
- struct igb_adapter *adapter = data;
- struct e1000_hw *hw = &adapter->hw;
-
- adapter->test_icr |= E1000_READ_REG(hw, E1000_ICR);
-
- return IRQ_HANDLED;
-}
-
-static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- u32 mask, ics_mask, i = 0, shared_int = TRUE;
- u32 irq = adapter->pdev->irq;
-
- *data = 0;
-
- /* Hook up test interrupt handler just for this test */
- if (adapter->msix_entries) {
- if (request_irq(adapter->msix_entries[0].vector,
- &igb_test_intr, 0, netdev->name, adapter)) {
- *data = 1;
- return -1;
- }
- } else if (adapter->flags & IGB_FLAG_HAS_MSI) {
- shared_int = FALSE;
- if (request_irq(irq,
- igb_test_intr, 0, netdev->name, adapter)) {
- *data = 1;
- return -1;
- }
- } else if (!request_irq(irq, igb_test_intr, IRQF_PROBE_SHARED,
- netdev->name, adapter)) {
- shared_int = FALSE;
- } else if (request_irq(irq, &igb_test_intr, IRQF_SHARED,
- netdev->name, adapter)) {
- *data = 1;
- return -1;
- }
- dev_info(pci_dev_to_dev(adapter->pdev), "testing %s interrupt\n",
- (shared_int ? "shared" : "unshared"));
-
- /* Disable all the interrupts */
- E1000_WRITE_REG(hw, E1000_IMC, ~0);
- E1000_WRITE_FLUSH(hw);
- usleep_range(10000, 20000);
-
- /* Define all writable bits for ICS */
- switch (hw->mac.type) {
- case e1000_82575:
- ics_mask = 0x37F47EDD;
- break;
- case e1000_82576:
- ics_mask = 0x77D4FBFD;
- break;
- case e1000_82580:
- ics_mask = 0x77DCFED5;
- break;
- case e1000_i350:
- case e1000_i354:
- ics_mask = 0x77DCFED5;
- break;
- case e1000_i210:
- case e1000_i211:
- ics_mask = 0x774CFED5;
- break;
- default:
- ics_mask = 0x7FFFFFFF;
- break;
- }
-
- /* Test each interrupt */
- for (; i < 31; i++) {
- /* Interrupt to test */
- mask = 1 << i;
-
- if (!(mask & ics_mask))
- continue;
-
- if (!shared_int) {
- /* Disable the interrupt to be reported in
- * the cause register and then force the same
- * interrupt and see if one gets posted. If
- * an interrupt was posted to the bus, the
- * test failed.
- */
- adapter->test_icr = 0;
-
- /* Flush any pending interrupts */
- E1000_WRITE_REG(hw, E1000_ICR, ~0);
-
- E1000_WRITE_REG(hw, E1000_IMC, mask);
- E1000_WRITE_REG(hw, E1000_ICS, mask);
- E1000_WRITE_FLUSH(hw);
- usleep_range(10000, 20000);
-
- if (adapter->test_icr & mask) {
- *data = 3;
- break;
- }
- }
-
- /* Enable the interrupt to be reported in
- * the cause register and then force the same
- * interrupt and see if one gets posted. If
- * an interrupt was not posted to the bus, the
- * test failed.
- */
- adapter->test_icr = 0;
-
- /* Flush any pending interrupts */
- E1000_WRITE_REG(hw, E1000_ICR, ~0);
-
- E1000_WRITE_REG(hw, E1000_IMS, mask);
- E1000_WRITE_REG(hw, E1000_ICS, mask);
- E1000_WRITE_FLUSH(hw);
- usleep_range(10000, 20000);
-
- if (!(adapter->test_icr & mask)) {
- *data = 4;
- break;
- }
-
- if (!shared_int) {
- /* Disable the other interrupts to be reported in
- * the cause register and then force the other
- * interrupts and see if any get posted. If
- * an interrupt was posted to the bus, the
- * test failed.
- */
- adapter->test_icr = 0;
-
- /* Flush any pending interrupts */
- E1000_WRITE_REG(hw, E1000_ICR, ~0);
-
- E1000_WRITE_REG(hw, E1000_IMC, ~mask);
- E1000_WRITE_REG(hw, E1000_ICS, ~mask);
- E1000_WRITE_FLUSH(hw);
- usleep_range(10000, 20000);
-
- if (adapter->test_icr & mask) {
- *data = 5;
- break;
- }
- }
- }
-
- /* Disable all the interrupts */
- E1000_WRITE_REG(hw, E1000_IMC, ~0);
- E1000_WRITE_FLUSH(hw);
- usleep_range(10000, 20000);
-
- /* Unhook test interrupt handler */
- if (adapter->msix_entries)
- free_irq(adapter->msix_entries[0].vector, adapter);
- else
- free_irq(irq, adapter);
-
- return *data;
-}
-
-static void igb_free_desc_rings(struct igb_adapter *adapter)
-{
- igb_free_tx_resources(&adapter->test_tx_ring);
- igb_free_rx_resources(&adapter->test_rx_ring);
-}
-
-static int igb_setup_desc_rings(struct igb_adapter *adapter)
-{
- struct igb_ring *tx_ring = &adapter->test_tx_ring;
- struct igb_ring *rx_ring = &adapter->test_rx_ring;
- struct e1000_hw *hw = &adapter->hw;
- int ret_val;
-
- /* Setup Tx descriptor ring and Tx buffers */
- tx_ring->count = IGB_DEFAULT_TXD;
- tx_ring->dev = pci_dev_to_dev(adapter->pdev);
- tx_ring->netdev = adapter->netdev;
- tx_ring->reg_idx = adapter->vfs_allocated_count;
-
- if (igb_setup_tx_resources(tx_ring)) {
- ret_val = 1;
- goto err_nomem;
- }
-
- igb_setup_tctl(adapter);
- igb_configure_tx_ring(adapter, tx_ring);
-
- /* Setup Rx descriptor ring and Rx buffers */
- rx_ring->count = IGB_DEFAULT_RXD;
- rx_ring->dev = pci_dev_to_dev(adapter->pdev);
- rx_ring->netdev = adapter->netdev;
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- rx_ring->rx_buffer_len = IGB_RX_HDR_LEN;
-#endif
- rx_ring->reg_idx = adapter->vfs_allocated_count;
-
- if (igb_setup_rx_resources(rx_ring)) {
- ret_val = 2;
- goto err_nomem;
- }
-
- /* set the default queue to queue 0 of PF */
- E1000_WRITE_REG(hw, E1000_MRQC, adapter->vfs_allocated_count << 3);
-
- /* enable receive ring */
- igb_setup_rctl(adapter);
- igb_configure_rx_ring(adapter, rx_ring);
-
- igb_alloc_rx_buffers(rx_ring, igb_desc_unused(rx_ring));
-
- return 0;
-
-err_nomem:
- igb_free_desc_rings(adapter);
- return ret_val;
-}
-
-static void igb_phy_disable_receiver(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- /* Write out to PHY registers 29 and 30 to disable the Receiver. */
- e1000_write_phy_reg(hw, 29, 0x001F);
- e1000_write_phy_reg(hw, 30, 0x8FFC);
- e1000_write_phy_reg(hw, 29, 0x001A);
- e1000_write_phy_reg(hw, 30, 0x8FF0);
-}
-
-static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl_reg = 0;
-
- hw->mac.autoneg = FALSE;
-
- if (hw->phy.type == e1000_phy_m88) {
- if (hw->phy.id != I210_I_PHY_ID) {
- /* Auto-MDI/MDIX Off */
- e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
- /* reset to update Auto-MDI/MDIX */
- e1000_write_phy_reg(hw, PHY_CONTROL, 0x9140);
- /* autoneg off */
- e1000_write_phy_reg(hw, PHY_CONTROL, 0x8140);
- } else {
- /* force 1000, set loopback */
- e1000_write_phy_reg(hw, I347AT4_PAGE_SELECT, 0);
- e1000_write_phy_reg(hw, PHY_CONTROL, 0x4140);
- }
- } else {
- /* enable MII loopback */
- if (hw->phy.type == e1000_phy_82580)
- e1000_write_phy_reg(hw, I82577_PHY_LBK_CTRL, 0x8041);
- }
-
- /* force 1000, set loopback */
- e1000_write_phy_reg(hw, PHY_CONTROL, 0x4140);
-
- /* Now set up the MAC to the same speed/duplex as the PHY. */
- ctrl_reg = E1000_READ_REG(hw, E1000_CTRL);
- ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
- ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
- E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
- E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
- E1000_CTRL_FD | /* Force Duplex to FULL */
- E1000_CTRL_SLU); /* Set link up enable bit */
-
- if (hw->phy.type == e1000_phy_m88)
- ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
-
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg);
-
- /* Disable the receiver on the PHY so when a cable is plugged in, the
- * PHY does not begin to autoneg when a cable is reconnected to the NIC.
- */
- if (hw->phy.type == e1000_phy_m88)
- igb_phy_disable_receiver(adapter);
-
- mdelay(500);
- return 0;
-}
-
-static int igb_set_phy_loopback(struct igb_adapter *adapter)
-{
- return igb_integrated_phy_loopback(adapter);
-}
-
-static int igb_setup_loopback_test(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 reg;
-
- reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
-
- /* use CTRL_EXT to identify link type as SGMII can appear as copper */
- if (reg & E1000_CTRL_EXT_LINK_MODE_MASK) {
- if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) ||
- (hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) ||
- (hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) ||
- (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) {
-
- /* Enable DH89xxCC MPHY for near end loopback */
- reg = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTL);
- reg = (reg & E1000_MPHY_ADDR_CTL_OFFSET_MASK) |
- E1000_MPHY_PCS_CLK_REG_OFFSET;
- E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTL, reg);
-
- reg = E1000_READ_REG(hw, E1000_MPHY_DATA);
- reg |= E1000_MPHY_PCS_CLK_REG_DIGINELBEN;
- E1000_WRITE_REG(hw, E1000_MPHY_DATA, reg);
- }
-
- reg = E1000_READ_REG(hw, E1000_RCTL);
- reg |= E1000_RCTL_LBM_TCVR;
- E1000_WRITE_REG(hw, E1000_RCTL, reg);
-
- E1000_WRITE_REG(hw, E1000_SCTL, E1000_ENABLE_SERDES_LOOPBACK);
-
- reg = E1000_READ_REG(hw, E1000_CTRL);
- reg &= ~(E1000_CTRL_RFCE |
- E1000_CTRL_TFCE |
- E1000_CTRL_LRST);
- reg |= E1000_CTRL_SLU |
- E1000_CTRL_FD;
- E1000_WRITE_REG(hw, E1000_CTRL, reg);
-
- /* Unset switch control to serdes energy detect */
- reg = E1000_READ_REG(hw, E1000_CONNSW);
- reg &= ~E1000_CONNSW_ENRGSRC;
- E1000_WRITE_REG(hw, E1000_CONNSW, reg);
-
- /* Unset sigdetect for SERDES loopback on
- * 82580 and newer devices
- */
- if (hw->mac.type >= e1000_82580) {
- reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
- reg |= E1000_PCS_CFG_IGN_SD;
- E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
- }
-
- /* Set PCS register for forced speed */
- reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
- reg &= ~E1000_PCS_LCTL_AN_ENABLE; /* Disable Autoneg*/
- reg |= E1000_PCS_LCTL_FLV_LINK_UP | /* Force link up */
- E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */
- E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */
- E1000_PCS_LCTL_FSD | /* Force Speed */
- E1000_PCS_LCTL_FORCE_LINK; /* Force Link */
- E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
-
- return 0;
- }
-
- return igb_set_phy_loopback(adapter);
-}
-
-static void igb_loopback_cleanup(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 rctl;
- u16 phy_reg;
-
- if ((hw->device_id == E1000_DEV_ID_DH89XXCC_SGMII) ||
- (hw->device_id == E1000_DEV_ID_DH89XXCC_SERDES) ||
- (hw->device_id == E1000_DEV_ID_DH89XXCC_BACKPLANE) ||
- (hw->device_id == E1000_DEV_ID_DH89XXCC_SFP)) {
- u32 reg;
-
- /* Disable near end loopback on DH89xxCC */
- reg = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTL);
- reg = (reg & E1000_MPHY_ADDR_CTL_OFFSET_MASK ) |
- E1000_MPHY_PCS_CLK_REG_OFFSET;
- E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTL, reg);
-
- reg = E1000_READ_REG(hw, E1000_MPHY_DATA);
- reg &= ~E1000_MPHY_PCS_CLK_REG_DIGINELBEN;
- E1000_WRITE_REG(hw, E1000_MPHY_DATA, reg);
- }
-
- rctl = E1000_READ_REG(hw, E1000_RCTL);
- rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
- E1000_WRITE_REG(hw, E1000_RCTL, rctl);
-
- hw->mac.autoneg = TRUE;
- e1000_read_phy_reg(hw, PHY_CONTROL, &phy_reg);
- if (phy_reg & MII_CR_LOOPBACK) {
- phy_reg &= ~MII_CR_LOOPBACK;
- if (hw->phy.type == I210_I_PHY_ID)
- e1000_write_phy_reg(hw, I347AT4_PAGE_SELECT, 0);
- e1000_write_phy_reg(hw, PHY_CONTROL, phy_reg);
- e1000_phy_commit(hw);
- }
-}
-static void igb_create_lbtest_frame(struct sk_buff *skb,
- unsigned int frame_size)
-{
- memset(skb->data, 0xFF, frame_size);
- frame_size /= 2;
- memset(&skb->data[frame_size], 0xAA, frame_size - 1);
- memset(&skb->data[frame_size + 10], 0xBE, 1);
- memset(&skb->data[frame_size + 12], 0xAF, 1);
-}
-
-static int igb_check_lbtest_frame(struct igb_rx_buffer *rx_buffer,
- unsigned int frame_size)
-{
- unsigned char *data;
- bool match = true;
-
- frame_size >>= 1;
-
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- data = rx_buffer->skb->data;
-#else
- data = kmap(rx_buffer->page);
-#endif
-
- if (data[3] != 0xFF ||
- data[frame_size + 10] != 0xBE ||
- data[frame_size + 12] != 0xAF)
- match = false;
-
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
- kunmap(rx_buffer->page);
-
-#endif
- return match;
-}
-
-static u16 igb_clean_test_rings(struct igb_ring *rx_ring,
- struct igb_ring *tx_ring,
- unsigned int size)
-{
- union e1000_adv_rx_desc *rx_desc;
- struct igb_rx_buffer *rx_buffer_info;
- struct igb_tx_buffer *tx_buffer_info;
- u16 rx_ntc, tx_ntc, count = 0;
-
- /* initialize next to clean and descriptor values */
- rx_ntc = rx_ring->next_to_clean;
- tx_ntc = tx_ring->next_to_clean;
- rx_desc = IGB_RX_DESC(rx_ring, rx_ntc);
-
- while (igb_test_staterr(rx_desc, E1000_RXD_STAT_DD)) {
- /* check rx buffer */
- rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc];
-
- /* sync Rx buffer for CPU read */
- dma_sync_single_for_cpu(rx_ring->dev,
- rx_buffer_info->dma,
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- IGB_RX_HDR_LEN,
-#else
- IGB_RX_BUFSZ,
-#endif
- DMA_FROM_DEVICE);
-
- /* verify contents of skb */
- if (igb_check_lbtest_frame(rx_buffer_info, size))
- count++;
-
- /* sync Rx buffer for device write */
- dma_sync_single_for_device(rx_ring->dev,
- rx_buffer_info->dma,
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- IGB_RX_HDR_LEN,
-#else
- IGB_RX_BUFSZ,
-#endif
- DMA_FROM_DEVICE);
-
- /* unmap buffer on tx side */
- tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc];
- igb_unmap_and_free_tx_resource(tx_ring, tx_buffer_info);
-
- /* increment rx/tx next to clean counters */
- rx_ntc++;
- if (rx_ntc == rx_ring->count)
- rx_ntc = 0;
- tx_ntc++;
- if (tx_ntc == tx_ring->count)
- tx_ntc = 0;
-
- /* fetch next descriptor */
- rx_desc = IGB_RX_DESC(rx_ring, rx_ntc);
- }
-
- /* re-map buffers to ring, store next to clean values */
- igb_alloc_rx_buffers(rx_ring, count);
- rx_ring->next_to_clean = rx_ntc;
- tx_ring->next_to_clean = tx_ntc;
-
- return count;
-}
-
-static int igb_run_loopback_test(struct igb_adapter *adapter)
-{
- struct igb_ring *tx_ring = &adapter->test_tx_ring;
- struct igb_ring *rx_ring = &adapter->test_rx_ring;
- u16 i, j, lc, good_cnt;
- int ret_val = 0;
- unsigned int size = IGB_RX_HDR_LEN;
- netdev_tx_t tx_ret_val;
- struct sk_buff *skb;
-
- /* allocate test skb */
- skb = alloc_skb(size, GFP_KERNEL);
- if (!skb)
- return 11;
-
- /* place data into test skb */
- igb_create_lbtest_frame(skb, size);
- skb_put(skb, size);
-
- /*
- * Calculate the loop count based on the largest descriptor ring
- * The idea is to wrap the largest ring a number of times using 64
- * send/receive pairs during each loop
- */
-
- if (rx_ring->count <= tx_ring->count)
- lc = ((tx_ring->count / 64) * 2) + 1;
- else
- lc = ((rx_ring->count / 64) * 2) + 1;
-
- for (j = 0; j <= lc; j++) { /* loop count loop */
- /* reset count of good packets */
- good_cnt = 0;
-
- /* place 64 packets on the transmit queue*/
- for (i = 0; i < 64; i++) {
- skb_get(skb);
- tx_ret_val = igb_xmit_frame_ring(skb, tx_ring);
- if (tx_ret_val == NETDEV_TX_OK)
- good_cnt++;
- }
-
- if (good_cnt != 64) {
- ret_val = 12;
- break;
- }
-
- /* allow 200 milliseconds for packets to go from tx to rx */
- msleep(200);
-
- good_cnt = igb_clean_test_rings(rx_ring, tx_ring, size);
- if (good_cnt != 64) {
- ret_val = 13;
- break;
- }
- } /* end loop count loop */
-
- /* free the original skb */
- kfree_skb(skb);
-
- return ret_val;
-}
-
-static int igb_loopback_test(struct igb_adapter *adapter, u64 *data)
-{
- /* PHY loopback cannot be performed if SoL/IDER
- * sessions are active */
- if (e1000_check_reset_block(&adapter->hw)) {
- dev_err(pci_dev_to_dev(adapter->pdev),
- "Cannot do PHY loopback test "
- "when SoL/IDER is active.\n");
- *data = 0;
- goto out;
- }
- if (adapter->hw.mac.type == e1000_i354) {
- dev_info(&adapter->pdev->dev,
- "Loopback test not supported on i354.\n");
- *data = 0;
- goto out;
- }
- *data = igb_setup_desc_rings(adapter);
- if (*data)
- goto out;
- *data = igb_setup_loopback_test(adapter);
- if (*data)
- goto err_loopback;
- *data = igb_run_loopback_test(adapter);
-
- igb_loopback_cleanup(adapter);
-
-err_loopback:
- igb_free_desc_rings(adapter);
-out:
- return *data;
-}
-
-static int igb_link_test(struct igb_adapter *adapter, u64 *data)
-{
- u32 link;
- int i, time;
-
- *data = 0;
- time = 0;
- if (adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
- int i = 0;
- adapter->hw.mac.serdes_has_link = FALSE;
-
- /* On some blade server designs, link establishment
- * could take as long as 2-3 minutes */
- do {
- e1000_check_for_link(&adapter->hw);
- if (adapter->hw.mac.serdes_has_link)
- goto out;
- msleep(20);
- } while (i++ < 3750);
-
- *data = 1;
- } else {
- for (i=0; i < IGB_MAX_LINK_TRIES; i++) {
- link = igb_has_link(adapter);
- if (link)
- goto out;
- else {
- time++;
- msleep(1000);
- }
- }
- if (!link)
- *data = 1;
- }
- out:
- return *data;
-}
-
-static void igb_diag_test(struct net_device *netdev,
- struct ethtool_test *eth_test, u64 *data)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- u16 autoneg_advertised;
- u8 forced_speed_duplex, autoneg;
- bool if_running = netif_running(netdev);
-
- set_bit(__IGB_TESTING, &adapter->state);
- if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
- /* Offline tests */
-
- /* save speed, duplex, autoneg settings */
- autoneg_advertised = adapter->hw.phy.autoneg_advertised;
- forced_speed_duplex = adapter->hw.mac.forced_speed_duplex;
- autoneg = adapter->hw.mac.autoneg;
-
- dev_info(pci_dev_to_dev(adapter->pdev), "offline testing starting\n");
-
- /* power up link for link test */
- igb_power_up_link(adapter);
-
- /* Link test performed before hardware reset so autoneg doesn't
- * interfere with test result */
- if (igb_link_test(adapter, &data[4]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- if (if_running)
- /* indicate we're in test mode */
- dev_close(netdev);
- else
- igb_reset(adapter);
-
- if (igb_reg_test(adapter, &data[0]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- igb_reset(adapter);
- if (igb_eeprom_test(adapter, &data[1]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- igb_reset(adapter);
- if (igb_intr_test(adapter, &data[2]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- igb_reset(adapter);
-
- /* power up link for loopback test */
- igb_power_up_link(adapter);
-
- if (igb_loopback_test(adapter, &data[3]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- /* restore speed, duplex, autoneg settings */
- adapter->hw.phy.autoneg_advertised = autoneg_advertised;
- adapter->hw.mac.forced_speed_duplex = forced_speed_duplex;
- adapter->hw.mac.autoneg = autoneg;
-
- /* force this routine to wait until autoneg complete/timeout */
- adapter->hw.phy.autoneg_wait_to_complete = TRUE;
- igb_reset(adapter);
- adapter->hw.phy.autoneg_wait_to_complete = FALSE;
-
- clear_bit(__IGB_TESTING, &adapter->state);
- if (if_running)
- dev_open(netdev);
- } else {
- dev_info(pci_dev_to_dev(adapter->pdev), "online testing starting\n");
-
- /* PHY is powered down when interface is down */
- if (if_running && igb_link_test(adapter, &data[4]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
- else
- data[4] = 0;
-
- /* Online tests aren't run; pass by default */
- data[0] = 0;
- data[1] = 0;
- data[2] = 0;
- data[3] = 0;
-
- clear_bit(__IGB_TESTING, &adapter->state);
- }
- msleep_interruptible(4 * 1000);
-}
-
-static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- wol->supported = WAKE_UCAST | WAKE_MCAST |
- WAKE_BCAST | WAKE_MAGIC |
- WAKE_PHY;
- wol->wolopts = 0;
-
- if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED))
- return;
-
- /* apply any specific unsupported masks here */
- switch (adapter->hw.device_id) {
- default:
- break;
- }
-
- if (adapter->wol & E1000_WUFC_EX)
- wol->wolopts |= WAKE_UCAST;
- if (adapter->wol & E1000_WUFC_MC)
- wol->wolopts |= WAKE_MCAST;
- if (adapter->wol & E1000_WUFC_BC)
- wol->wolopts |= WAKE_BCAST;
- if (adapter->wol & E1000_WUFC_MAG)
- wol->wolopts |= WAKE_MAGIC;
- if (adapter->wol & E1000_WUFC_LNKC)
- wol->wolopts |= WAKE_PHY;
-}
-
-static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
- return -EOPNOTSUPP;
-
- if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED))
- return wol->wolopts ? -EOPNOTSUPP : 0;
-
- /* these settings will always override what we currently have */
- adapter->wol = 0;
-
- if (wol->wolopts & WAKE_UCAST)
- adapter->wol |= E1000_WUFC_EX;
- if (wol->wolopts & WAKE_MCAST)
- adapter->wol |= E1000_WUFC_MC;
- if (wol->wolopts & WAKE_BCAST)
- adapter->wol |= E1000_WUFC_BC;
- if (wol->wolopts & WAKE_MAGIC)
- adapter->wol |= E1000_WUFC_MAG;
- if (wol->wolopts & WAKE_PHY)
- adapter->wol |= E1000_WUFC_LNKC;
- device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
-
- return 0;
-}
-
-/* bit defines for adapter->led_status */
-#ifdef HAVE_ETHTOOL_SET_PHYS_ID
-static int igb_set_phys_id(struct net_device *netdev,
- enum ethtool_phys_id_state state)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
- switch (state) {
- case ETHTOOL_ID_ACTIVE:
- e1000_blink_led(hw);
- return 2;
- case ETHTOOL_ID_ON:
- e1000_led_on(hw);
- break;
- case ETHTOOL_ID_OFF:
- e1000_led_off(hw);
- break;
- case ETHTOOL_ID_INACTIVE:
- e1000_led_off(hw);
- e1000_cleanup_led(hw);
- break;
- }
-
- return 0;
-}
-#else
-static int igb_phys_id(struct net_device *netdev, u32 data)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- unsigned long timeout;
-
- timeout = data * 1000;
-
- /*
- * msleep_interruptable only accepts unsigned int so we are limited
- * in how long a duration we can wait
- */
- if (!timeout || timeout > UINT_MAX)
- timeout = UINT_MAX;
-
- e1000_blink_led(hw);
- msleep_interruptible(timeout);
-
- e1000_led_off(hw);
- e1000_cleanup_led(hw);
-
- return 0;
-}
-#endif /* HAVE_ETHTOOL_SET_PHYS_ID */
-
-static int igb_set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *ec)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- int i;
-
- if ((ec->rx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
- ((ec->rx_coalesce_usecs > 3) &&
- (ec->rx_coalesce_usecs < IGB_MIN_ITR_USECS)) ||
- (ec->rx_coalesce_usecs == 2))
- {
- printk("set_coalesce:invalid parameter..");
- return -EINVAL;
- }
-
- if ((ec->tx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
- ((ec->tx_coalesce_usecs > 3) &&
- (ec->tx_coalesce_usecs < IGB_MIN_ITR_USECS)) ||
- (ec->tx_coalesce_usecs == 2))
- return -EINVAL;
-
- if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs)
- return -EINVAL;
-
- if (ec->tx_max_coalesced_frames_irq)
- adapter->tx_work_limit = ec->tx_max_coalesced_frames_irq;
-
- /* If ITR is disabled, disable DMAC */
- if (ec->rx_coalesce_usecs == 0) {
- adapter->dmac = IGB_DMAC_DISABLE;
- }
-
- /* convert to rate of irq's per second */
- if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3)
- adapter->rx_itr_setting = ec->rx_coalesce_usecs;
- else
- adapter->rx_itr_setting = ec->rx_coalesce_usecs << 2;
-
- /* convert to rate of irq's per second */
- if (adapter->flags & IGB_FLAG_QUEUE_PAIRS)
- adapter->tx_itr_setting = adapter->rx_itr_setting;
- else if (ec->tx_coalesce_usecs && ec->tx_coalesce_usecs <= 3)
- adapter->tx_itr_setting = ec->tx_coalesce_usecs;
- else
- adapter->tx_itr_setting = ec->tx_coalesce_usecs << 2;
-
- for (i = 0; i < adapter->num_q_vectors; i++) {
- struct igb_q_vector *q_vector = adapter->q_vector[i];
- q_vector->tx.work_limit = adapter->tx_work_limit;
- if (q_vector->rx.ring)
- q_vector->itr_val = adapter->rx_itr_setting;
- else
- q_vector->itr_val = adapter->tx_itr_setting;
- if (q_vector->itr_val && q_vector->itr_val <= 3)
- q_vector->itr_val = IGB_START_ITR;
- q_vector->set_itr = 1;
- }
-
- return 0;
-}
-
-static int igb_get_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *ec)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- if (adapter->rx_itr_setting <= 3)
- ec->rx_coalesce_usecs = adapter->rx_itr_setting;
- else
- ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2;
-
- ec->tx_max_coalesced_frames_irq = adapter->tx_work_limit;
-
- if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) {
- if (adapter->tx_itr_setting <= 3)
- ec->tx_coalesce_usecs = adapter->tx_itr_setting;
- else
- ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2;
- }
-
- return 0;
-}
-
-static int igb_nway_reset(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- if (netif_running(netdev))
- igb_reinit_locked(adapter);
- return 0;
-}
-
-#ifdef HAVE_ETHTOOL_GET_SSET_COUNT
-static int igb_get_sset_count(struct net_device *netdev, int sset)
-{
- switch (sset) {
- case ETH_SS_STATS:
- return IGB_STATS_LEN;
- case ETH_SS_TEST:
- return IGB_TEST_LEN;
- default:
- return -ENOTSUPP;
- }
-}
-#else
-static int igb_get_stats_count(struct net_device *netdev)
-{
- return IGB_STATS_LEN;
-}
-
-static int igb_diag_test_count(struct net_device *netdev)
-{
- return IGB_TEST_LEN;
-}
-#endif
-
-static void igb_get_ethtool_stats(struct net_device *netdev,
- struct ethtool_stats *stats, u64 *data)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-#ifdef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats *net_stats = &netdev->stats;
-#else
- struct net_device_stats *net_stats = &adapter->net_stats;
-#endif
- u64 *queue_stat;
- int i, j, k;
- char *p;
-
- igb_update_stats(adapter);
-
- for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
- p = (char *)adapter + igb_gstrings_stats[i].stat_offset;
- data[i] = (igb_gstrings_stats[i].sizeof_stat ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
- }
- for (j = 0; j < IGB_NETDEV_STATS_LEN; j++, i++) {
- p = (char *)net_stats + igb_gstrings_net_stats[j].stat_offset;
- data[i] = (igb_gstrings_net_stats[j].sizeof_stat ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
- }
- for (j = 0; j < adapter->num_tx_queues; j++) {
- queue_stat = (u64 *)&adapter->tx_ring[j]->tx_stats;
- for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++)
- data[i] = queue_stat[k];
- }
- for (j = 0; j < adapter->num_rx_queues; j++) {
- queue_stat = (u64 *)&adapter->rx_ring[j]->rx_stats;
- for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++)
- data[i] = queue_stat[k];
- }
-}
-
-static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- u8 *p = data;
- int i;
-
- switch (stringset) {
- case ETH_SS_TEST:
- memcpy(data, *igb_gstrings_test,
- IGB_TEST_LEN*ETH_GSTRING_LEN);
- break;
- case ETH_SS_STATS:
- for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
- memcpy(p, igb_gstrings_stats[i].stat_string,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < IGB_NETDEV_STATS_LEN; i++) {
- memcpy(p, igb_gstrings_net_stats[i].stat_string,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < adapter->num_tx_queues; i++) {
- sprintf(p, "tx_queue_%u_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "tx_queue_%u_bytes", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "tx_queue_%u_restart", i);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < adapter->num_rx_queues; i++) {
- sprintf(p, "rx_queue_%u_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_bytes", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_drops", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_csum_err", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_alloc_failed", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_ipv4_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_ipv4e_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_ipv6_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_ipv6e_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_tcp_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_udp_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_sctp_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_nfs_packets", i);
- p += ETH_GSTRING_LEN;
- }
-/* BUG_ON(p - data != IGB_STATS_LEN * ETH_GSTRING_LEN); */
- break;
- }
-}
-
-#ifdef HAVE_ETHTOOL_GET_TS_INFO
-static int igb_get_ts_info(struct net_device *dev,
- struct ethtool_ts_info *info)
-{
- struct igb_adapter *adapter = netdev_priv(dev);
-
- switch (adapter->hw.mac.type) {
-#ifdef HAVE_PTP_1588_CLOCK
- case e1000_82575:
- info->so_timestamping =
- SOF_TIMESTAMPING_TX_SOFTWARE |
- SOF_TIMESTAMPING_RX_SOFTWARE |
- SOF_TIMESTAMPING_SOFTWARE;
- return 0;
- case e1000_82576:
- case e1000_82580:
- case e1000_i350:
- case e1000_i354:
- case e1000_i210:
- case e1000_i211:
- info->so_timestamping =
- SOF_TIMESTAMPING_TX_SOFTWARE |
- SOF_TIMESTAMPING_RX_SOFTWARE |
- SOF_TIMESTAMPING_SOFTWARE |
- SOF_TIMESTAMPING_TX_HARDWARE |
- SOF_TIMESTAMPING_RX_HARDWARE |
- SOF_TIMESTAMPING_RAW_HARDWARE;
-
- if (adapter->ptp_clock)
- info->phc_index = ptp_clock_index(adapter->ptp_clock);
- else
- info->phc_index = -1;
-
- info->tx_types =
- (1 << HWTSTAMP_TX_OFF) |
- (1 << HWTSTAMP_TX_ON);
-
- info->rx_filters = 1 << HWTSTAMP_FILTER_NONE;
-
- /* 82576 does not support timestamping all packets. */
- if (adapter->hw.mac.type >= e1000_82580)
- info->rx_filters |= 1 << HWTSTAMP_FILTER_ALL;
- else
- info->rx_filters |=
- (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
- (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
- (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
- (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
- (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
- (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
- (1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
-
- return 0;
-#endif /* HAVE_PTP_1588_CLOCK */
- default:
- return -EOPNOTSUPP;
- }
-}
-#endif /* HAVE_ETHTOOL_GET_TS_INFO */
-
-#ifdef CONFIG_PM_RUNTIME
-static int igb_ethtool_begin(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- pm_runtime_get_sync(&adapter->pdev->dev);
-
- return 0;
-}
-
-static void igb_ethtool_complete(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- pm_runtime_put(&adapter->pdev->dev);
-}
-#endif /* CONFIG_PM_RUNTIME */
-
-#ifndef HAVE_NDO_SET_FEATURES
-static u32 igb_get_rx_csum(struct net_device *netdev)
-{
- return !!(netdev->features & NETIF_F_RXCSUM);
-}
-
-static int igb_set_rx_csum(struct net_device *netdev, u32 data)
-{
- const u32 feature_list = NETIF_F_RXCSUM;
-
- if (data)
- netdev->features |= feature_list;
- else
- netdev->features &= ~feature_list;
-
- return 0;
-}
-
-static int igb_set_tx_csum(struct net_device *netdev, u32 data)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-#ifdef NETIF_F_IPV6_CSUM
- u32 feature_list = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-#else
- u32 feature_list = NETIF_F_IP_CSUM;
-#endif
-
- if (adapter->hw.mac.type >= e1000_82576)
- feature_list |= NETIF_F_SCTP_CSUM;
-
- if (data)
- netdev->features |= feature_list;
- else
- netdev->features &= ~feature_list;
-
- return 0;
-}
-
-#ifdef NETIF_F_TSO
-static int igb_set_tso(struct net_device *netdev, u32 data)
-{
-#ifdef NETIF_F_TSO6
- const u32 feature_list = NETIF_F_TSO | NETIF_F_TSO6;
-#else
- const u32 feature_list = NETIF_F_TSO;
-#endif
-
- if (data)
- netdev->features |= feature_list;
- else
- netdev->features &= ~feature_list;
-
-#ifndef HAVE_NETDEV_VLAN_FEATURES
- if (!data) {
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct net_device *v_netdev;
- int i;
-
- /* disable TSO on all VLANs if they're present */
- if (!adapter->vlgrp)
- goto tso_out;
-
- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
- v_netdev = vlan_group_get_device(adapter->vlgrp, i);
- if (!v_netdev)
- continue;
-
- v_netdev->features &= ~feature_list;
- vlan_group_set_device(adapter->vlgrp, i, v_netdev);
- }
- }
-
-tso_out:
-
-#endif /* HAVE_NETDEV_VLAN_FEATURES */
- return 0;
-}
-
-#endif /* NETIF_F_TSO */
-#ifdef ETHTOOL_GFLAGS
-static int igb_set_flags(struct net_device *netdev, u32 data)
-{
- u32 supported_flags = ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
- ETH_FLAG_RXHASH;
-#ifndef HAVE_VLAN_RX_REGISTER
- u32 changed = netdev->features ^ data;
-#endif
- int rc;
-#ifndef IGB_NO_LRO
-
- supported_flags |= ETH_FLAG_LRO;
-#endif
- /*
- * Since there is no support for separate tx vlan accel
- * enabled make sure tx flag is cleared if rx is.
- */
- if (!(data & ETH_FLAG_RXVLAN))
- data &= ~ETH_FLAG_TXVLAN;
-
- rc = ethtool_op_set_flags(netdev, data, supported_flags);
- if (rc)
- return rc;
-#ifndef HAVE_VLAN_RX_REGISTER
-
- if (changed & ETH_FLAG_RXVLAN)
- igb_vlan_mode(netdev, data);
-#endif
-
- return 0;
-}
-
-#endif /* ETHTOOL_GFLAGS */
-#endif /* HAVE_NDO_SET_FEATURES */
-#ifdef ETHTOOL_SADV_COAL
-static int igb_set_adv_coal(struct net_device *netdev, struct ethtool_value *edata)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- switch (edata->data) {
- case IGB_DMAC_DISABLE:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_MIN:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_500:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_EN_DEFAULT:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_2000:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_3000:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_4000:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_5000:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_6000:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_7000:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_8000:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_9000:
- adapter->dmac = edata->data;
- break;
- case IGB_DMAC_MAX:
- adapter->dmac = edata->data;
- break;
- default:
- adapter->dmac = IGB_DMAC_DISABLE;
- printk("set_dmac: invalid setting, setting DMAC to %d\n",
- adapter->dmac);
- }
- printk("%s: setting DMAC to %d\n", netdev->name, adapter->dmac);
- return 0;
-}
-#endif /* ETHTOOL_SADV_COAL */
-#ifdef ETHTOOL_GADV_COAL
-static void igb_get_dmac(struct net_device *netdev,
- struct ethtool_value *edata)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- edata->data = adapter->dmac;
-
- return;
-}
-#endif
-
-#ifdef ETHTOOL_GEEE
-static int igb_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 ret_val;
- u16 phy_data;
-
- if ((hw->mac.type < e1000_i350) ||
- (hw->phy.media_type != e1000_media_type_copper))
- return -EOPNOTSUPP;
-
- edata->supported = (SUPPORTED_1000baseT_Full |
- SUPPORTED_100baseT_Full);
-
- if (!hw->dev_spec._82575.eee_disable)
- edata->advertised =
- mmd_eee_adv_to_ethtool_adv_t(adapter->eee_advert);
-
- /* The IPCNFG and EEER registers are not supported on I354. */
- if (hw->mac.type == e1000_i354) {
- e1000_get_eee_status_i354(hw, (bool *)&edata->eee_active);
- } else {
- u32 eeer;
-
- eeer = E1000_READ_REG(hw, E1000_EEER);
-
- /* EEE status on negotiated link */
- if (eeer & E1000_EEER_EEE_NEG)
- edata->eee_active = true;
-
- if (eeer & E1000_EEER_TX_LPI_EN)
- edata->tx_lpi_enabled = true;
- }
-
- /* EEE Link Partner Advertised */
- switch (hw->mac.type) {
- case e1000_i350:
- ret_val = e1000_read_emi_reg(hw, E1000_EEE_LP_ADV_ADDR_I350,
- &phy_data);
- if (ret_val)
- return -ENODATA;
-
- edata->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data);
-
- break;
- case e1000_i354:
- case e1000_i210:
- case e1000_i211:
- ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_LP_ADV_ADDR_I210,
- E1000_EEE_LP_ADV_DEV_I210,
- &phy_data);
- if (ret_val)
- return -ENODATA;
-
- edata->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data);
-
- break;
- default:
- break;
- }
-
- edata->eee_enabled = !hw->dev_spec._82575.eee_disable;
-
- if ((hw->mac.type == e1000_i354) &&
- (edata->eee_enabled))
- edata->tx_lpi_enabled = true;
-
- /*
- * report correct negotiated EEE status for devices that
- * wrongly report EEE at half-duplex
- */
- if (adapter->link_duplex == HALF_DUPLEX) {
- edata->eee_enabled = false;
- edata->eee_active = false;
- edata->tx_lpi_enabled = false;
- edata->advertised &= ~edata->advertised;
- }
-
- return 0;
-}
-#endif
-
-#ifdef ETHTOOL_SEEE
-static int igb_set_eee(struct net_device *netdev,
- struct ethtool_eee *edata)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- struct ethtool_eee eee_curr;
- s32 ret_val;
-
- if ((hw->mac.type < e1000_i350) ||
- (hw->phy.media_type != e1000_media_type_copper))
- return -EOPNOTSUPP;
-
- ret_val = igb_get_eee(netdev, &eee_curr);
- if (ret_val)
- return ret_val;
-
- if (eee_curr.eee_enabled) {
- if (eee_curr.tx_lpi_enabled != edata->tx_lpi_enabled) {
- dev_err(pci_dev_to_dev(adapter->pdev),
- "Setting EEE tx-lpi is not supported\n");
- return -EINVAL;
- }
-
- /* Tx LPI time is not implemented currently */
- if (edata->tx_lpi_timer) {
- dev_err(pci_dev_to_dev(adapter->pdev),
- "Setting EEE Tx LPI timer is not supported\n");
- return -EINVAL;
- }
-
- if (edata->advertised &
- ~(ADVERTISE_100_FULL | ADVERTISE_1000_FULL)) {
- dev_err(pci_dev_to_dev(adapter->pdev),
- "EEE Advertisement supports only 100Tx and or 100T full duplex\n");
- return -EINVAL;
- }
-
- } else if (!edata->eee_enabled) {
- dev_err(pci_dev_to_dev(adapter->pdev),
- "Setting EEE options is not supported with EEE disabled\n");
- return -EINVAL;
- }
-
- adapter->eee_advert = ethtool_adv_to_mmd_eee_adv_t(edata->advertised);
-
- if (hw->dev_spec._82575.eee_disable != !edata->eee_enabled) {
- hw->dev_spec._82575.eee_disable = !edata->eee_enabled;
-
- /* reset link */
- if (netif_running(netdev))
- igb_reinit_locked(adapter);
- else
- igb_reset(adapter);
- }
-
- return 0;
-}
-#endif /* ETHTOOL_SEEE */
-
-#ifdef ETHTOOL_GRXRINGS
-static int igb_get_rss_hash_opts(struct igb_adapter *adapter,
- struct ethtool_rxnfc *cmd)
-{
- cmd->data = 0;
-
- /* Report default options for RSS on igb */
- switch (cmd->flow_type) {
- case TCP_V4_FLOW:
- cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- case UDP_V4_FLOW:
- if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV4_UDP)
- cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- case SCTP_V4_FLOW:
- case AH_ESP_V4_FLOW:
- case AH_V4_FLOW:
- case ESP_V4_FLOW:
- case IPV4_FLOW:
- cmd->data |= RXH_IP_SRC | RXH_IP_DST;
- break;
- case TCP_V6_FLOW:
- cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- case UDP_V6_FLOW:
- if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV6_UDP)
- cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- case SCTP_V6_FLOW:
- case AH_ESP_V6_FLOW:
- case AH_V6_FLOW:
- case ESP_V6_FLOW:
- case IPV6_FLOW:
- cmd->data |= RXH_IP_SRC | RXH_IP_DST;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int igb_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
-#ifdef HAVE_ETHTOOL_GET_RXNFC_VOID_RULE_LOCS
- void *rule_locs)
-#else
- u32 *rule_locs)
-#endif
-{
- struct igb_adapter *adapter = netdev_priv(dev);
- int ret = -EOPNOTSUPP;
-
- switch (cmd->cmd) {
- case ETHTOOL_GRXRINGS:
- cmd->data = adapter->num_rx_queues;
- ret = 0;
- break;
- case ETHTOOL_GRXFH:
- ret = igb_get_rss_hash_opts(adapter, cmd);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-#define UDP_RSS_FLAGS (IGB_FLAG_RSS_FIELD_IPV4_UDP | \
- IGB_FLAG_RSS_FIELD_IPV6_UDP)
-static int igb_set_rss_hash_opt(struct igb_adapter *adapter,
- struct ethtool_rxnfc *nfc)
-{
- u32 flags = adapter->flags;
-
- /*
- * RSS does not support anything other than hashing
- * to queues on src and dst IPs and ports
- */
- if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
- RXH_L4_B_0_1 | RXH_L4_B_2_3))
- return -EINVAL;
-
- switch (nfc->flow_type) {
- case TCP_V4_FLOW:
- case TCP_V6_FLOW:
- if (!(nfc->data & RXH_IP_SRC) ||
- !(nfc->data & RXH_IP_DST) ||
- !(nfc->data & RXH_L4_B_0_1) ||
- !(nfc->data & RXH_L4_B_2_3))
- return -EINVAL;
- break;
- case UDP_V4_FLOW:
- if (!(nfc->data & RXH_IP_SRC) ||
- !(nfc->data & RXH_IP_DST))
- return -EINVAL;
- switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
- case 0:
- flags &= ~IGB_FLAG_RSS_FIELD_IPV4_UDP;
- break;
- case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
- flags |= IGB_FLAG_RSS_FIELD_IPV4_UDP;
- break;
- default:
- return -EINVAL;
- }
- break;
- case UDP_V6_FLOW:
- if (!(nfc->data & RXH_IP_SRC) ||
- !(nfc->data & RXH_IP_DST))
- return -EINVAL;
- switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
- case 0:
- flags &= ~IGB_FLAG_RSS_FIELD_IPV6_UDP;
- break;
- case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
- flags |= IGB_FLAG_RSS_FIELD_IPV6_UDP;
- break;
- default:
- return -EINVAL;
- }
- break;
- case AH_ESP_V4_FLOW:
- case AH_V4_FLOW:
- case ESP_V4_FLOW:
- case SCTP_V4_FLOW:
- case AH_ESP_V6_FLOW:
- case AH_V6_FLOW:
- case ESP_V6_FLOW:
- case SCTP_V6_FLOW:
- if (!(nfc->data & RXH_IP_SRC) ||
- !(nfc->data & RXH_IP_DST) ||
- (nfc->data & RXH_L4_B_0_1) ||
- (nfc->data & RXH_L4_B_2_3))
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- /* if we changed something we need to update flags */
- if (flags != adapter->flags) {
- struct e1000_hw *hw = &adapter->hw;
- u32 mrqc = E1000_READ_REG(hw, E1000_MRQC);
-
- if ((flags & UDP_RSS_FLAGS) &&
- !(adapter->flags & UDP_RSS_FLAGS))
- DPRINTK(DRV, WARNING,
- "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n");
-
- adapter->flags = flags;
-
- /* Perform hash on these packet types */
- mrqc |= E1000_MRQC_RSS_FIELD_IPV4 |
- E1000_MRQC_RSS_FIELD_IPV4_TCP |
- E1000_MRQC_RSS_FIELD_IPV6 |
- E1000_MRQC_RSS_FIELD_IPV6_TCP;
-
- mrqc &= ~(E1000_MRQC_RSS_FIELD_IPV4_UDP |
- E1000_MRQC_RSS_FIELD_IPV6_UDP);
-
- if (flags & IGB_FLAG_RSS_FIELD_IPV4_UDP)
- mrqc |= E1000_MRQC_RSS_FIELD_IPV4_UDP;
-
- if (flags & IGB_FLAG_RSS_FIELD_IPV6_UDP)
- mrqc |= E1000_MRQC_RSS_FIELD_IPV6_UDP;
-
- E1000_WRITE_REG(hw, E1000_MRQC, mrqc);
- }
-
- return 0;
-}
-
-static int igb_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
-{
- struct igb_adapter *adapter = netdev_priv(dev);
- int ret = -EOPNOTSUPP;
-
- switch (cmd->cmd) {
- case ETHTOOL_SRXFH:
- ret = igb_set_rss_hash_opt(adapter, cmd);
- break;
- default:
- break;
- }
-
- return ret;
-}
-#endif /* ETHTOOL_GRXRINGS */
-
-static const struct ethtool_ops igb_ethtool_ops = {
-#ifndef ETHTOOL_GLINKSETTINGS
- .get_settings = igb_get_settings,
-#endif
-#ifndef ETHTOOL_SLINKSETTINGS
- .set_settings = igb_set_settings,
-#endif
- .get_drvinfo = igb_get_drvinfo,
- .get_regs_len = igb_get_regs_len,
- .get_regs = igb_get_regs,
- .get_wol = igb_get_wol,
- .set_wol = igb_set_wol,
- .get_msglevel = igb_get_msglevel,
- .set_msglevel = igb_set_msglevel,
- .nway_reset = igb_nway_reset,
- .get_link = igb_get_link,
- .get_eeprom_len = igb_get_eeprom_len,
- .get_eeprom = igb_get_eeprom,
- .set_eeprom = igb_set_eeprom,
- .get_ringparam = igb_get_ringparam,
- .set_ringparam = igb_set_ringparam,
- .get_pauseparam = igb_get_pauseparam,
- .set_pauseparam = igb_set_pauseparam,
- .self_test = igb_diag_test,
- .get_strings = igb_get_strings,
-#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT
-#ifdef HAVE_ETHTOOL_SET_PHYS_ID
- .set_phys_id = igb_set_phys_id,
-#else
- .phys_id = igb_phys_id,
-#endif /* HAVE_ETHTOOL_SET_PHYS_ID */
-#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */
-#ifdef HAVE_ETHTOOL_GET_SSET_COUNT
- .get_sset_count = igb_get_sset_count,
-#else
- .get_stats_count = igb_get_stats_count,
- .self_test_count = igb_diag_test_count,
-#endif
- .get_ethtool_stats = igb_get_ethtool_stats,
-#ifdef HAVE_ETHTOOL_GET_PERM_ADDR
- .get_perm_addr = ethtool_op_get_perm_addr,
-#endif
- .get_coalesce = igb_get_coalesce,
- .set_coalesce = igb_set_coalesce,
-#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT
-#ifdef HAVE_ETHTOOL_GET_TS_INFO
- .get_ts_info = igb_get_ts_info,
-#endif /* HAVE_ETHTOOL_GET_TS_INFO */
-#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */
-#ifdef CONFIG_PM_RUNTIME
- .begin = igb_ethtool_begin,
- .complete = igb_ethtool_complete,
-#endif /* CONFIG_PM_RUNTIME */
-#ifndef HAVE_NDO_SET_FEATURES
- .get_rx_csum = igb_get_rx_csum,
- .set_rx_csum = igb_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = igb_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
-#ifdef NETIF_F_TSO
- .get_tso = ethtool_op_get_tso,
- .set_tso = igb_set_tso,
-#endif
-#ifdef ETHTOOL_GFLAGS
- .get_flags = ethtool_op_get_flags,
- .set_flags = igb_set_flags,
-#endif /* ETHTOOL_GFLAGS */
-#endif /* HAVE_NDO_SET_FEATURES */
-#ifdef ETHTOOL_GADV_COAL
- .get_advcoal = igb_get_adv_coal,
- .set_advcoal = igb_set_dmac_coal,
-#endif /* ETHTOOL_GADV_COAL */
-#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT
-#ifdef ETHTOOL_GEEE
- .get_eee = igb_get_eee,
-#endif
-#ifdef ETHTOOL_SEEE
- .set_eee = igb_set_eee,
-#endif
-#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */
-#ifdef ETHTOOL_GRXRINGS
- .get_rxnfc = igb_get_rxnfc,
- .set_rxnfc = igb_set_rxnfc,
-#endif
-};
-
-#ifdef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT
-static const struct ethtool_ops_ext igb_ethtool_ops_ext = {
- .size = sizeof(struct ethtool_ops_ext),
- .get_ts_info = igb_get_ts_info,
- .set_phys_id = igb_set_phys_id,
- .get_eee = igb_get_eee,
- .set_eee = igb_set_eee,
-};
-
-void igb_set_ethtool_ops(struct net_device *netdev)
-{
- SET_ETHTOOL_OPS(netdev, &igb_ethtool_ops);
- set_ethtool_ops_ext(netdev, &igb_ethtool_ops_ext);
-}
-#else
-void igb_set_ethtool_ops(struct net_device *netdev)
-{
- /* have to "undeclare" const on this struct to remove warnings */
- SET_ETHTOOL_OPS(netdev, (struct ethtool_ops *)&igb_ethtool_ops);
-}
-#endif /* HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT */
-#endif /* SIOCETHTOOL */
diff --git a/kernel/linux/kni/ethtool/igb/igb_main.c b/kernel/linux/kni/ethtool/igb/igb_main.c
deleted file mode 100644
index af378d2f2..000000000
--- a/kernel/linux/kni/ethtool/igb/igb_main.c
+++ /dev/null
@@ -1,10344 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
-#include <linux/netdevice.h>
-#include <linux/tcp.h>
-#ifdef NETIF_F_TSO
-#include <net/checksum.h>
-#ifdef NETIF_F_TSO6
-#include <linux/ipv6.h>
-#include <net/ip6_checksum.h>
-#endif
-#endif
-#ifdef SIOCGMIIPHY
-#include <linux/mii.h>
-#endif
-#ifdef SIOCETHTOOL
-#include <linux/ethtool.h>
-#endif
-#include <linux/if_vlan.h>
-#ifdef CONFIG_PM_RUNTIME
-#include <linux/pm_runtime.h>
-#endif /* CONFIG_PM_RUNTIME */
-
-#include <linux/if_bridge.h>
-#include "igb.h"
-#include "igb_vmdq.h"
-
-#include <linux/uio_driver.h>
-
-#if defined(DEBUG) || defined (DEBUG_DUMP) || defined (DEBUG_ICR) || defined(DEBUG_ITR)
-#define DRV_DEBUG "_debug"
-#else
-#define DRV_DEBUG
-#endif
-#define DRV_HW_PERF
-#define VERSION_SUFFIX
-
-#define MAJ 5
-#define MIN 0
-#define BUILD 6
-#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." __stringify(BUILD) VERSION_SUFFIX DRV_DEBUG DRV_HW_PERF
-
-char igb_driver_name[] = "igb";
-char igb_driver_version[] = DRV_VERSION;
-static const char igb_driver_string[] =
- "Intel(R) Gigabit Ethernet Network Driver";
-static const char igb_copyright[] =
- "Copyright (c) 2007-2013 Intel Corporation.";
-
-const struct pci_device_id igb_pci_tbl[] = {
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_BACKPLANE_1GBPS) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_SGMII) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_BACKPLANE_2_5GBPS) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_COPPER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_FIBER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SERDES) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SGMII) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_COPPER_FLASHLESS) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SERDES_FLASHLESS) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I211_COPPER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_COPPER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_FIBER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SERDES) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SGMII) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_FIBER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_QUAD_FIBER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SGMII) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SGMII) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SERDES) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_BACKPLANE) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SFP) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER_ET2) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES) },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER) },
- /* required last entry */
- {0, }
-};
-
-//MODULE_DEVICE_TABLE(pci, igb_pci_tbl);
-static void igb_set_sriov_capability(struct igb_adapter *adapter) __attribute__((__unused__));
-void igb_reset(struct igb_adapter *);
-static int igb_setup_all_tx_resources(struct igb_adapter *);
-static int igb_setup_all_rx_resources(struct igb_adapter *);
-static void igb_free_all_tx_resources(struct igb_adapter *);
-static void igb_free_all_rx_resources(struct igb_adapter *);
-static void igb_setup_mrqc(struct igb_adapter *);
-void igb_update_stats(struct igb_adapter *);
-static int igb_probe(struct pci_dev *, const struct pci_device_id *);
-static void __devexit igb_remove(struct pci_dev *pdev);
-static int igb_sw_init(struct igb_adapter *);
-static int igb_open(struct net_device *);
-static int igb_close(struct net_device *);
-static void igb_configure(struct igb_adapter *);
-static void igb_configure_tx(struct igb_adapter *);
-static void igb_configure_rx(struct igb_adapter *);
-static void igb_clean_all_tx_rings(struct igb_adapter *);
-static void igb_clean_all_rx_rings(struct igb_adapter *);
-static void igb_clean_tx_ring(struct igb_ring *);
-static void igb_set_rx_mode(struct net_device *);
-#ifdef HAVE_TIMER_SETUP
-static void igb_update_phy_info(struct timer_list *);
-static void igb_watchdog(struct timer_list *);
-#else
-static void igb_update_phy_info(unsigned long);
-static void igb_watchdog(unsigned long);
-#endif
-static void igb_watchdog_task(struct work_struct *);
-static void igb_dma_err_task(struct work_struct *);
-#ifdef HAVE_TIMER_SETUP
-static void igb_dma_err_timer(struct timer_list *);
-#else
-static void igb_dma_err_timer(unsigned long data);
-#endif
-static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, struct net_device *);
-static struct net_device_stats *igb_get_stats(struct net_device *);
-static int igb_change_mtu(struct net_device *, int);
-void igb_full_sync_mac_table(struct igb_adapter *adapter);
-static int igb_set_mac(struct net_device *, void *);
-static void igb_set_uta(struct igb_adapter *adapter);
-static irqreturn_t igb_intr(int irq, void *);
-static irqreturn_t igb_intr_msi(int irq, void *);
-static irqreturn_t igb_msix_other(int irq, void *);
-static irqreturn_t igb_msix_ring(int irq, void *);
-#ifdef IGB_DCA
-static void igb_update_dca(struct igb_q_vector *);
-static void igb_setup_dca(struct igb_adapter *);
-#endif /* IGB_DCA */
-static int igb_poll(struct napi_struct *, int);
-static bool igb_clean_tx_irq(struct igb_q_vector *);
-static bool igb_clean_rx_irq(struct igb_q_vector *, int);
-static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
-static void igb_tx_timeout(struct net_device *);
-static void igb_reset_task(struct work_struct *);
-#ifdef HAVE_VLAN_RX_REGISTER
-static void igb_vlan_mode(struct net_device *, struct vlan_group *);
-#endif
-#ifdef HAVE_VLAN_PROTOCOL
-static int igb_vlan_rx_add_vid(struct net_device *,
- __be16 proto, u16);
-static int igb_vlan_rx_kill_vid(struct net_device *,
- __be16 proto, u16);
-#elif defined HAVE_INT_NDO_VLAN_RX_ADD_VID
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
-static int igb_vlan_rx_add_vid(struct net_device *,
- __always_unused __be16 proto, u16);
-static int igb_vlan_rx_kill_vid(struct net_device *,
- __always_unused __be16 proto, u16);
-#else
-static int igb_vlan_rx_add_vid(struct net_device *, u16);
-static int igb_vlan_rx_kill_vid(struct net_device *, u16);
-#endif
-#else
-static void igb_vlan_rx_add_vid(struct net_device *, u16);
-static void igb_vlan_rx_kill_vid(struct net_device *, u16);
-#endif
-static void igb_restore_vlan(struct igb_adapter *);
-void igb_rar_set(struct igb_adapter *adapter, u32 index);
-static void igb_ping_all_vfs(struct igb_adapter *);
-static void igb_msg_task(struct igb_adapter *);
-static void igb_vmm_control(struct igb_adapter *);
-static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *);
-static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
-static void igb_process_mdd_event(struct igb_adapter *);
-#ifdef IFLA_VF_MAX
-static int igb_ndo_set_vf_mac( struct net_device *netdev, int vf, u8 *mac);
-static int igb_ndo_set_vf_vlan(struct net_device *netdev,
-#ifdef HAVE_VF_VLAN_PROTO
- int vf, u16 vlan, u8 qos, __be16 vlan_proto);
-#else
- int vf, u16 vlan, u8 qos);
-#endif
-#ifdef HAVE_VF_SPOOFCHK_CONFIGURE
-static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
- bool setting);
-#endif
-#ifdef HAVE_VF_MIN_MAX_TXRATE
-static int igb_ndo_set_vf_bw(struct net_device *, int, int, int);
-#else /* HAVE_VF_MIN_MAX_TXRATE */
-static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
-#endif /* HAVE_VF_MIN_MAX_TXRATE */
-static int igb_ndo_get_vf_config(struct net_device *netdev, int vf,
- struct ifla_vf_info *ivi);
-static void igb_check_vf_rate_limit(struct igb_adapter *);
-#endif
-static int igb_vf_configure(struct igb_adapter *adapter, int vf);
-#ifdef CONFIG_PM
-#ifdef HAVE_SYSTEM_SLEEP_PM_OPS
-static int igb_suspend(struct device *dev);
-static int igb_resume(struct device *dev);
-#ifdef CONFIG_PM_RUNTIME
-static int igb_runtime_suspend(struct device *dev);
-static int igb_runtime_resume(struct device *dev);
-static int igb_runtime_idle(struct device *dev);
-#endif /* CONFIG_PM_RUNTIME */
-static const struct dev_pm_ops igb_pm_ops = {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
- .suspend = igb_suspend,
- .resume = igb_resume,
- .freeze = igb_suspend,
- .thaw = igb_resume,
- .poweroff = igb_suspend,
- .restore = igb_resume,
-#ifdef CONFIG_PM_RUNTIME
- .runtime_suspend = igb_runtime_suspend,
- .runtime_resume = igb_runtime_resume,
- .runtime_idle = igb_runtime_idle,
-#endif
-#else /* Linux >= 2.6.34 */
- SET_SYSTEM_SLEEP_PM_OPS(igb_suspend, igb_resume)
-#ifdef CONFIG_PM_RUNTIME
- SET_RUNTIME_PM_OPS(igb_runtime_suspend, igb_runtime_resume,
- igb_runtime_idle)
-#endif /* CONFIG_PM_RUNTIME */
-#endif /* Linux version */
-};
-#else
-static int igb_suspend(struct pci_dev *pdev, pm_message_t state);
-static int igb_resume(struct pci_dev *pdev);
-#endif /* HAVE_SYSTEM_SLEEP_PM_OPS */
-#endif /* CONFIG_PM */
-#ifndef USE_REBOOT_NOTIFIER
-static void igb_shutdown(struct pci_dev *);
-#else
-static int igb_notify_reboot(struct notifier_block *, unsigned long, void *);
-static struct notifier_block igb_notifier_reboot = {
- .notifier_call = igb_notify_reboot,
- .next = NULL,
- .priority = 0
-};
-#endif
-#ifdef IGB_DCA
-static int igb_notify_dca(struct notifier_block *, unsigned long, void *);
-static struct notifier_block dca_notifier = {
- .notifier_call = igb_notify_dca,
- .next = NULL,
- .priority = 0
-};
-#endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* for netdump / net console */
-static void igb_netpoll(struct net_device *);
-#endif
-
-#ifdef HAVE_PCI_ERS
-static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
- pci_channel_state_t);
-static pci_ers_result_t igb_io_slot_reset(struct pci_dev *);
-static void igb_io_resume(struct pci_dev *);
-
-static struct pci_error_handlers igb_err_handler = {
- .error_detected = igb_io_error_detected,
- .slot_reset = igb_io_slot_reset,
- .resume = igb_io_resume,
-};
-#endif
-
-static void igb_init_fw(struct igb_adapter *adapter);
-static void igb_init_dmac(struct igb_adapter *adapter, u32 pba);
-
-static struct pci_driver igb_driver = {
- .name = igb_driver_name,
- .id_table = igb_pci_tbl,
- .probe = igb_probe,
- .remove = __devexit_p(igb_remove),
-#ifdef CONFIG_PM
-#ifdef HAVE_SYSTEM_SLEEP_PM_OPS
- .driver.pm = &igb_pm_ops,
-#else
- .suspend = igb_suspend,
- .resume = igb_resume,
-#endif /* HAVE_SYSTEM_SLEEP_PM_OPS */
-#endif /* CONFIG_PM */
-#ifndef USE_REBOOT_NOTIFIER
- .shutdown = igb_shutdown,
-#endif
-#ifdef HAVE_PCI_ERS
- .err_handler = &igb_err_handler
-#endif
-};
-
-//MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
-//MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
-//MODULE_LICENSE("GPL");
-//MODULE_VERSION(DRV_VERSION);
-
-static void igb_vfta_set(struct igb_adapter *adapter, u32 vid, bool add)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_host_mng_dhcp_cookie *mng_cookie = &hw->mng_cookie;
- u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
- u32 mask = 1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
- u32 vfta;
-
- /*
- * if this is the management vlan the only option is to add it in so
- * that the management pass through will continue to work
- */
- if ((mng_cookie->status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
- (vid == mng_cookie->vlan_id))
- add = TRUE;
-
- vfta = adapter->shadow_vfta[index];
-
- if (add)
- vfta |= mask;
- else
- vfta &= ~mask;
-
- e1000_write_vfta(hw, index, vfta);
- adapter->shadow_vfta[index] = vfta;
-}
-
-static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
-//module_param(debug, int, 0);
-//MODULE_PARM_DESC(debug, "Debug level (0=none, ..., 16=all)");
-
-/**
- * igb_init_module - Driver Registration Routine
- *
- * igb_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- **/
-static int __init igb_init_module(void)
-{
- int ret;
-
- printk(KERN_INFO "%s - version %s\n",
- igb_driver_string, igb_driver_version);
-
- printk(KERN_INFO "%s\n", igb_copyright);
-#ifdef IGB_HWMON
-/* only use IGB_PROCFS if IGB_HWMON is not defined */
-#else
-#ifdef IGB_PROCFS
- if (igb_procfs_topdir_init())
- printk(KERN_INFO "Procfs failed to initialize topdir\n");
-#endif /* IGB_PROCFS */
-#endif /* IGB_HWMON */
-
-#ifdef IGB_DCA
- dca_register_notify(&dca_notifier);
-#endif
- ret = pci_register_driver(&igb_driver);
-#ifdef USE_REBOOT_NOTIFIER
- if (ret >= 0) {
- register_reboot_notifier(&igb_notifier_reboot);
- }
-#endif
- return ret;
-}
-
-#undef module_init
-#define module_init(x) static int x(void) __attribute__((__unused__));
-module_init(igb_init_module);
-
-/**
- * igb_exit_module - Driver Exit Cleanup Routine
- *
- * igb_exit_module is called just before the driver is removed
- * from memory.
- **/
-static void __exit igb_exit_module(void)
-{
-#ifdef IGB_DCA
- dca_unregister_notify(&dca_notifier);
-#endif
-#ifdef USE_REBOOT_NOTIFIER
- unregister_reboot_notifier(&igb_notifier_reboot);
-#endif
- pci_unregister_driver(&igb_driver);
-
-#ifdef IGB_HWMON
-/* only compile IGB_PROCFS if IGB_HWMON is not defined */
-#else
-#ifdef IGB_PROCFS
- igb_procfs_topdir_exit();
-#endif /* IGB_PROCFS */
-#endif /* IGB_HWMON */
-}
-
-#undef module_exit
-#define module_exit(x) static void x(void) __attribute__((__unused__));
-module_exit(igb_exit_module);
-
-#define Q_IDX_82576(i) (((i & 0x1) << 3) + (i >> 1))
-/**
- * igb_cache_ring_register - Descriptor ring to register mapping
- * @adapter: board private structure to initialize
- *
- * Once we know the feature-set enabled for the device, we'll cache
- * the register offset the descriptor ring is assigned to.
- **/
-static void igb_cache_ring_register(struct igb_adapter *adapter)
-{
- int i = 0, j = 0;
- u32 rbase_offset = adapter->vfs_allocated_count;
-
- switch (adapter->hw.mac.type) {
- case e1000_82576:
- /* The queues are allocated for virtualization such that VF 0
- * is allocated queues 0 and 8, VF 1 queues 1 and 9, etc.
- * In order to avoid collision we start at the first free queue
- * and continue consuming queues in the same sequence
- */
- if ((adapter->rss_queues > 1) && adapter->vmdq_pools) {
- for (; i < adapter->rss_queues; i++)
- adapter->rx_ring[i]->reg_idx = rbase_offset +
- Q_IDX_82576(i);
- }
- case e1000_82575:
- case e1000_82580:
- case e1000_i350:
- case e1000_i354:
- case e1000_i210:
- case e1000_i211:
- default:
- for (; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i]->reg_idx = rbase_offset + i;
- for (; j < adapter->num_tx_queues; j++)
- adapter->tx_ring[j]->reg_idx = rbase_offset + j;
- break;
- }
-}
-
-static void igb_configure_lli(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u16 port;
-
- /* LLI should only be enabled for MSI-X or MSI interrupts */
- if (!adapter->msix_entries && !(adapter->flags & IGB_FLAG_HAS_MSI))
- return;
-
- if (adapter->lli_port) {
- /* use filter 0 for port */
- port = htons((u16)adapter->lli_port);
- E1000_WRITE_REG(hw, E1000_IMIR(0),
- (port | E1000_IMIR_PORT_IM_EN));
- E1000_WRITE_REG(hw, E1000_IMIREXT(0),
- (E1000_IMIREXT_SIZE_BP | E1000_IMIREXT_CTRL_BP));
- }
-
- if (adapter->flags & IGB_FLAG_LLI_PUSH) {
- /* use filter 1 for push flag */
- E1000_WRITE_REG(hw, E1000_IMIR(1),
- (E1000_IMIR_PORT_BP | E1000_IMIR_PORT_IM_EN));
- E1000_WRITE_REG(hw, E1000_IMIREXT(1),
- (E1000_IMIREXT_SIZE_BP | E1000_IMIREXT_CTRL_PSH));
- }
-
- if (adapter->lli_size) {
- /* use filter 2 for size */
- E1000_WRITE_REG(hw, E1000_IMIR(2),
- (E1000_IMIR_PORT_BP | E1000_IMIR_PORT_IM_EN));
- E1000_WRITE_REG(hw, E1000_IMIREXT(2),
- (adapter->lli_size | E1000_IMIREXT_CTRL_BP));
- }
-
-}
-
-/**
- * igb_write_ivar - configure ivar for given MSI-X vector
- * @hw: pointer to the HW structure
- * @msix_vector: vector number we are allocating to a given ring
- * @index: row index of IVAR register to write within IVAR table
- * @offset: column offset of in IVAR, should be multiple of 8
- *
- * This function is intended to handle the writing of the IVAR register
- * for adapters 82576 and newer. The IVAR table consists of 2 columns,
- * each containing an cause allocation for an Rx and Tx ring, and a
- * variable number of rows depending on the number of queues supported.
- **/
-static void igb_write_ivar(struct e1000_hw *hw, int msix_vector,
- int index, int offset)
-{
- u32 ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index);
-
- /* clear any bits that are currently set */
- ivar &= ~((u32)0xFF << offset);
-
- /* write vector and valid bit */
- ivar |= (msix_vector | E1000_IVAR_VALID) << offset;
-
- E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar);
-}
-
-#define IGB_N0_QUEUE -1
-static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector)
-{
- struct igb_adapter *adapter = q_vector->adapter;
- struct e1000_hw *hw = &adapter->hw;
- int rx_queue = IGB_N0_QUEUE;
- int tx_queue = IGB_N0_QUEUE;
- u32 msixbm = 0;
-
- if (q_vector->rx.ring)
- rx_queue = q_vector->rx.ring->reg_idx;
- if (q_vector->tx.ring)
- tx_queue = q_vector->tx.ring->reg_idx;
-
- switch (hw->mac.type) {
- case e1000_82575:
- /* The 82575 assigns vectors using a bitmask, which matches the
- bitmask for the EICR/EIMS/EIMC registers. To assign one
- or more queues to a vector, we write the appropriate bits
- into the MSIXBM register for that vector. */
- if (rx_queue > IGB_N0_QUEUE)
- msixbm = E1000_EICR_RX_QUEUE0 << rx_queue;
- if (tx_queue > IGB_N0_QUEUE)
- msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue;
- if (!adapter->msix_entries && msix_vector == 0)
- msixbm |= E1000_EIMS_OTHER;
- E1000_WRITE_REG_ARRAY(hw, E1000_MSIXBM(0), msix_vector, msixbm);
- q_vector->eims_value = msixbm;
- break;
- case e1000_82576:
- /*
- * 82576 uses a table that essentially consists of 2 columns
- * with 8 rows. The ordering is column-major so we use the
- * lower 3 bits as the row index, and the 4th bit as the
- * column offset.
- */
- if (rx_queue > IGB_N0_QUEUE)
- igb_write_ivar(hw, msix_vector,
- rx_queue & 0x7,
- (rx_queue & 0x8) << 1);
- if (tx_queue > IGB_N0_QUEUE)
- igb_write_ivar(hw, msix_vector,
- tx_queue & 0x7,
- ((tx_queue & 0x8) << 1) + 8);
- q_vector->eims_value = 1 << msix_vector;
- break;
- case e1000_82580:
- case e1000_i350:
- case e1000_i354:
- case e1000_i210:
- case e1000_i211:
- /*
- * On 82580 and newer adapters the scheme is similar to 82576
- * however instead of ordering column-major we have things
- * ordered row-major. So we traverse the table by using
- * bit 0 as the column offset, and the remaining bits as the
- * row index.
- */
- if (rx_queue > IGB_N0_QUEUE)
- igb_write_ivar(hw, msix_vector,
- rx_queue >> 1,
- (rx_queue & 0x1) << 4);
- if (tx_queue > IGB_N0_QUEUE)
- igb_write_ivar(hw, msix_vector,
- tx_queue >> 1,
- ((tx_queue & 0x1) << 4) + 8);
- q_vector->eims_value = 1 << msix_vector;
- break;
- default:
- BUG();
- break;
- }
-
- /* add q_vector eims value to global eims_enable_mask */
- adapter->eims_enable_mask |= q_vector->eims_value;
-
- /* configure q_vector to set itr on first interrupt */
- q_vector->set_itr = 1;
-}
-
-/**
- * igb_configure_msix - Configure MSI-X hardware
- *
- * igb_configure_msix sets up the hardware to properly
- * generate MSI-X interrupts.
- **/
-static void igb_configure_msix(struct igb_adapter *adapter)
-{
- u32 tmp;
- int i, vector = 0;
- struct e1000_hw *hw = &adapter->hw;
-
- adapter->eims_enable_mask = 0;
-
- /* set vector for other causes, i.e. link changes */
- switch (hw->mac.type) {
- case e1000_82575:
- tmp = E1000_READ_REG(hw, E1000_CTRL_EXT);
- /* enable MSI-X PBA support*/
- tmp |= E1000_CTRL_EXT_PBA_CLR;
-
- /* Auto-Mask interrupts upon ICR read. */
- tmp |= E1000_CTRL_EXT_EIAME;
- tmp |= E1000_CTRL_EXT_IRCA;
-
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, tmp);
-
- /* enable msix_other interrupt */
- E1000_WRITE_REG_ARRAY(hw, E1000_MSIXBM(0), vector++,
- E1000_EIMS_OTHER);
- adapter->eims_other = E1000_EIMS_OTHER;
-
- break;
-
- case e1000_82576:
- case e1000_82580:
- case e1000_i350:
- case e1000_i354:
- case e1000_i210:
- case e1000_i211:
- /* Turn on MSI-X capability first, or our settings
- * won't stick. And it will take days to debug. */
- E1000_WRITE_REG(hw, E1000_GPIE, E1000_GPIE_MSIX_MODE |
- E1000_GPIE_PBA | E1000_GPIE_EIAME |
- E1000_GPIE_NSICR);
-
- /* enable msix_other interrupt */
- adapter->eims_other = 1 << vector;
- tmp = (vector++ | E1000_IVAR_VALID) << 8;
-
- E1000_WRITE_REG(hw, E1000_IVAR_MISC, tmp);
- break;
- default:
- /* do nothing, since nothing else supports MSI-X */
- break;
- } /* switch (hw->mac.type) */
-
- adapter->eims_enable_mask |= adapter->eims_other;
-
- for (i = 0; i < adapter->num_q_vectors; i++)
- igb_assign_vector(adapter->q_vector[i], vector++);
-
- E1000_WRITE_FLUSH(hw);
-}
-
-/**
- * igb_request_msix - Initialize MSI-X interrupts
- *
- * igb_request_msix allocates MSI-X vectors and requests interrupts from the
- * kernel.
- **/
-static int igb_request_msix(struct igb_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- struct e1000_hw *hw = &adapter->hw;
- int i, err = 0, vector = 0, free_vector = 0;
-
- err = request_irq(adapter->msix_entries[vector].vector,
- &igb_msix_other, 0, netdev->name, adapter);
- if (err)
- goto err_out;
-
- for (i = 0; i < adapter->num_q_vectors; i++) {
- struct igb_q_vector *q_vector = adapter->q_vector[i];
-
- vector++;
-
- q_vector->itr_register = hw->hw_addr + E1000_EITR(vector);
-
- if (q_vector->rx.ring && q_vector->tx.ring)
- sprintf(q_vector->name, "%s-TxRx-%u", netdev->name,
- q_vector->rx.ring->queue_index);
- else if (q_vector->tx.ring)
- sprintf(q_vector->name, "%s-tx-%u", netdev->name,
- q_vector->tx.ring->queue_index);
- else if (q_vector->rx.ring)
- sprintf(q_vector->name, "%s-rx-%u", netdev->name,
- q_vector->rx.ring->queue_index);
- else
- sprintf(q_vector->name, "%s-unused", netdev->name);
-
- err = request_irq(adapter->msix_entries[vector].vector,
- igb_msix_ring, 0, q_vector->name,
- q_vector);
- if (err)
- goto err_free;
- }
-
- igb_configure_msix(adapter);
- return 0;
-
-err_free:
- /* free already assigned IRQs */
- free_irq(adapter->msix_entries[free_vector++].vector, adapter);
-
- vector--;
- for (i = 0; i < vector; i++) {
- free_irq(adapter->msix_entries[free_vector++].vector,
- adapter->q_vector[i]);
- }
-err_out:
- return err;
-}
-
-static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
-{
- if (adapter->msix_entries) {
- pci_disable_msix(adapter->pdev);
- kfree(adapter->msix_entries);
- adapter->msix_entries = NULL;
- } else if (adapter->flags & IGB_FLAG_HAS_MSI) {
- pci_disable_msi(adapter->pdev);
- }
-}
-
-/**
- * igb_free_q_vector - Free memory allocated for specific interrupt vector
- * @adapter: board private structure to initialize
- * @v_idx: Index of vector to be freed
- *
- * This function frees the memory allocated to the q_vector. In addition if
- * NAPI is enabled it will delete any references to the NAPI struct prior
- * to freeing the q_vector.
- **/
-static void igb_free_q_vector(struct igb_adapter *adapter, int v_idx)
-{
- struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
-
- if (q_vector->tx.ring)
- adapter->tx_ring[q_vector->tx.ring->queue_index] = NULL;
-
- if (q_vector->rx.ring)
- adapter->tx_ring[q_vector->rx.ring->queue_index] = NULL;
-
- adapter->q_vector[v_idx] = NULL;
- netif_napi_del(&q_vector->napi);
-#ifndef IGB_NO_LRO
- __skb_queue_purge(&q_vector->lrolist.active);
-#endif
- kfree(q_vector);
-}
-
-/**
- * igb_free_q_vectors - Free memory allocated for interrupt vectors
- * @adapter: board private structure to initialize
- *
- * This function frees the memory allocated to the q_vectors. In addition if
- * NAPI is enabled it will delete any references to the NAPI struct prior
- * to freeing the q_vector.
- **/
-static void igb_free_q_vectors(struct igb_adapter *adapter)
-{
- int v_idx = adapter->num_q_vectors;
-
- adapter->num_tx_queues = 0;
- adapter->num_rx_queues = 0;
- adapter->num_q_vectors = 0;
-
- while (v_idx--)
- igb_free_q_vector(adapter, v_idx);
-}
-
-/**
- * igb_clear_interrupt_scheme - reset the device to a state of no interrupts
- *
- * This function resets the device so that it has 0 rx queues, tx queues, and
- * MSI-X interrupts allocated.
- */
-static void igb_clear_interrupt_scheme(struct igb_adapter *adapter)
-{
- igb_free_q_vectors(adapter);
- igb_reset_interrupt_capability(adapter);
-}
-
-/**
- * igb_process_mdd_event
- * @adapter - board private structure
- *
- * Identify a malicious VF, disable the VF TX/RX queues and log a message.
- */
-static void igb_process_mdd_event(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 lvmmc, vfte, vfre, mdfb;
- u8 vf_queue;
-
- lvmmc = E1000_READ_REG(hw, E1000_LVMMC);
- vf_queue = lvmmc >> 29;
-
- /* VF index cannot be bigger or equal to VFs allocated */
- if (vf_queue >= adapter->vfs_allocated_count)
- return;
-
- netdev_info(adapter->netdev,
- "VF %d misbehaved. VF queues are disabled. "
- "VM misbehavior code is 0x%x\n", vf_queue, lvmmc);
-
- /* Disable VFTE and VFRE related bits */
- vfte = E1000_READ_REG(hw, E1000_VFTE);
- vfte &= ~(1 << vf_queue);
- E1000_WRITE_REG(hw, E1000_VFTE, vfte);
-
- vfre = E1000_READ_REG(hw, E1000_VFRE);
- vfre &= ~(1 << vf_queue);
- E1000_WRITE_REG(hw, E1000_VFRE, vfre);
-
- /* Disable MDFB related bit. Clear on write */
- mdfb = E1000_READ_REG(hw, E1000_MDFB);
- mdfb |= (1 << vf_queue);
- E1000_WRITE_REG(hw, E1000_MDFB, mdfb);
-
- /* Reset the specific VF */
- E1000_WRITE_REG(hw, E1000_VTCTRL(vf_queue), E1000_VTCTRL_RST);
-}
-
-/**
- * igb_disable_mdd
- * @adapter - board private structure
- *
- * Disable MDD behavior in the HW
- **/
-static void igb_disable_mdd(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 reg;
-
- if ((hw->mac.type != e1000_i350) ||
- (hw->mac.type != e1000_i354))
- return;
-
- reg = E1000_READ_REG(hw, E1000_DTXCTL);
- reg &= (~E1000_DTXCTL_MDP_EN);
- E1000_WRITE_REG(hw, E1000_DTXCTL, reg);
-}
-
-/**
- * igb_enable_mdd
- * @adapter - board private structure
- *
- * Enable the HW to detect malicious driver and sends an interrupt to
- * the driver.
- **/
-static void igb_enable_mdd(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 reg;
-
- /* Only available on i350 device */
- if (hw->mac.type != e1000_i350)
- return;
-
- reg = E1000_READ_REG(hw, E1000_DTXCTL);
- reg |= E1000_DTXCTL_MDP_EN;
- E1000_WRITE_REG(hw, E1000_DTXCTL, reg);
-}
-
-/**
- * igb_reset_sriov_capability - disable SR-IOV if enabled
- *
- * Attempt to disable single root IO virtualization capabilites present in the
- * kernel.
- **/
-static void igb_reset_sriov_capability(struct igb_adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_hw *hw = &adapter->hw;
-
- /* reclaim resources allocated to VFs */
- if (adapter->vf_data) {
- if (!pci_vfs_assigned(pdev)) {
- /*
- * disable iov and allow time for transactions to
- * clear
- */
- pci_disable_sriov(pdev);
- msleep(500);
-
- dev_info(pci_dev_to_dev(pdev), "IOV Disabled\n");
- } else {
- dev_info(pci_dev_to_dev(pdev), "IOV Not Disabled\n "
- "VF(s) are assigned to guests!\n");
- }
- /* Disable Malicious Driver Detection */
- igb_disable_mdd(adapter);
-
- /* free vf data storage */
- kfree(adapter->vf_data);
- adapter->vf_data = NULL;
-
- /* switch rings back to PF ownership */
- E1000_WRITE_REG(hw, E1000_IOVCTL,
- E1000_IOVCTL_REUSE_VFQ);
- E1000_WRITE_FLUSH(hw);
- msleep(100);
- }
-
- adapter->vfs_allocated_count = 0;
-}
-
-/**
- * igb_set_sriov_capability - setup SR-IOV if supported
- *
- * Attempt to enable single root IO virtualization capabilites present in the
- * kernel.
- **/
-static void igb_set_sriov_capability(struct igb_adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- int old_vfs = 0;
- int i;
-
- old_vfs = pci_num_vf(pdev);
- if (old_vfs) {
- dev_info(pci_dev_to_dev(pdev),
- "%d pre-allocated VFs found - override "
- "max_vfs setting of %d\n", old_vfs,
- adapter->vfs_allocated_count);
- adapter->vfs_allocated_count = old_vfs;
- }
- /* no VFs requested, do nothing */
- if (!adapter->vfs_allocated_count)
- return;
-
- /* allocate vf data storage */
- adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
- sizeof(struct vf_data_storage),
- GFP_KERNEL);
-
- if (adapter->vf_data) {
- if (!old_vfs) {
- if (pci_enable_sriov(pdev,
- adapter->vfs_allocated_count))
- goto err_out;
- }
- for (i = 0; i < adapter->vfs_allocated_count; i++)
- igb_vf_configure(adapter, i);
-
- switch (adapter->hw.mac.type) {
- case e1000_82576:
- case e1000_i350:
- /* Enable VM to VM loopback by default */
- adapter->flags |= IGB_FLAG_LOOPBACK_ENABLE;
- break;
- default:
- /* Currently no other hardware supports loopback */
- break;
- }
-
- /* DMA Coalescing is not supported in IOV mode. */
- if (adapter->hw.mac.type >= e1000_i350)
- adapter->dmac = IGB_DMAC_DISABLE;
- if (adapter->hw.mac.type < e1000_i350)
- adapter->flags |= IGB_FLAG_DETECT_BAD_DMA;
- return;
-
- }
-
-err_out:
- kfree(adapter->vf_data);
- adapter->vf_data = NULL;
- adapter->vfs_allocated_count = 0;
- dev_warn(pci_dev_to_dev(pdev),
- "Failed to initialize SR-IOV virtualization\n");
-}
-
-/**
- * igb_set_interrupt_capability - set MSI or MSI-X if supported
- *
- * Attempt to configure interrupts using the best available
- * capabilities of the hardware and kernel.
- **/
-static void igb_set_interrupt_capability(struct igb_adapter *adapter, bool msix)
-{
- struct pci_dev *pdev = adapter->pdev;
- int err;
- int numvecs, i;
-
- if (!msix)
- adapter->int_mode = IGB_INT_MODE_MSI;
-
- /* Number of supported queues. */
- adapter->num_rx_queues = adapter->rss_queues;
-
- if (adapter->vmdq_pools > 1)
- adapter->num_rx_queues += adapter->vmdq_pools - 1;
-
-#ifdef HAVE_TX_MQ
- if (adapter->vmdq_pools)
- adapter->num_tx_queues = adapter->vmdq_pools;
- else
- adapter->num_tx_queues = adapter->num_rx_queues;
-#else
- adapter->num_tx_queues = max_t(u32, 1, adapter->vmdq_pools);
-#endif
-
- switch (adapter->int_mode) {
- case IGB_INT_MODE_MSIX:
- /* start with one vector for every rx queue */
- numvecs = adapter->num_rx_queues;
-
- /* if tx handler is separate add 1 for every tx queue */
- if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS))
- numvecs += adapter->num_tx_queues;
-
- /* store the number of vectors reserved for queues */
- adapter->num_q_vectors = numvecs;
-
- /* add 1 vector for link status interrupts */
- numvecs++;
- adapter->msix_entries = kcalloc(numvecs,
- sizeof(struct msix_entry),
- GFP_KERNEL);
- if (adapter->msix_entries) {
- for (i = 0; i < numvecs; i++)
- adapter->msix_entries[i].entry = i;
-
-#ifdef HAVE_PCI_ENABLE_MSIX
- err = pci_enable_msix(pdev,
- adapter->msix_entries, numvecs);
-#else
- err = pci_enable_msix_range(pdev,
- adapter->msix_entries,
- numvecs,
- numvecs);
-#endif
- if (err == 0)
- break;
- }
- /* MSI-X failed, so fall through and try MSI */
- dev_warn(pci_dev_to_dev(pdev), "Failed to initialize MSI-X interrupts. "
- "Falling back to MSI interrupts.\n");
- igb_reset_interrupt_capability(adapter);
- case IGB_INT_MODE_MSI:
- if (!pci_enable_msi(pdev))
- adapter->flags |= IGB_FLAG_HAS_MSI;
- else
- dev_warn(pci_dev_to_dev(pdev), "Failed to initialize MSI "
- "interrupts. Falling back to legacy "
- "interrupts.\n");
- /* Fall through */
- case IGB_INT_MODE_LEGACY:
- /* disable advanced features and set number of queues to 1 */
- igb_reset_sriov_capability(adapter);
- adapter->vmdq_pools = 0;
- adapter->rss_queues = 1;
- adapter->flags |= IGB_FLAG_QUEUE_PAIRS;
- adapter->num_rx_queues = 1;
- adapter->num_tx_queues = 1;
- adapter->num_q_vectors = 1;
- /* Don't do anything; this is system default */
- break;
- }
-}
-
-static void igb_add_ring(struct igb_ring *ring,
- struct igb_ring_container *head)
-{
- head->ring = ring;
- head->count++;
-}
-
-/**
- * igb_alloc_q_vector - Allocate memory for a single interrupt vector
- * @adapter: board private structure to initialize
- * @v_count: q_vectors allocated on adapter, used for ring interleaving
- * @v_idx: index of vector in adapter struct
- * @txr_count: total number of Tx rings to allocate
- * @txr_idx: index of first Tx ring to allocate
- * @rxr_count: total number of Rx rings to allocate
- * @rxr_idx: index of first Rx ring to allocate
- *
- * We allocate one q_vector. If allocation fails we return -ENOMEM.
- **/
-static int igb_alloc_q_vector(struct igb_adapter *adapter,
- unsigned int v_count, unsigned int v_idx,
- unsigned int txr_count, unsigned int txr_idx,
- unsigned int rxr_count, unsigned int rxr_idx)
-{
- struct igb_q_vector *q_vector;
- struct igb_ring *ring;
- int ring_count, size;
-
- /* igb only supports 1 Tx and/or 1 Rx queue per vector */
- if (txr_count > 1 || rxr_count > 1)
- return -ENOMEM;
-
- ring_count = txr_count + rxr_count;
- size = sizeof(struct igb_q_vector) +
- (sizeof(struct igb_ring) * ring_count);
-
- /* allocate q_vector and rings */
- q_vector = kzalloc(size, GFP_KERNEL);
- if (!q_vector)
- return -ENOMEM;
-
-#ifndef IGB_NO_LRO
- /* initialize LRO */
- __skb_queue_head_init(&q_vector->lrolist.active);
-
-#endif
- /* initialize NAPI */
- netif_napi_add(adapter->netdev, &q_vector->napi,
- igb_poll, 64);
-
- /* tie q_vector and adapter together */
- adapter->q_vector[v_idx] = q_vector;
- q_vector->adapter = adapter;
-
- /* initialize work limits */
- q_vector->tx.work_limit = adapter->tx_work_limit;
-
- /* initialize ITR configuration */
- q_vector->itr_register = adapter->hw.hw_addr + E1000_EITR(0);
- q_vector->itr_val = IGB_START_ITR;
-
- /* initialize pointer to rings */
- ring = q_vector->ring;
-
- /* initialize ITR */
- if (rxr_count) {
- /* rx or rx/tx vector */
- if (!adapter->rx_itr_setting || adapter->rx_itr_setting > 3)
- q_vector->itr_val = adapter->rx_itr_setting;
- } else {
- /* tx only vector */
- if (!adapter->tx_itr_setting || adapter->tx_itr_setting > 3)
- q_vector->itr_val = adapter->tx_itr_setting;
- }
-
- if (txr_count) {
- /* assign generic ring traits */
- ring->dev = &adapter->pdev->dev;
- ring->netdev = adapter->netdev;
-
- /* configure backlink on ring */
- ring->q_vector = q_vector;
-
- /* update q_vector Tx values */
- igb_add_ring(ring, &q_vector->tx);
-
- /* For 82575, context index must be unique per ring. */
- if (adapter->hw.mac.type == e1000_82575)
- set_bit(IGB_RING_FLAG_TX_CTX_IDX, &ring->flags);
-
- /* apply Tx specific ring traits */
- ring->count = adapter->tx_ring_count;
- ring->queue_index = txr_idx;
-
- /* assign ring to adapter */
- adapter->tx_ring[txr_idx] = ring;
-
- /* push pointer to next ring */
- ring++;
- }
-
- if (rxr_count) {
- /* assign generic ring traits */
- ring->dev = &adapter->pdev->dev;
- ring->netdev = adapter->netdev;
-
- /* configure backlink on ring */
- ring->q_vector = q_vector;
-
- /* update q_vector Rx values */
- igb_add_ring(ring, &q_vector->rx);
-
-#ifndef HAVE_NDO_SET_FEATURES
- /* enable rx checksum */
- set_bit(IGB_RING_FLAG_RX_CSUM, &ring->flags);
-
-#endif
- /* set flag indicating ring supports SCTP checksum offload */
- if (adapter->hw.mac.type >= e1000_82576)
- set_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags);
-
- if ((adapter->hw.mac.type == e1000_i350) ||
- (adapter->hw.mac.type == e1000_i354))
- set_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags);
-
- /* apply Rx specific ring traits */
- ring->count = adapter->rx_ring_count;
- ring->queue_index = rxr_idx;
-
- /* assign ring to adapter */
- adapter->rx_ring[rxr_idx] = ring;
- }
-
- return 0;
-}
-
-/**
- * igb_alloc_q_vectors - Allocate memory for interrupt vectors
- * @adapter: board private structure to initialize
- *
- * We allocate one q_vector per queue interrupt. If allocation fails we
- * return -ENOMEM.
- **/
-static int igb_alloc_q_vectors(struct igb_adapter *adapter)
-{
- int q_vectors = adapter->num_q_vectors;
- int rxr_remaining = adapter->num_rx_queues;
- int txr_remaining = adapter->num_tx_queues;
- int rxr_idx = 0, txr_idx = 0, v_idx = 0;
- int err;
-
- if (q_vectors >= (rxr_remaining + txr_remaining)) {
- for (; rxr_remaining; v_idx++) {
- err = igb_alloc_q_vector(adapter, q_vectors, v_idx,
- 0, 0, 1, rxr_idx);
-
- if (err)
- goto err_out;
-
- /* update counts and index */
- rxr_remaining--;
- rxr_idx++;
- }
- }
-
- for (; v_idx < q_vectors; v_idx++) {
- int rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - v_idx);
- int tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - v_idx);
- err = igb_alloc_q_vector(adapter, q_vectors, v_idx,
- tqpv, txr_idx, rqpv, rxr_idx);
-
- if (err)
- goto err_out;
-
- /* update counts and index */
- rxr_remaining -= rqpv;
- txr_remaining -= tqpv;
- rxr_idx++;
- txr_idx++;
- }
-
- return 0;
-
-err_out:
- adapter->num_tx_queues = 0;
- adapter->num_rx_queues = 0;
- adapter->num_q_vectors = 0;
-
- while (v_idx--)
- igb_free_q_vector(adapter, v_idx);
-
- return -ENOMEM;
-}
-
-/**
- * igb_init_interrupt_scheme - initialize interrupts, allocate queues/vectors
- *
- * This function initializes the interrupts and allocates all of the queues.
- **/
-static int igb_init_interrupt_scheme(struct igb_adapter *adapter, bool msix)
-{
- struct pci_dev *pdev = adapter->pdev;
- int err;
-
- igb_set_interrupt_capability(adapter, msix);
-
- err = igb_alloc_q_vectors(adapter);
- if (err) {
- dev_err(pci_dev_to_dev(pdev), "Unable to allocate memory for vectors\n");
- goto err_alloc_q_vectors;
- }
-
- igb_cache_ring_register(adapter);
-
- return 0;
-
-err_alloc_q_vectors:
- igb_reset_interrupt_capability(adapter);
- return err;
-}
-
-/**
- * igb_request_irq - initialize interrupts
- *
- * Attempts to configure interrupts using the best available
- * capabilities of the hardware and kernel.
- **/
-static int igb_request_irq(struct igb_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
- int err = 0;
-
- if (adapter->msix_entries) {
- err = igb_request_msix(adapter);
- if (!err)
- goto request_done;
- /* fall back to MSI */
- igb_free_all_tx_resources(adapter);
- igb_free_all_rx_resources(adapter);
-
- igb_clear_interrupt_scheme(adapter);
- igb_reset_sriov_capability(adapter);
- err = igb_init_interrupt_scheme(adapter, false);
- if (err)
- goto request_done;
- igb_setup_all_tx_resources(adapter);
- igb_setup_all_rx_resources(adapter);
- igb_configure(adapter);
- }
-
- igb_assign_vector(adapter->q_vector[0], 0);
-
- if (adapter->flags & IGB_FLAG_HAS_MSI) {
- err = request_irq(pdev->irq, &igb_intr_msi, 0,
- netdev->name, adapter);
- if (!err)
- goto request_done;
-
- /* fall back to legacy interrupts */
- igb_reset_interrupt_capability(adapter);
- adapter->flags &= ~IGB_FLAG_HAS_MSI;
- }
-
- err = request_irq(pdev->irq, &igb_intr, IRQF_SHARED,
- netdev->name, adapter);
-
- if (err)
- dev_err(pci_dev_to_dev(pdev), "Error %d getting interrupt\n",
- err);
-
-request_done:
- return err;
-}
-
-static void igb_free_irq(struct igb_adapter *adapter)
-{
- if (adapter->msix_entries) {
- int vector = 0, i;
-
- free_irq(adapter->msix_entries[vector++].vector, adapter);
-
- for (i = 0; i < adapter->num_q_vectors; i++)
- free_irq(adapter->msix_entries[vector++].vector,
- adapter->q_vector[i]);
- } else {
- free_irq(adapter->pdev->irq, adapter);
- }
-}
-
-/**
- * igb_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- **/
-static void igb_irq_disable(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- /*
- * we need to be careful when disabling interrupts. The VFs are also
- * mapped into these registers and so clearing the bits can cause
- * issues on the VF drivers so we only need to clear what we set
- */
- if (adapter->msix_entries) {
- u32 regval = E1000_READ_REG(hw, E1000_EIAM);
- E1000_WRITE_REG(hw, E1000_EIAM, regval & ~adapter->eims_enable_mask);
- E1000_WRITE_REG(hw, E1000_EIMC, adapter->eims_enable_mask);
- regval = E1000_READ_REG(hw, E1000_EIAC);
- E1000_WRITE_REG(hw, E1000_EIAC, regval & ~adapter->eims_enable_mask);
- }
-
- E1000_WRITE_REG(hw, E1000_IAM, 0);
- E1000_WRITE_REG(hw, E1000_IMC, ~0);
- E1000_WRITE_FLUSH(hw);
-
- if (adapter->msix_entries) {
- int vector = 0, i;
-
- synchronize_irq(adapter->msix_entries[vector++].vector);
-
- for (i = 0; i < adapter->num_q_vectors; i++)
- synchronize_irq(adapter->msix_entries[vector++].vector);
- } else {
- synchronize_irq(adapter->pdev->irq);
- }
-}
-
-/**
- * igb_irq_enable - Enable default interrupt generation settings
- * @adapter: board private structure
- **/
-static void igb_irq_enable(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- if (adapter->msix_entries) {
- u32 ims = E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_DRSTA;
- u32 regval = E1000_READ_REG(hw, E1000_EIAC);
- E1000_WRITE_REG(hw, E1000_EIAC, regval | adapter->eims_enable_mask);
- regval = E1000_READ_REG(hw, E1000_EIAM);
- E1000_WRITE_REG(hw, E1000_EIAM, regval | adapter->eims_enable_mask);
- E1000_WRITE_REG(hw, E1000_EIMS, adapter->eims_enable_mask);
- if (adapter->vfs_allocated_count) {
- E1000_WRITE_REG(hw, E1000_MBVFIMR, 0xFF);
- ims |= E1000_IMS_VMMB;
- if (adapter->mdd)
- if ((adapter->hw.mac.type == e1000_i350) ||
- (adapter->hw.mac.type == e1000_i354))
- ims |= E1000_IMS_MDDET;
- }
- E1000_WRITE_REG(hw, E1000_IMS, ims);
- } else {
- E1000_WRITE_REG(hw, E1000_IMS, IMS_ENABLE_MASK |
- E1000_IMS_DRSTA);
- E1000_WRITE_REG(hw, E1000_IAM, IMS_ENABLE_MASK |
- E1000_IMS_DRSTA);
- }
-}
-
-static void igb_update_mng_vlan(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u16 vid = adapter->hw.mng_cookie.vlan_id;
- u16 old_vid = adapter->mng_vlan_id;
-
- if (hw->mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
- /* add VID to filter table */
- igb_vfta_set(adapter, vid, TRUE);
- adapter->mng_vlan_id = vid;
- } else {
- adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
- }
-
- if ((old_vid != (u16)IGB_MNG_VLAN_NONE) &&
- (vid != old_vid) &&
-#ifdef HAVE_VLAN_RX_REGISTER
- !vlan_group_get_device(adapter->vlgrp, old_vid)) {
-#else
- !test_bit(old_vid, adapter->active_vlans)) {
-#endif
- /* remove VID from filter table */
- igb_vfta_set(adapter, old_vid, FALSE);
- }
-}
-
-/**
- * igb_release_hw_control - release control of the h/w to f/w
- * @adapter: address of board private structure
- *
- * igb_release_hw_control resets CTRL_EXT:DRV_LOAD bit.
- * For ASF and Pass Through versions of f/w this means that the
- * driver is no longer loaded.
- *
- **/
-static void igb_release_hw_control(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl_ext;
-
- /* Let firmware take over control of h/w */
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- E1000_WRITE_REG(hw, E1000_CTRL_EXT,
- ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
-}
-
-/**
- * igb_get_hw_control - get control of the h/w from f/w
- * @adapter: address of board private structure
- *
- * igb_get_hw_control sets CTRL_EXT:DRV_LOAD bit.
- * For ASF and Pass Through versions of f/w this means that
- * the driver is loaded.
- *
- **/
-static void igb_get_hw_control(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl_ext;
-
- /* Let firmware know the driver has taken over */
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- E1000_WRITE_REG(hw, E1000_CTRL_EXT,
- ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
-}
-
-/**
- * igb_configure - configure the hardware for RX and TX
- * @adapter: private board structure
- **/
-static void igb_configure(struct igb_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- int i;
-
- igb_get_hw_control(adapter);
- igb_set_rx_mode(netdev);
-
- igb_restore_vlan(adapter);
-
- igb_setup_tctl(adapter);
- igb_setup_mrqc(adapter);
- igb_setup_rctl(adapter);
-
- igb_configure_tx(adapter);
- igb_configure_rx(adapter);
-
- e1000_rx_fifo_flush_82575(&adapter->hw);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- if (adapter->num_tx_queues > 1)
- netdev->features |= NETIF_F_MULTI_QUEUE;
- else
- netdev->features &= ~NETIF_F_MULTI_QUEUE;
-#endif
-
- /* call igb_desc_unused which always leaves
- * at least 1 descriptor unused to make sure
- * next_to_use != next_to_clean */
- for (i = 0; i < adapter->num_rx_queues; i++) {
- struct igb_ring *ring = adapter->rx_ring[i];
- igb_alloc_rx_buffers(ring, igb_desc_unused(ring));
- }
-}
-
-/**
- * igb_power_up_link - Power up the phy/serdes link
- * @adapter: address of board private structure
- **/
-void igb_power_up_link(struct igb_adapter *adapter)
-{
- e1000_phy_hw_reset(&adapter->hw);
-
- if (adapter->hw.phy.media_type == e1000_media_type_copper)
- e1000_power_up_phy(&adapter->hw);
- else
- e1000_power_up_fiber_serdes_link(&adapter->hw);
-}
-
-/**
- * igb_power_down_link - Power down the phy/serdes link
- * @adapter: address of board private structure
- */
-static void igb_power_down_link(struct igb_adapter *adapter)
-{
- if (adapter->hw.phy.media_type == e1000_media_type_copper)
- e1000_power_down_phy(&adapter->hw);
- else
- e1000_shutdown_fiber_serdes_link(&adapter->hw);
-}
-
-/* Detect and switch function for Media Auto Sense */
-static void igb_check_swap_media(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl_ext, connsw;
- bool swap_now = false;
- bool link;
-
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- connsw = E1000_READ_REG(hw, E1000_CONNSW);
- link = igb_has_link(adapter);
- (void) link;
-
- /* need to live swap if current media is copper and we have fiber/serdes
- * to go to.
- */
-
- if ((hw->phy.media_type == e1000_media_type_copper) &&
- (!(connsw & E1000_CONNSW_AUTOSENSE_EN))) {
- swap_now = true;
- } else if (!(connsw & E1000_CONNSW_SERDESD)) {
- /* copper signal takes time to appear */
- if (adapter->copper_tries < 2) {
- adapter->copper_tries++;
- connsw |= E1000_CONNSW_AUTOSENSE_CONF;
- E1000_WRITE_REG(hw, E1000_CONNSW, connsw);
- return;
- } else {
- adapter->copper_tries = 0;
- if ((connsw & E1000_CONNSW_PHYSD) &&
- (!(connsw & E1000_CONNSW_PHY_PDN))) {
- swap_now = true;
- connsw &= ~E1000_CONNSW_AUTOSENSE_CONF;
- E1000_WRITE_REG(hw, E1000_CONNSW, connsw);
- }
- }
- }
-
- if (swap_now) {
- switch (hw->phy.media_type) {
- case e1000_media_type_copper:
- dev_info(pci_dev_to_dev(adapter->pdev),
- "%s:MAS: changing media to fiber/serdes\n",
- adapter->netdev->name);
- ctrl_ext |=
- E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
- adapter->flags |= IGB_FLAG_MEDIA_RESET;
- adapter->copper_tries = 0;
- break;
- case e1000_media_type_internal_serdes:
- case e1000_media_type_fiber:
- dev_info(pci_dev_to_dev(adapter->pdev),
- "%s:MAS: changing media to copper\n",
- adapter->netdev->name);
- ctrl_ext &=
- ~E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
- adapter->flags |= IGB_FLAG_MEDIA_RESET;
- break;
- default:
- /* shouldn't get here during regular operation */
- dev_err(pci_dev_to_dev(adapter->pdev),
- "%s:AMS: Invalid media type found, returning\n",
- adapter->netdev->name);
- break;
- }
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
- }
-}
-
-#ifdef HAVE_I2C_SUPPORT
-/* igb_get_i2c_data - Reads the I2C SDA data bit
- * @hw: pointer to hardware structure
- * @i2cctl: Current value of I2CCTL register
- *
- * Returns the I2C data bit value
- */
-static int igb_get_i2c_data(void *data)
-{
- struct igb_adapter *adapter = data;
- struct e1000_hw *hw = &adapter->hw;
- s32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
-
- return (i2cctl & E1000_I2C_DATA_IN) != 0;
-}
-
-/* igb_set_i2c_data - Sets the I2C data bit
- * @data: pointer to hardware structure
- * @state: I2C data value (0 or 1) to set
- *
- * Sets the I2C data bit
- */
-static void igb_set_i2c_data(void *data, int state)
-{
- struct igb_adapter *adapter = data;
- struct e1000_hw *hw = &adapter->hw;
- s32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
-
- if (state)
- i2cctl |= E1000_I2C_DATA_OUT;
- else
- i2cctl &= ~E1000_I2C_DATA_OUT;
-
- i2cctl &= ~E1000_I2C_DATA_OE_N;
- i2cctl |= E1000_I2C_CLK_OE_N;
-
- E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cctl);
- E1000_WRITE_FLUSH(hw);
-
-}
-
-/* igb_set_i2c_clk - Sets the I2C SCL clock
- * @data: pointer to hardware structure
- * @state: state to set clock
- *
- * Sets the I2C clock line to state
- */
-static void igb_set_i2c_clk(void *data, int state)
-{
- struct igb_adapter *adapter = data;
- struct e1000_hw *hw = &adapter->hw;
- s32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
-
- if (state) {
- i2cctl |= E1000_I2C_CLK_OUT;
- i2cctl &= ~E1000_I2C_CLK_OE_N;
- } else {
- i2cctl &= ~E1000_I2C_CLK_OUT;
- i2cctl &= ~E1000_I2C_CLK_OE_N;
- }
- E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cctl);
- E1000_WRITE_FLUSH(hw);
-}
-
-/* igb_get_i2c_clk - Gets the I2C SCL clock state
- * @data: pointer to hardware structure
- *
- * Gets the I2C clock state
- */
-static int igb_get_i2c_clk(void *data)
-{
- struct igb_adapter *adapter = data;
- struct e1000_hw *hw = &adapter->hw;
- s32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
-
- return (i2cctl & E1000_I2C_CLK_IN) != 0;
-}
-
-static const struct i2c_algo_bit_data igb_i2c_algo = {
- .setsda = igb_set_i2c_data,
- .setscl = igb_set_i2c_clk,
- .getsda = igb_get_i2c_data,
- .getscl = igb_get_i2c_clk,
- .udelay = 5,
- .timeout = 20,
-};
-
-/* igb_init_i2c - Init I2C interface
- * @adapter: pointer to adapter structure
- *
- */
-static s32 igb_init_i2c(struct igb_adapter *adapter)
-{
- s32 status = E1000_SUCCESS;
-
- /* I2C interface supported on i350 devices */
- if (adapter->hw.mac.type != e1000_i350)
- return E1000_SUCCESS;
-
- /* Initialize the i2c bus which is controlled by the registers.
- * This bus will use the i2c_algo_bit structue that implements
- * the protocol through toggling of the 4 bits in the register.
- */
- adapter->i2c_adap.owner = THIS_MODULE;
- adapter->i2c_algo = igb_i2c_algo;
- adapter->i2c_algo.data = adapter;
- adapter->i2c_adap.algo_data = &adapter->i2c_algo;
- adapter->i2c_adap.dev.parent = &adapter->pdev->dev;
- strlcpy(adapter->i2c_adap.name, "igb BB",
- sizeof(adapter->i2c_adap.name));
- status = i2c_bit_add_bus(&adapter->i2c_adap);
- return status;
-}
-
-#endif /* HAVE_I2C_SUPPORT */
-/**
- * igb_up - Open the interface and prepare it to handle traffic
- * @adapter: board private structure
- **/
-int igb_up(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- int i;
-
- /* hardware has been reset, we need to reload some things */
- igb_configure(adapter);
-
- clear_bit(__IGB_DOWN, &adapter->state);
-
- for (i = 0; i < adapter->num_q_vectors; i++)
- napi_enable(&(adapter->q_vector[i]->napi));
-
- if (adapter->msix_entries)
- igb_configure_msix(adapter);
- else
- igb_assign_vector(adapter->q_vector[0], 0);
-
- igb_configure_lli(adapter);
-
- /* Clear any pending interrupts. */
- E1000_READ_REG(hw, E1000_ICR);
- igb_irq_enable(adapter);
-
- /* notify VFs that reset has been completed */
- if (adapter->vfs_allocated_count) {
- u32 reg_data = E1000_READ_REG(hw, E1000_CTRL_EXT);
- reg_data |= E1000_CTRL_EXT_PFRSTD;
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg_data);
- }
-
- netif_tx_start_all_queues(adapter->netdev);
-
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- schedule_work(&adapter->dma_err_task);
- /* start the watchdog. */
- hw->mac.get_link_status = 1;
- schedule_work(&adapter->watchdog_task);
-
- if ((adapter->flags & IGB_FLAG_EEE) &&
- (!hw->dev_spec._82575.eee_disable))
- adapter->eee_advert = MDIO_EEE_100TX | MDIO_EEE_1000T;
-
- return 0;
-}
-
-void igb_down(struct igb_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- struct e1000_hw *hw = &adapter->hw;
- u32 tctl, rctl;
- int i;
-
- /* signal that we're down so the interrupt handler does not
- * reschedule our watchdog timer */
- set_bit(__IGB_DOWN, &adapter->state);
-
- /* disable receives in the hardware */
- rctl = E1000_READ_REG(hw, E1000_RCTL);
- E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
- /* flush and sleep below */
-
- netif_tx_stop_all_queues(netdev);
-
- /* disable transmits in the hardware */
- tctl = E1000_READ_REG(hw, E1000_TCTL);
- tctl &= ~E1000_TCTL_EN;
- E1000_WRITE_REG(hw, E1000_TCTL, tctl);
- /* flush both disables and wait for them to finish */
- E1000_WRITE_FLUSH(hw);
- usleep_range(10000, 20000);
-
- for (i = 0; i < adapter->num_q_vectors; i++)
- napi_disable(&(adapter->q_vector[i]->napi));
-
- igb_irq_disable(adapter);
-
- adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
-
- del_timer_sync(&adapter->watchdog_timer);
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- del_timer_sync(&adapter->dma_err_timer);
- del_timer_sync(&adapter->phy_info_timer);
-
- netif_carrier_off(netdev);
-
- /* record the stats before reset*/
- igb_update_stats(adapter);
-
- adapter->link_speed = 0;
- adapter->link_duplex = 0;
-
-#ifdef HAVE_PCI_ERS
- if (!pci_channel_offline(adapter->pdev))
- igb_reset(adapter);
-#else
- igb_reset(adapter);
-#endif
- igb_clean_all_tx_rings(adapter);
- igb_clean_all_rx_rings(adapter);
-#ifdef IGB_DCA
- /* since we reset the hardware DCA settings were cleared */
- igb_setup_dca(adapter);
-#endif
-}
-
-void igb_reinit_locked(struct igb_adapter *adapter)
-{
- WARN_ON(in_interrupt());
- while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- usleep_range(1000, 2000);
- igb_down(adapter);
- igb_up(adapter);
- clear_bit(__IGB_RESETTING, &adapter->state);
-}
-
-/**
- * igb_enable_mas - Media Autosense re-enable after swap
- *
- * @adapter: adapter struct
- **/
-static s32 igb_enable_mas(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 connsw;
- s32 ret_val = E1000_SUCCESS;
-
- connsw = E1000_READ_REG(hw, E1000_CONNSW);
- if (hw->phy.media_type == e1000_media_type_copper) {
- /* configure for SerDes media detect */
- if (!(connsw & E1000_CONNSW_SERDESD)) {
- connsw |= E1000_CONNSW_ENRGSRC;
- connsw |= E1000_CONNSW_AUTOSENSE_EN;
- E1000_WRITE_REG(hw, E1000_CONNSW, connsw);
- E1000_WRITE_FLUSH(hw);
- } else if (connsw & E1000_CONNSW_SERDESD) {
- /* already SerDes, no need to enable anything */
- return ret_val;
- } else {
- dev_info(pci_dev_to_dev(adapter->pdev),
- "%s:MAS: Unable to configure feature, disabling..\n",
- adapter->netdev->name);
- adapter->flags &= ~IGB_FLAG_MAS_ENABLE;
- }
- }
- return ret_val;
-}
-
-void igb_reset(struct igb_adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_mac_info *mac = &hw->mac;
- struct e1000_fc_info *fc = &hw->fc;
- u32 pba = 0, tx_space, min_tx_space, min_rx_space, hwm;
-
- /* Repartition Pba for greater than 9k mtu
- * To take effect CTRL.RST is required.
- */
- switch (mac->type) {
- case e1000_i350:
- case e1000_82580:
- case e1000_i354:
- pba = E1000_READ_REG(hw, E1000_RXPBS);
- pba = e1000_rxpbs_adjust_82580(pba);
- break;
- case e1000_82576:
- pba = E1000_READ_REG(hw, E1000_RXPBS);
- pba &= E1000_RXPBS_SIZE_MASK_82576;
- break;
- case e1000_82575:
- case e1000_i210:
- case e1000_i211:
- default:
- pba = E1000_PBA_34K;
- break;
- }
-
- if ((adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) &&
- (mac->type < e1000_82576)) {
- /* adjust PBA for jumbo frames */
- E1000_WRITE_REG(hw, E1000_PBA, pba);
-
- /* To maintain wire speed transmits, the Tx FIFO should be
- * large enough to accommodate two full transmit packets,
- * rounded up to the next 1KB and expressed in KB. Likewise,
- * the Rx FIFO should be large enough to accommodate at least
- * one full receive packet and is similarly rounded up and
- * expressed in KB. */
- pba = E1000_READ_REG(hw, E1000_PBA);
- /* upper 16 bits has Tx packet buffer allocation size in KB */
- tx_space = pba >> 16;
- /* lower 16 bits has Rx packet buffer allocation size in KB */
- pba &= 0xffff;
- /* the tx fifo also stores 16 bytes of information about the tx
- * but don't include ethernet FCS because hardware appends it */
- min_tx_space = (adapter->max_frame_size +
- sizeof(union e1000_adv_tx_desc) -
- ETH_FCS_LEN) * 2;
- min_tx_space = ALIGN(min_tx_space, 1024);
- min_tx_space >>= 10;
- /* software strips receive CRC, so leave room for it */
- min_rx_space = adapter->max_frame_size;
- min_rx_space = ALIGN(min_rx_space, 1024);
- min_rx_space >>= 10;
-
- /* If current Tx allocation is less than the min Tx FIFO size,
- * and the min Tx FIFO size is less than the current Rx FIFO
- * allocation, take space away from current Rx allocation */
- if (tx_space < min_tx_space &&
- ((min_tx_space - tx_space) < pba)) {
- pba = pba - (min_tx_space - tx_space);
-
- /* if short on rx space, rx wins and must trump tx
- * adjustment */
- if (pba < min_rx_space)
- pba = min_rx_space;
- }
- E1000_WRITE_REG(hw, E1000_PBA, pba);
- }
-
- /* flow control settings */
- /* The high water mark must be low enough to fit one full frame
- * (or the size used for early receive) above it in the Rx FIFO.
- * Set it to the lower of:
- * - 90% of the Rx FIFO size, or
- * - the full Rx FIFO size minus one full frame */
- hwm = min(((pba << 10) * 9 / 10),
- ((pba << 10) - 2 * adapter->max_frame_size));
-
- fc->high_water = hwm & 0xFFFFFFF0; /* 16-byte granularity */
- fc->low_water = fc->high_water - 16;
- fc->pause_time = 0xFFFF;
- fc->send_xon = 1;
- fc->current_mode = fc->requested_mode;
-
- /* disable receive for all VFs and wait one second */
- if (adapter->vfs_allocated_count) {
- int i;
- /*
- * Clear all flags except indication that the PF has set
- * the VF MAC addresses administratively
- */
- for (i = 0 ; i < adapter->vfs_allocated_count; i++)
- adapter->vf_data[i].flags &= IGB_VF_FLAG_PF_SET_MAC;
-
- /* ping all the active vfs to let them know we are going down */
- igb_ping_all_vfs(adapter);
-
- /* disable transmits and receives */
- E1000_WRITE_REG(hw, E1000_VFRE, 0);
- E1000_WRITE_REG(hw, E1000_VFTE, 0);
- }
-
- /* Allow time for pending master requests to run */
- e1000_reset_hw(hw);
- E1000_WRITE_REG(hw, E1000_WUC, 0);
-
- if (adapter->flags & IGB_FLAG_MEDIA_RESET) {
- e1000_setup_init_funcs(hw, TRUE);
- igb_check_options(adapter);
- e1000_get_bus_info(hw);
- adapter->flags &= ~IGB_FLAG_MEDIA_RESET;
- }
- if (adapter->flags & IGB_FLAG_MAS_ENABLE) {
- if (igb_enable_mas(adapter))
- dev_err(pci_dev_to_dev(pdev),
- "Error enabling Media Auto Sense\n");
- }
- if (e1000_init_hw(hw))
- dev_err(pci_dev_to_dev(pdev), "Hardware Error\n");
-
- /*
- * Flow control settings reset on hardware reset, so guarantee flow
- * control is off when forcing speed.
- */
- if (!hw->mac.autoneg)
- e1000_force_mac_fc(hw);
-
- igb_init_dmac(adapter, pba);
- /* Re-initialize the thermal sensor on i350 devices. */
- if (mac->type == e1000_i350 && hw->bus.func == 0) {
- /*
- * If present, re-initialize the external thermal sensor
- * interface.
- */
- if (adapter->ets)
- e1000_set_i2c_bb(hw);
- e1000_init_thermal_sensor_thresh(hw);
- }
-
- /*Re-establish EEE setting */
- if (hw->phy.media_type == e1000_media_type_copper) {
- switch (mac->type) {
- case e1000_i350:
- case e1000_i210:
- case e1000_i211:
- e1000_set_eee_i350(hw);
- break;
- case e1000_i354:
- e1000_set_eee_i354(hw);
- break;
- default:
- break;
- }
- }
-
- if (!netif_running(adapter->netdev))
- igb_power_down_link(adapter);
-
- igb_update_mng_vlan(adapter);
-
- /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
- E1000_WRITE_REG(hw, E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
-
-
-#ifdef HAVE_PTP_1588_CLOCK
- /* Re-enable PTP, where applicable. */
- igb_ptp_reset(adapter);
-#endif /* HAVE_PTP_1588_CLOCK */
-
- e1000_get_phy_info(hw);
-
- adapter->devrc++;
-}
-
-#ifdef HAVE_NDO_SET_FEATURES
-static kni_netdev_features_t igb_fix_features(struct net_device *netdev,
- kni_netdev_features_t features)
-{
- /*
- * Since there is no support for separate tx vlan accel
- * enabled make sure tx flag is cleared if rx is.
- */
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
- if (!(features & NETIF_F_HW_VLAN_CTAG_RX))
- features &= ~NETIF_F_HW_VLAN_CTAG_TX;
-#else
- if (!(features & NETIF_F_HW_VLAN_RX))
- features &= ~NETIF_F_HW_VLAN_TX;
-#endif
-
- /* If Rx checksum is disabled, then LRO should also be disabled */
- if (!(features & NETIF_F_RXCSUM))
- features &= ~NETIF_F_LRO;
-
- return features;
-}
-
-static int igb_set_features(struct net_device *netdev,
- kni_netdev_features_t features)
-{
- u32 changed = netdev->features ^ features;
-
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
- if (changed & NETIF_F_HW_VLAN_CTAG_RX)
-#else
- if (changed & NETIF_F_HW_VLAN_RX)
-#endif
- igb_vlan_mode(netdev, features);
-
- return 0;
-}
-
-#ifdef NTF_SELF
-#ifdef USE_CONST_DEV_UC_CHAR
-static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
- struct net_device *dev,
- const unsigned char *addr,
-#ifdef HAVE_NDO_FDB_ADD_VID
- u16 vid,
-#endif
- u16 flags)
-#else
-static int igb_ndo_fdb_add(struct ndmsg *ndm,
- struct net_device *dev,
- unsigned char *addr,
- u16 flags)
-#endif
-{
- struct igb_adapter *adapter = netdev_priv(dev);
- struct e1000_hw *hw = &adapter->hw;
- int err;
-
- if (!(adapter->vfs_allocated_count))
- return -EOPNOTSUPP;
-
- /* Hardware does not support aging addresses so if a
- * ndm_state is given only allow permanent addresses
- */
- if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) {
- pr_info("%s: FDB only supports static addresses\n",
- igb_driver_name);
- return -EINVAL;
- }
-
- if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) {
- u32 rar_uc_entries = hw->mac.rar_entry_count -
- (adapter->vfs_allocated_count + 1);
-
- if (netdev_uc_count(dev) < rar_uc_entries)
- err = dev_uc_add_excl(dev, addr);
- else
- err = -ENOMEM;
- } else if (is_multicast_ether_addr(addr)) {
- err = dev_mc_add_excl(dev, addr);
- } else {
- err = -EINVAL;
- }
-
- /* Only return duplicate errors if NLM_F_EXCL is set */
- if (err == -EEXIST && !(flags & NLM_F_EXCL))
- err = 0;
-
- return err;
-}
-
-#ifndef USE_DEFAULT_FDB_DEL_DUMP
-#ifdef USE_CONST_DEV_UC_CHAR
-static int igb_ndo_fdb_del(struct ndmsg *ndm,
- struct net_device *dev,
- const unsigned char *addr)
-#else
-static int igb_ndo_fdb_del(struct ndmsg *ndm,
- struct net_device *dev,
- unsigned char *addr)
-#endif
-{
- struct igb_adapter *adapter = netdev_priv(dev);
- int err = -EOPNOTSUPP;
-
- if (ndm->ndm_state & NUD_PERMANENT) {
- pr_info("%s: FDB only supports static addresses\n",
- igb_driver_name);
- return -EINVAL;
- }
-
- if (adapter->vfs_allocated_count) {
- if (is_unicast_ether_addr(addr))
- err = dev_uc_del(dev, addr);
- else if (is_multicast_ether_addr(addr))
- err = dev_mc_del(dev, addr);
- else
- err = -EINVAL;
- }
-
- return err;
-}
-
-static int igb_ndo_fdb_dump(struct sk_buff *skb,
- struct netlink_callback *cb,
- struct net_device *dev,
- int idx)
-{
- struct igb_adapter *adapter = netdev_priv(dev);
-
- if (adapter->vfs_allocated_count)
- idx = ndo_dflt_fdb_dump(skb, cb, dev, idx);
-
- return idx;
-}
-#endif /* USE_DEFAULT_FDB_DEL_DUMP */
-
-#ifdef HAVE_BRIDGE_ATTRIBS
-#ifdef HAVE_NDO_BRIDGE_SET_DEL_LINK_FLAGS
-static int igb_ndo_bridge_setlink(struct net_device *dev,
- struct nlmsghdr *nlh,
- u16 flags)
-#else
-static int igb_ndo_bridge_setlink(struct net_device *dev,
- struct nlmsghdr *nlh)
-#endif /* HAVE_NDO_BRIDGE_SET_DEL_LINK_FLAGS */
-{
- struct igb_adapter *adapter = netdev_priv(dev);
- struct e1000_hw *hw = &adapter->hw;
- struct nlattr *attr, *br_spec;
- int rem;
-
- if (!(adapter->vfs_allocated_count))
- return -EOPNOTSUPP;
-
- switch (adapter->hw.mac.type) {
- case e1000_82576:
- case e1000_i350:
- case e1000_i354:
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
-
- nla_for_each_nested(attr, br_spec, rem) {
- __u16 mode;
-
- if (nla_type(attr) != IFLA_BRIDGE_MODE)
- continue;
-
- mode = nla_get_u16(attr);
- if (mode == BRIDGE_MODE_VEPA) {
- e1000_vmdq_set_loopback_pf(hw, 0);
- adapter->flags &= ~IGB_FLAG_LOOPBACK_ENABLE;
- } else if (mode == BRIDGE_MODE_VEB) {
- e1000_vmdq_set_loopback_pf(hw, 1);
- adapter->flags |= IGB_FLAG_LOOPBACK_ENABLE;
- } else
- return -EINVAL;
-
- netdev_info(adapter->netdev, "enabling bridge mode: %s\n",
- mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
- }
-
- return 0;
-}
-
-#ifdef HAVE_BRIDGE_FILTER
-#ifdef HAVE_NDO_BRIDGE_GETLINK_NLFLAGS
-static int igb_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
- struct net_device *dev, u32 filter_mask,
- int nlflags)
-#else
-static int igb_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
- struct net_device *dev, u32 filter_mask)
-#endif /* HAVE_NDO_BRIDGE_GETLINK_NLFLAGS */
-#else
-static int igb_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
- struct net_device *dev)
-#endif
-{
- struct igb_adapter *adapter = netdev_priv(dev);
- u16 mode;
-
- if (!(adapter->vfs_allocated_count))
- return -EOPNOTSUPP;
-
- if (adapter->flags & IGB_FLAG_LOOPBACK_ENABLE)
- mode = BRIDGE_MODE_VEB;
- else
- mode = BRIDGE_MODE_VEPA;
-
-#ifdef HAVE_NDO_DFLT_BRIDGE_ADD_MASK
-#ifdef HAVE_NDO_BRIDGE_GETLINK_NLFLAGS
-#ifdef HAVE_NDO_BRIDGE_GETLINK_FILTER_MASK_VLAN_FILL
- return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode, 0, 0,
- nlflags, filter_mask, NULL);
-#else
- return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode, 0, 0, nlflags);
-#endif /* HAVE_NDO_BRIDGE_GETLINK_FILTER_MASK_VLAN_FILL */
-#else
- return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode, 0, 0);
-#endif /* HAVE_NDO_BRIDGE_GETLINK_NLFLAGS */
-#else
- return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode);
-#endif /* HAVE_NDO_DFLT_BRIDGE_ADD_MASK */
-}
-#endif /* HAVE_BRIDGE_ATTRIBS */
-#endif /* NTF_SELF */
-
-#endif /* HAVE_NDO_SET_FEATURES */
-#ifdef HAVE_NET_DEVICE_OPS
-static const struct net_device_ops igb_netdev_ops = {
- .ndo_open = igb_open,
- .ndo_stop = igb_close,
- .ndo_start_xmit = igb_xmit_frame,
- .ndo_get_stats = igb_get_stats,
- .ndo_set_rx_mode = igb_set_rx_mode,
- .ndo_set_mac_address = igb_set_mac,
- .ndo_change_mtu = igb_change_mtu,
- .ndo_do_ioctl = igb_ioctl,
- .ndo_tx_timeout = igb_tx_timeout,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_vlan_rx_add_vid = igb_vlan_rx_add_vid,
- .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid,
-#ifdef IFLA_VF_MAX
- .ndo_set_vf_mac = igb_ndo_set_vf_mac,
- .ndo_set_vf_vlan = igb_ndo_set_vf_vlan,
-#ifdef HAVE_VF_MIN_MAX_TXRATE
- .ndo_set_vf_rate = igb_ndo_set_vf_bw,
-#else /* HAVE_VF_MIN_MAX_TXRATE */
- .ndo_set_vf_tx_rate = igb_ndo_set_vf_bw,
-#endif /* HAVE_VF_MIN_MAX_TXRATE */
- .ndo_get_vf_config = igb_ndo_get_vf_config,
-#ifdef HAVE_VF_SPOOFCHK_CONFIGURE
- .ndo_set_vf_spoofchk = igb_ndo_set_vf_spoofchk,
-#endif /* HAVE_VF_SPOOFCHK_CONFIGURE */
-#endif /* IFLA_VF_MAX */
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = igb_netpoll,
-#endif
-#ifdef HAVE_NDO_SET_FEATURES
- .ndo_fix_features = igb_fix_features,
- .ndo_set_features = igb_set_features,
-#endif
-#ifdef HAVE_VLAN_RX_REGISTER
- .ndo_vlan_rx_register = igb_vlan_mode,
-#endif
-#ifndef HAVE_RHEL6_NETDEV_OPS_EXT_FDB
-#ifdef NTF_SELF
- .ndo_fdb_add = igb_ndo_fdb_add,
-#ifndef USE_DEFAULT_FDB_DEL_DUMP
- .ndo_fdb_del = igb_ndo_fdb_del,
- .ndo_fdb_dump = igb_ndo_fdb_dump,
-#endif
-#endif /* ! HAVE_RHEL6_NETDEV_OPS_EXT_FDB */
-#ifdef HAVE_BRIDGE_ATTRIBS
- .ndo_bridge_setlink = igb_ndo_bridge_setlink,
- .ndo_bridge_getlink = igb_ndo_bridge_getlink,
-#endif /* HAVE_BRIDGE_ATTRIBS */
-#endif
-};
-
-#ifdef CONFIG_IGB_VMDQ_NETDEV
-static const struct net_device_ops igb_vmdq_ops = {
- .ndo_open = &igb_vmdq_open,
- .ndo_stop = &igb_vmdq_close,
- .ndo_start_xmit = &igb_vmdq_xmit_frame,
- .ndo_get_stats = &igb_vmdq_get_stats,
- .ndo_set_rx_mode = &igb_vmdq_set_rx_mode,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = &igb_vmdq_set_mac,
- .ndo_change_mtu = &igb_vmdq_change_mtu,
- .ndo_tx_timeout = &igb_vmdq_tx_timeout,
- .ndo_vlan_rx_register = &igb_vmdq_vlan_rx_register,
- .ndo_vlan_rx_add_vid = &igb_vmdq_vlan_rx_add_vid,
- .ndo_vlan_rx_kill_vid = &igb_vmdq_vlan_rx_kill_vid,
-};
-
-#endif /* CONFIG_IGB_VMDQ_NETDEV */
-#endif /* HAVE_NET_DEVICE_OPS */
-#ifdef CONFIG_IGB_VMDQ_NETDEV
-void igb_assign_vmdq_netdev_ops(struct net_device *vnetdev)
-{
-#ifdef HAVE_NET_DEVICE_OPS
- vnetdev->netdev_ops = &igb_vmdq_ops;
-#else
- dev->open = &igb_vmdq_open;
- dev->stop = &igb_vmdq_close;
- dev->hard_start_xmit = &igb_vmdq_xmit_frame;
- dev->get_stats = &igb_vmdq_get_stats;
-#ifdef HAVE_SET_RX_MODE
- dev->set_rx_mode = &igb_vmdq_set_rx_mode;
-#endif
- dev->set_multicast_list = &igb_vmdq_set_rx_mode;
- dev->set_mac_address = &igb_vmdq_set_mac;
- dev->change_mtu = &igb_vmdq_change_mtu;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = &igb_vmdq_tx_timeout;
-#endif
-#if defined(NETIF_F_HW_VLAN_TX) || defined(NETIF_F_HW_VLAN_CTAG_TX)
- dev->vlan_rx_register = &igb_vmdq_vlan_rx_register;
- dev->vlan_rx_add_vid = &igb_vmdq_vlan_rx_add_vid;
- dev->vlan_rx_kill_vid = &igb_vmdq_vlan_rx_kill_vid;
-#endif
-#endif
- igb_vmdq_set_ethtool_ops(vnetdev);
- vnetdev->watchdog_timeo = 5 * HZ;
-
-}
-
-int igb_init_vmdq_netdevs(struct igb_adapter *adapter)
-{
- int pool, err = 0, base_queue;
- struct net_device *vnetdev;
- struct igb_vmdq_adapter *vmdq_adapter;
-
- for (pool = 1; pool < adapter->vmdq_pools; pool++) {
- int qpp = (!adapter->rss_queues ? 1 : adapter->rss_queues);
- base_queue = pool * qpp;
- vnetdev = alloc_etherdev(sizeof(struct igb_vmdq_adapter));
- if (!vnetdev) {
- err = -ENOMEM;
- break;
- }
- vmdq_adapter = netdev_priv(vnetdev);
- vmdq_adapter->vnetdev = vnetdev;
- vmdq_adapter->real_adapter = adapter;
- vmdq_adapter->rx_ring = adapter->rx_ring[base_queue];
- vmdq_adapter->tx_ring = adapter->tx_ring[base_queue];
- igb_assign_vmdq_netdev_ops(vnetdev);
- snprintf(vnetdev->name, IFNAMSIZ, "%sv%d",
- adapter->netdev->name, pool);
- vnetdev->features = adapter->netdev->features;
-#ifdef HAVE_NETDEV_VLAN_FEATURES
- vnetdev->vlan_features = adapter->netdev->vlan_features;
-#endif
- adapter->vmdq_netdev[pool-1] = vnetdev;
- err = register_netdev(vnetdev);
- if (err)
- break;
- }
- return err;
-}
-
-int igb_remove_vmdq_netdevs(struct igb_adapter *adapter)
-{
- int pool, err = 0;
-
- for (pool = 1; pool < adapter->vmdq_pools; pool++) {
- unregister_netdev(adapter->vmdq_netdev[pool-1]);
- free_netdev(adapter->vmdq_netdev[pool-1]);
- adapter->vmdq_netdev[pool-1] = NULL;
- }
- return err;
-}
-#endif /* CONFIG_IGB_VMDQ_NETDEV */
-
-/**
- * igb_set_fw_version - Configure version string for ethtool
- * @adapter: adapter struct
- *
- **/
-static void igb_set_fw_version(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_fw_version fw;
-
- e1000_get_fw_version(hw, &fw);
-
- switch (hw->mac.type) {
- case e1000_i210:
- case e1000_i211:
- if (!(e1000_get_flash_presence_i210(hw))) {
- snprintf(adapter->fw_version,
- sizeof(adapter->fw_version),
- "%2d.%2d-%d",
- fw.invm_major, fw.invm_minor, fw.invm_img_type);
- break;
- }
- /* fall through */
- default:
- /* if option rom is valid, display its version too*/
- if (fw.or_valid) {
- snprintf(adapter->fw_version,
- sizeof(adapter->fw_version),
- "%d.%d, 0x%08x, %d.%d.%d",
- fw.eep_major, fw.eep_minor, fw.etrack_id,
- fw.or_major, fw.or_build, fw.or_patch);
- /* no option rom */
- } else {
- if (fw.etrack_id != 0X0000) {
- snprintf(adapter->fw_version,
- sizeof(adapter->fw_version),
- "%d.%d, 0x%08x",
- fw.eep_major, fw.eep_minor, fw.etrack_id);
- } else {
- snprintf(adapter->fw_version,
- sizeof(adapter->fw_version),
- "%d.%d.%d",
- fw.eep_major, fw.eep_minor, fw.eep_build);
- }
- }
- break;
- }
-
- return;
-}
-
-/**
- * igb_init_mas - init Media Autosense feature if enabled in the NVM
- *
- * @adapter: adapter struct
- **/
-static void igb_init_mas(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u16 eeprom_data;
-
- e1000_read_nvm(hw, NVM_COMPAT, 1, &eeprom_data);
- switch (hw->bus.func) {
- case E1000_FUNC_0:
- if (eeprom_data & IGB_MAS_ENABLE_0)
- adapter->flags |= IGB_FLAG_MAS_ENABLE;
- break;
- case E1000_FUNC_1:
- if (eeprom_data & IGB_MAS_ENABLE_1)
- adapter->flags |= IGB_FLAG_MAS_ENABLE;
- break;
- case E1000_FUNC_2:
- if (eeprom_data & IGB_MAS_ENABLE_2)
- adapter->flags |= IGB_FLAG_MAS_ENABLE;
- break;
- case E1000_FUNC_3:
- if (eeprom_data & IGB_MAS_ENABLE_3)
- adapter->flags |= IGB_FLAG_MAS_ENABLE;
- break;
- default:
- /* Shouldn't get here */
- dev_err(pci_dev_to_dev(adapter->pdev),
- "%s:AMS: Invalid port configuration, returning\n",
- adapter->netdev->name);
- break;
- }
-}
-
-/**
- * igb_probe - Device Initialization Routine
- * @pdev: PCI device information struct
- * @ent: entry in igb_pci_tbl
- *
- * Returns 0 on success, negative on failure
- *
- * igb_probe initializes an adapter identified by a pci_dev structure.
- * The OS initialization, configuring of the adapter private structure,
- * and a hardware reset occur.
- **/
-static int __devinit igb_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct net_device *netdev;
- struct igb_adapter *adapter;
- struct e1000_hw *hw;
- u16 eeprom_data = 0;
- u8 pba_str[E1000_PBANUM_LENGTH];
- s32 ret_val;
- static int global_quad_port_a; /* global quad port a indication */
- int i, err, pci_using_dac;
- static int cards_found;
-
- err = pci_enable_device_mem(pdev);
- if (err)
- return err;
-
- pci_using_dac = 0;
- err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64));
- if (!err) {
- err = dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64));
- if (!err)
- pci_using_dac = 1;
- } else {
- err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32));
- if (err) {
- err = dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32));
- if (err) {
- IGB_ERR("No usable DMA configuration, "
- "aborting\n");
- goto err_dma;
- }
- }
- }
-
-#ifndef HAVE_ASPM_QUIRKS
- /* 82575 requires that the pci-e link partner disable the L0s state */
- switch (pdev->device) {
- case E1000_DEV_ID_82575EB_COPPER:
- case E1000_DEV_ID_82575EB_FIBER_SERDES:
- case E1000_DEV_ID_82575GB_QUAD_COPPER:
- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
- default:
- break;
- }
-
-#endif /* HAVE_ASPM_QUIRKS */
- err = pci_request_selected_regions(pdev,
- pci_select_bars(pdev,
- IORESOURCE_MEM),
- igb_driver_name);
- if (err)
- goto err_pci_reg;
-
- pci_enable_pcie_error_reporting(pdev);
-
- pci_set_master(pdev);
-
- err = -ENOMEM;
-#ifdef HAVE_TX_MQ
- netdev = alloc_etherdev_mq(sizeof(struct igb_adapter),
- IGB_MAX_TX_QUEUES);
-#else
- netdev = alloc_etherdev(sizeof(struct igb_adapter));
-#endif /* HAVE_TX_MQ */
- if (!netdev)
- goto err_alloc_etherdev;
-
- SET_MODULE_OWNER(netdev);
- SET_NETDEV_DEV(netdev, &pdev->dev);
-
- pci_set_drvdata(pdev, netdev);
- adapter = netdev_priv(netdev);
- adapter->netdev = netdev;
- adapter->pdev = pdev;
- hw = &adapter->hw;
- hw->back = adapter;
- adapter->port_num = hw->bus.func;
- adapter->msg_enable = (1 << debug) - 1;
-
-#ifdef HAVE_PCI_ERS
- err = pci_save_state(pdev);
- if (err)
- goto err_ioremap;
-#endif
- err = -EIO;
- hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- if (!hw->hw_addr)
- goto err_ioremap;
-
-#ifdef HAVE_NET_DEVICE_OPS
- netdev->netdev_ops = &igb_netdev_ops;
-#else /* HAVE_NET_DEVICE_OPS */
- netdev->open = &igb_open;
- netdev->stop = &igb_close;
- netdev->get_stats = &igb_get_stats;
-#ifdef HAVE_SET_RX_MODE
- netdev->set_rx_mode = &igb_set_rx_mode;
-#endif
- netdev->set_multicast_list = &igb_set_rx_mode;
- netdev->set_mac_address = &igb_set_mac;
- netdev->change_mtu = &igb_change_mtu;
- netdev->do_ioctl = &igb_ioctl;
-#ifdef HAVE_TX_TIMEOUT
- netdev->tx_timeout = &igb_tx_timeout;
-#endif
- netdev->vlan_rx_register = igb_vlan_mode;
- netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = igb_netpoll;
-#endif
- netdev->hard_start_xmit = &igb_xmit_frame;
-#endif /* HAVE_NET_DEVICE_OPS */
- igb_set_ethtool_ops(netdev);
-#ifdef HAVE_TX_TIMEOUT
- netdev->watchdog_timeo = 5 * HZ;
-#endif
-
- strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
-
- adapter->bd_number = cards_found;
-
- /* setup the private structure */
- err = igb_sw_init(adapter);
- if (err)
- goto err_sw_init;
-
- e1000_get_bus_info(hw);
-
- hw->phy.autoneg_wait_to_complete = FALSE;
- hw->mac.adaptive_ifs = FALSE;
-
- /* Copper options */
- if (hw->phy.media_type == e1000_media_type_copper) {
- hw->phy.mdix = AUTO_ALL_MODES;
- hw->phy.disable_polarity_correction = FALSE;
- hw->phy.ms_type = e1000_ms_hw_default;
- }
-
- if (e1000_check_reset_block(hw))
- dev_info(pci_dev_to_dev(pdev),
- "PHY reset is blocked due to SOL/IDER session.\n");
-
- /*
- * features is initialized to 0 in allocation, it might have bits
- * set by igb_sw_init so we should use an or instead of an
- * assignment.
- */
- netdev->features |= NETIF_F_SG |
- NETIF_F_IP_CSUM |
-#ifdef NETIF_F_IPV6_CSUM
- NETIF_F_IPV6_CSUM |
-#endif
-#ifdef NETIF_F_TSO
- NETIF_F_TSO |
-#ifdef NETIF_F_TSO6
- NETIF_F_TSO6 |
-#endif
-#endif /* NETIF_F_TSO */
-#ifdef NETIF_F_RXHASH
- NETIF_F_RXHASH |
-#endif
- NETIF_F_RXCSUM |
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
- NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HW_VLAN_CTAG_TX;
-#else
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_TX;
-#endif
-
- if (hw->mac.type >= e1000_82576)
- netdev->features |= NETIF_F_SCTP_CSUM;
-
-#ifdef HAVE_NDO_SET_FEATURES
- /* copy netdev features into list of user selectable features */
- netdev->hw_features |= netdev->features;
-#ifndef IGB_NO_LRO
-
- /* give us the option of enabling LRO later */
- netdev->hw_features |= NETIF_F_LRO;
-#endif
-#else
-#ifdef NETIF_F_GRO
-
- /* this is only needed on kernels prior to 2.6.39 */
- netdev->features |= NETIF_F_GRO;
-#endif
-#endif
-
- /* set this bit last since it cannot be part of hw_features */
-#ifdef NETIF_F_HW_VLAN_CTAG_FILTER
- netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
-#else
- netdev->features |= NETIF_F_HW_VLAN_FILTER;
-#endif
-
-#ifdef HAVE_NETDEV_VLAN_FEATURES
- netdev->vlan_features |= NETIF_F_TSO |
- NETIF_F_TSO6 |
- NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM |
- NETIF_F_SG;
-
-#endif
- if (pci_using_dac)
- netdev->features |= NETIF_F_HIGHDMA;
-
- adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
-#ifdef DEBUG
- if (adapter->dmac != IGB_DMAC_DISABLE)
- printk("%s: DMA Coalescing is enabled..\n", netdev->name);
-#endif
-
- /* before reading the NVM, reset the controller to put the device in a
- * known good starting state */
- e1000_reset_hw(hw);
-
- /* make sure the NVM is good */
- if (e1000_validate_nvm_checksum(hw) < 0) {
- dev_err(pci_dev_to_dev(pdev), "The NVM Checksum Is Not"
- " Valid\n");
- err = -EIO;
- goto err_eeprom;
- }
-
- /* copy the MAC address out of the NVM */
- if (e1000_read_mac_addr(hw))
- dev_err(pci_dev_to_dev(pdev), "NVM Read Error\n");
- memcpy(netdev->dev_addr, hw->mac.addr, netdev->addr_len);
-#ifdef ETHTOOL_GPERMADDR
- memcpy(netdev->perm_addr, hw->mac.addr, netdev->addr_len);
-
- if (!is_valid_ether_addr(netdev->perm_addr)) {
-#else
- if (!is_valid_ether_addr(netdev->dev_addr)) {
-#endif
- dev_err(pci_dev_to_dev(pdev), "Invalid MAC Address\n");
- err = -EIO;
- goto err_eeprom;
- }
-
- memcpy(&adapter->mac_table[0].addr, hw->mac.addr, netdev->addr_len);
- adapter->mac_table[0].queue = adapter->vfs_allocated_count;
- adapter->mac_table[0].state = (IGB_MAC_STATE_DEFAULT | IGB_MAC_STATE_IN_USE);
- igb_rar_set(adapter, 0);
-
- /* get firmware version for ethtool -i */
- igb_set_fw_version(adapter);
-
- /* Check if Media Autosense is enabled */
- if (hw->mac.type == e1000_82580)
- igb_init_mas(adapter);
-#ifdef HAVE_TIMER_SETUP
- timer_setup(&adapter->watchdog_timer, &igb_watchdog, 0);
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- timer_setup(&adapter->dma_err_timer, &igb_dma_err_timer, 0);
- timer_setup(&adapter->phy_info_timer, &igb_update_phy_info, 0);
-#else
- setup_timer(&adapter->watchdog_timer, &igb_watchdog,
- (unsigned long) adapter);
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- setup_timer(&adapter->dma_err_timer, &igb_dma_err_timer,
- (unsigned long) adapter);
- setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
- (unsigned long) adapter);
-#endif
-
- INIT_WORK(&adapter->reset_task, igb_reset_task);
- INIT_WORK(&adapter->watchdog_task, igb_watchdog_task);
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- INIT_WORK(&adapter->dma_err_task, igb_dma_err_task);
-
- /* Initialize link properties that are user-changeable */
- adapter->fc_autoneg = true;
- hw->mac.autoneg = true;
- hw->phy.autoneg_advertised = 0x2f;
-
- hw->fc.requested_mode = e1000_fc_default;
- hw->fc.current_mode = e1000_fc_default;
-
- e1000_validate_mdi_setting(hw);
-
- /* By default, support wake on port A */
- if (hw->bus.func == 0)
- adapter->flags |= IGB_FLAG_WOL_SUPPORTED;
-
- /* Check the NVM for wake support for non-port A ports */
- if (hw->mac.type >= e1000_82580)
- hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
- NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
- &eeprom_data);
- else if (hw->bus.func == 1)
- e1000_read_nvm(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
-
- if (eeprom_data & IGB_EEPROM_APME)
- adapter->flags |= IGB_FLAG_WOL_SUPPORTED;
-
- /* now that we have the eeprom settings, apply the special cases where
- * the eeprom may be wrong or the board simply won't support wake on
- * lan on a particular port */
- switch (pdev->device) {
- case E1000_DEV_ID_82575GB_QUAD_COPPER:
- adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
- break;
- case E1000_DEV_ID_82575EB_FIBER_SERDES:
- case E1000_DEV_ID_82576_FIBER:
- case E1000_DEV_ID_82576_SERDES:
- /* Wake events only supported on port A for dual fiber
- * regardless of eeprom setting */
- if (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_FUNC_1)
- adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
- break;
- case E1000_DEV_ID_82576_QUAD_COPPER:
- case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
- /* if quad port adapter, disable WoL on all but port A */
- if (global_quad_port_a != 0)
- adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
- else
- adapter->flags |= IGB_FLAG_QUAD_PORT_A;
- /* Reset for multiple quad port adapters */
- if (++global_quad_port_a == 4)
- global_quad_port_a = 0;
- break;
- default:
- /* If the device can't wake, don't set software support */
- if (!device_can_wakeup(&adapter->pdev->dev))
- adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
- break;
- }
-
- /* initialize the wol settings based on the eeprom settings */
- if (adapter->flags & IGB_FLAG_WOL_SUPPORTED)
- adapter->wol |= E1000_WUFC_MAG;
-
- /* Some vendors want WoL disabled by default, but still supported */
- if ((hw->mac.type == e1000_i350) &&
- (pdev->subsystem_vendor == PCI_VENDOR_ID_HP)) {
- adapter->flags |= IGB_FLAG_WOL_SUPPORTED;
- adapter->wol = 0;
- }
-
- device_set_wakeup_enable(pci_dev_to_dev(adapter->pdev),
- adapter->flags & IGB_FLAG_WOL_SUPPORTED);
-
- /* reset the hardware with the new settings */
- igb_reset(adapter);
- adapter->devrc = 0;
-
-#ifdef HAVE_I2C_SUPPORT
- /* Init the I2C interface */
- err = igb_init_i2c(adapter);
- if (err) {
- dev_err(&pdev->dev, "failed to init i2c interface\n");
- goto err_eeprom;
- }
-#endif /* HAVE_I2C_SUPPORT */
-
- /* let the f/w know that the h/w is now under the control of the
- * driver. */
- igb_get_hw_control(adapter);
-
- strncpy(netdev->name, "eth%d", IFNAMSIZ);
- err = register_netdev(netdev);
- if (err)
- goto err_register;
-
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- err = igb_init_vmdq_netdevs(adapter);
- if (err)
- goto err_register;
-#endif
- /* carrier off reporting is important to ethtool even BEFORE open */
- netif_carrier_off(netdev);
-
-#ifdef IGB_DCA
- if (dca_add_requester(&pdev->dev) == E1000_SUCCESS) {
- adapter->flags |= IGB_FLAG_DCA_ENABLED;
- dev_info(pci_dev_to_dev(pdev), "DCA enabled\n");
- igb_setup_dca(adapter);
- }
-
-#endif
-#ifdef HAVE_PTP_1588_CLOCK
- /* do hw tstamp init after resetting */
- igb_ptp_init(adapter);
-#endif /* HAVE_PTP_1588_CLOCK */
-
- dev_info(pci_dev_to_dev(pdev), "Intel(R) Gigabit Ethernet Network Connection\n");
- /* print bus type/speed/width info */
- dev_info(pci_dev_to_dev(pdev), "%s: (PCIe:%s:%s) ",
- netdev->name,
- ((hw->bus.speed == e1000_bus_speed_2500) ? "2.5GT/s" :
- (hw->bus.speed == e1000_bus_speed_5000) ? "5.0GT/s" :
- (hw->mac.type == e1000_i354) ? "integrated" :
- "unknown"),
- ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
- (hw->bus.width == e1000_bus_width_pcie_x2) ? "Width x2" :
- (hw->bus.width == e1000_bus_width_pcie_x1) ? "Width x1" :
- (hw->mac.type == e1000_i354) ? "integrated" :
- "unknown"));
- dev_info(pci_dev_to_dev(pdev), "%s: MAC: ", netdev->name);
- for (i = 0; i < 6; i++)
- printk("%2.2x%c", netdev->dev_addr[i], i == 5 ? '\n' : ':');
-
- ret_val = e1000_read_pba_string(hw, pba_str, E1000_PBANUM_LENGTH);
- if (ret_val)
- strncpy(pba_str, "Unknown", sizeof(pba_str) - 1);
- dev_info(pci_dev_to_dev(pdev), "%s: PBA No: %s\n", netdev->name,
- pba_str);
-
-
- /* Initialize the thermal sensor on i350 devices. */
- if (hw->mac.type == e1000_i350) {
- if (hw->bus.func == 0) {
- u16 ets_word;
-
- /*
- * Read the NVM to determine if this i350 device
- * supports an external thermal sensor.
- */
- e1000_read_nvm(hw, NVM_ETS_CFG, 1, &ets_word);
- if (ets_word != 0x0000 && ets_word != 0xFFFF)
- adapter->ets = true;
- else
- adapter->ets = false;
- }
-#ifdef IGB_HWMON
-
- igb_sysfs_init(adapter);
-#else
-#ifdef IGB_PROCFS
-
- igb_procfs_init(adapter);
-#endif /* IGB_PROCFS */
-#endif /* IGB_HWMON */
- } else {
- adapter->ets = false;
- }
-
- if (hw->phy.media_type == e1000_media_type_copper) {
- switch (hw->mac.type) {
- case e1000_i350:
- case e1000_i210:
- case e1000_i211:
- /* Enable EEE for internal copper PHY devices */
- err = e1000_set_eee_i350(hw);
- if (!err &&
- (adapter->flags & IGB_FLAG_EEE))
- adapter->eee_advert =
- MDIO_EEE_100TX | MDIO_EEE_1000T;
- break;
- case e1000_i354:
- if ((E1000_READ_REG(hw, E1000_CTRL_EXT)) &
- (E1000_CTRL_EXT_LINK_MODE_SGMII)) {
- err = e1000_set_eee_i354(hw);
- if ((!err) &&
- (adapter->flags & IGB_FLAG_EEE))
- adapter->eee_advert =
- MDIO_EEE_100TX | MDIO_EEE_1000T;
- }
- break;
- default:
- break;
- }
- }
-
- /* send driver version info to firmware */
- if (hw->mac.type >= e1000_i350)
- igb_init_fw(adapter);
-
-#ifndef IGB_NO_LRO
- if (netdev->features & NETIF_F_LRO)
- dev_info(pci_dev_to_dev(pdev), "Internal LRO is enabled \n");
- else
- dev_info(pci_dev_to_dev(pdev), "LRO is disabled \n");
-#endif
- dev_info(pci_dev_to_dev(pdev),
- "Using %s interrupts. %d rx queue(s), %d tx queue(s)\n",
- adapter->msix_entries ? "MSI-X" :
- (adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy",
- adapter->num_rx_queues, adapter->num_tx_queues);
-
- cards_found++;
-
- pm_runtime_put_noidle(&pdev->dev);
- return 0;
-
-err_register:
- igb_release_hw_control(adapter);
-#ifdef HAVE_I2C_SUPPORT
- memset(&adapter->i2c_adap, 0, sizeof(adapter->i2c_adap));
-#endif /* HAVE_I2C_SUPPORT */
-err_eeprom:
- if (!e1000_check_reset_block(hw))
- e1000_phy_hw_reset(hw);
-
- if (hw->flash_address)
- iounmap(hw->flash_address);
-err_sw_init:
- igb_clear_interrupt_scheme(adapter);
- igb_reset_sriov_capability(adapter);
- iounmap(hw->hw_addr);
-err_ioremap:
- free_netdev(netdev);
-err_alloc_etherdev:
- pci_release_selected_regions(pdev,
- pci_select_bars(pdev, IORESOURCE_MEM));
-err_pci_reg:
-err_dma:
- pci_disable_device(pdev);
- return err;
-}
-#ifdef HAVE_I2C_SUPPORT
-/*
- * igb_remove_i2c - Cleanup I2C interface
- * @adapter: pointer to adapter structure
- *
- */
-static void igb_remove_i2c(struct igb_adapter *adapter)
-{
-
- /* free the adapter bus structure */
- i2c_del_adapter(&adapter->i2c_adap);
-}
-#endif /* HAVE_I2C_SUPPORT */
-
-/**
- * igb_remove - Device Removal Routine
- * @pdev: PCI device information struct
- *
- * igb_remove is called by the PCI subsystem to alert the driver
- * that it should release a PCI device. The could be caused by a
- * Hot-Plug event, or because the driver is going to be removed from
- * memory.
- **/
-static void __devexit igb_remove(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
- pm_runtime_get_noresume(&pdev->dev);
-#ifdef HAVE_I2C_SUPPORT
- igb_remove_i2c(adapter);
-#endif /* HAVE_I2C_SUPPORT */
-#ifdef HAVE_PTP_1588_CLOCK
- igb_ptp_stop(adapter);
-#endif /* HAVE_PTP_1588_CLOCK */
-
- /* flush_scheduled work may reschedule our watchdog task, so
- * explicitly disable watchdog tasks from being rescheduled */
- set_bit(__IGB_DOWN, &adapter->state);
- del_timer_sync(&adapter->watchdog_timer);
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- del_timer_sync(&adapter->dma_err_timer);
- del_timer_sync(&adapter->phy_info_timer);
-
- flush_scheduled_work();
-
-#ifdef IGB_DCA
- if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
- dev_info(pci_dev_to_dev(pdev), "DCA disabled\n");
- dca_remove_requester(&pdev->dev);
- adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
- E1000_WRITE_REG(hw, E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_DISABLE);
- }
-#endif
-
- /* Release control of h/w to f/w. If f/w is AMT enabled, this
- * would have already happened in close and is redundant. */
- igb_release_hw_control(adapter);
-
- unregister_netdev(netdev);
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- igb_remove_vmdq_netdevs(adapter);
-#endif
-
- igb_clear_interrupt_scheme(adapter);
- igb_reset_sriov_capability(adapter);
-
- iounmap(hw->hw_addr);
- if (hw->flash_address)
- iounmap(hw->flash_address);
- pci_release_selected_regions(pdev,
- pci_select_bars(pdev, IORESOURCE_MEM));
-
-#ifdef IGB_HWMON
- igb_sysfs_exit(adapter);
-#else
-#ifdef IGB_PROCFS
- igb_procfs_exit(adapter);
-#endif /* IGB_PROCFS */
-#endif /* IGB_HWMON */
- kfree(adapter->mac_table);
- kfree(adapter->shadow_vfta);
- free_netdev(netdev);
-
- pci_disable_pcie_error_reporting(pdev);
-
- pci_disable_device(pdev);
-}
-
-/**
- * igb_sw_init - Initialize general software structures (struct igb_adapter)
- * @adapter: board private structure to initialize
- *
- * igb_sw_init initializes the Adapter private data structure.
- * Fields are initialized based on PCI device information and
- * OS network device settings (MTU size).
- **/
-static int igb_sw_init(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
-
- /* PCI config space info */
-
- hw->vendor_id = pdev->vendor;
- hw->device_id = pdev->device;
- hw->subsystem_vendor_id = pdev->subsystem_vendor;
- hw->subsystem_device_id = pdev->subsystem_device;
-
- pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
-
- pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
-
- /* set default ring sizes */
- adapter->tx_ring_count = IGB_DEFAULT_TXD;
- adapter->rx_ring_count = IGB_DEFAULT_RXD;
-
- /* set default work limits */
- adapter->tx_work_limit = IGB_DEFAULT_TX_WORK;
-
- adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN +
- VLAN_HLEN;
-
- /* Initialize the hardware-specific values */
- if (e1000_setup_init_funcs(hw, TRUE)) {
- dev_err(pci_dev_to_dev(pdev), "Hardware Initialization Failure\n");
- return -EIO;
- }
-
- adapter->mac_table = kzalloc(sizeof(struct igb_mac_addr) *
- hw->mac.rar_entry_count,
- GFP_ATOMIC);
-
- /* Setup and initialize a copy of the hw vlan table array */
- adapter->shadow_vfta = kzalloc(sizeof(u32) * E1000_VFTA_ENTRIES,
- GFP_ATOMIC);
-#ifdef NO_KNI
- /* These calls may decrease the number of queues */
- if (hw->mac.type < e1000_i210) {
- igb_set_sriov_capability(adapter);
- }
-
- if (igb_init_interrupt_scheme(adapter, true)) {
- dev_err(pci_dev_to_dev(pdev), "Unable to allocate memory for queues\n");
- return -ENOMEM;
- }
-
- /* Explicitly disable IRQ since the NIC can be in any state. */
- igb_irq_disable(adapter);
-
- set_bit(__IGB_DOWN, &adapter->state);
-#endif
- return 0;
-}
-
-/**
- * igb_open - Called when a network interface is made active
- * @netdev: network interface device structure
- *
- * Returns 0 on success, negative value on failure
- *
- * The open entry point is called when a network interface is made
- * active by the system (IFF_UP). At this point all resources needed
- * for transmit and receive operations are allocated, the interrupt
- * handler is registered with the OS, the watchdog timer is started,
- * and the stack is notified that the interface is ready.
- **/
-static int __igb_open(struct net_device *netdev, bool resuming)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-#ifdef CONFIG_PM_RUNTIME
- struct pci_dev *pdev = adapter->pdev;
-#endif /* CONFIG_PM_RUNTIME */
- int err;
- int i;
-
- /* disallow open during test */
- if (test_bit(__IGB_TESTING, &adapter->state)) {
- WARN_ON(resuming);
- return -EBUSY;
- }
-
-#ifdef CONFIG_PM_RUNTIME
- if (!resuming)
- pm_runtime_get_sync(&pdev->dev);
-#endif /* CONFIG_PM_RUNTIME */
-
- netif_carrier_off(netdev);
-
- /* allocate transmit descriptors */
- err = igb_setup_all_tx_resources(adapter);
- if (err)
- goto err_setup_tx;
-
- /* allocate receive descriptors */
- err = igb_setup_all_rx_resources(adapter);
- if (err)
- goto err_setup_rx;
-
- igb_power_up_link(adapter);
-
- /* before we allocate an interrupt, we must be ready to handle it.
- * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
- * as soon as we call pci_request_irq, so we have to setup our
- * clean_rx handler before we do so. */
- igb_configure(adapter);
-
- err = igb_request_irq(adapter);
- if (err)
- goto err_req_irq;
-
- /* Notify the stack of the actual queue counts. */
- netif_set_real_num_tx_queues(netdev,
- adapter->vmdq_pools ? 1 :
- adapter->num_tx_queues);
-
- err = netif_set_real_num_rx_queues(netdev,
- adapter->vmdq_pools ? 1 :
- adapter->num_rx_queues);
- if (err)
- goto err_set_queues;
-
- /* From here on the code is the same as igb_up() */
- clear_bit(__IGB_DOWN, &adapter->state);
-
- for (i = 0; i < adapter->num_q_vectors; i++)
- napi_enable(&(adapter->q_vector[i]->napi));
- igb_configure_lli(adapter);
-
- /* Clear any pending interrupts. */
- E1000_READ_REG(hw, E1000_ICR);
-
- igb_irq_enable(adapter);
-
- /* notify VFs that reset has been completed */
- if (adapter->vfs_allocated_count) {
- u32 reg_data = E1000_READ_REG(hw, E1000_CTRL_EXT);
- reg_data |= E1000_CTRL_EXT_PFRSTD;
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg_data);
- }
-
- netif_tx_start_all_queues(netdev);
-
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- schedule_work(&adapter->dma_err_task);
-
- /* start the watchdog. */
- hw->mac.get_link_status = 1;
- schedule_work(&adapter->watchdog_task);
-
- return E1000_SUCCESS;
-
-err_set_queues:
- igb_free_irq(adapter);
-err_req_irq:
- igb_release_hw_control(adapter);
- igb_power_down_link(adapter);
- igb_free_all_rx_resources(adapter);
-err_setup_rx:
- igb_free_all_tx_resources(adapter);
-err_setup_tx:
- igb_reset(adapter);
-
-#ifdef CONFIG_PM_RUNTIME
- if (!resuming)
- pm_runtime_put(&pdev->dev);
-#endif /* CONFIG_PM_RUNTIME */
-
- return err;
-}
-
-static int igb_open(struct net_device *netdev)
-{
- return __igb_open(netdev, false);
-}
-
-/**
- * igb_close - Disables a network interface
- * @netdev: network interface device structure
- *
- * Returns 0, this is not allowed to fail
- *
- * The close entry point is called when an interface is de-activated
- * by the OS. The hardware is still under the driver's control, but
- * needs to be disabled. A global MAC reset is issued to stop the
- * hardware, and all transmit and receive resources are freed.
- **/
-static int __igb_close(struct net_device *netdev, bool suspending)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_PM_RUNTIME
- struct pci_dev *pdev = adapter->pdev;
-#endif /* CONFIG_PM_RUNTIME */
-
- WARN_ON(test_bit(__IGB_RESETTING, &adapter->state));
-
-#ifdef CONFIG_PM_RUNTIME
- if (!suspending)
- pm_runtime_get_sync(&pdev->dev);
-#endif /* CONFIG_PM_RUNTIME */
-
- igb_down(adapter);
-
- igb_release_hw_control(adapter);
-
- igb_free_irq(adapter);
-
- igb_free_all_tx_resources(adapter);
- igb_free_all_rx_resources(adapter);
-
-#ifdef CONFIG_PM_RUNTIME
- if (!suspending)
- pm_runtime_put_sync(&pdev->dev);
-#endif /* CONFIG_PM_RUNTIME */
-
- return 0;
-}
-
-static int igb_close(struct net_device *netdev)
-{
- return __igb_close(netdev, false);
-}
-
-/**
- * igb_setup_tx_resources - allocate Tx resources (Descriptors)
- * @tx_ring: tx descriptor ring (for a specific queue) to setup
- *
- * Return 0 on success, negative on failure
- **/
-int igb_setup_tx_resources(struct igb_ring *tx_ring)
-{
- struct device *dev = tx_ring->dev;
- int size;
-
- size = sizeof(struct igb_tx_buffer) * tx_ring->count;
- tx_ring->tx_buffer_info = vzalloc(size);
- if (!tx_ring->tx_buffer_info)
- goto err;
-
- /* round up to nearest 4K */
- tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
- tx_ring->size = ALIGN(tx_ring->size, 4096);
-
- tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size,
- &tx_ring->dma, GFP_KERNEL);
-
- if (!tx_ring->desc)
- goto err;
-
- tx_ring->next_to_use = 0;
- tx_ring->next_to_clean = 0;
-
- return 0;
-
-err:
- vfree(tx_ring->tx_buffer_info);
- dev_err(dev,
- "Unable to allocate memory for the transmit descriptor ring\n");
- return -ENOMEM;
-}
-
-/**
- * igb_setup_all_tx_resources - wrapper to allocate Tx resources
- * (Descriptors) for all queues
- * @adapter: board private structure
- *
- * Return 0 on success, negative on failure
- **/
-static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- int i, err = 0;
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- err = igb_setup_tx_resources(adapter->tx_ring[i]);
- if (err) {
- dev_err(pci_dev_to_dev(pdev),
- "Allocation for Tx Queue %u failed\n", i);
- for (i--; i >= 0; i--)
- igb_free_tx_resources(adapter->tx_ring[i]);
- break;
- }
- }
-
- return err;
-}
-
-/**
- * igb_setup_tctl - configure the transmit control registers
- * @adapter: Board private structure
- **/
-void igb_setup_tctl(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 tctl;
-
- /* disable queue 0 which is enabled by default on 82575 and 82576 */
- E1000_WRITE_REG(hw, E1000_TXDCTL(0), 0);
-
- /* Program the Transmit Control Register */
- tctl = E1000_READ_REG(hw, E1000_TCTL);
- tctl &= ~E1000_TCTL_CT;
- tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
- (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
-
- e1000_config_collision_dist(hw);
-
- /* Enable transmits */
- tctl |= E1000_TCTL_EN;
-
- E1000_WRITE_REG(hw, E1000_TCTL, tctl);
-}
-
-static u32 igb_tx_wthresh(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- switch (hw->mac.type) {
- case e1000_i354:
- return 4;
- case e1000_82576:
- if (adapter->msix_entries)
- return 1;
- default:
- break;
- }
-
- return 16;
-}
-
-/**
- * igb_configure_tx_ring - Configure transmit ring after Reset
- * @adapter: board private structure
- * @ring: tx ring to configure
- *
- * Configure a transmit ring after a reset.
- **/
-void igb_configure_tx_ring(struct igb_adapter *adapter,
- struct igb_ring *ring)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 txdctl = 0;
- u64 tdba = ring->dma;
- int reg_idx = ring->reg_idx;
-
- /* disable the queue */
- E1000_WRITE_REG(hw, E1000_TXDCTL(reg_idx), 0);
- E1000_WRITE_FLUSH(hw);
- mdelay(10);
-
- E1000_WRITE_REG(hw, E1000_TDLEN(reg_idx),
- ring->count * sizeof(union e1000_adv_tx_desc));
- E1000_WRITE_REG(hw, E1000_TDBAL(reg_idx),
- tdba & 0x00000000ffffffffULL);
- E1000_WRITE_REG(hw, E1000_TDBAH(reg_idx), tdba >> 32);
-
- ring->tail = hw->hw_addr + E1000_TDT(reg_idx);
- E1000_WRITE_REG(hw, E1000_TDH(reg_idx), 0);
- writel(0, ring->tail);
-
- txdctl |= IGB_TX_PTHRESH;
- txdctl |= IGB_TX_HTHRESH << 8;
- txdctl |= igb_tx_wthresh(adapter) << 16;
-
- txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
- E1000_WRITE_REG(hw, E1000_TXDCTL(reg_idx), txdctl);
-}
-
-/**
- * igb_configure_tx - Configure transmit Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Tx unit of the MAC after a reset.
- **/
-static void igb_configure_tx(struct igb_adapter *adapter)
-{
- int i;
-
- for (i = 0; i < adapter->num_tx_queues; i++)
- igb_configure_tx_ring(adapter, adapter->tx_ring[i]);
-}
-
-/**
- * igb_setup_rx_resources - allocate Rx resources (Descriptors)
- * @rx_ring: rx descriptor ring (for a specific queue) to setup
- *
- * Returns 0 on success, negative on failure
- **/
-int igb_setup_rx_resources(struct igb_ring *rx_ring)
-{
- struct device *dev = rx_ring->dev;
- int size, desc_len;
-
- size = sizeof(struct igb_rx_buffer) * rx_ring->count;
- rx_ring->rx_buffer_info = vzalloc(size);
- if (!rx_ring->rx_buffer_info)
- goto err;
-
- desc_len = sizeof(union e1000_adv_rx_desc);
-
- /* Round up to nearest 4K */
- rx_ring->size = rx_ring->count * desc_len;
- rx_ring->size = ALIGN(rx_ring->size, 4096);
-
- rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size,
- &rx_ring->dma, GFP_KERNEL);
-
- if (!rx_ring->desc)
- goto err;
-
- rx_ring->next_to_alloc = 0;
- rx_ring->next_to_clean = 0;
- rx_ring->next_to_use = 0;
-
- return 0;
-
-err:
- vfree(rx_ring->rx_buffer_info);
- rx_ring->rx_buffer_info = NULL;
- dev_err(dev, "Unable to allocate memory for the receive descriptor"
- " ring\n");
- return -ENOMEM;
-}
-
-/**
- * igb_setup_all_rx_resources - wrapper to allocate Rx resources
- * (Descriptors) for all queues
- * @adapter: board private structure
- *
- * Return 0 on success, negative on failure
- **/
-static int igb_setup_all_rx_resources(struct igb_adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- int i, err = 0;
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- err = igb_setup_rx_resources(adapter->rx_ring[i]);
- if (err) {
- dev_err(pci_dev_to_dev(pdev),
- "Allocation for Rx Queue %u failed\n", i);
- for (i--; i >= 0; i--)
- igb_free_rx_resources(adapter->rx_ring[i]);
- break;
- }
- }
-
- return err;
-}
-
-/**
- * igb_setup_mrqc - configure the multiple receive queue control registers
- * @adapter: Board private structure
- **/
-static void igb_setup_mrqc(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 mrqc, rxcsum;
- u32 j, num_rx_queues, shift = 0, shift2 = 0;
- static const u32 rsskey[10] = { 0xDA565A6D, 0xC20E5B25, 0x3D256741,
- 0xB08FA343, 0xCB2BCAD0, 0xB4307BAE,
- 0xA32DCB77, 0x0CF23080, 0x3BB7426A,
- 0xFA01ACBE };
-
- /* Fill out hash function seeds */
- for (j = 0; j < 10; j++)
- E1000_WRITE_REG(hw, E1000_RSSRK(j), rsskey[j]);
-
- num_rx_queues = adapter->rss_queues;
-
- /* 82575 and 82576 supports 2 RSS queues for VMDq */
- switch (hw->mac.type) {
- case e1000_82575:
- if (adapter->vmdq_pools) {
- shift = 2;
- shift2 = 6;
- break;
- }
- shift = 6;
- break;
- case e1000_82576:
- /* 82576 supports 2 RSS queues for SR-IOV */
- if (adapter->vfs_allocated_count || adapter->vmdq_pools) {
- shift = 3;
- num_rx_queues = 2;
- }
- break;
- default:
- break;
- }
-
- /*
- * Populate the redirection table 4 entries at a time. To do this
- * we are generating the results for n and n+2 and then interleaving
- * those with the results with n+1 and n+3.
- */
- for (j = 0; j < 32; j++) {
- /* first pass generates n and n+2 */
- u32 base = ((j * 0x00040004) + 0x00020000) * num_rx_queues;
- u32 reta = (base & 0x07800780) >> (7 - shift);
-
- /* second pass generates n+1 and n+3 */
- base += 0x00010001 * num_rx_queues;
- reta |= (base & 0x07800780) << (1 + shift);
-
- /* generate 2nd table for 82575 based parts */
- if (shift2)
- reta |= (0x01010101 * num_rx_queues) << shift2;
-
- E1000_WRITE_REG(hw, E1000_RETA(j), reta);
- }
-
- /*
- * Disable raw packet checksumming so that RSS hash is placed in
- * descriptor on writeback. No need to enable TCP/UDP/IP checksum
- * offloads as they are enabled by default
- */
- rxcsum = E1000_READ_REG(hw, E1000_RXCSUM);
- rxcsum |= E1000_RXCSUM_PCSD;
-
- if (adapter->hw.mac.type >= e1000_82576)
- /* Enable Receive Checksum Offload for SCTP */
- rxcsum |= E1000_RXCSUM_CRCOFL;
-
- /* Don't need to set TUOFL or IPOFL, they default to 1 */
- E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);
-
- /* Generate RSS hash based on packet types, TCP/UDP
- * port numbers and/or IPv4/v6 src and dst addresses
- */
- mrqc = E1000_MRQC_RSS_FIELD_IPV4 |
- E1000_MRQC_RSS_FIELD_IPV4_TCP |
- E1000_MRQC_RSS_FIELD_IPV6 |
- E1000_MRQC_RSS_FIELD_IPV6_TCP |
- E1000_MRQC_RSS_FIELD_IPV6_TCP_EX;
-
- if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV4_UDP)
- mrqc |= E1000_MRQC_RSS_FIELD_IPV4_UDP;
- if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV6_UDP)
- mrqc |= E1000_MRQC_RSS_FIELD_IPV6_UDP;
-
- /* If VMDq is enabled then we set the appropriate mode for that, else
- * we default to RSS so that an RSS hash is calculated per packet even
- * if we are only using one queue */
- if (adapter->vfs_allocated_count || adapter->vmdq_pools) {
- if (hw->mac.type > e1000_82575) {
- /* Set the default pool for the PF's first queue */
- u32 vtctl = E1000_READ_REG(hw, E1000_VT_CTL);
- vtctl &= ~(E1000_VT_CTL_DEFAULT_POOL_MASK |
- E1000_VT_CTL_DISABLE_DEF_POOL);
- vtctl |= adapter->vfs_allocated_count <<
- E1000_VT_CTL_DEFAULT_POOL_SHIFT;
- E1000_WRITE_REG(hw, E1000_VT_CTL, vtctl);
- } else if (adapter->rss_queues > 1) {
- /* set default queue for pool 1 to queue 2 */
- E1000_WRITE_REG(hw, E1000_VT_CTL,
- adapter->rss_queues << 7);
- }
- if (adapter->rss_queues > 1)
- mrqc |= E1000_MRQC_ENABLE_VMDQ_RSS_2Q;
- else
- mrqc |= E1000_MRQC_ENABLE_VMDQ;
- } else {
- mrqc |= E1000_MRQC_ENABLE_RSS_4Q;
- }
- igb_vmm_control(adapter);
-
- E1000_WRITE_REG(hw, E1000_MRQC, mrqc);
-}
-
-/**
- * igb_setup_rctl - configure the receive control registers
- * @adapter: Board private structure
- **/
-void igb_setup_rctl(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 rctl;
-
- rctl = E1000_READ_REG(hw, E1000_RCTL);
-
- rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
- rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
-
- rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
- (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
-
- /*
- * enable stripping of CRC. It's unlikely this will break BMC
- * redirection as it did with e1000. Newer features require
- * that the HW strips the CRC.
- */
- rctl |= E1000_RCTL_SECRC;
-
- /* disable store bad packets and clear size bits. */
- rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256);
-
- /* enable LPE to prevent packets larger than max_frame_size */
- rctl |= E1000_RCTL_LPE;
-
- /* disable queue 0 to prevent tail write w/o re-config */
- E1000_WRITE_REG(hw, E1000_RXDCTL(0), 0);
-
- /* Attention!!! For SR-IOV PF driver operations you must enable
- * queue drop for all VF and PF queues to prevent head of line blocking
- * if an un-trusted VF does not provide descriptors to hardware.
- */
- if (adapter->vfs_allocated_count) {
- /* set all queue drop enable bits */
- E1000_WRITE_REG(hw, E1000_QDE, ALL_QUEUES);
- }
-
- E1000_WRITE_REG(hw, E1000_RCTL, rctl);
-}
-
-static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
- int vfn)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 vmolr;
-
- /* if it isn't the PF check to see if VFs are enabled and
- * increase the size to support vlan tags */
- if (vfn < adapter->vfs_allocated_count &&
- adapter->vf_data[vfn].vlans_enabled)
- size += VLAN_HLEN;
-
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- if (vfn >= adapter->vfs_allocated_count) {
- int queue = vfn - adapter->vfs_allocated_count;
- struct igb_vmdq_adapter *vadapter;
-
- vadapter = netdev_priv(adapter->vmdq_netdev[queue-1]);
- if (vadapter->vlgrp)
- size += VLAN_HLEN;
- }
-#endif
- vmolr = E1000_READ_REG(hw, E1000_VMOLR(vfn));
- vmolr &= ~E1000_VMOLR_RLPML_MASK;
- vmolr |= size | E1000_VMOLR_LPE;
- E1000_WRITE_REG(hw, E1000_VMOLR(vfn), vmolr);
-
- return 0;
-}
-
-/**
- * igb_rlpml_set - set maximum receive packet size
- * @adapter: board private structure
- *
- * Configure maximum receivable packet size.
- **/
-static void igb_rlpml_set(struct igb_adapter *adapter)
-{
- u32 max_frame_size = adapter->max_frame_size;
- struct e1000_hw *hw = &adapter->hw;
- u16 pf_id = adapter->vfs_allocated_count;
-
- if (adapter->vmdq_pools && hw->mac.type != e1000_82575) {
- int i;
- for (i = 0; i < adapter->vmdq_pools; i++)
- igb_set_vf_rlpml(adapter, max_frame_size, pf_id + i);
- /*
- * If we're in VMDQ or SR-IOV mode, then set global RLPML
- * to our max jumbo frame size, in case we need to enable
- * jumbo frames on one of the rings later.
- * This will not pass over-length frames into the default
- * queue because it's gated by the VMOLR.RLPML.
- */
- max_frame_size = MAX_JUMBO_FRAME_SIZE;
- }
- /* Set VF RLPML for the PF device. */
- if (adapter->vfs_allocated_count)
- igb_set_vf_rlpml(adapter, max_frame_size, pf_id);
-
- E1000_WRITE_REG(hw, E1000_RLPML, max_frame_size);
-}
-
-static inline void igb_set_vf_vlan_strip(struct igb_adapter *adapter,
- int vfn, bool enable)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 val;
- void __iomem *reg;
-
- if (hw->mac.type < e1000_82576)
- return;
-
- if (hw->mac.type == e1000_i350)
- reg = hw->hw_addr + E1000_DVMOLR(vfn);
- else
- reg = hw->hw_addr + E1000_VMOLR(vfn);
-
- val = readl(reg);
- if (enable)
- val |= E1000_VMOLR_STRVLAN;
- else
- val &= ~(E1000_VMOLR_STRVLAN);
- writel(val, reg);
-}
-static inline void igb_set_vmolr(struct igb_adapter *adapter,
- int vfn, bool aupe)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 vmolr;
-
- /*
- * This register exists only on 82576 and newer so if we are older then
- * we should exit and do nothing
- */
- if (hw->mac.type < e1000_82576)
- return;
-
- vmolr = E1000_READ_REG(hw, E1000_VMOLR(vfn));
-
- if (aupe)
- vmolr |= E1000_VMOLR_AUPE; /* Accept untagged packets */
- else
- vmolr &= ~(E1000_VMOLR_AUPE); /* Tagged packets ONLY */
-
- /* clear all bits that might not be set */
- vmolr &= ~E1000_VMOLR_RSSE;
-
- if (adapter->rss_queues > 1 && vfn == adapter->vfs_allocated_count)
- vmolr |= E1000_VMOLR_RSSE; /* enable RSS */
-
- vmolr |= E1000_VMOLR_BAM; /* Accept broadcast */
- vmolr |= E1000_VMOLR_LPE; /* Accept long packets */
-
- E1000_WRITE_REG(hw, E1000_VMOLR(vfn), vmolr);
-}
-
-/**
- * igb_configure_rx_ring - Configure a receive ring after Reset
- * @adapter: board private structure
- * @ring: receive ring to be configured
- *
- * Configure the Rx unit of the MAC after a reset.
- **/
-void igb_configure_rx_ring(struct igb_adapter *adapter,
- struct igb_ring *ring)
-{
- struct e1000_hw *hw = &adapter->hw;
- u64 rdba = ring->dma;
- int reg_idx = ring->reg_idx;
- u32 srrctl = 0, rxdctl = 0;
-
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- /*
- * RLPML prevents us from receiving a frame larger than max_frame so
- * it is safe to just set the rx_buffer_len to max_frame without the
- * risk of an skb over panic.
- */
- ring->rx_buffer_len = max_t(u32, adapter->max_frame_size,
- MAXIMUM_ETHERNET_VLAN_SIZE);
-
-#endif
- /* disable the queue */
- E1000_WRITE_REG(hw, E1000_RXDCTL(reg_idx), 0);
-
- /* Set DMA base address registers */
- E1000_WRITE_REG(hw, E1000_RDBAL(reg_idx),
- rdba & 0x00000000ffffffffULL);
- E1000_WRITE_REG(hw, E1000_RDBAH(reg_idx), rdba >> 32);
- E1000_WRITE_REG(hw, E1000_RDLEN(reg_idx),
- ring->count * sizeof(union e1000_adv_rx_desc));
-
- /* initialize head and tail */
- ring->tail = hw->hw_addr + E1000_RDT(reg_idx);
- E1000_WRITE_REG(hw, E1000_RDH(reg_idx), 0);
- writel(0, ring->tail);
-
- /* reset next-to- use/clean to place SW in sync with hardwdare */
- ring->next_to_clean = 0;
- ring->next_to_use = 0;
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
- ring->next_to_alloc = 0;
-
-#endif
- /* set descriptor configuration */
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
- srrctl = IGB_RX_HDR_LEN << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
- srrctl |= IGB_RX_BUFSZ >> E1000_SRRCTL_BSIZEPKT_SHIFT;
-#else /* CONFIG_IGB_DISABLE_PACKET_SPLIT */
- srrctl = ALIGN(ring->rx_buffer_len, 1024) >>
- E1000_SRRCTL_BSIZEPKT_SHIFT;
-#endif /* CONFIG_IGB_DISABLE_PACKET_SPLIT */
- srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
-#ifdef HAVE_PTP_1588_CLOCK
- if (hw->mac.type >= e1000_82580)
- srrctl |= E1000_SRRCTL_TIMESTAMP;
-#endif /* HAVE_PTP_1588_CLOCK */
- /*
- * We should set the drop enable bit if:
- * SR-IOV is enabled
- * or
- * Flow Control is disabled and number of RX queues > 1
- *
- * This allows us to avoid head of line blocking for security
- * and performance reasons.
- */
- if (adapter->vfs_allocated_count ||
- (adapter->num_rx_queues > 1 &&
- (hw->fc.requested_mode == e1000_fc_none ||
- hw->fc.requested_mode == e1000_fc_rx_pause)))
- srrctl |= E1000_SRRCTL_DROP_EN;
-
- E1000_WRITE_REG(hw, E1000_SRRCTL(reg_idx), srrctl);
-
- /* set filtering for VMDQ pools */
- igb_set_vmolr(adapter, reg_idx & 0x7, true);
-
- rxdctl |= IGB_RX_PTHRESH;
- rxdctl |= IGB_RX_HTHRESH << 8;
- rxdctl |= IGB_RX_WTHRESH << 16;
-
- /* enable receive descriptor fetching */
- rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
- E1000_WRITE_REG(hw, E1000_RXDCTL(reg_idx), rxdctl);
-}
-
-/**
- * igb_configure_rx - Configure receive Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Rx unit of the MAC after a reset.
- **/
-static void igb_configure_rx(struct igb_adapter *adapter)
-{
- int i;
-
- /* set UTA to appropriate mode */
- igb_set_uta(adapter);
-
- igb_full_sync_mac_table(adapter);
- /* Setup the HW Rx Head and Tail Descriptor Pointers and
- * the Base and Length of the Rx Descriptor Ring */
- for (i = 0; i < adapter->num_rx_queues; i++)
- igb_configure_rx_ring(adapter, adapter->rx_ring[i]);
-}
-
-/**
- * igb_free_tx_resources - Free Tx Resources per Queue
- * @tx_ring: Tx descriptor ring for a specific queue
- *
- * Free all transmit software resources
- **/
-void igb_free_tx_resources(struct igb_ring *tx_ring)
-{
- igb_clean_tx_ring(tx_ring);
-
- vfree(tx_ring->tx_buffer_info);
- tx_ring->tx_buffer_info = NULL;
-
- /* if not set, then don't free */
- if (!tx_ring->desc)
- return;
-
- dma_free_coherent(tx_ring->dev, tx_ring->size,
- tx_ring->desc, tx_ring->dma);
-
- tx_ring->desc = NULL;
-}
-
-/**
- * igb_free_all_tx_resources - Free Tx Resources for All Queues
- * @adapter: board private structure
- *
- * Free all transmit software resources
- **/
-static void igb_free_all_tx_resources(struct igb_adapter *adapter)
-{
- int i;
-
- for (i = 0; i < adapter->num_tx_queues; i++)
- igb_free_tx_resources(adapter->tx_ring[i]);
-}
-
-void igb_unmap_and_free_tx_resource(struct igb_ring *ring,
- struct igb_tx_buffer *tx_buffer)
-{
- if (tx_buffer->skb) {
- dev_kfree_skb_any(tx_buffer->skb);
- if (dma_unmap_len(tx_buffer, len))
- dma_unmap_single(ring->dev,
- dma_unmap_addr(tx_buffer, dma),
- dma_unmap_len(tx_buffer, len),
- DMA_TO_DEVICE);
- } else if (dma_unmap_len(tx_buffer, len)) {
- dma_unmap_page(ring->dev,
- dma_unmap_addr(tx_buffer, dma),
- dma_unmap_len(tx_buffer, len),
- DMA_TO_DEVICE);
- }
- tx_buffer->next_to_watch = NULL;
- tx_buffer->skb = NULL;
- dma_unmap_len_set(tx_buffer, len, 0);
- /* buffer_info must be completely set up in the transmit path */
-}
-
-/**
- * igb_clean_tx_ring - Free Tx Buffers
- * @tx_ring: ring to be cleaned
- **/
-static void igb_clean_tx_ring(struct igb_ring *tx_ring)
-{
- struct igb_tx_buffer *buffer_info;
- unsigned long size;
- u16 i;
-
- if (!tx_ring->tx_buffer_info)
- return;
- /* Free all the Tx ring sk_buffs */
-
- for (i = 0; i < tx_ring->count; i++) {
- buffer_info = &tx_ring->tx_buffer_info[i];
- igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
- }
-
- netdev_tx_reset_queue(txring_txq(tx_ring));
-
- size = sizeof(struct igb_tx_buffer) * tx_ring->count;
- memset(tx_ring->tx_buffer_info, 0, size);
-
- /* Zero out the descriptor ring */
- memset(tx_ring->desc, 0, tx_ring->size);
-
- tx_ring->next_to_use = 0;
- tx_ring->next_to_clean = 0;
-}
-
-/**
- * igb_clean_all_tx_rings - Free Tx Buffers for all queues
- * @adapter: board private structure
- **/
-static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
-{
- int i;
-
- for (i = 0; i < adapter->num_tx_queues; i++)
- igb_clean_tx_ring(adapter->tx_ring[i]);
-}
-
-/**
- * igb_free_rx_resources - Free Rx Resources
- * @rx_ring: ring to clean the resources from
- *
- * Free all receive software resources
- **/
-void igb_free_rx_resources(struct igb_ring *rx_ring)
-{
- igb_clean_rx_ring(rx_ring);
-
- vfree(rx_ring->rx_buffer_info);
- rx_ring->rx_buffer_info = NULL;
-
- /* if not set, then don't free */
- if (!rx_ring->desc)
- return;
-
- dma_free_coherent(rx_ring->dev, rx_ring->size,
- rx_ring->desc, rx_ring->dma);
-
- rx_ring->desc = NULL;
-}
-
-/**
- * igb_free_all_rx_resources - Free Rx Resources for All Queues
- * @adapter: board private structure
- *
- * Free all receive software resources
- **/
-static void igb_free_all_rx_resources(struct igb_adapter *adapter)
-{
- int i;
-
- for (i = 0; i < adapter->num_rx_queues; i++)
- igb_free_rx_resources(adapter->rx_ring[i]);
-}
-
-/**
- * igb_clean_rx_ring - Free Rx Buffers per Queue
- * @rx_ring: ring to free buffers from
- **/
-void igb_clean_rx_ring(struct igb_ring *rx_ring)
-{
- unsigned long size;
- u16 i;
-
- if (!rx_ring->rx_buffer_info)
- return;
-
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
- if (rx_ring->skb)
- dev_kfree_skb(rx_ring->skb);
- rx_ring->skb = NULL;
-
-#endif
- /* Free all the Rx ring sk_buffs */
- for (i = 0; i < rx_ring->count; i++) {
- struct igb_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i];
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- if (buffer_info->dma) {
- dma_unmap_single(rx_ring->dev,
- buffer_info->dma,
- rx_ring->rx_buffer_len,
- DMA_FROM_DEVICE);
- buffer_info->dma = 0;
- }
-
- if (buffer_info->skb) {
- dev_kfree_skb(buffer_info->skb);
- buffer_info->skb = NULL;
- }
-#else
- if (!buffer_info->page)
- continue;
-
- dma_unmap_page(rx_ring->dev,
- buffer_info->dma,
- PAGE_SIZE,
- DMA_FROM_DEVICE);
- __free_page(buffer_info->page);
-
- buffer_info->page = NULL;
-#endif
- }
-
- size = sizeof(struct igb_rx_buffer) * rx_ring->count;
- memset(rx_ring->rx_buffer_info, 0, size);
-
- /* Zero out the descriptor ring */
- memset(rx_ring->desc, 0, rx_ring->size);
-
- rx_ring->next_to_alloc = 0;
- rx_ring->next_to_clean = 0;
- rx_ring->next_to_use = 0;
-}
-
-/**
- * igb_clean_all_rx_rings - Free Rx Buffers for all queues
- * @adapter: board private structure
- **/
-static void igb_clean_all_rx_rings(struct igb_adapter *adapter)
-{
- int i;
-
- for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_ring(adapter->rx_ring[i]);
-}
-
-/**
- * igb_set_mac - Change the Ethernet Address of the NIC
- * @netdev: network interface device structure
- * @p: pointer to an address structure
- *
- * Returns 0 on success, negative on failure
- **/
-static int igb_set_mac(struct net_device *netdev, void *p)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- struct sockaddr *addr = p;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- igb_del_mac_filter(adapter, hw->mac.addr,
- adapter->vfs_allocated_count);
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
-
- /* set the correct pool for the new PF MAC address in entry 0 */
- return igb_add_mac_filter(adapter, hw->mac.addr,
- adapter->vfs_allocated_count);
-}
-
-/**
- * igb_write_mc_addr_list - write multicast addresses to MTA
- * @netdev: network interface device structure
- *
- * Writes multicast address list to the MTA hash table.
- * Returns: -ENOMEM on failure
- * 0 on no addresses written
- * X on writing X addresses to MTA
- **/
-int igb_write_mc_addr_list(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-#ifdef NETDEV_HW_ADDR_T_MULTICAST
- struct netdev_hw_addr *ha;
-#else
- struct dev_mc_list *ha;
-#endif
- u8 *mta_list;
- int i, count;
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- int vm;
-#endif
- count = netdev_mc_count(netdev);
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- for (vm = 1; vm < adapter->vmdq_pools; vm++) {
- if (!adapter->vmdq_netdev[vm])
- break;
- if (!netif_running(adapter->vmdq_netdev[vm]))
- continue;
- count += netdev_mc_count(adapter->vmdq_netdev[vm]);
- }
-#endif
-
- if (!count) {
- e1000_update_mc_addr_list(hw, NULL, 0);
- return 0;
- }
- mta_list = kzalloc(count * 6, GFP_ATOMIC);
- if (!mta_list)
- return -ENOMEM;
-
- /* The shared function expects a packed array of only addresses. */
- i = 0;
- netdev_for_each_mc_addr(ha, netdev)
-#ifdef NETDEV_HW_ADDR_T_MULTICAST
- memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN);
-#else
- memcpy(mta_list + (i++ * ETH_ALEN), ha->dmi_addr, ETH_ALEN);
-#endif
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- for (vm = 1; vm < adapter->vmdq_pools; vm++) {
- if (!adapter->vmdq_netdev[vm])
- break;
- if (!netif_running(adapter->vmdq_netdev[vm]) ||
- !netdev_mc_count(adapter->vmdq_netdev[vm]))
- continue;
- netdev_for_each_mc_addr(ha, adapter->vmdq_netdev[vm])
-#ifdef NETDEV_HW_ADDR_T_MULTICAST
- memcpy(mta_list + (i++ * ETH_ALEN),
- ha->addr, ETH_ALEN);
-#else
- memcpy(mta_list + (i++ * ETH_ALEN),
- ha->dmi_addr, ETH_ALEN);
-#endif
- }
-#endif
- e1000_update_mc_addr_list(hw, mta_list, i);
- kfree(mta_list);
-
- return count;
-}
-
-void igb_rar_set(struct igb_adapter *adapter, u32 index)
-{
- u32 rar_low, rar_high;
- struct e1000_hw *hw = &adapter->hw;
- u8 *addr = adapter->mac_table[index].addr;
- /* HW expects these in little endian so we reverse the byte order
- * from network order (big endian) to little endian
- */
- rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
- ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
- rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
-
- /* Indicate to hardware the Address is Valid. */
- if (adapter->mac_table[index].state & IGB_MAC_STATE_IN_USE)
- rar_high |= E1000_RAH_AV;
-
- if (hw->mac.type == e1000_82575)
- rar_high |= E1000_RAH_POOL_1 * adapter->mac_table[index].queue;
- else
- rar_high |= E1000_RAH_POOL_1 << adapter->mac_table[index].queue;
-
- E1000_WRITE_REG(hw, E1000_RAL(index), rar_low);
- E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG(hw, E1000_RAH(index), rar_high);
- E1000_WRITE_FLUSH(hw);
-}
-
-void igb_full_sync_mac_table(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- int i;
- for (i = 0; i < hw->mac.rar_entry_count; i++) {
- igb_rar_set(adapter, i);
- }
-}
-
-void igb_sync_mac_table(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- int i;
- for (i = 0; i < hw->mac.rar_entry_count; i++) {
- if (adapter->mac_table[i].state & IGB_MAC_STATE_MODIFIED)
- igb_rar_set(adapter, i);
- adapter->mac_table[i].state &= ~(IGB_MAC_STATE_MODIFIED);
- }
-}
-
-int igb_available_rars(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- int i, count = 0;
-
- for (i = 0; i < hw->mac.rar_entry_count; i++) {
- if (adapter->mac_table[i].state == 0)
- count++;
- }
- return count;
-}
-
-#ifdef HAVE_SET_RX_MODE
-/**
- * igb_write_uc_addr_list - write unicast addresses to RAR table
- * @netdev: network interface device structure
- *
- * Writes unicast address list to the RAR table.
- * Returns: -ENOMEM on failure/insufficient address space
- * 0 on no addresses written
- * X on writing X addresses to the RAR table
- **/
-static int igb_write_uc_addr_list(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- unsigned int vfn = adapter->vfs_allocated_count;
- int count = 0;
-
- /* return ENOMEM indicating insufficient memory for addresses */
- if (netdev_uc_count(netdev) > igb_available_rars(adapter))
- return -ENOMEM;
- if (!netdev_uc_empty(netdev)) {
-#ifdef NETDEV_HW_ADDR_T_UNICAST
- struct netdev_hw_addr *ha;
-#else
- struct dev_mc_list *ha;
-#endif
- netdev_for_each_uc_addr(ha, netdev) {
-#ifdef NETDEV_HW_ADDR_T_UNICAST
- igb_del_mac_filter(adapter, ha->addr, vfn);
- igb_add_mac_filter(adapter, ha->addr, vfn);
-#else
- igb_del_mac_filter(adapter, ha->da_addr, vfn);
- igb_add_mac_filter(adapter, ha->da_addr, vfn);
-#endif
- count++;
- }
- }
- return count;
-}
-
-#endif /* HAVE_SET_RX_MODE */
-/**
- * igb_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
- * @netdev: network interface device structure
- *
- * The set_rx_mode entry point is called whenever the unicast or multicast
- * address lists or the network interface flags are updated. This routine is
- * responsible for configuring the hardware for proper unicast, multicast,
- * promiscuous mode, and all-multi behavior.
- **/
-static void igb_set_rx_mode(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- unsigned int vfn = adapter->vfs_allocated_count;
- u32 rctl, vmolr = 0;
- int count;
-
- /* Check for Promiscuous and All Multicast modes */
- rctl = E1000_READ_REG(hw, E1000_RCTL);
-
- /* clear the effected bits */
- rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_VFE);
-
- if (netdev->flags & IFF_PROMISC) {
- rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
- vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME);
- /* retain VLAN HW filtering if in VT mode */
- if (adapter->vfs_allocated_count || adapter->vmdq_pools)
- rctl |= E1000_RCTL_VFE;
- } else {
- if (netdev->flags & IFF_ALLMULTI) {
- rctl |= E1000_RCTL_MPE;
- vmolr |= E1000_VMOLR_MPME;
- } else {
- /*
- * Write addresses to the MTA, if the attempt fails
- * then we should just turn on promiscuous mode so
- * that we can at least receive multicast traffic
- */
- count = igb_write_mc_addr_list(netdev);
- if (count < 0) {
- rctl |= E1000_RCTL_MPE;
- vmolr |= E1000_VMOLR_MPME;
- } else if (count) {
- vmolr |= E1000_VMOLR_ROMPE;
- }
- }
-#ifdef HAVE_SET_RX_MODE
- /*
- * Write addresses to available RAR registers, if there is not
- * sufficient space to store all the addresses then enable
- * unicast promiscuous mode
- */
- count = igb_write_uc_addr_list(netdev);
- if (count < 0) {
- rctl |= E1000_RCTL_UPE;
- vmolr |= E1000_VMOLR_ROPE;
- }
-#endif /* HAVE_SET_RX_MODE */
- rctl |= E1000_RCTL_VFE;
- }
- E1000_WRITE_REG(hw, E1000_RCTL, rctl);
-
- /*
- * In order to support SR-IOV and eventually VMDq it is necessary to set
- * the VMOLR to enable the appropriate modes. Without this workaround
- * we will have issues with VLAN tag stripping not being done for frames
- * that are only arriving because we are the default pool
- */
- if (hw->mac.type < e1000_82576)
- return;
-
- vmolr |= E1000_READ_REG(hw, E1000_VMOLR(vfn)) &
- ~(E1000_VMOLR_ROPE | E1000_VMOLR_MPME | E1000_VMOLR_ROMPE);
- E1000_WRITE_REG(hw, E1000_VMOLR(vfn), vmolr);
- igb_restore_vf_multicasts(adapter);
-}
-
-static void igb_check_wvbr(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 wvbr = 0;
-
- switch (hw->mac.type) {
- case e1000_82576:
- case e1000_i350:
- if (!(wvbr = E1000_READ_REG(hw, E1000_WVBR)))
- return;
- break;
- default:
- break;
- }
-
- adapter->wvbr |= wvbr;
-}
-
-#define IGB_STAGGERED_QUEUE_OFFSET 8
-
-static void igb_spoof_check(struct igb_adapter *adapter)
-{
- int j;
-
- if (!adapter->wvbr)
- return;
-
- switch (adapter->hw.mac.type) {
- case e1000_82576:
- for (j = 0; j < adapter->vfs_allocated_count; j++) {
- if (adapter->wvbr & (1 << j) ||
- adapter->wvbr & (1 << (j + IGB_STAGGERED_QUEUE_OFFSET))) {
- DPRINTK(DRV, WARNING,
- "Spoof event(s) detected on VF %d\n", j);
- adapter->wvbr &=
- ~((1 << j) |
- (1 << (j + IGB_STAGGERED_QUEUE_OFFSET)));
- }
- }
- break;
- case e1000_i350:
- for (j = 0; j < adapter->vfs_allocated_count; j++) {
- if (adapter->wvbr & (1 << j)) {
- DPRINTK(DRV, WARNING,
- "Spoof event(s) detected on VF %d\n", j);
- adapter->wvbr &= ~(1 << j);
- }
- }
- break;
- default:
- break;
- }
-}
-
-/* Need to wait a few seconds after link up to get diagnostic information from
- * the phy */
-#ifdef HAVE_TIMER_SETUP
-static void igb_update_phy_info(struct timer_list *t)
-{
- struct igb_adapter *adapter = from_timer(adapter, t, phy_info_timer);
-#else
-static void igb_update_phy_info(unsigned long data)
-{
- struct igb_adapter *adapter = (struct igb_adapter *) data;
-#endif
- e1000_get_phy_info(&adapter->hw);
-}
-
-/**
- * igb_has_link - check shared code for link and determine up/down
- * @adapter: pointer to driver private info
- **/
-bool igb_has_link(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- bool link_active = FALSE;
-
- /* get_link_status is set on LSC (link status) interrupt or
- * rx sequence error interrupt. get_link_status will stay
- * false until the e1000_check_for_link establishes link
- * for copper adapters ONLY
- */
- switch (hw->phy.media_type) {
- case e1000_media_type_copper:
- if (!hw->mac.get_link_status)
- return true;
- case e1000_media_type_internal_serdes:
- e1000_check_for_link(hw);
- link_active = !hw->mac.get_link_status;
- break;
- case e1000_media_type_unknown:
- default:
- break;
- }
-
- if (((hw->mac.type == e1000_i210) ||
- (hw->mac.type == e1000_i211)) &&
- (hw->phy.id == I210_I_PHY_ID)) {
- if (!netif_carrier_ok(adapter->netdev)) {
- adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
- } else if (!(adapter->flags & IGB_FLAG_NEED_LINK_UPDATE)) {
- adapter->flags |= IGB_FLAG_NEED_LINK_UPDATE;
- adapter->link_check_timeout = jiffies;
- }
- }
-
- return link_active;
-}
-
-/**
- * igb_watchdog - Timer Call-back
- * @data: pointer to adapter cast into an unsigned long
- **/
-#ifdef HAVE_TIMER_SETUP
-static void igb_watchdog(struct timer_list *t)
-{
- struct igb_adapter *adapter = from_timer(adapter, t, watchdog_timer);
-#else
-static void igb_watchdog(unsigned long data)
-{
- struct igb_adapter *adapter = (struct igb_adapter *)data;
-#endif
- /* Do the rest outside of interrupt context */
- schedule_work(&adapter->watchdog_task);
-}
-
-static void igb_watchdog_task(struct work_struct *work)
-{
- struct igb_adapter *adapter = container_of(work,
- struct igb_adapter,
- watchdog_task);
- struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- u32 link;
- int i;
- u32 thstat, ctrl_ext;
- u32 connsw;
-
- link = igb_has_link(adapter);
- /* Force link down if we have fiber to swap to */
- if (adapter->flags & IGB_FLAG_MAS_ENABLE) {
- if (hw->phy.media_type == e1000_media_type_copper) {
- connsw = E1000_READ_REG(hw, E1000_CONNSW);
- if (!(connsw & E1000_CONNSW_AUTOSENSE_EN))
- link = 0;
- }
- }
-
- if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) {
- if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
- adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
- else
- link = FALSE;
- }
-
- if (link) {
- /* Perform a reset if the media type changed. */
- if (hw->dev_spec._82575.media_changed) {
- hw->dev_spec._82575.media_changed = false;
- adapter->flags |= IGB_FLAG_MEDIA_RESET;
- igb_reset(adapter);
- }
-
- /* Cancel scheduled suspend requests. */
- pm_runtime_resume(netdev->dev.parent);
-
- if (!netif_carrier_ok(netdev)) {
- u32 ctrl;
- e1000_get_speed_and_duplex(hw,
- &adapter->link_speed,
- &adapter->link_duplex);
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- /* Links status message must follow this format */
- printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s, "
- "Flow Control: %s\n",
- netdev->name,
- adapter->link_speed,
- adapter->link_duplex == FULL_DUPLEX ?
- "Full Duplex" : "Half Duplex",
- ((ctrl & E1000_CTRL_TFCE) &&
- (ctrl & E1000_CTRL_RFCE)) ? "RX/TX":
- ((ctrl & E1000_CTRL_RFCE) ? "RX" :
- ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None")));
- /* adjust timeout factor according to speed/duplex */
- adapter->tx_timeout_factor = 1;
- switch (adapter->link_speed) {
- case SPEED_10:
- adapter->tx_timeout_factor = 14;
- break;
- case SPEED_100:
- /* maybe add some timeout factor ? */
- break;
- default:
- break;
- }
-
- netif_carrier_on(netdev);
- netif_tx_wake_all_queues(netdev);
-
- igb_ping_all_vfs(adapter);
-#ifdef IFLA_VF_MAX
- igb_check_vf_rate_limit(adapter);
-#endif /* IFLA_VF_MAX */
-
- /* link state has changed, schedule phy info update */
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->phy_info_timer,
- round_jiffies(jiffies + 2 * HZ));
- }
- } else {
- if (netif_carrier_ok(netdev)) {
- adapter->link_speed = 0;
- adapter->link_duplex = 0;
- /* check for thermal sensor event on i350 */
- if (hw->mac.type == e1000_i350) {
- thstat = E1000_READ_REG(hw, E1000_THSTAT);
- ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- if ((hw->phy.media_type ==
- e1000_media_type_copper) &&
- !(ctrl_ext &
- E1000_CTRL_EXT_LINK_MODE_SGMII)) {
- if (thstat & E1000_THSTAT_PWR_DOWN) {
- printk(KERN_ERR "igb: %s The "
- "network adapter was stopped "
- "because it overheated.\n",
- netdev->name);
- }
- if (thstat & E1000_THSTAT_LINK_THROTTLE) {
- printk(KERN_INFO
- "igb: %s The network "
- "adapter supported "
- "link speed "
- "was downshifted "
- "because it "
- "overheated.\n",
- netdev->name);
- }
- }
- }
-
- /* Links status message must follow this format */
- printk(KERN_INFO "igb: %s NIC Link is Down\n",
- netdev->name);
- netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
-
- igb_ping_all_vfs(adapter);
-
- /* link state has changed, schedule phy info update */
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->phy_info_timer,
- round_jiffies(jiffies + 2 * HZ));
- /* link is down, time to check for alternate media */
- if (adapter->flags & IGB_FLAG_MAS_ENABLE) {
- igb_check_swap_media(adapter);
- if (adapter->flags & IGB_FLAG_MEDIA_RESET) {
- schedule_work(&adapter->reset_task);
- /* return immediately */
- return;
- }
- }
- pm_schedule_suspend(netdev->dev.parent,
- MSEC_PER_SEC * 5);
-
- /* also check for alternate media here */
- } else if (!netif_carrier_ok(netdev) &&
- (adapter->flags & IGB_FLAG_MAS_ENABLE)) {
- hw->mac.ops.power_up_serdes(hw);
- igb_check_swap_media(adapter);
- if (adapter->flags & IGB_FLAG_MEDIA_RESET) {
- schedule_work(&adapter->reset_task);
- /* return immediately */
- return;
- }
- }
- }
-
- igb_update_stats(adapter);
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- struct igb_ring *tx_ring = adapter->tx_ring[i];
- if (!netif_carrier_ok(netdev)) {
- /* We've lost link, so the controller stops DMA,
- * but we've got queued Tx work that's never going
- * to get done, so reset controller to flush Tx.
- * (Do the reset outside of interrupt context). */
- if (igb_desc_unused(tx_ring) + 1 < tx_ring->count) {
- adapter->tx_timeout_count++;
- schedule_work(&adapter->reset_task);
- /* return immediately since reset is imminent */
- return;
- }
- }
-
- /* Force detection of hung controller every watchdog period */
- set_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags);
- }
-
- /* Cause software interrupt to ensure rx ring is cleaned */
- if (adapter->msix_entries) {
- u32 eics = 0;
- for (i = 0; i < adapter->num_q_vectors; i++)
- eics |= adapter->q_vector[i]->eims_value;
- E1000_WRITE_REG(hw, E1000_EICS, eics);
- } else {
- E1000_WRITE_REG(hw, E1000_ICS, E1000_ICS_RXDMT0);
- }
-
- igb_spoof_check(adapter);
-
- /* Reset the timer */
- if (!test_bit(__IGB_DOWN, &adapter->state)) {
- if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE)
- mod_timer(&adapter->watchdog_timer,
- round_jiffies(jiffies + HZ));
- else
- mod_timer(&adapter->watchdog_timer,
- round_jiffies(jiffies + 2 * HZ));
- }
-}
-
-static void igb_dma_err_task(struct work_struct *work)
-{
- struct igb_adapter *adapter = container_of(work,
- struct igb_adapter,
- dma_err_task);
- int vf;
- struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- u32 hgptc;
- u32 ciaa, ciad;
-
- hgptc = E1000_READ_REG(hw, E1000_HGPTC);
- if (hgptc) /* If incrementing then no need for the check below */
- goto dma_timer_reset;
- /*
- * Check to see if a bad DMA write target from an errant or
- * malicious VF has caused a PCIe error. If so then we can
- * issue a VFLR to the offending VF(s) and then resume without
- * requesting a full slot reset.
- */
-
- for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
- ciaa = (vf << 16) | 0x80000000;
- /* 32 bit read so align, we really want status at offset 6 */
- ciaa |= PCI_COMMAND;
- E1000_WRITE_REG(hw, E1000_CIAA, ciaa);
- ciad = E1000_READ_REG(hw, E1000_CIAD);
- ciaa &= 0x7FFFFFFF;
- /* disable debug mode asap after reading data */
- E1000_WRITE_REG(hw, E1000_CIAA, ciaa);
- /* Get the upper 16 bits which will be the PCI status reg */
- ciad >>= 16;
- if (ciad & (PCI_STATUS_REC_MASTER_ABORT |
- PCI_STATUS_REC_TARGET_ABORT |
- PCI_STATUS_SIG_SYSTEM_ERROR)) {
- netdev_err(netdev, "VF %d suffered error\n", vf);
- /* Issue VFLR */
- ciaa = (vf << 16) | 0x80000000;
- ciaa |= 0xA8;
- E1000_WRITE_REG(hw, E1000_CIAA, ciaa);
- ciad = 0x00008000; /* VFLR */
- E1000_WRITE_REG(hw, E1000_CIAD, ciad);
- ciaa &= 0x7FFFFFFF;
- E1000_WRITE_REG(hw, E1000_CIAA, ciaa);
- }
- }
-dma_timer_reset:
- /* Reset the timer */
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->dma_err_timer,
- round_jiffies(jiffies + HZ / 10));
-}
-
-/**
- * igb_dma_err_timer - Timer Call-back
- * @data: pointer to adapter cast into an unsigned long
- **/
-#ifdef HAVE_TIMER_SETUP
-static void igb_dma_err_timer(struct timer_list *t)
-{
- struct igb_adapter *adapter = from_timer(adapter, t, dma_err_timer);
-#else
-static void igb_dma_err_timer(unsigned long data)
-{
- struct igb_adapter *adapter = (struct igb_adapter *)data;
-#endif
- /* Do the rest outside of interrupt context */
- schedule_work(&adapter->dma_err_task);
-}
-
-enum latency_range {
- lowest_latency = 0,
- low_latency = 1,
- bulk_latency = 2,
- latency_invalid = 255
-};
-
-/**
- * igb_update_ring_itr - update the dynamic ITR value based on packet size
- *
- * Stores a new ITR value based on strictly on packet size. This
- * algorithm is less sophisticated than that used in igb_update_itr,
- * due to the difficulty of synchronizing statistics across multiple
- * receive rings. The divisors and thresholds used by this function
- * were determined based on theoretical maximum wire speed and testing
- * data, in order to minimize response time while increasing bulk
- * throughput.
- * This functionality is controlled by the InterruptThrottleRate module
- * parameter (see igb_param.c)
- * NOTE: This function is called only when operating in a multiqueue
- * receive environment.
- * @q_vector: pointer to q_vector
- **/
-static void igb_update_ring_itr(struct igb_q_vector *q_vector)
-{
- int new_val = q_vector->itr_val;
- int avg_wire_size = 0;
- struct igb_adapter *adapter = q_vector->adapter;
- unsigned int packets;
-
- /* For non-gigabit speeds, just fix the interrupt rate at 4000
- * ints/sec - ITR timer value of 120 ticks.
- */
- switch (adapter->link_speed) {
- case SPEED_10:
- case SPEED_100:
- new_val = IGB_4K_ITR;
- goto set_itr_val;
- default:
- break;
- }
-
- packets = q_vector->rx.total_packets;
- if (packets)
- avg_wire_size = q_vector->rx.total_bytes / packets;
-
- packets = q_vector->tx.total_packets;
- if (packets)
- avg_wire_size = max_t(u32, avg_wire_size,
- q_vector->tx.total_bytes / packets);
-
- /* if avg_wire_size isn't set no work was done */
- if (!avg_wire_size)
- goto clear_counts;
-
- /* Add 24 bytes to size to account for CRC, preamble, and gap */
- avg_wire_size += 24;
-
- /* Don't starve jumbo frames */
- avg_wire_size = min(avg_wire_size, 3000);
-
- /* Give a little boost to mid-size frames */
- if ((avg_wire_size > 300) && (avg_wire_size < 1200))
- new_val = avg_wire_size / 3;
- else
- new_val = avg_wire_size / 2;
-
- /* conservative mode (itr 3) eliminates the lowest_latency setting */
- if (new_val < IGB_20K_ITR &&
- ((q_vector->rx.ring && adapter->rx_itr_setting == 3) ||
- (!q_vector->rx.ring && adapter->tx_itr_setting == 3)))
- new_val = IGB_20K_ITR;
-
-set_itr_val:
- if (new_val != q_vector->itr_val) {
- q_vector->itr_val = new_val;
- q_vector->set_itr = 1;
- }
-clear_counts:
- q_vector->rx.total_bytes = 0;
- q_vector->rx.total_packets = 0;
- q_vector->tx.total_bytes = 0;
- q_vector->tx.total_packets = 0;
-}
-
-/**
- * igb_update_itr - update the dynamic ITR value based on statistics
- * 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.
- * this functionality is controlled by the InterruptThrottleRate module
- * parameter (see igb_param.c)
- * NOTE: These calculations are only valid when operating in a single-
- * queue environment.
- * @q_vector: pointer to q_vector
- * @ring_container: ring info to update the itr for
- **/
-static void igb_update_itr(struct igb_q_vector *q_vector,
- struct igb_ring_container *ring_container)
-{
- unsigned int packets = ring_container->total_packets;
- unsigned int bytes = ring_container->total_bytes;
- u8 itrval = ring_container->itr;
-
- /* no packets, exit with status unchanged */
- if (packets == 0)
- return;
-
- switch (itrval) {
- case lowest_latency:
- /* handle TSO and jumbo frames */
- if (bytes/packets > 8000)
- itrval = bulk_latency;
- else if ((packets < 5) && (bytes > 512))
- itrval = low_latency;
- break;
- case low_latency: /* 50 usec aka 20000 ints/s */
- if (bytes > 10000) {
- /* this if handles the TSO accounting */
- if (bytes/packets > 8000) {
- itrval = bulk_latency;
- } else if ((packets < 10) || ((bytes/packets) > 1200)) {
- itrval = bulk_latency;
- } else if (packets > 35) {
- itrval = lowest_latency;
- }
- } else if (bytes/packets > 2000) {
- itrval = bulk_latency;
- } else if (packets <= 2 && bytes < 512) {
- itrval = lowest_latency;
- }
- break;
- case bulk_latency: /* 250 usec aka 4000 ints/s */
- if (bytes > 25000) {
- if (packets > 35)
- itrval = low_latency;
- } else if (bytes < 1500) {
- itrval = low_latency;
- }
- break;
- }
-
- /* clear work counters since we have the values we need */
- ring_container->total_bytes = 0;
- ring_container->total_packets = 0;
-
- /* write updated itr to ring container */
- ring_container->itr = itrval;
-}
-
-static void igb_set_itr(struct igb_q_vector *q_vector)
-{
- struct igb_adapter *adapter = q_vector->adapter;
- u32 new_itr = q_vector->itr_val;
- u8 current_itr = 0;
-
- /* for non-gigabit speeds, just fix the interrupt rate at 4000 */
- switch (adapter->link_speed) {
- case SPEED_10:
- case SPEED_100:
- current_itr = 0;
- new_itr = IGB_4K_ITR;
- goto set_itr_now;
- default:
- break;
- }
-
- igb_update_itr(q_vector, &q_vector->tx);
- igb_update_itr(q_vector, &q_vector->rx);
-
- current_itr = max(q_vector->rx.itr, q_vector->tx.itr);
-
- /* conservative mode (itr 3) eliminates the lowest_latency setting */
- if (current_itr == lowest_latency &&
- ((q_vector->rx.ring && adapter->rx_itr_setting == 3) ||
- (!q_vector->rx.ring && adapter->tx_itr_setting == 3)))
- current_itr = low_latency;
-
- switch (current_itr) {
- /* counts and packets in update_itr are dependent on these numbers */
- case lowest_latency:
- new_itr = IGB_70K_ITR; /* 70,000 ints/sec */
- break;
- case low_latency:
- new_itr = IGB_20K_ITR; /* 20,000 ints/sec */
- break;
- case bulk_latency:
- new_itr = IGB_4K_ITR; /* 4,000 ints/sec */
- break;
- default:
- break;
- }
-
-set_itr_now:
- if (new_itr != q_vector->itr_val) {
- /* this attempts to bias the interrupt rate towards Bulk
- * by adding intermediate steps when interrupt rate is
- * increasing */
- new_itr = new_itr > q_vector->itr_val ?
- max((new_itr * q_vector->itr_val) /
- (new_itr + (q_vector->itr_val >> 2)),
- new_itr) :
- new_itr;
- /* Don't write the value here; it resets the adapter's
- * internal timer, and causes us to delay far longer than
- * we should between interrupts. Instead, we write the ITR
- * value at the beginning of the next interrupt so the timing
- * ends up being correct.
- */
- q_vector->itr_val = new_itr;
- q_vector->set_itr = 1;
- }
-}
-
-void igb_tx_ctxtdesc(struct igb_ring *tx_ring, u32 vlan_macip_lens,
- u32 type_tucmd, u32 mss_l4len_idx)
-{
- struct e1000_adv_tx_context_desc *context_desc;
- u16 i = tx_ring->next_to_use;
-
- context_desc = IGB_TX_CTXTDESC(tx_ring, i);
-
- i++;
- tx_ring->next_to_use = (i < tx_ring->count) ? i : 0;
-
- /* set bits to identify this as an advanced context descriptor */
- type_tucmd |= E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT;
-
- /* For 82575, context index must be unique per ring. */
- if (test_bit(IGB_RING_FLAG_TX_CTX_IDX, &tx_ring->flags))
- mss_l4len_idx |= tx_ring->reg_idx << 4;
-
- context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
- context_desc->seqnum_seed = 0;
- context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd);
- context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
-}
-
-static int igb_tso(struct igb_ring *tx_ring,
- struct igb_tx_buffer *first,
- u8 *hdr_len)
-{
-#ifdef NETIF_F_TSO
- struct sk_buff *skb = first->skb;
- u32 vlan_macip_lens, type_tucmd;
- u32 mss_l4len_idx, l4len;
-
- if (skb->ip_summed != CHECKSUM_PARTIAL)
- return 0;
-
- if (!skb_is_gso(skb))
-#endif /* NETIF_F_TSO */
- return 0;
-#ifdef NETIF_F_TSO
-
- if (skb_header_cloned(skb)) {
- int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
- if (err)
- return err;
- }
-
- /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
- type_tucmd = E1000_ADVTXD_TUCMD_L4T_TCP;
-
- if (first->protocol == __constant_htons(ETH_P_IP)) {
- struct iphdr *iph = ip_hdr(skb);
- iph->tot_len = 0;
- iph->check = 0;
- tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
- iph->daddr, 0,
- IPPROTO_TCP,
- 0);
- type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
- first->tx_flags |= IGB_TX_FLAGS_TSO |
- IGB_TX_FLAGS_CSUM |
- IGB_TX_FLAGS_IPV4;
-#ifdef NETIF_F_TSO6
- } else if (skb_is_gso_v6(skb)) {
- ipv6_hdr(skb)->payload_len = 0;
- tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
- &ipv6_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0);
- first->tx_flags |= IGB_TX_FLAGS_TSO |
- IGB_TX_FLAGS_CSUM;
-#endif
- }
-
- /* compute header lengths */
- l4len = tcp_hdrlen(skb);
- *hdr_len = skb_transport_offset(skb) + l4len;
-
- /* update gso size and bytecount with header size */
- first->gso_segs = skb_shinfo(skb)->gso_segs;
- first->bytecount += (first->gso_segs - 1) * *hdr_len;
-
- /* MSS L4LEN IDX */
- mss_l4len_idx = l4len << E1000_ADVTXD_L4LEN_SHIFT;
- mss_l4len_idx |= skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT;
-
- /* VLAN MACLEN IPLEN */
- vlan_macip_lens = skb_network_header_len(skb);
- vlan_macip_lens |= skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT;
- vlan_macip_lens |= first->tx_flags & IGB_TX_FLAGS_VLAN_MASK;
-
- igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx);
-
- return 1;
-#endif /* NETIF_F_TSO */
-}
-
-static void igb_tx_csum(struct igb_ring *tx_ring, struct igb_tx_buffer *first)
-{
- struct sk_buff *skb = first->skb;
- u32 vlan_macip_lens = 0;
- u32 mss_l4len_idx = 0;
- u32 type_tucmd = 0;
-
- if (skb->ip_summed != CHECKSUM_PARTIAL) {
- if (!(first->tx_flags & IGB_TX_FLAGS_VLAN))
- return;
- } else {
- u8 nexthdr = 0;
- switch (first->protocol) {
- case __constant_htons(ETH_P_IP):
- vlan_macip_lens |= skb_network_header_len(skb);
- type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
- nexthdr = ip_hdr(skb)->protocol;
- break;
-#ifdef NETIF_F_IPV6_CSUM
- case __constant_htons(ETH_P_IPV6):
- vlan_macip_lens |= skb_network_header_len(skb);
- nexthdr = ipv6_hdr(skb)->nexthdr;
- break;
-#endif
- default:
- if (unlikely(net_ratelimit())) {
- dev_warn(tx_ring->dev,
- "partial checksum but proto=%x!\n",
- first->protocol);
- }
- break;
- }
-
- switch (nexthdr) {
- case IPPROTO_TCP:
- type_tucmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
- mss_l4len_idx = tcp_hdrlen(skb) <<
- E1000_ADVTXD_L4LEN_SHIFT;
- break;
-#ifdef HAVE_SCTP
- case IPPROTO_SCTP:
- type_tucmd |= E1000_ADVTXD_TUCMD_L4T_SCTP;
- mss_l4len_idx = sizeof(struct sctphdr) <<
- E1000_ADVTXD_L4LEN_SHIFT;
- break;
-#endif
- case IPPROTO_UDP:
- mss_l4len_idx = sizeof(struct udphdr) <<
- E1000_ADVTXD_L4LEN_SHIFT;
- break;
- default:
- if (unlikely(net_ratelimit())) {
- dev_warn(tx_ring->dev,
- "partial checksum but l4 proto=%x!\n",
- nexthdr);
- }
- break;
- }
-
- /* update TX checksum flag */
- first->tx_flags |= IGB_TX_FLAGS_CSUM;
- }
-
- vlan_macip_lens |= skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT;
- vlan_macip_lens |= first->tx_flags & IGB_TX_FLAGS_VLAN_MASK;
-
- igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx);
-}
-
-#define IGB_SET_FLAG(_input, _flag, _result) \
- ((_flag <= _result) ? \
- ((u32)(_input & _flag) * (_result / _flag)) : \
- ((u32)(_input & _flag) / (_flag / _result)))
-
-static u32 igb_tx_cmd_type(struct sk_buff *skb, u32 tx_flags)
-{
- /* set type for advanced descriptor with frame checksum insertion */
- u32 cmd_type = E1000_ADVTXD_DTYP_DATA |
- E1000_ADVTXD_DCMD_DEXT |
- E1000_ADVTXD_DCMD_IFCS;
-
- /* set HW vlan bit if vlan is present */
- cmd_type |= IGB_SET_FLAG(tx_flags, IGB_TX_FLAGS_VLAN,
- (E1000_ADVTXD_DCMD_VLE));
-
- /* set segmentation bits for TSO */
- cmd_type |= IGB_SET_FLAG(tx_flags, IGB_TX_FLAGS_TSO,
- (E1000_ADVTXD_DCMD_TSE));
-
- /* set timestamp bit if present */
- cmd_type |= IGB_SET_FLAG(tx_flags, IGB_TX_FLAGS_TSTAMP,
- (E1000_ADVTXD_MAC_TSTAMP));
-
- return cmd_type;
-}
-
-static void igb_tx_olinfo_status(struct igb_ring *tx_ring,
- union e1000_adv_tx_desc *tx_desc,
- u32 tx_flags, unsigned int paylen)
-{
- u32 olinfo_status = paylen << E1000_ADVTXD_PAYLEN_SHIFT;
-
- /* 82575 requires a unique index per ring */
- if (test_bit(IGB_RING_FLAG_TX_CTX_IDX, &tx_ring->flags))
- olinfo_status |= tx_ring->reg_idx << 4;
-
- /* insert L4 checksum */
- olinfo_status |= IGB_SET_FLAG(tx_flags,
- IGB_TX_FLAGS_CSUM,
- (E1000_TXD_POPTS_TXSM << 8));
-
- /* insert IPv4 checksum */
- olinfo_status |= IGB_SET_FLAG(tx_flags,
- IGB_TX_FLAGS_IPV4,
- (E1000_TXD_POPTS_IXSM << 8));
-
- tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
-}
-
-static void igb_tx_map(struct igb_ring *tx_ring,
- struct igb_tx_buffer *first,
- const u8 hdr_len)
-{
- struct sk_buff *skb = first->skb;
- struct igb_tx_buffer *tx_buffer;
- union e1000_adv_tx_desc *tx_desc;
- struct skb_frag_struct *frag;
- dma_addr_t dma;
- unsigned int data_len, size;
- u32 tx_flags = first->tx_flags;
- u32 cmd_type = igb_tx_cmd_type(skb, tx_flags);
- u16 i = tx_ring->next_to_use;
-
- tx_desc = IGB_TX_DESC(tx_ring, i);
-
- igb_tx_olinfo_status(tx_ring, tx_desc, tx_flags, skb->len - hdr_len);
-
- size = skb_headlen(skb);
- data_len = skb->data_len;
-
- dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE);
-
- tx_buffer = first;
-
- for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
- if (dma_mapping_error(tx_ring->dev, dma))
- goto dma_error;
-
- /* record length, and DMA address */
- dma_unmap_len_set(tx_buffer, len, size);
- dma_unmap_addr_set(tx_buffer, dma, dma);
-
- tx_desc->read.buffer_addr = cpu_to_le64(dma);
-
- while (unlikely(size > IGB_MAX_DATA_PER_TXD)) {
- tx_desc->read.cmd_type_len =
- cpu_to_le32(cmd_type ^ IGB_MAX_DATA_PER_TXD);
-
- i++;
- tx_desc++;
- if (i == tx_ring->count) {
- tx_desc = IGB_TX_DESC(tx_ring, 0);
- i = 0;
- }
- tx_desc->read.olinfo_status = 0;
-
- dma += IGB_MAX_DATA_PER_TXD;
- size -= IGB_MAX_DATA_PER_TXD;
-
- tx_desc->read.buffer_addr = cpu_to_le64(dma);
- }
-
- if (likely(!data_len))
- break;
-
- tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type ^ size);
-
- i++;
- tx_desc++;
- if (i == tx_ring->count) {
- tx_desc = IGB_TX_DESC(tx_ring, 0);
- i = 0;
- }
- tx_desc->read.olinfo_status = 0;
-
- size = skb_frag_size(frag);
- data_len -= size;
-
- dma = skb_frag_dma_map(tx_ring->dev, frag, 0,
- size, DMA_TO_DEVICE);
-
- tx_buffer = &tx_ring->tx_buffer_info[i];
- }
-
- /* write last descriptor with RS and EOP bits */
- cmd_type |= size | IGB_TXD_DCMD;
- tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
-
- netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount);
- /* set the timestamp */
- first->time_stamp = jiffies;
-
- /*
- * Force memory writes to complete before letting h/w know there
- * are new descriptors to fetch. (Only applicable for weak-ordered
- * memory model archs, such as IA-64).
- *
- * We also need this memory barrier to make certain all of the
- * status bits have been updated before next_to_watch is written.
- */
- wmb();
-
- /* set next_to_watch value indicating a packet is present */
- first->next_to_watch = tx_desc;
-
- i++;
- if (i == tx_ring->count)
- i = 0;
-
- tx_ring->next_to_use = i;
-
- writel(i, tx_ring->tail);
-
- /* we need this if more than one processor can write to our tail
- * at a time, it syncronizes IO on IA64/Altix systems */
- mmiowb();
-
- return;
-
-dma_error:
- dev_err(tx_ring->dev, "TX DMA map failed\n");
-
- /* clear dma mappings for failed tx_buffer_info map */
- for (;;) {
- tx_buffer = &tx_ring->tx_buffer_info[i];
- igb_unmap_and_free_tx_resource(tx_ring, tx_buffer);
- if (tx_buffer == first)
- break;
- if (i == 0)
- i = tx_ring->count;
- i--;
- }
-
- tx_ring->next_to_use = i;
-}
-
-static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
-{
- struct net_device *netdev = netdev_ring(tx_ring);
-
- if (netif_is_multiqueue(netdev))
- netif_stop_subqueue(netdev, ring_queue_index(tx_ring));
- else
- netif_stop_queue(netdev);
-
- /* Herbert's original patch had:
- * smp_mb__after_netif_stop_queue();
- * but since that doesn't exist yet, just open code it. */
- smp_mb();
-
- /* We need to check again in a case another CPU has just
- * made room available. */
- if (igb_desc_unused(tx_ring) < size)
- return -EBUSY;
-
- /* A reprieve! */
- if (netif_is_multiqueue(netdev))
- netif_wake_subqueue(netdev, ring_queue_index(tx_ring));
- else
- netif_wake_queue(netdev);
-
- tx_ring->tx_stats.restart_queue++;
-
- return 0;
-}
-
-static inline int igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
-{
- if (igb_desc_unused(tx_ring) >= size)
- return 0;
- return __igb_maybe_stop_tx(tx_ring, size);
-}
-
-netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
- struct igb_ring *tx_ring)
-{
- struct igb_tx_buffer *first;
- int tso;
- u32 tx_flags = 0;
-#if PAGE_SIZE > IGB_MAX_DATA_PER_TXD
- unsigned short f;
-#endif
- u16 count = TXD_USE_COUNT(skb_headlen(skb));
- __be16 protocol = vlan_get_protocol(skb);
- u8 hdr_len = 0;
-
- /*
- * need: 1 descriptor per page * PAGE_SIZE/IGB_MAX_DATA_PER_TXD,
- * + 1 desc for skb_headlen/IGB_MAX_DATA_PER_TXD,
- * + 2 desc gap to keep tail from touching head,
- * + 1 desc for context descriptor,
- * otherwise try next time
- */
-#if PAGE_SIZE > IGB_MAX_DATA_PER_TXD
- for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
- count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
-#else
- count += skb_shinfo(skb)->nr_frags;
-#endif
- if (igb_maybe_stop_tx(tx_ring, count + 3)) {
- /* this is a hard error */
- return NETDEV_TX_BUSY;
- }
-
- /* record the location of the first descriptor for this packet */
- first = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
- first->skb = skb;
- first->bytecount = skb->len;
- first->gso_segs = 1;
-
- skb_tx_timestamp(skb);
-
-#ifdef HAVE_PTP_1588_CLOCK
- if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
- struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
- if (!adapter->ptp_tx_skb) {
- skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
- tx_flags |= IGB_TX_FLAGS_TSTAMP;
-
- adapter->ptp_tx_skb = skb_get(skb);
- adapter->ptp_tx_start = jiffies;
- if (adapter->hw.mac.type == e1000_82576)
- schedule_work(&adapter->ptp_tx_work);
- }
- }
-#endif /* HAVE_PTP_1588_CLOCK */
-
- if (vlan_tx_tag_present(skb)) {
- tx_flags |= IGB_TX_FLAGS_VLAN;
- tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
- }
-
- /* record initial flags and protocol */
- first->tx_flags = tx_flags;
- first->protocol = protocol;
-
- tso = igb_tso(tx_ring, first, &hdr_len);
- if (tso < 0)
- goto out_drop;
- else if (!tso)
- igb_tx_csum(tx_ring, first);
-
- igb_tx_map(tx_ring, first, hdr_len);
-
-#ifndef HAVE_TRANS_START_IN_QUEUE
- netdev_ring(tx_ring)->trans_start = jiffies;
-
-#endif
- /* Make sure there is space in the ring for the next send. */
- igb_maybe_stop_tx(tx_ring, DESC_NEEDED);
-
- return NETDEV_TX_OK;
-
-out_drop:
- igb_unmap_and_free_tx_resource(tx_ring, first);
-
- return NETDEV_TX_OK;
-}
-
-#ifdef HAVE_TX_MQ
-static inline struct igb_ring *igb_tx_queue_mapping(struct igb_adapter *adapter,
- struct sk_buff *skb)
-{
- unsigned int r_idx = skb->queue_mapping;
-
- if (r_idx >= adapter->num_tx_queues)
- r_idx = r_idx % adapter->num_tx_queues;
-
- return adapter->tx_ring[r_idx];
-}
-#else
-#define igb_tx_queue_mapping(_adapter, _skb) (_adapter)->tx_ring[0]
-#endif
-
-static netdev_tx_t igb_xmit_frame(struct sk_buff *skb,
- struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- if (test_bit(__IGB_DOWN, &adapter->state)) {
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- if (skb->len <= 0) {
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- /*
- * The minimum packet size with TCTL.PSP set is 17 so pad the skb
- * in order to meet this minimum size requirement.
- */
- if (skb->len < 17) {
- if (skb_padto(skb, 17))
- return NETDEV_TX_OK;
- skb->len = 17;
- }
-
- return igb_xmit_frame_ring(skb, igb_tx_queue_mapping(adapter, skb));
-}
-
-/**
- * igb_tx_timeout - Respond to a Tx Hang
- * @netdev: network interface device structure
- **/
-static void igb_tx_timeout(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
- /* Do the reset outside of interrupt context */
- adapter->tx_timeout_count++;
-
- if (hw->mac.type >= e1000_82580)
- hw->dev_spec._82575.global_device_reset = true;
-
- schedule_work(&adapter->reset_task);
- E1000_WRITE_REG(hw, E1000_EICS,
- (adapter->eims_enable_mask & ~adapter->eims_other));
-}
-
-static void igb_reset_task(struct work_struct *work)
-{
- struct igb_adapter *adapter;
- adapter = container_of(work, struct igb_adapter, reset_task);
-
- igb_reinit_locked(adapter);
-}
-
-/**
- * igb_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are updated here and also from the timer callback.
- **/
-static struct net_device_stats *igb_get_stats(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- if (!test_bit(__IGB_RESETTING, &adapter->state))
- igb_update_stats(adapter);
-
-#ifdef HAVE_NETDEV_STATS_IN_NETDEV
- /* only return the current stats */
- return &netdev->stats;
-#else
- /* only return the current stats */
- return &adapter->net_stats;
-#endif /* HAVE_NETDEV_STATS_IN_NETDEV */
-}
-
-/**
- * igb_change_mtu - Change the Maximum Transfer Unit
- * @netdev: network interface device structure
- * @new_mtu: new value for maximum frame size
- *
- * Returns 0 on success, negative on failure
- **/
-static int igb_change_mtu(struct net_device *netdev, int new_mtu)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- struct pci_dev *pdev = adapter->pdev;
- int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
-
- if ((new_mtu < 68) || (max_frame > MAX_JUMBO_FRAME_SIZE)) {
- dev_err(pci_dev_to_dev(pdev), "Invalid MTU setting\n");
- return -EINVAL;
- }
-
-#define MAX_STD_JUMBO_FRAME_SIZE 9238
- if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
- dev_err(pci_dev_to_dev(pdev), "MTU > 9216 not supported.\n");
- return -EINVAL;
- }
-
- /* adjust max frame to be at least the size of a standard frame */
- if (max_frame < (ETH_FRAME_LEN + ETH_FCS_LEN))
- max_frame = ETH_FRAME_LEN + ETH_FCS_LEN;
-
- while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- usleep_range(1000, 2000);
-
- /* igb_down has a dependency on max_frame_size */
- adapter->max_frame_size = max_frame;
-
- if (netif_running(netdev))
- igb_down(adapter);
-
- dev_info(pci_dev_to_dev(pdev), "changing MTU from %d to %d\n",
- netdev->mtu, new_mtu);
- netdev->mtu = new_mtu;
- hw->dev_spec._82575.mtu = new_mtu;
-
- if (netif_running(netdev))
- igb_up(adapter);
- else
- igb_reset(adapter);
-
- clear_bit(__IGB_RESETTING, &adapter->state);
-
- return 0;
-}
-
-/**
- * igb_update_stats - Update the board statistics counters
- * @adapter: board private structure
- **/
-
-void igb_update_stats(struct igb_adapter *adapter)
-{
-#ifdef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats *net_stats = &adapter->netdev->stats;
-#else
- struct net_device_stats *net_stats = &adapter->net_stats;
-#endif /* HAVE_NETDEV_STATS_IN_NETDEV */
- struct e1000_hw *hw = &adapter->hw;
-#ifdef HAVE_PCI_ERS
- struct pci_dev *pdev = adapter->pdev;
-#endif
- u32 reg, mpc;
- u16 phy_tmp;
- int i;
- u64 bytes, packets;
-#ifndef IGB_NO_LRO
- u32 flushed = 0, coal = 0;
- struct igb_q_vector *q_vector;
-#endif
-
-#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
-
- /*
- * Prevent stats update while adapter is being reset, or if the pci
- * connection is down.
- */
- if (adapter->link_speed == 0)
- return;
-#ifdef HAVE_PCI_ERS
- if (pci_channel_offline(pdev))
- return;
-
-#endif
-#ifndef IGB_NO_LRO
- for (i = 0; i < adapter->num_q_vectors; i++) {
- q_vector = adapter->q_vector[i];
- if (!q_vector)
- continue;
- flushed += q_vector->lrolist.stats.flushed;
- coal += q_vector->lrolist.stats.coal;
- }
- adapter->lro_stats.flushed = flushed;
- adapter->lro_stats.coal = coal;
-
-#endif
- bytes = 0;
- packets = 0;
- for (i = 0; i < adapter->num_rx_queues; i++) {
- u32 rqdpc_tmp = E1000_READ_REG(hw, E1000_RQDPC(i)) & 0x0FFF;
- struct igb_ring *ring = adapter->rx_ring[i];
- ring->rx_stats.drops += rqdpc_tmp;
- net_stats->rx_fifo_errors += rqdpc_tmp;
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- if (!ring->vmdq_netdev) {
- bytes += ring->rx_stats.bytes;
- packets += ring->rx_stats.packets;
- }
-#else
- bytes += ring->rx_stats.bytes;
- packets += ring->rx_stats.packets;
-#endif
- }
-
- net_stats->rx_bytes = bytes;
- net_stats->rx_packets = packets;
-
- bytes = 0;
- packets = 0;
- for (i = 0; i < adapter->num_tx_queues; i++) {
- struct igb_ring *ring = adapter->tx_ring[i];
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- if (!ring->vmdq_netdev) {
- bytes += ring->tx_stats.bytes;
- packets += ring->tx_stats.packets;
- }
-#else
- bytes += ring->tx_stats.bytes;
- packets += ring->tx_stats.packets;
-#endif
- }
- net_stats->tx_bytes = bytes;
- net_stats->tx_packets = packets;
-
- /* read stats registers */
- adapter->stats.crcerrs += E1000_READ_REG(hw, E1000_CRCERRS);
- adapter->stats.gprc += E1000_READ_REG(hw, E1000_GPRC);
- adapter->stats.gorc += E1000_READ_REG(hw, E1000_GORCL);
- E1000_READ_REG(hw, E1000_GORCH); /* clear GORCL */
- adapter->stats.bprc += E1000_READ_REG(hw, E1000_BPRC);
- adapter->stats.mprc += E1000_READ_REG(hw, E1000_MPRC);
- adapter->stats.roc += E1000_READ_REG(hw, E1000_ROC);
-
- adapter->stats.prc64 += E1000_READ_REG(hw, E1000_PRC64);
- adapter->stats.prc127 += E1000_READ_REG(hw, E1000_PRC127);
- adapter->stats.prc255 += E1000_READ_REG(hw, E1000_PRC255);
- adapter->stats.prc511 += E1000_READ_REG(hw, E1000_PRC511);
- adapter->stats.prc1023 += E1000_READ_REG(hw, E1000_PRC1023);
- adapter->stats.prc1522 += E1000_READ_REG(hw, E1000_PRC1522);
- adapter->stats.symerrs += E1000_READ_REG(hw, E1000_SYMERRS);
- adapter->stats.sec += E1000_READ_REG(hw, E1000_SEC);
-
- mpc = E1000_READ_REG(hw, E1000_MPC);
- adapter->stats.mpc += mpc;
- net_stats->rx_fifo_errors += mpc;
- adapter->stats.scc += E1000_READ_REG(hw, E1000_SCC);
- adapter->stats.ecol += E1000_READ_REG(hw, E1000_ECOL);
- adapter->stats.mcc += E1000_READ_REG(hw, E1000_MCC);
- adapter->stats.latecol += E1000_READ_REG(hw, E1000_LATECOL);
- adapter->stats.dc += E1000_READ_REG(hw, E1000_DC);
- adapter->stats.rlec += E1000_READ_REG(hw, E1000_RLEC);
- adapter->stats.xonrxc += E1000_READ_REG(hw, E1000_XONRXC);
- adapter->stats.xontxc += E1000_READ_REG(hw, E1000_XONTXC);
- adapter->stats.xoffrxc += E1000_READ_REG(hw, E1000_XOFFRXC);
- adapter->stats.xofftxc += E1000_READ_REG(hw, E1000_XOFFTXC);
- adapter->stats.fcruc += E1000_READ_REG(hw, E1000_FCRUC);
- adapter->stats.gptc += E1000_READ_REG(hw, E1000_GPTC);
- adapter->stats.gotc += E1000_READ_REG(hw, E1000_GOTCL);
- E1000_READ_REG(hw, E1000_GOTCH); /* clear GOTCL */
- adapter->stats.rnbc += E1000_READ_REG(hw, E1000_RNBC);
- adapter->stats.ruc += E1000_READ_REG(hw, E1000_RUC);
- adapter->stats.rfc += E1000_READ_REG(hw, E1000_RFC);
- adapter->stats.rjc += E1000_READ_REG(hw, E1000_RJC);
- adapter->stats.tor += E1000_READ_REG(hw, E1000_TORH);
- adapter->stats.tot += E1000_READ_REG(hw, E1000_TOTH);
- adapter->stats.tpr += E1000_READ_REG(hw, E1000_TPR);
-
- adapter->stats.ptc64 += E1000_READ_REG(hw, E1000_PTC64);
- adapter->stats.ptc127 += E1000_READ_REG(hw, E1000_PTC127);
- adapter->stats.ptc255 += E1000_READ_REG(hw, E1000_PTC255);
- adapter->stats.ptc511 += E1000_READ_REG(hw, E1000_PTC511);
- adapter->stats.ptc1023 += E1000_READ_REG(hw, E1000_PTC1023);
- adapter->stats.ptc1522 += E1000_READ_REG(hw, E1000_PTC1522);
-
- adapter->stats.mptc += E1000_READ_REG(hw, E1000_MPTC);
- adapter->stats.bptc += E1000_READ_REG(hw, E1000_BPTC);
-
- adapter->stats.tpt += E1000_READ_REG(hw, E1000_TPT);
- adapter->stats.colc += E1000_READ_REG(hw, E1000_COLC);
-
- adapter->stats.algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC);
- /* read internal phy sepecific stats */
- reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
- if (!(reg & E1000_CTRL_EXT_LINK_MODE_MASK)) {
- adapter->stats.rxerrc += E1000_READ_REG(hw, E1000_RXERRC);
-
- /* this stat has invalid values on i210/i211 */
- if ((hw->mac.type != e1000_i210) &&
- (hw->mac.type != e1000_i211))
- adapter->stats.tncrs += E1000_READ_REG(hw, E1000_TNCRS);
- }
- adapter->stats.tsctc += E1000_READ_REG(hw, E1000_TSCTC);
- adapter->stats.tsctfc += E1000_READ_REG(hw, E1000_TSCTFC);
-
- adapter->stats.iac += E1000_READ_REG(hw, E1000_IAC);
- adapter->stats.icrxoc += E1000_READ_REG(hw, E1000_ICRXOC);
- adapter->stats.icrxptc += E1000_READ_REG(hw, E1000_ICRXPTC);
- adapter->stats.icrxatc += E1000_READ_REG(hw, E1000_ICRXATC);
- adapter->stats.ictxptc += E1000_READ_REG(hw, E1000_ICTXPTC);
- adapter->stats.ictxatc += E1000_READ_REG(hw, E1000_ICTXATC);
- adapter->stats.ictxqec += E1000_READ_REG(hw, E1000_ICTXQEC);
- adapter->stats.ictxqmtc += E1000_READ_REG(hw, E1000_ICTXQMTC);
- adapter->stats.icrxdmtc += E1000_READ_REG(hw, E1000_ICRXDMTC);
-
- /* Fill out the OS statistics structure */
- net_stats->multicast = adapter->stats.mprc;
- net_stats->collisions = adapter->stats.colc;
-
- /* Rx Errors */
-
- /* RLEC on some newer hardware can be incorrect so build
- * our own version based on RUC and ROC */
- net_stats->rx_errors = adapter->stats.rxerrc +
- adapter->stats.crcerrs + adapter->stats.algnerrc +
- adapter->stats.ruc + adapter->stats.roc +
- adapter->stats.cexterr;
- net_stats->rx_length_errors = adapter->stats.ruc +
- adapter->stats.roc;
- net_stats->rx_crc_errors = adapter->stats.crcerrs;
- net_stats->rx_frame_errors = adapter->stats.algnerrc;
- net_stats->rx_missed_errors = adapter->stats.mpc;
-
- /* Tx Errors */
- net_stats->tx_errors = adapter->stats.ecol +
- adapter->stats.latecol;
- net_stats->tx_aborted_errors = adapter->stats.ecol;
- net_stats->tx_window_errors = adapter->stats.latecol;
- net_stats->tx_carrier_errors = adapter->stats.tncrs;
-
- /* Tx Dropped needs to be maintained elsewhere */
-
- /* Phy Stats */
- if (hw->phy.media_type == e1000_media_type_copper) {
- if ((adapter->link_speed == SPEED_1000) &&
- (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
- phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
- adapter->phy_stats.idle_errors += phy_tmp;
- }
- }
-
- /* Management Stats */
- adapter->stats.mgptc += E1000_READ_REG(hw, E1000_MGTPTC);
- adapter->stats.mgprc += E1000_READ_REG(hw, E1000_MGTPRC);
- if (hw->mac.type > e1000_82580) {
- adapter->stats.o2bgptc += E1000_READ_REG(hw, E1000_O2BGPTC);
- adapter->stats.o2bspc += E1000_READ_REG(hw, E1000_O2BSPC);
- adapter->stats.b2ospc += E1000_READ_REG(hw, E1000_B2OSPC);
- adapter->stats.b2ogprc += E1000_READ_REG(hw, E1000_B2OGPRC);
- }
-}
-
-static irqreturn_t igb_msix_other(int irq, void *data)
-{
- struct igb_adapter *adapter = data;
- struct e1000_hw *hw = &adapter->hw;
- u32 icr = E1000_READ_REG(hw, E1000_ICR);
- /* reading ICR causes bit 31 of EICR to be cleared */
-
- if (icr & E1000_ICR_DRSTA)
- schedule_work(&adapter->reset_task);
-
- if (icr & E1000_ICR_DOUTSYNC) {
- /* HW is reporting DMA is out of sync */
- adapter->stats.doosync++;
- /* The DMA Out of Sync is also indication of a spoof event
- * in IOV mode. Check the Wrong VM Behavior register to
- * see if it is really a spoof event. */
- igb_check_wvbr(adapter);
- }
-
- /* Check for a mailbox event */
- if (icr & E1000_ICR_VMMB)
- igb_msg_task(adapter);
-
- if (icr & E1000_ICR_LSC) {
- hw->mac.get_link_status = 1;
- /* guard against interrupt when we're going down */
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
- }
-
-#ifdef HAVE_PTP_1588_CLOCK
- if (icr & E1000_ICR_TS) {
- u32 tsicr = E1000_READ_REG(hw, E1000_TSICR);
-
- if (tsicr & E1000_TSICR_TXTS) {
- /* acknowledge the interrupt */
- E1000_WRITE_REG(hw, E1000_TSICR, E1000_TSICR_TXTS);
- /* retrieve hardware timestamp */
- schedule_work(&adapter->ptp_tx_work);
- }
- }
-#endif /* HAVE_PTP_1588_CLOCK */
-
- /* Check for MDD event */
- if (icr & E1000_ICR_MDDET)
- igb_process_mdd_event(adapter);
-
- E1000_WRITE_REG(hw, E1000_EIMS, adapter->eims_other);
-
- return IRQ_HANDLED;
-}
-
-static void igb_write_itr(struct igb_q_vector *q_vector)
-{
- struct igb_adapter *adapter = q_vector->adapter;
- u32 itr_val = q_vector->itr_val & 0x7FFC;
-
- if (!q_vector->set_itr)
- return;
-
- if (!itr_val)
- itr_val = 0x4;
-
- if (adapter->hw.mac.type == e1000_82575)
- itr_val |= itr_val << 16;
- else
- itr_val |= E1000_EITR_CNT_IGNR;
-
- writel(itr_val, q_vector->itr_register);
- q_vector->set_itr = 0;
-}
-
-static irqreturn_t igb_msix_ring(int irq, void *data)
-{
- struct igb_q_vector *q_vector = data;
-
- /* Write the ITR value calculated from the previous interrupt. */
- igb_write_itr(q_vector);
-
- napi_schedule(&q_vector->napi);
-
- return IRQ_HANDLED;
-}
-
-#ifdef IGB_DCA
-static void igb_update_tx_dca(struct igb_adapter *adapter,
- struct igb_ring *tx_ring,
- int cpu)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 txctrl = dca3_get_tag(tx_ring->dev, cpu);
-
- if (hw->mac.type != e1000_82575)
- txctrl <<= E1000_DCA_TXCTRL_CPUID_SHIFT_82576;
-
- /*
- * We can enable relaxed ordering for reads, but not writes when
- * DCA is enabled. This is due to a known issue in some chipsets
- * which will cause the DCA tag to be cleared.
- */
- txctrl |= E1000_DCA_TXCTRL_DESC_RRO_EN |
- E1000_DCA_TXCTRL_DATA_RRO_EN |
- E1000_DCA_TXCTRL_DESC_DCA_EN;
-
- E1000_WRITE_REG(hw, E1000_DCA_TXCTRL(tx_ring->reg_idx), txctrl);
-}
-
-static void igb_update_rx_dca(struct igb_adapter *adapter,
- struct igb_ring *rx_ring,
- int cpu)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 rxctrl = dca3_get_tag(&adapter->pdev->dev, cpu);
-
- if (hw->mac.type != e1000_82575)
- rxctrl <<= E1000_DCA_RXCTRL_CPUID_SHIFT_82576;
-
- /*
- * We can enable relaxed ordering for reads, but not writes when
- * DCA is enabled. This is due to a known issue in some chipsets
- * which will cause the DCA tag to be cleared.
- */
- rxctrl |= E1000_DCA_RXCTRL_DESC_RRO_EN |
- E1000_DCA_RXCTRL_DESC_DCA_EN;
-
- E1000_WRITE_REG(hw, E1000_DCA_RXCTRL(rx_ring->reg_idx), rxctrl);
-}
-
-static void igb_update_dca(struct igb_q_vector *q_vector)
-{
- struct igb_adapter *adapter = q_vector->adapter;
- int cpu = get_cpu();
-
- if (q_vector->cpu == cpu)
- goto out_no_update;
-
- if (q_vector->tx.ring)
- igb_update_tx_dca(adapter, q_vector->tx.ring, cpu);
-
- if (q_vector->rx.ring)
- igb_update_rx_dca(adapter, q_vector->rx.ring, cpu);
-
- q_vector->cpu = cpu;
-out_no_update:
- put_cpu();
-}
-
-static void igb_setup_dca(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- int i;
-
- if (!(adapter->flags & IGB_FLAG_DCA_ENABLED))
- return;
-
- /* Always use CB2 mode, difference is masked in the CB driver. */
- E1000_WRITE_REG(hw, E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
-
- for (i = 0; i < adapter->num_q_vectors; i++) {
- adapter->q_vector[i]->cpu = -1;
- igb_update_dca(adapter->q_vector[i]);
- }
-}
-
-static int __igb_notify_dca(struct device *dev, void *data)
-{
- struct net_device *netdev = dev_get_drvdata(dev);
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_hw *hw = &adapter->hw;
- unsigned long event = *(unsigned long *)data;
-
- switch (event) {
- case DCA_PROVIDER_ADD:
- /* if already enabled, don't do it again */
- if (adapter->flags & IGB_FLAG_DCA_ENABLED)
- break;
- if (dca_add_requester(dev) == E1000_SUCCESS) {
- adapter->flags |= IGB_FLAG_DCA_ENABLED;
- dev_info(pci_dev_to_dev(pdev), "DCA enabled\n");
- igb_setup_dca(adapter);
- break;
- }
- /* Fall Through since DCA is disabled. */
- case DCA_PROVIDER_REMOVE:
- if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
- /* without this a class_device is left
- * hanging around in the sysfs model */
- dca_remove_requester(dev);
- dev_info(pci_dev_to_dev(pdev), "DCA disabled\n");
- adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
- E1000_WRITE_REG(hw, E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_DISABLE);
- }
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-static int igb_notify_dca(struct notifier_block *nb, unsigned long event,
- void *p)
-{
- int ret_val;
-
- ret_val = driver_for_each_device(&igb_driver.driver, NULL, &event,
- __igb_notify_dca);
-
- return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
-}
-#endif /* IGB_DCA */
-
-static int igb_vf_configure(struct igb_adapter *adapter, int vf)
-{
- unsigned char mac_addr[ETH_ALEN];
-
- random_ether_addr(mac_addr);
- igb_set_vf_mac(adapter, vf, mac_addr);
-
-#ifdef IFLA_VF_MAX
-#ifdef HAVE_VF_SPOOFCHK_CONFIGURE
- /* By default spoof check is enabled for all VFs */
- adapter->vf_data[vf].spoofchk_enabled = true;
-#endif
-#endif
-
- return true;
-}
-
-static void igb_ping_all_vfs(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 ping;
- int i;
-
- for (i = 0 ; i < adapter->vfs_allocated_count; i++) {
- ping = E1000_PF_CONTROL_MSG;
- if (adapter->vf_data[i].flags & IGB_VF_FLAG_CTS)
- ping |= E1000_VT_MSGTYPE_CTS;
- e1000_write_mbx(hw, &ping, 1, i);
- }
-}
-
-/**
- * igb_mta_set_ - Set multicast filter table address
- * @adapter: pointer to the adapter structure
- * @hash_value: determines the MTA register and bit to set
- *
- * The multicast table address is a register array of 32-bit registers.
- * The hash_value is used to determine what register the bit is in, the
- * current value is read, the new bit is OR'd in and the new value is
- * written back into the register.
- **/
-void igb_mta_set(struct igb_adapter *adapter, u32 hash_value)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 hash_bit, hash_reg, mta;
-
- /*
- * The MTA is a register array of 32-bit registers. It is
- * treated like an array of (32*mta_reg_count) bits. We want to
- * set bit BitArray[hash_value]. So we figure out what register
- * the bit is in, read it, OR in the new bit, then write
- * back the new value. The (hw->mac.mta_reg_count - 1) serves as a
- * mask to bits 31:5 of the hash value which gives us the
- * register we're modifying. The hash bit within that register
- * is determined by the lower 5 bits of the hash value.
- */
- hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
- hash_bit = hash_value & 0x1F;
-
- mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg);
-
- mta |= (1 << hash_bit);
-
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta);
- E1000_WRITE_FLUSH(hw);
-}
-
-static int igb_set_vf_promisc(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
-{
-
- struct e1000_hw *hw = &adapter->hw;
- u32 vmolr = E1000_READ_REG(hw, E1000_VMOLR(vf));
- struct vf_data_storage *vf_data = &adapter->vf_data[vf];
-
- vf_data->flags &= ~(IGB_VF_FLAG_UNI_PROMISC |
- IGB_VF_FLAG_MULTI_PROMISC);
- vmolr &= ~(E1000_VMOLR_ROPE | E1000_VMOLR_ROMPE | E1000_VMOLR_MPME);
-
-#ifdef IGB_ENABLE_VF_PROMISC
- if (*msgbuf & E1000_VF_SET_PROMISC_UNICAST) {
- vmolr |= E1000_VMOLR_ROPE;
- vf_data->flags |= IGB_VF_FLAG_UNI_PROMISC;
- *msgbuf &= ~E1000_VF_SET_PROMISC_UNICAST;
- }
-#endif
- if (*msgbuf & E1000_VF_SET_PROMISC_MULTICAST) {
- vmolr |= E1000_VMOLR_MPME;
- vf_data->flags |= IGB_VF_FLAG_MULTI_PROMISC;
- *msgbuf &= ~E1000_VF_SET_PROMISC_MULTICAST;
- } else {
- /*
- * if we have hashes and we are clearing a multicast promisc
- * flag we need to write the hashes to the MTA as this step
- * was previously skipped
- */
- if (vf_data->num_vf_mc_hashes > 30) {
- vmolr |= E1000_VMOLR_MPME;
- } else if (vf_data->num_vf_mc_hashes) {
- int j;
- vmolr |= E1000_VMOLR_ROMPE;
- for (j = 0; j < vf_data->num_vf_mc_hashes; j++)
- igb_mta_set(adapter, vf_data->vf_mc_hashes[j]);
- }
- }
-
- E1000_WRITE_REG(hw, E1000_VMOLR(vf), vmolr);
-
- /* there are flags left unprocessed, likely not supported */
- if (*msgbuf & E1000_VT_MSGINFO_MASK)
- return -EINVAL;
-
- return 0;
-
-}
-
-static int igb_set_vf_multicasts(struct igb_adapter *adapter,
- u32 *msgbuf, u32 vf)
-{
- int n = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
- u16 *hash_list = (u16 *)&msgbuf[1];
- struct vf_data_storage *vf_data = &adapter->vf_data[vf];
- int i;
-
- /* salt away the number of multicast addresses assigned
- * to this VF for later use to restore when the PF multi cast
- * list changes
- */
- vf_data->num_vf_mc_hashes = n;
-
- /* only up to 30 hash values supported */
- if (n > 30)
- n = 30;
-
- /* store the hashes for later use */
- for (i = 0; i < n; i++)
- vf_data->vf_mc_hashes[i] = hash_list[i];
-
- /* Flush and reset the mta with the new values */
- igb_set_rx_mode(adapter->netdev);
-
- return 0;
-}
-
-static void igb_restore_vf_multicasts(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct vf_data_storage *vf_data;
- int i, j;
-
- for (i = 0; i < adapter->vfs_allocated_count; i++) {
- u32 vmolr = E1000_READ_REG(hw, E1000_VMOLR(i));
- vmolr &= ~(E1000_VMOLR_ROMPE | E1000_VMOLR_MPME);
-
- vf_data = &adapter->vf_data[i];
-
- if ((vf_data->num_vf_mc_hashes > 30) ||
- (vf_data->flags & IGB_VF_FLAG_MULTI_PROMISC)) {
- vmolr |= E1000_VMOLR_MPME;
- } else if (vf_data->num_vf_mc_hashes) {
- vmolr |= E1000_VMOLR_ROMPE;
- for (j = 0; j < vf_data->num_vf_mc_hashes; j++)
- igb_mta_set(adapter, vf_data->vf_mc_hashes[j]);
- }
- E1000_WRITE_REG(hw, E1000_VMOLR(i), vmolr);
- }
-}
-
-static void igb_clear_vf_vfta(struct igb_adapter *adapter, u32 vf)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 pool_mask, reg, vid;
- u16 vlan_default;
- int i;
-
- pool_mask = 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
-
- /* Find the vlan filter for this id */
- for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
- reg = E1000_READ_REG(hw, E1000_VLVF(i));
-
- /* remove the vf from the pool */
- reg &= ~pool_mask;
-
- /* if pool is empty then remove entry from vfta */
- if (!(reg & E1000_VLVF_POOLSEL_MASK) &&
- (reg & E1000_VLVF_VLANID_ENABLE)) {
- reg = 0;
- vid = reg & E1000_VLVF_VLANID_MASK;
- igb_vfta_set(adapter, vid, FALSE);
- }
-
- E1000_WRITE_REG(hw, E1000_VLVF(i), reg);
- }
-
- adapter->vf_data[vf].vlans_enabled = 0;
-
- vlan_default = adapter->vf_data[vf].default_vf_vlan_id;
- if (vlan_default)
- igb_vlvf_set(adapter, vlan_default, true, vf);
-}
-
-s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 reg, i;
-
- /* The vlvf table only exists on 82576 hardware and newer */
- if (hw->mac.type < e1000_82576)
- return -1;
-
- /* we only need to do this if VMDq is enabled */
- if (!adapter->vmdq_pools)
- return -1;
-
- /* Find the vlan filter for this id */
- for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
- reg = E1000_READ_REG(hw, E1000_VLVF(i));
- if ((reg & E1000_VLVF_VLANID_ENABLE) &&
- vid == (reg & E1000_VLVF_VLANID_MASK))
- break;
- }
-
- if (add) {
- if (i == E1000_VLVF_ARRAY_SIZE) {
- /* Did not find a matching VLAN ID entry that was
- * enabled. Search for a free filter entry, i.e.
- * one without the enable bit set
- */
- for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
- reg = E1000_READ_REG(hw, E1000_VLVF(i));
- if (!(reg & E1000_VLVF_VLANID_ENABLE))
- break;
- }
- }
- if (i < E1000_VLVF_ARRAY_SIZE) {
- /* Found an enabled/available entry */
- reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
-
- /* if !enabled we need to set this up in vfta */
- if (!(reg & E1000_VLVF_VLANID_ENABLE)) {
- /* add VID to filter table */
- igb_vfta_set(adapter, vid, TRUE);
- reg |= E1000_VLVF_VLANID_ENABLE;
- }
- reg &= ~E1000_VLVF_VLANID_MASK;
- reg |= vid;
- E1000_WRITE_REG(hw, E1000_VLVF(i), reg);
-
- /* do not modify RLPML for PF devices */
- if (vf >= adapter->vfs_allocated_count)
- return E1000_SUCCESS;
-
- if (!adapter->vf_data[vf].vlans_enabled) {
- u32 size;
- reg = E1000_READ_REG(hw, E1000_VMOLR(vf));
- size = reg & E1000_VMOLR_RLPML_MASK;
- size += 4;
- reg &= ~E1000_VMOLR_RLPML_MASK;
- reg |= size;
- E1000_WRITE_REG(hw, E1000_VMOLR(vf), reg);
- }
-
- adapter->vf_data[vf].vlans_enabled++;
- }
- } else {
- if (i < E1000_VLVF_ARRAY_SIZE) {
- /* remove vf from the pool */
- reg &= ~(1 << (E1000_VLVF_POOLSEL_SHIFT + vf));
- /* if pool is empty then remove entry from vfta */
- if (!(reg & E1000_VLVF_POOLSEL_MASK)) {
- reg = 0;
- igb_vfta_set(adapter, vid, FALSE);
- }
- E1000_WRITE_REG(hw, E1000_VLVF(i), reg);
-
- /* do not modify RLPML for PF devices */
- if (vf >= adapter->vfs_allocated_count)
- return E1000_SUCCESS;
-
- adapter->vf_data[vf].vlans_enabled--;
- if (!adapter->vf_data[vf].vlans_enabled) {
- u32 size;
- reg = E1000_READ_REG(hw, E1000_VMOLR(vf));
- size = reg & E1000_VMOLR_RLPML_MASK;
- size -= 4;
- reg &= ~E1000_VMOLR_RLPML_MASK;
- reg |= size;
- E1000_WRITE_REG(hw, E1000_VMOLR(vf), reg);
- }
- }
- }
- return E1000_SUCCESS;
-}
-
-#ifdef IFLA_VF_MAX
-static void igb_set_vmvir(struct igb_adapter *adapter, u32 vid, u32 vf)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- if (vid)
- E1000_WRITE_REG(hw, E1000_VMVIR(vf), (vid | E1000_VMVIR_VLANA_DEFAULT));
- else
- E1000_WRITE_REG(hw, E1000_VMVIR(vf), 0);
-}
-
-static int igb_ndo_set_vf_vlan(struct net_device *netdev,
-#ifdef HAVE_VF_VLAN_PROTO
- int vf, u16 vlan, u8 qos, __be16 vlan_proto)
-#else
- int vf, u16 vlan, u8 qos)
-#endif
-{
- int err = 0;
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- /* VLAN IDs accepted range 0-4094 */
- if ((vf >= adapter->vfs_allocated_count) || (vlan > VLAN_VID_MASK-1) || (qos > 7))
- return -EINVAL;
-
-#ifdef HAVE_VF_VLAN_PROTO
- if (vlan_proto != htons(ETH_P_8021Q))
- return -EPROTONOSUPPORT;
-#endif
-
- if (vlan || qos) {
- err = igb_vlvf_set(adapter, vlan, !!vlan, vf);
- if (err)
- goto out;
- igb_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
- igb_set_vmolr(adapter, vf, !vlan);
- adapter->vf_data[vf].pf_vlan = vlan;
- adapter->vf_data[vf].pf_qos = qos;
- igb_set_vf_vlan_strip(adapter, vf, true);
- dev_info(&adapter->pdev->dev,
- "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf);
- if (test_bit(__IGB_DOWN, &adapter->state)) {
- dev_warn(&adapter->pdev->dev,
- "The VF VLAN has been set,"
- " but the PF device is not up.\n");
- dev_warn(&adapter->pdev->dev,
- "Bring the PF device up before"
- " attempting to use the VF device.\n");
- }
- } else {
- if (adapter->vf_data[vf].pf_vlan)
- dev_info(&adapter->pdev->dev,
- "Clearing VLAN on VF %d\n", vf);
- igb_vlvf_set(adapter, adapter->vf_data[vf].pf_vlan,
- false, vf);
- igb_set_vmvir(adapter, vlan, vf);
- igb_set_vmolr(adapter, vf, true);
- igb_set_vf_vlan_strip(adapter, vf, false);
- adapter->vf_data[vf].pf_vlan = 0;
- adapter->vf_data[vf].pf_qos = 0;
- }
-out:
- return err;
-}
-
-#ifdef HAVE_VF_SPOOFCHK_CONFIGURE
-static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
- bool setting)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 dtxswc, reg_offset;
-
- if (!adapter->vfs_allocated_count)
- return -EOPNOTSUPP;
-
- if (vf >= adapter->vfs_allocated_count)
- return -EINVAL;
-
- reg_offset = (hw->mac.type == e1000_82576) ? E1000_DTXSWC : E1000_TXSWC;
- dtxswc = E1000_READ_REG(hw, reg_offset);
- if (setting)
- dtxswc |= ((1 << vf) |
- (1 << (vf + E1000_DTXSWC_VLAN_SPOOF_SHIFT)));
- else
- dtxswc &= ~((1 << vf) |
- (1 << (vf + E1000_DTXSWC_VLAN_SPOOF_SHIFT)));
- E1000_WRITE_REG(hw, reg_offset, dtxswc);
-
- adapter->vf_data[vf].spoofchk_enabled = setting;
- return E1000_SUCCESS;
-}
-#endif /* HAVE_VF_SPOOFCHK_CONFIGURE */
-#endif /* IFLA_VF_MAX */
-
-static int igb_find_vlvf_entry(struct igb_adapter *adapter, int vid)
-{
- struct e1000_hw *hw = &adapter->hw;
- int i;
- u32 reg;
-
- /* Find the vlan filter for this id */
- for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
- reg = E1000_READ_REG(hw, E1000_VLVF(i));
- if ((reg & E1000_VLVF_VLANID_ENABLE) &&
- vid == (reg & E1000_VLVF_VLANID_MASK))
- break;
- }
-
- if (i >= E1000_VLVF_ARRAY_SIZE)
- i = -1;
-
- return i;
-}
-
-static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
-{
- struct e1000_hw *hw = &adapter->hw;
- int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
- int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK);
- int err = 0;
-
- if (vid)
- igb_set_vf_vlan_strip(adapter, vf, true);
- else
- igb_set_vf_vlan_strip(adapter, vf, false);
-
- /* If in promiscuous mode we need to make sure the PF also has
- * the VLAN filter set.
- */
- if (add && (adapter->netdev->flags & IFF_PROMISC))
- err = igb_vlvf_set(adapter, vid, add,
- adapter->vfs_allocated_count);
- if (err)
- goto out;
-
- err = igb_vlvf_set(adapter, vid, add, vf);
-
- if (err)
- goto out;
-
- /* Go through all the checks to see if the VLAN filter should
- * be wiped completely.
- */
- if (!add && (adapter->netdev->flags & IFF_PROMISC)) {
- u32 vlvf, bits;
-
- int regndx = igb_find_vlvf_entry(adapter, vid);
- if (regndx < 0)
- goto out;
- /* See if any other pools are set for this VLAN filter
- * entry other than the PF.
- */
- vlvf = bits = E1000_READ_REG(hw, E1000_VLVF(regndx));
- bits &= 1 << (E1000_VLVF_POOLSEL_SHIFT +
- adapter->vfs_allocated_count);
- /* If the filter was removed then ensure PF pool bit
- * is cleared if the PF only added itself to the pool
- * because the PF is in promiscuous mode.
- */
- if ((vlvf & VLAN_VID_MASK) == vid &&
-#ifndef HAVE_VLAN_RX_REGISTER
- !test_bit(vid, adapter->active_vlans) &&
-#endif
- !bits)
- igb_vlvf_set(adapter, vid, add,
- adapter->vfs_allocated_count);
- }
-
-out:
- return err;
-}
-
-static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- /* clear flags except flag that the PF has set the MAC */
- adapter->vf_data[vf].flags &= IGB_VF_FLAG_PF_SET_MAC;
- adapter->vf_data[vf].last_nack = jiffies;
-
- /* reset offloads to defaults */
- igb_set_vmolr(adapter, vf, true);
-
- /* reset vlans for device */
- igb_clear_vf_vfta(adapter, vf);
-#ifdef IFLA_VF_MAX
- if (adapter->vf_data[vf].pf_vlan)
- igb_ndo_set_vf_vlan(adapter->netdev, vf,
- adapter->vf_data[vf].pf_vlan,
-#ifdef HAVE_VF_VLAN_PROTO
- adapter->vf_data[vf].pf_qos,
- htons(ETH_P_8021Q));
-#else
- adapter->vf_data[vf].pf_qos);
-#endif
- else
- igb_clear_vf_vfta(adapter, vf);
-#endif
-
- /* reset multicast table array for vf */
- adapter->vf_data[vf].num_vf_mc_hashes = 0;
-
- /* Flush and reset the mta with the new values */
- igb_set_rx_mode(adapter->netdev);
-
- /*
- * Reset the VFs TDWBAL and TDWBAH registers which are not
- * cleared by a VFLR
- */
- E1000_WRITE_REG(hw, E1000_TDWBAH(vf), 0);
- E1000_WRITE_REG(hw, E1000_TDWBAL(vf), 0);
- if (hw->mac.type == e1000_82576) {
- E1000_WRITE_REG(hw, E1000_TDWBAH(IGB_MAX_VF_FUNCTIONS + vf), 0);
- E1000_WRITE_REG(hw, E1000_TDWBAL(IGB_MAX_VF_FUNCTIONS + vf), 0);
- }
-}
-
-static void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
-{
- unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
-
- /* generate a new mac address as we were hotplug removed/added */
- if (!(adapter->vf_data[vf].flags & IGB_VF_FLAG_PF_SET_MAC))
- random_ether_addr(vf_mac);
-
- /* process remaining reset events */
- igb_vf_reset(adapter, vf);
-}
-
-static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
-{
- struct e1000_hw *hw = &adapter->hw;
- unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
- u32 reg, msgbuf[3];
- u8 *addr = (u8 *)(&msgbuf[1]);
-
- /* process all the same items cleared in a function level reset */
- igb_vf_reset(adapter, vf);
-
- /* set vf mac address */
- igb_del_mac_filter(adapter, vf_mac, vf);
- igb_add_mac_filter(adapter, vf_mac, vf);
-
- /* enable transmit and receive for vf */
- reg = E1000_READ_REG(hw, E1000_VFTE);
- E1000_WRITE_REG(hw, E1000_VFTE, reg | (1 << vf));
- reg = E1000_READ_REG(hw, E1000_VFRE);
- E1000_WRITE_REG(hw, E1000_VFRE, reg | (1 << vf));
-
- adapter->vf_data[vf].flags |= IGB_VF_FLAG_CTS;
-
- /* reply to reset with ack and vf mac address */
- msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK;
- memcpy(addr, vf_mac, 6);
- e1000_write_mbx(hw, msgbuf, 3, vf);
-}
-
-static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf)
-{
- /*
- * The VF MAC Address is stored in a packed array of bytes
- * starting at the second 32 bit word of the msg array
- */
- unsigned char *addr = (unsigned char *)&msg[1];
- int err = -1;
-
- if (is_valid_ether_addr(addr))
- err = igb_set_vf_mac(adapter, vf, addr);
-
- return err;
-}
-
-static void igb_rcv_ack_from_vf(struct igb_adapter *adapter, u32 vf)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct vf_data_storage *vf_data = &adapter->vf_data[vf];
- u32 msg = E1000_VT_MSGTYPE_NACK;
-
- /* if device isn't clear to send it shouldn't be reading either */
- if (!(vf_data->flags & IGB_VF_FLAG_CTS) &&
- time_after(jiffies, vf_data->last_nack + (2 * HZ))) {
- e1000_write_mbx(hw, &msg, 1, vf);
- vf_data->last_nack = jiffies;
- }
-}
-
-static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
-{
- struct pci_dev *pdev = adapter->pdev;
- u32 msgbuf[E1000_VFMAILBOX_SIZE];
- struct e1000_hw *hw = &adapter->hw;
- struct vf_data_storage *vf_data = &adapter->vf_data[vf];
- s32 retval;
-
- retval = e1000_read_mbx(hw, msgbuf, E1000_VFMAILBOX_SIZE, vf);
-
- if (retval) {
- dev_err(pci_dev_to_dev(pdev), "Error receiving message from VF\n");
- return;
- }
-
- /* this is a message we already processed, do nothing */
- if (msgbuf[0] & (E1000_VT_MSGTYPE_ACK | E1000_VT_MSGTYPE_NACK))
- return;
-
- /*
- * until the vf completes a reset it should not be
- * allowed to start any configuration.
- */
-
- if (msgbuf[0] == E1000_VF_RESET) {
- igb_vf_reset_msg(adapter, vf);
- return;
- }
-
- if (!(vf_data->flags & IGB_VF_FLAG_CTS)) {
- msgbuf[0] = E1000_VT_MSGTYPE_NACK;
- if (time_after(jiffies, vf_data->last_nack + (2 * HZ))) {
- e1000_write_mbx(hw, msgbuf, 1, vf);
- vf_data->last_nack = jiffies;
- }
- return;
- }
-
- switch ((msgbuf[0] & 0xFFFF)) {
- case E1000_VF_SET_MAC_ADDR:
- retval = -EINVAL;
-#ifndef IGB_DISABLE_VF_MAC_SET
- if (!(vf_data->flags & IGB_VF_FLAG_PF_SET_MAC))
- retval = igb_set_vf_mac_addr(adapter, msgbuf, vf);
- else
- DPRINTK(DRV, INFO,
- "VF %d attempted to override administratively "
- "set MAC address\nReload the VF driver to "
- "resume operations\n", vf);
-#endif
- break;
- case E1000_VF_SET_PROMISC:
- retval = igb_set_vf_promisc(adapter, msgbuf, vf);
- break;
- case E1000_VF_SET_MULTICAST:
- retval = igb_set_vf_multicasts(adapter, msgbuf, vf);
- break;
- case E1000_VF_SET_LPE:
- retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf);
- break;
- case E1000_VF_SET_VLAN:
- retval = -1;
-#ifdef IFLA_VF_MAX
- if (vf_data->pf_vlan)
- DPRINTK(DRV, INFO,
- "VF %d attempted to override administratively "
- "set VLAN tag\nReload the VF driver to "
- "resume operations\n", vf);
- else
-#endif
- retval = igb_set_vf_vlan(adapter, msgbuf, vf);
- break;
- default:
- dev_err(pci_dev_to_dev(pdev), "Unhandled Msg %08x\n", msgbuf[0]);
- retval = -E1000_ERR_MBX;
- break;
- }
-
- /* notify the VF of the results of what it sent us */
- if (retval)
- msgbuf[0] |= E1000_VT_MSGTYPE_NACK;
- else
- msgbuf[0] |= E1000_VT_MSGTYPE_ACK;
-
- msgbuf[0] |= E1000_VT_MSGTYPE_CTS;
-
- e1000_write_mbx(hw, msgbuf, 1, vf);
-}
-
-static void igb_msg_task(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 vf;
-
- for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
- /* process any reset requests */
- if (!e1000_check_for_rst(hw, vf))
- igb_vf_reset_event(adapter, vf);
-
- /* process any messages pending */
- if (!e1000_check_for_msg(hw, vf))
- igb_rcv_msg_from_vf(adapter, vf);
-
- /* process any acks */
- if (!e1000_check_for_ack(hw, vf))
- igb_rcv_ack_from_vf(adapter, vf);
- }
-}
-
-/**
- * igb_set_uta - Set unicast filter table address
- * @adapter: board private structure
- *
- * The unicast table address is a register array of 32-bit registers.
- * The table is meant to be used in a way similar to how the MTA is used
- * however due to certain limitations in the hardware it is necessary to
- * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscuous
- * enable bit to allow vlan tag stripping when promiscuous mode is enabled
- **/
-static void igb_set_uta(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- int i;
-
- /* The UTA table only exists on 82576 hardware and newer */
- if (hw->mac.type < e1000_82576)
- return;
-
- /* we only need to do this if VMDq is enabled */
- if (!adapter->vmdq_pools)
- return;
-
- for (i = 0; i < hw->mac.uta_reg_count; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, ~0);
-}
-
-/**
- * igb_intr_msi - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- **/
-static irqreturn_t igb_intr_msi(int irq, void *data)
-{
- struct igb_adapter *adapter = data;
- struct igb_q_vector *q_vector = adapter->q_vector[0];
- struct e1000_hw *hw = &adapter->hw;
- /* read ICR disables interrupts using IAM */
- u32 icr = E1000_READ_REG(hw, E1000_ICR);
-
- igb_write_itr(q_vector);
-
- if (icr & E1000_ICR_DRSTA)
- schedule_work(&adapter->reset_task);
-
- if (icr & E1000_ICR_DOUTSYNC) {
- /* HW is reporting DMA is out of sync */
- adapter->stats.doosync++;
- }
-
- if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- hw->mac.get_link_status = 1;
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
- }
-
-#ifdef HAVE_PTP_1588_CLOCK
- if (icr & E1000_ICR_TS) {
- u32 tsicr = E1000_READ_REG(hw, E1000_TSICR);
-
- if (tsicr & E1000_TSICR_TXTS) {
- /* acknowledge the interrupt */
- E1000_WRITE_REG(hw, E1000_TSICR, E1000_TSICR_TXTS);
- /* retrieve hardware timestamp */
- schedule_work(&adapter->ptp_tx_work);
- }
- }
-#endif /* HAVE_PTP_1588_CLOCK */
-
- napi_schedule(&q_vector->napi);
-
- return IRQ_HANDLED;
-}
-
-/**
- * igb_intr - Legacy Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- **/
-static irqreturn_t igb_intr(int irq, void *data)
-{
- struct igb_adapter *adapter = data;
- struct igb_q_vector *q_vector = adapter->q_vector[0];
- struct e1000_hw *hw = &adapter->hw;
- /* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No
- * need for the IMC write */
- u32 icr = E1000_READ_REG(hw, E1000_ICR);
-
- /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
- * not set, then the adapter didn't send an interrupt */
- if (!(icr & E1000_ICR_INT_ASSERTED))
- return IRQ_NONE;
-
- igb_write_itr(q_vector);
-
- if (icr & E1000_ICR_DRSTA)
- schedule_work(&adapter->reset_task);
-
- if (icr & E1000_ICR_DOUTSYNC) {
- /* HW is reporting DMA is out of sync */
- adapter->stats.doosync++;
- }
-
- if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- hw->mac.get_link_status = 1;
- /* guard against interrupt when we're going down */
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
- }
-
-#ifdef HAVE_PTP_1588_CLOCK
- if (icr & E1000_ICR_TS) {
- u32 tsicr = E1000_READ_REG(hw, E1000_TSICR);
-
- if (tsicr & E1000_TSICR_TXTS) {
- /* acknowledge the interrupt */
- E1000_WRITE_REG(hw, E1000_TSICR, E1000_TSICR_TXTS);
- /* retrieve hardware timestamp */
- schedule_work(&adapter->ptp_tx_work);
- }
- }
-#endif /* HAVE_PTP_1588_CLOCK */
-
- napi_schedule(&q_vector->napi);
-
- return IRQ_HANDLED;
-}
-
-void igb_ring_irq_enable(struct igb_q_vector *q_vector)
-{
- struct igb_adapter *adapter = q_vector->adapter;
- struct e1000_hw *hw = &adapter->hw;
-
- if ((q_vector->rx.ring && (adapter->rx_itr_setting & 3)) ||
- (!q_vector->rx.ring && (adapter->tx_itr_setting & 3))) {
- if ((adapter->num_q_vectors == 1) && !adapter->vf_data)
- igb_set_itr(q_vector);
- else
- igb_update_ring_itr(q_vector);
- }
-
- if (!test_bit(__IGB_DOWN, &adapter->state)) {
- if (adapter->msix_entries)
- E1000_WRITE_REG(hw, E1000_EIMS, q_vector->eims_value);
- else
- igb_irq_enable(adapter);
- }
-}
-
-/**
- * igb_poll - NAPI Rx polling callback
- * @napi: napi polling structure
- * @budget: count of how many packets we should handle
- **/
-static int igb_poll(struct napi_struct *napi, int budget)
-{
- struct igb_q_vector *q_vector = container_of(napi, struct igb_q_vector, napi);
- bool clean_complete = true;
-
-#ifdef IGB_DCA
- if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
- igb_update_dca(q_vector);
-#endif
- if (q_vector->tx.ring)
- clean_complete = igb_clean_tx_irq(q_vector);
-
- if (q_vector->rx.ring)
- clean_complete &= igb_clean_rx_irq(q_vector, budget);
-
-#ifndef HAVE_NETDEV_NAPI_LIST
- /* if netdev is disabled we need to stop polling */
- if (!netif_running(q_vector->adapter->netdev))
- clean_complete = true;
-
-#endif
- /* If all work not completed, return budget and keep polling */
- if (!clean_complete)
- return budget;
-
- /* If not enough Rx work done, exit the polling mode */
- napi_complete(napi);
- igb_ring_irq_enable(q_vector);
-
- return 0;
-}
-
-/**
- * igb_clean_tx_irq - Reclaim resources after transmit completes
- * @q_vector: pointer to q_vector containing needed info
- * returns TRUE if ring is completely cleaned
- **/
-static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
-{
- struct igb_adapter *adapter = q_vector->adapter;
- struct igb_ring *tx_ring = q_vector->tx.ring;
- struct igb_tx_buffer *tx_buffer;
- union e1000_adv_tx_desc *tx_desc;
- unsigned int total_bytes = 0, total_packets = 0;
- unsigned int budget = q_vector->tx.work_limit;
- unsigned int i = tx_ring->next_to_clean;
-
- if (test_bit(__IGB_DOWN, &adapter->state))
- return true;
-
- tx_buffer = &tx_ring->tx_buffer_info[i];
- tx_desc = IGB_TX_DESC(tx_ring, i);
- i -= tx_ring->count;
-
- do {
- union e1000_adv_tx_desc *eop_desc = tx_buffer->next_to_watch;
-
- /* if next_to_watch is not set then there is no work pending */
- if (!eop_desc)
- break;
-
- /* prevent any other reads prior to eop_desc */
- read_barrier_depends();
-
- /* if DD is not set pending work has not been completed */
- if (!(eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)))
- break;
-
- /* clear next_to_watch to prevent false hangs */
- tx_buffer->next_to_watch = NULL;
-
- /* update the statistics for this packet */
- total_bytes += tx_buffer->bytecount;
- total_packets += tx_buffer->gso_segs;
-
- /* free the skb */
- dev_kfree_skb_any(tx_buffer->skb);
-
- /* unmap skb header data */
- dma_unmap_single(tx_ring->dev,
- dma_unmap_addr(tx_buffer, dma),
- dma_unmap_len(tx_buffer, len),
- DMA_TO_DEVICE);
-
- /* clear tx_buffer data */
- tx_buffer->skb = NULL;
- dma_unmap_len_set(tx_buffer, len, 0);
-
- /* clear last DMA location and unmap remaining buffers */
- while (tx_desc != eop_desc) {
- tx_buffer++;
- tx_desc++;
- i++;
- if (unlikely(!i)) {
- i -= tx_ring->count;
- tx_buffer = tx_ring->tx_buffer_info;
- tx_desc = IGB_TX_DESC(tx_ring, 0);
- }
-
- /* unmap any remaining paged data */
- if (dma_unmap_len(tx_buffer, len)) {
- dma_unmap_page(tx_ring->dev,
- dma_unmap_addr(tx_buffer, dma),
- dma_unmap_len(tx_buffer, len),
- DMA_TO_DEVICE);
- dma_unmap_len_set(tx_buffer, len, 0);
- }
- }
-
- /* move us one more past the eop_desc for start of next pkt */
- tx_buffer++;
- tx_desc++;
- i++;
- if (unlikely(!i)) {
- i -= tx_ring->count;
- tx_buffer = tx_ring->tx_buffer_info;
- tx_desc = IGB_TX_DESC(tx_ring, 0);
- }
-
- /* issue prefetch for next Tx descriptor */
- prefetch(tx_desc);
-
- /* update budget accounting */
- budget--;
- } while (likely(budget));
-
- netdev_tx_completed_queue(txring_txq(tx_ring),
- total_packets, total_bytes);
-
- i += tx_ring->count;
- tx_ring->next_to_clean = i;
- tx_ring->tx_stats.bytes += total_bytes;
- tx_ring->tx_stats.packets += total_packets;
- q_vector->tx.total_bytes += total_bytes;
- q_vector->tx.total_packets += total_packets;
-
-#ifdef DEBUG
- if (test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags) &&
- !(adapter->disable_hw_reset && adapter->tx_hang_detected)) {
-#else
- if (test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
-#endif
- struct e1000_hw *hw = &adapter->hw;
-
- /* Detect a transmit hang in hardware, this serializes the
- * check with the clearing of time_stamp and movement of i */
- clear_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags);
- if (tx_buffer->next_to_watch &&
- time_after(jiffies, tx_buffer->time_stamp +
- (adapter->tx_timeout_factor * HZ))
- && !(E1000_READ_REG(hw, E1000_STATUS) &
- E1000_STATUS_TXOFF)) {
-
- /* detected Tx unit hang */
-#ifdef DEBUG
- adapter->tx_hang_detected = TRUE;
- if (adapter->disable_hw_reset) {
- DPRINTK(DRV, WARNING,
- "Deactivating netdev watchdog timer\n");
- if (del_timer(&netdev_ring(tx_ring)->watchdog_timer))
- dev_put(netdev_ring(tx_ring));
-#ifndef HAVE_NET_DEVICE_OPS
- netdev_ring(tx_ring)->tx_timeout = NULL;
-#endif
- }
-#endif /* DEBUG */
- dev_err(tx_ring->dev,
- "Detected Tx Unit Hang\n"
- " Tx Queue <%d>\n"
- " TDH <%x>\n"
- " TDT <%x>\n"
- " next_to_use <%x>\n"
- " next_to_clean <%x>\n"
- "buffer_info[next_to_clean]\n"
- " time_stamp <%lx>\n"
- " next_to_watch <%p>\n"
- " jiffies <%lx>\n"
- " desc.status <%x>\n",
- tx_ring->queue_index,
- E1000_READ_REG(hw, E1000_TDH(tx_ring->reg_idx)),
- readl(tx_ring->tail),
- tx_ring->next_to_use,
- tx_ring->next_to_clean,
- tx_buffer->time_stamp,
- tx_buffer->next_to_watch,
- jiffies,
- tx_buffer->next_to_watch->wb.status);
- if (netif_is_multiqueue(netdev_ring(tx_ring)))
- netif_stop_subqueue(netdev_ring(tx_ring),
- ring_queue_index(tx_ring));
- else
- netif_stop_queue(netdev_ring(tx_ring));
-
- /* we are about to reset, no point in enabling stuff */
- return true;
- }
- }
-
-#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
- if (unlikely(total_packets &&
- netif_carrier_ok(netdev_ring(tx_ring)) &&
- igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) {
- /* Make sure that anybody stopping the queue after this
- * sees the new next_to_clean.
- */
- smp_mb();
- if (netif_is_multiqueue(netdev_ring(tx_ring))) {
- if (__netif_subqueue_stopped(netdev_ring(tx_ring),
- ring_queue_index(tx_ring)) &&
- !(test_bit(__IGB_DOWN, &adapter->state))) {
- netif_wake_subqueue(netdev_ring(tx_ring),
- ring_queue_index(tx_ring));
- tx_ring->tx_stats.restart_queue++;
- }
- } else {
- if (netif_queue_stopped(netdev_ring(tx_ring)) &&
- !(test_bit(__IGB_DOWN, &adapter->state))) {
- netif_wake_queue(netdev_ring(tx_ring));
- tx_ring->tx_stats.restart_queue++;
- }
- }
- }
-
- return !!budget;
-}
-
-#ifdef HAVE_VLAN_RX_REGISTER
-/**
- * igb_receive_skb - helper function to handle rx indications
- * @q_vector: structure containing interrupt and ring information
- * @skb: packet to send up
- **/
-static void igb_receive_skb(struct igb_q_vector *q_vector,
- struct sk_buff *skb)
-{
- struct vlan_group **vlgrp = netdev_priv(skb->dev);
-
- if (IGB_CB(skb)->vid) {
- if (*vlgrp) {
- vlan_gro_receive(&q_vector->napi, *vlgrp,
- IGB_CB(skb)->vid, skb);
- } else {
- dev_kfree_skb_any(skb);
- }
- } else {
- napi_gro_receive(&q_vector->napi, skb);
- }
-}
-
-#endif /* HAVE_VLAN_RX_REGISTER */
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
-/**
- * igb_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 igb_reuse_rx_page(struct igb_ring *rx_ring,
- struct igb_rx_buffer *old_buff)
-{
- struct igb_rx_buffer *new_buff;
- u16 nta = rx_ring->next_to_alloc;
-
- new_buff = &rx_ring->rx_buffer_info[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 */
- memcpy(new_buff, old_buff, sizeof(struct igb_rx_buffer));
-
- /* sync the buffer for use by the device */
- dma_sync_single_range_for_device(rx_ring->dev, old_buff->dma,
- old_buff->page_offset,
- IGB_RX_BUFSZ,
- DMA_FROM_DEVICE);
-}
-
-static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
- struct page *page,
- unsigned int truesize)
-{
- /* avoid re-using remote pages */
- if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
-
-#if (PAGE_SIZE < 8192)
- /* if we are only owner of page we can reuse it */
- if (unlikely(page_count(page) != 1))
- return false;
-
- /* flip page offset to other buffer */
- rx_buffer->page_offset ^= IGB_RX_BUFSZ;
-
-#else
- /* move offset up to the next cache line */
- rx_buffer->page_offset += truesize;
-
- if (rx_buffer->page_offset > (PAGE_SIZE - IGB_RX_BUFSZ))
- return false;
-#endif
-
- /* bump ref count on page before it is given to the stack */
- get_page(page);
-
- return true;
-}
-
-/**
- * igb_add_rx_frag - Add contents of Rx buffer to sk_buff
- * @rx_ring: rx descriptor ring to transact packets on
- * @rx_buffer: buffer containing page to add
- * @rx_desc: descriptor containing length of buffer written by hardware
- * @skb: sk_buff to place the data into
- *
- * This function will add the data contained in rx_buffer->page to the skb.
- * This is done either through a direct copy if the data in the buffer is
- * less than the skb header size, otherwise it will just attach the page as
- * a frag to the skb.
- *
- * The function will then update the page offset if necessary and return
- * true if the buffer can be reused by the adapter.
- **/
-static bool igb_add_rx_frag(struct igb_ring *rx_ring,
- struct igb_rx_buffer *rx_buffer,
- union e1000_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
- struct page *page = rx_buffer->page;
- unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
-#if (PAGE_SIZE < 8192)
- unsigned int truesize = IGB_RX_BUFSZ;
-#else
- unsigned int truesize = ALIGN(size, L1_CACHE_BYTES);
-#endif
-
- if ((size <= IGB_RX_HDR_LEN) && !skb_is_nonlinear(skb)) {
- unsigned char *va = page_address(page) + rx_buffer->page_offset;
-
-#ifdef HAVE_PTP_1588_CLOCK
- if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
- igb_ptp_rx_pktstamp(rx_ring->q_vector, va, skb);
- va += IGB_TS_HDR_LEN;
- size -= IGB_TS_HDR_LEN;
- }
-#endif /* HAVE_PTP_1588_CLOCK */
-
- memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long)));
-
- /* we can reuse buffer as-is, just make sure it is local */
- if (likely(page_to_nid(page) == numa_node_id()))
- return true;
-
- /* this page cannot be reused so discard it */
- put_page(page);
- return false;
- }
-
- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
- rx_buffer->page_offset, size, truesize);
-
- return igb_can_reuse_rx_page(rx_buffer, page, truesize);
-}
-
-static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
- union e1000_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
- struct igb_rx_buffer *rx_buffer;
- struct page *page;
-
- rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
-
- page = rx_buffer->page;
- prefetchw(page);
-
- if (likely(!skb)) {
- void *page_addr = page_address(page) +
- rx_buffer->page_offset;
-
- /* prefetch first cache line of first page */
- prefetch(page_addr);
-#if L1_CACHE_BYTES < 128
- prefetch(page_addr + L1_CACHE_BYTES);
-#endif
-
- /* allocate a skb to store the frags */
- skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
- IGB_RX_HDR_LEN);
- if (unlikely(!skb)) {
- rx_ring->rx_stats.alloc_failed++;
- return NULL;
- }
-
- /*
- * we will be copying header into skb->data in
- * pskb_may_pull so it is in our interest to prefetch
- * it now to avoid a possible cache miss
- */
- prefetchw(skb->data);
- }
-
- /* we are reusing so sync this buffer for CPU use */
- dma_sync_single_range_for_cpu(rx_ring->dev,
- rx_buffer->dma,
- rx_buffer->page_offset,
- IGB_RX_BUFSZ,
- DMA_FROM_DEVICE);
-
- /* pull page into skb */
- if (igb_add_rx_frag(rx_ring, rx_buffer, rx_desc, skb)) {
- /* hand second half of page back to the ring */
- igb_reuse_rx_page(rx_ring, rx_buffer);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rx_ring->dev, rx_buffer->dma,
- PAGE_SIZE, DMA_FROM_DEVICE);
- }
-
- /* clear contents of rx_buffer */
- rx_buffer->page = NULL;
-
- return skb;
-}
-
-#endif
-static inline void igb_rx_checksum(struct igb_ring *ring,
- union e1000_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
- skb_checksum_none_assert(skb);
-
- /* Ignore Checksum bit is set */
- if (igb_test_staterr(rx_desc, E1000_RXD_STAT_IXSM))
- return;
-
- /* Rx checksum disabled via ethtool */
- if (!(netdev_ring(ring)->features & NETIF_F_RXCSUM))
- return;
-
- /* TCP/UDP checksum error bit is set */
- if (igb_test_staterr(rx_desc,
- E1000_RXDEXT_STATERR_TCPE |
- E1000_RXDEXT_STATERR_IPE)) {
- /*
- * work around errata with sctp packets where the TCPE aka
- * L4E bit is set incorrectly on 64 byte (60 byte w/o crc)
- * packets, (aka let the stack check the crc32c)
- */
- if (!((skb->len == 60) &&
- test_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags)))
- ring->rx_stats.csum_err++;
-
- /* let the stack verify checksum errors */
- return;
- }
- /* It must be a TCP or UDP packet with a valid checksum */
- if (igb_test_staterr(rx_desc, E1000_RXD_STAT_TCPCS |
- E1000_RXD_STAT_UDPCS))
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-}
-
-#ifdef NETIF_F_RXHASH
-static inline void igb_rx_hash(struct igb_ring *ring,
- union e1000_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
- if (netdev_ring(ring)->features & NETIF_F_RXHASH)
- skb_set_hash(skb, le32_to_cpu(rx_desc->wb.lower.hi_dword.rss),
- PKT_HASH_TYPE_L3);
-}
-
-#endif
-#ifndef IGB_NO_LRO
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
-/**
- * igb_merge_active_tail - merge active tail into lro skb
- * @tail: pointer to active tail in frag_list
- *
- * This function merges the length and data of an active tail into the
- * skb containing the frag_list. It resets the tail's pointer to the head,
- * but it leaves the heads pointer to tail intact.
- **/
-static inline struct sk_buff *igb_merge_active_tail(struct sk_buff *tail)
-{
- struct sk_buff *head = IGB_CB(tail)->head;
-
- if (!head)
- return tail;
-
- head->len += tail->len;
- head->data_len += tail->len;
- head->truesize += tail->len;
-
- IGB_CB(tail)->head = NULL;
-
- return head;
-}
-
-/**
- * igb_add_active_tail - adds an active tail into the skb frag_list
- * @head: pointer to the start of the skb
- * @tail: pointer to active tail to add to frag_list
- *
- * This function adds an active tail to the end of the frag list. This tail
- * will still be receiving data so we cannot yet ad it's stats to the main
- * skb. That is done via igb_merge_active_tail.
- **/
-static inline void igb_add_active_tail(struct sk_buff *head, struct sk_buff *tail)
-{
- struct sk_buff *old_tail = IGB_CB(head)->tail;
-
- if (old_tail) {
- igb_merge_active_tail(old_tail);
- old_tail->next = tail;
- } else {
- skb_shinfo(head)->frag_list = tail;
- }
-
- IGB_CB(tail)->head = head;
- IGB_CB(head)->tail = tail;
-
- IGB_CB(head)->append_cnt++;
-}
-
-/**
- * igb_close_active_frag_list - cleanup pointers on a frag_list skb
- * @head: pointer to head of an active frag list
- *
- * This function will clear the frag_tail_tracker pointer on an active
- * frag_list and returns true if the pointer was actually set
- **/
-static inline bool igb_close_active_frag_list(struct sk_buff *head)
-{
- struct sk_buff *tail = IGB_CB(head)->tail;
-
- if (!tail)
- return false;
-
- igb_merge_active_tail(tail);
-
- IGB_CB(head)->tail = NULL;
-
- return true;
-}
-
-#endif /* CONFIG_IGB_DISABLE_PACKET_SPLIT */
-/**
- * igb_can_lro - returns true if packet is TCP/IPV4 and LRO is enabled
- * @adapter: board private structure
- * @rx_desc: pointer to the rx descriptor
- * @skb: pointer to the skb to be merged
- *
- **/
-static inline bool igb_can_lro(struct igb_ring *rx_ring,
- union e1000_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
- struct iphdr *iph = (struct iphdr *)skb->data;
- __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
-
- /* verify hardware indicates this is IPv4/TCP */
- if((!(pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_TCP)) ||
- !(pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_IPV4))))
- return false;
-
- /* .. and LRO is enabled */
- if (!(netdev_ring(rx_ring)->features & NETIF_F_LRO))
- return false;
-
- /* .. and we are not in promiscuous mode */
- if (netdev_ring(rx_ring)->flags & IFF_PROMISC)
- return false;
-
- /* .. and the header is large enough for us to read IP/TCP fields */
- if (!pskb_may_pull(skb, sizeof(struct igb_lrohdr)))
- return false;
-
- /* .. and there are no VLANs on packet */
- if (skb->protocol != __constant_htons(ETH_P_IP))
- return false;
-
- /* .. and we are version 4 with no options */
- if (*(u8 *)iph != 0x45)
- return false;
-
- /* .. and the packet is not fragmented */
- if (iph->frag_off & htons(IP_MF | IP_OFFSET))
- return false;
-
- /* .. and that next header is TCP */
- if (iph->protocol != IPPROTO_TCP)
- return false;
-
- return true;
-}
-
-static inline struct igb_lrohdr *igb_lro_hdr(struct sk_buff *skb)
-{
- return (struct igb_lrohdr *)skb->data;
-}
-
-/**
- * igb_lro_flush - Indicate packets to upper layer.
- *
- * Update IP and TCP header part of head skb if more than one
- * skb's chained and indicate packets to upper layer.
- **/
-static void igb_lro_flush(struct igb_q_vector *q_vector,
- struct sk_buff *skb)
-{
- struct igb_lro_list *lrolist = &q_vector->lrolist;
-
- __skb_unlink(skb, &lrolist->active);
-
- if (IGB_CB(skb)->append_cnt) {
- struct igb_lrohdr *lroh = igb_lro_hdr(skb);
-
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- /* close any active lro contexts */
- igb_close_active_frag_list(skb);
-
-#endif
- /* incorporate ip header and re-calculate checksum */
- lroh->iph.tot_len = ntohs(skb->len);
- lroh->iph.check = 0;
-
- /* header length is 5 since we know no options exist */
- lroh->iph.check = ip_fast_csum((u8 *)lroh, 5);
-
- /* clear TCP checksum to indicate we are an LRO frame */
- lroh->th.check = 0;
-
- /* incorporate latest timestamp into the tcp header */
- if (IGB_CB(skb)->tsecr) {
- lroh->ts[2] = IGB_CB(skb)->tsecr;
- lroh->ts[1] = htonl(IGB_CB(skb)->tsval);
- }
-#ifdef NETIF_F_GSO
-
- skb_shinfo(skb)->gso_size = IGB_CB(skb)->mss;
- skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
-#endif
- }
-
-#ifdef HAVE_VLAN_RX_REGISTER
- igb_receive_skb(q_vector, skb);
-#else
- napi_gro_receive(&q_vector->napi, skb);
-#endif
- lrolist->stats.flushed++;
-}
-
-static void igb_lro_flush_all(struct igb_q_vector *q_vector)
-{
- struct igb_lro_list *lrolist = &q_vector->lrolist;
- struct sk_buff *skb, *tmp;
-
- skb_queue_reverse_walk_safe(&lrolist->active, skb, tmp)
- igb_lro_flush(q_vector, skb);
-}
-
-/*
- * igb_lro_header_ok - Main LRO function.
- **/
-static void igb_lro_header_ok(struct sk_buff *skb)
-{
- struct igb_lrohdr *lroh = igb_lro_hdr(skb);
- u16 opt_bytes, data_len;
-
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- IGB_CB(skb)->tail = NULL;
-#endif
- IGB_CB(skb)->tsecr = 0;
- IGB_CB(skb)->append_cnt = 0;
- IGB_CB(skb)->mss = 0;
-
- /* ensure that the checksum is valid */
- if (skb->ip_summed != CHECKSUM_UNNECESSARY)
- return;
-
- /* If we see CE codepoint in IP header, packet is not mergeable */
- if (INET_ECN_is_ce(ipv4_get_dsfield(&lroh->iph)))
- return;
-
- /* ensure no bits set besides ack or psh */
- if (lroh->th.fin || lroh->th.syn || lroh->th.rst ||
- lroh->th.urg || lroh->th.ece || lroh->th.cwr ||
- !lroh->th.ack)
- return;
-
- /* store the total packet length */
- data_len = ntohs(lroh->iph.tot_len);
-
- /* remove any padding from the end of the skb */
- __pskb_trim(skb, data_len);
-
- /* remove header length from data length */
- data_len -= sizeof(struct igb_lrohdr);
-
- /*
- * check for timestamps. Since the only option we handle are timestamps,
- * we only have to handle the simple case of aligned timestamps
- */
- opt_bytes = (lroh->th.doff << 2) - sizeof(struct tcphdr);
- if (opt_bytes != 0) {
- if ((opt_bytes != TCPOLEN_TSTAMP_ALIGNED) ||
- !pskb_may_pull(skb, sizeof(struct igb_lrohdr) +
- TCPOLEN_TSTAMP_ALIGNED) ||
- (lroh->ts[0] != htonl((TCPOPT_NOP << 24) |
- (TCPOPT_NOP << 16) |
- (TCPOPT_TIMESTAMP << 8) |
- TCPOLEN_TIMESTAMP)) ||
- (lroh->ts[2] == 0)) {
- return;
- }
-
- IGB_CB(skb)->tsval = ntohl(lroh->ts[1]);
- IGB_CB(skb)->tsecr = lroh->ts[2];
-
- data_len -= TCPOLEN_TSTAMP_ALIGNED;
- }
-
- /* record data_len as mss for the packet */
- IGB_CB(skb)->mss = data_len;
- IGB_CB(skb)->next_seq = ntohl(lroh->th.seq);
-}
-
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
-static void igb_merge_frags(struct sk_buff *lro_skb, struct sk_buff *new_skb)
-{
- struct skb_shared_info *sh_info;
- struct skb_shared_info *new_skb_info;
- unsigned int data_len;
-
- sh_info = skb_shinfo(lro_skb);
- new_skb_info = skb_shinfo(new_skb);
-
- /* copy frags into the last skb */
- memcpy(sh_info->frags + sh_info->nr_frags,
- new_skb_info->frags,
- new_skb_info->nr_frags * sizeof(skb_frag_t));
-
- /* copy size data over */
- sh_info->nr_frags += new_skb_info->nr_frags;
- data_len = IGB_CB(new_skb)->mss;
- lro_skb->len += data_len;
- lro_skb->data_len += data_len;
- lro_skb->truesize += data_len;
-
- /* wipe record of data from new_skb */
- new_skb_info->nr_frags = 0;
- new_skb->len = new_skb->data_len = 0;
- dev_kfree_skb_any(new_skb);
-}
-
-#endif /* CONFIG_IGB_DISABLE_PACKET_SPLIT */
-/**
- * igb_lro_receive - if able, queue skb into lro chain
- * @q_vector: structure containing interrupt and ring information
- * @new_skb: pointer to current skb being checked
- *
- * Checks whether the skb given is eligible for LRO and if that's
- * fine chains it to the existing lro_skb based on flowid. If an LRO for
- * the flow doesn't exist create one.
- **/
-static void igb_lro_receive(struct igb_q_vector *q_vector,
- struct sk_buff *new_skb)
-{
- struct sk_buff *lro_skb;
- struct igb_lro_list *lrolist = &q_vector->lrolist;
- struct igb_lrohdr *lroh = igb_lro_hdr(new_skb);
- __be32 saddr = lroh->iph.saddr;
- __be32 daddr = lroh->iph.daddr;
- __be32 tcp_ports = *(__be32 *)&lroh->th;
- u16 data_len;
-#ifdef HAVE_VLAN_RX_REGISTER
- u16 vid = IGB_CB(new_skb)->vid;
-#else
- u16 vid = new_skb->vlan_tci;
-#endif
-
- igb_lro_header_ok(new_skb);
-
- /*
- * we have a packet that might be eligible for LRO,
- * so see if it matches anything we might expect
- */
- skb_queue_walk(&lrolist->active, lro_skb) {
- if (*(__be32 *)&igb_lro_hdr(lro_skb)->th != tcp_ports ||
- igb_lro_hdr(lro_skb)->iph.saddr != saddr ||
- igb_lro_hdr(lro_skb)->iph.daddr != daddr)
- continue;
-
-#ifdef HAVE_VLAN_RX_REGISTER
- if (IGB_CB(lro_skb)->vid != vid)
-#else
- if (lro_skb->vlan_tci != vid)
-#endif
- continue;
-
- /* out of order packet */
- if (IGB_CB(lro_skb)->next_seq != IGB_CB(new_skb)->next_seq) {
- igb_lro_flush(q_vector, lro_skb);
- IGB_CB(new_skb)->mss = 0;
- break;
- }
-
- /* TCP timestamp options have changed */
- if (!IGB_CB(lro_skb)->tsecr != !IGB_CB(new_skb)->tsecr) {
- igb_lro_flush(q_vector, lro_skb);
- break;
- }
-
- /* make sure timestamp values are increasing */
- if (IGB_CB(lro_skb)->tsecr &&
- IGB_CB(lro_skb)->tsval > IGB_CB(new_skb)->tsval) {
- igb_lro_flush(q_vector, lro_skb);
- IGB_CB(new_skb)->mss = 0;
- break;
- }
-
- data_len = IGB_CB(new_skb)->mss;
-
- /* Check for all of the above below
- * malformed header
- * no tcp data
- * resultant packet would be too large
- * new skb is larger than our current mss
- * data would remain in header
- * we would consume more frags then the sk_buff contains
- * ack sequence numbers changed
- * window size has changed
- */
- if (data_len == 0 ||
- data_len > IGB_CB(lro_skb)->mss ||
- data_len > IGB_CB(lro_skb)->free ||
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
- data_len != new_skb->data_len ||
- skb_shinfo(new_skb)->nr_frags >=
- (MAX_SKB_FRAGS - skb_shinfo(lro_skb)->nr_frags) ||
-#endif
- igb_lro_hdr(lro_skb)->th.ack_seq != lroh->th.ack_seq ||
- igb_lro_hdr(lro_skb)->th.window != lroh->th.window) {
- igb_lro_flush(q_vector, lro_skb);
- break;
- }
-
- /* Remove IP and TCP header*/
- skb_pull(new_skb, new_skb->len - data_len);
-
- /* update timestamp and timestamp echo response */
- IGB_CB(lro_skb)->tsval = IGB_CB(new_skb)->tsval;
- IGB_CB(lro_skb)->tsecr = IGB_CB(new_skb)->tsecr;
-
- /* update sequence and free space */
- IGB_CB(lro_skb)->next_seq += data_len;
- IGB_CB(lro_skb)->free -= data_len;
-
- /* update append_cnt */
- IGB_CB(lro_skb)->append_cnt++;
-
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
- /* if header is empty pull pages into current skb */
- igb_merge_frags(lro_skb, new_skb);
-#else
- /* chain this new skb in frag_list */
- igb_add_active_tail(lro_skb, new_skb);
-#endif
-
- if ((data_len < IGB_CB(lro_skb)->mss) || lroh->th.psh ||
- skb_shinfo(lro_skb)->nr_frags == MAX_SKB_FRAGS) {
- igb_lro_hdr(lro_skb)->th.psh |= lroh->th.psh;
- igb_lro_flush(q_vector, lro_skb);
- }
-
- lrolist->stats.coal++;
- return;
- }
-
- if (IGB_CB(new_skb)->mss && !lroh->th.psh) {
- /* if we are at capacity flush the tail */
- if (skb_queue_len(&lrolist->active) >= IGB_LRO_MAX) {
- lro_skb = skb_peek_tail(&lrolist->active);
- if (lro_skb)
- igb_lro_flush(q_vector, lro_skb);
- }
-
- /* update sequence and free space */
- IGB_CB(new_skb)->next_seq += IGB_CB(new_skb)->mss;
- IGB_CB(new_skb)->free = 65521 - new_skb->len;
-
- /* .. and insert at the front of the active list */
- __skb_queue_head(&lrolist->active, new_skb);
-
- lrolist->stats.coal++;
- return;
- }
-
- /* packet not handled by any of the above, pass it to the stack */
-#ifdef HAVE_VLAN_RX_REGISTER
- igb_receive_skb(q_vector, new_skb);
-#else
- napi_gro_receive(&q_vector->napi, new_skb);
-#endif
-}
-
-#endif /* IGB_NO_LRO */
-/**
- * igb_process_skb_fields - Populate skb header fields from Rx descriptor
- * @rx_ring: rx descriptor ring packet is being transacted on
- * @rx_desc: pointer to the EOP Rx descriptor
- * @skb: pointer to current skb being populated
- *
- * This function checks the ring, descriptor, and packet information in
- * order to populate the hash, checksum, VLAN, timestamp, protocol, and
- * other fields within the skb.
- **/
-static void igb_process_skb_fields(struct igb_ring *rx_ring,
- union e1000_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
- struct net_device *dev = rx_ring->netdev;
- __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
-
-#ifdef NETIF_F_RXHASH
- igb_rx_hash(rx_ring, rx_desc, skb);
-
-#endif
- igb_rx_checksum(rx_ring, rx_desc, skb);
-
- /* update packet type stats */
- if (pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_IPV4))
- rx_ring->rx_stats.ipv4_packets++;
- else if (pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_IPV4_EX))
- rx_ring->rx_stats.ipv4e_packets++;
- else if (pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_IPV6))
- rx_ring->rx_stats.ipv6_packets++;
- else if (pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_IPV6_EX))
- rx_ring->rx_stats.ipv6e_packets++;
- else if (pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_TCP))
- rx_ring->rx_stats.tcp_packets++;
- else if (pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_UDP))
- rx_ring->rx_stats.udp_packets++;
- else if (pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_SCTP))
- rx_ring->rx_stats.sctp_packets++;
- else if (pkt_info & cpu_to_le16(E1000_RXDADV_PKTTYPE_NFS))
- rx_ring->rx_stats.nfs_packets++;
-
-#ifdef HAVE_PTP_1588_CLOCK
- igb_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
-#endif /* HAVE_PTP_1588_CLOCK */
-
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
- if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
-#else
- if ((dev->features & NETIF_F_HW_VLAN_RX) &&
-#endif
- igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) {
- u16 vid = 0;
- if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) &&
- test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &rx_ring->flags))
- vid = be16_to_cpu(rx_desc->wb.upper.vlan);
- else
- vid = le16_to_cpu(rx_desc->wb.upper.vlan);
-#ifdef HAVE_VLAN_RX_REGISTER
- IGB_CB(skb)->vid = vid;
- } else {
- IGB_CB(skb)->vid = 0;
-#else
-
-#ifdef HAVE_VLAN_PROTOCOL
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
-#else
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
-#endif
-
-
-#endif
- }
-
- skb_record_rx_queue(skb, rx_ring->queue_index);
-
- skb->protocol = eth_type_trans(skb, dev);
-}
-
-/**
- * igb_is_non_eop - process handling of non-EOP buffers
- * @rx_ring: Rx ring being processed
- * @rx_desc: Rx descriptor for current buffer
- *
- * This function updates next to clean. If the buffer is an EOP buffer
- * this function exits returning false, otherwise it will place the
- * sk_buff in the next buffer to be chained and return true indicating
- * that this is in fact a non-EOP buffer.
- **/
-static bool igb_is_non_eop(struct igb_ring *rx_ring,
- union e1000_adv_rx_desc *rx_desc)
-{
- u32 ntc = rx_ring->next_to_clean + 1;
-
- /* fetch, update, and store next to clean */
- ntc = (ntc < rx_ring->count) ? ntc : 0;
- rx_ring->next_to_clean = ntc;
-
- prefetch(IGB_RX_DESC(rx_ring, ntc));
-
- if (likely(igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP)))
- return false;
-
- return true;
-}
-
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
-/* igb_clean_rx_irq -- * legacy */
-static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget)
-{
- struct igb_ring *rx_ring = q_vector->rx.ring;
- unsigned int total_bytes = 0, total_packets = 0;
- u16 cleaned_count = igb_desc_unused(rx_ring);
-
- do {
- struct igb_rx_buffer *rx_buffer;
- union e1000_adv_rx_desc *rx_desc;
- struct sk_buff *skb;
- u16 ntc;
-
- /* return some buffers to hardware, one at a time is too slow */
- if (cleaned_count >= IGB_RX_BUFFER_WRITE) {
- igb_alloc_rx_buffers(rx_ring, cleaned_count);
- cleaned_count = 0;
- }
-
- ntc = rx_ring->next_to_clean;
- rx_desc = IGB_RX_DESC(rx_ring, ntc);
- rx_buffer = &rx_ring->rx_buffer_info[ntc];
-
- if (!igb_test_staterr(rx_desc, E1000_RXD_STAT_DD))
- break;
-
- /*
- * This memory barrier is needed to keep us from reading
- * any other fields out of the rx_desc until we know the
- * RXD_STAT_DD bit is set
- */
- rmb();
-
- skb = rx_buffer->skb;
-
- prefetch(skb->data);
-
- /* pull the header of the skb in */
- __skb_put(skb, le16_to_cpu(rx_desc->wb.upper.length));
-
- /* clear skb reference in buffer info structure */
- rx_buffer->skb = NULL;
-
- cleaned_count++;
-
- BUG_ON(igb_is_non_eop(rx_ring, rx_desc));
-
- dma_unmap_single(rx_ring->dev, rx_buffer->dma,
- rx_ring->rx_buffer_len,
- DMA_FROM_DEVICE);
- rx_buffer->dma = 0;
-
- if (igb_test_staterr(rx_desc,
- E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
- dev_kfree_skb_any(skb);
- continue;
- }
-
- total_bytes += skb->len;
-
- /* populate checksum, timestamp, VLAN, and protocol */
- igb_process_skb_fields(rx_ring, rx_desc, skb);
-
-#ifndef IGB_NO_LRO
- if (igb_can_lro(rx_ring, rx_desc, skb))
- igb_lro_receive(q_vector, skb);
- else
-#endif
-#ifdef HAVE_VLAN_RX_REGISTER
- igb_receive_skb(q_vector, skb);
-#else
- napi_gro_receive(&q_vector->napi, skb);
-#endif
-
-#ifndef NETIF_F_GRO
- netdev_ring(rx_ring)->last_rx = jiffies;
-
-#endif
- /* update budget accounting */
- total_packets++;
- } while (likely(total_packets < budget));
-
- rx_ring->rx_stats.packets += total_packets;
- rx_ring->rx_stats.bytes += total_bytes;
- q_vector->rx.total_packets += total_packets;
- q_vector->rx.total_bytes += total_bytes;
-
- if (cleaned_count)
- igb_alloc_rx_buffers(rx_ring, cleaned_count);
-
-#ifndef IGB_NO_LRO
- igb_lro_flush_all(q_vector);
-
-#endif /* IGB_NO_LRO */
- return total_packets < budget;
-}
-#else /* CONFIG_IGB_DISABLE_PACKET_SPLIT */
-/**
- * igb_get_headlen - determine size of header for LRO/GRO
- * @data: pointer to the start of the headers
- * @max_len: total length of section to find headers in
- *
- * This function is meant to determine the length of headers that will
- * be recognized by hardware for LRO, and GRO offloads. The main
- * motivation of doing this is to only perform one pull for IPv4 TCP
- * packets so that we can do basic things like calculating the gso_size
- * based on the average data per packet.
- **/
-static unsigned int igb_get_headlen(unsigned char *data,
- unsigned int max_len)
-{
- union {
- unsigned char *network;
- /* l2 headers */
- struct ethhdr *eth;
- struct vlan_hdr *vlan;
- /* l3 headers */
- struct iphdr *ipv4;
- struct ipv6hdr *ipv6;
- } hdr;
- __be16 protocol;
- u8 nexthdr = 0; /* default to not TCP */
- u8 hlen;
-
- /* this should never happen, but better safe than sorry */
- if (max_len < ETH_HLEN)
- return max_len;
-
- /* initialize network frame pointer */
- hdr.network = data;
-
- /* set first protocol and move network header forward */
- protocol = hdr.eth->h_proto;
- hdr.network += ETH_HLEN;
-
- /* handle any vlan tag if present */
- if (protocol == __constant_htons(ETH_P_8021Q)) {
- if ((hdr.network - data) > (max_len - VLAN_HLEN))
- return max_len;
-
- protocol = hdr.vlan->h_vlan_encapsulated_proto;
- hdr.network += VLAN_HLEN;
- }
-
- /* handle L3 protocols */
- if (protocol == __constant_htons(ETH_P_IP)) {
- if ((hdr.network - data) > (max_len - sizeof(struct iphdr)))
- return max_len;
-
- /* access ihl as a u8 to avoid unaligned access on ia64 */
- hlen = (hdr.network[0] & 0x0F) << 2;
-
- /* verify hlen meets minimum size requirements */
- if (hlen < sizeof(struct iphdr))
- return hdr.network - data;
-
- /* record next protocol if header is present */
- if (!(hdr.ipv4->frag_off & htons(IP_OFFSET)))
- nexthdr = hdr.ipv4->protocol;
-#ifdef NETIF_F_TSO6
- } else if (protocol == __constant_htons(ETH_P_IPV6)) {
- if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))
- return max_len;
-
- /* record next protocol */
- nexthdr = hdr.ipv6->nexthdr;
- hlen = sizeof(struct ipv6hdr);
-#endif /* NETIF_F_TSO6 */
- } else {
- return hdr.network - data;
- }
-
- /* relocate pointer to start of L4 header */
- hdr.network += hlen;
-
- /* finally sort out TCP */
- if (nexthdr == IPPROTO_TCP) {
- if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))
- return max_len;
-
- /* access doff as a u8 to avoid unaligned access on ia64 */
- hlen = (hdr.network[12] & 0xF0) >> 2;
-
- /* verify hlen meets minimum size requirements */
- if (hlen < sizeof(struct tcphdr))
- return hdr.network - data;
-
- hdr.network += hlen;
- } else if (nexthdr == IPPROTO_UDP) {
- if ((hdr.network - data) > (max_len - sizeof(struct udphdr)))
- return max_len;
-
- hdr.network += sizeof(struct udphdr);
- }
-
- /*
- * If everything has gone correctly hdr.network should be the
- * data section of the packet and will be the end of the header.
- * If not then it probably represents the end of the last recognized
- * header.
- */
- if ((hdr.network - data) < max_len)
- return hdr.network - data;
- else
- return max_len;
-}
-
-/**
- * igb_pull_tail - igb specific version of skb_pull_tail
- * @rx_ring: rx descriptor ring packet is being transacted on
- * @rx_desc: pointer to the EOP Rx descriptor
- * @skb: pointer to current skb being adjusted
- *
- * This function is an igb specific version of __pskb_pull_tail. The
- * main difference between this version and the original function is that
- * this function can make several assumptions about the state of things
- * that allow for significant optimizations versus the standard function.
- * As a result we can do things like drop a frag and maintain an accurate
- * truesize for the skb.
- */
-static void igb_pull_tail(struct igb_ring *rx_ring,
- union e1000_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
- struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
- unsigned char *va;
- unsigned int pull_len;
-
- /*
- * it is valid to use page_address instead of kmap since we are
- * working with pages allocated out of the lomem pool per
- * alloc_page(GFP_ATOMIC)
- */
- va = skb_frag_address(frag);
-
-#ifdef HAVE_PTP_1588_CLOCK
- if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
- /* retrieve timestamp from buffer */
- igb_ptp_rx_pktstamp(rx_ring->q_vector, va, skb);
-
- /* update pointers to remove timestamp header */
- skb_frag_size_sub(frag, IGB_TS_HDR_LEN);
- frag->page_offset += IGB_TS_HDR_LEN;
- skb->data_len -= IGB_TS_HDR_LEN;
- skb->len -= IGB_TS_HDR_LEN;
-
- /* move va to start of packet data */
- va += IGB_TS_HDR_LEN;
- }
-#endif /* HAVE_PTP_1588_CLOCK */
-
- /*
- * we need the header to contain the greater of either ETH_HLEN or
- * 60 bytes if the skb->len is less than 60 for skb_pad.
- */
- pull_len = igb_get_headlen(va, IGB_RX_HDR_LEN);
-
- /* align pull length to size of long to optimize memcpy performance */
- skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long)));
-
- /* update all of the pointers */
- skb_frag_size_sub(frag, pull_len);
- frag->page_offset += pull_len;
- skb->data_len -= pull_len;
- skb->tail += pull_len;
-}
-
-/**
- * igb_cleanup_headers - Correct corrupted or empty headers
- * @rx_ring: rx descriptor ring packet is being transacted on
- * @rx_desc: pointer to the EOP Rx descriptor
- * @skb: pointer to current skb being fixed
- *
- * Address the case where we are pulling data in on pages only
- * and as such no data is present in the skb header.
- *
- * In addition if skb is not at least 60 bytes we need to pad it so that
- * it is large enough to qualify as a valid Ethernet frame.
- *
- * Returns true if an error was encountered and skb was freed.
- **/
-static bool igb_cleanup_headers(struct igb_ring *rx_ring,
- union e1000_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
-
- if (unlikely((igb_test_staterr(rx_desc,
- E1000_RXDEXT_ERR_FRAME_ERR_MASK)))) {
- struct net_device *netdev = rx_ring->netdev;
- if (!(netdev->features & NETIF_F_RXALL)) {
- dev_kfree_skb_any(skb);
- return true;
- }
- }
-
- /* place header in linear portion of buffer */
- if (skb_is_nonlinear(skb))
- igb_pull_tail(rx_ring, rx_desc, skb);
-
- /* if skb_pad returns an error the skb was freed */
- if (unlikely(skb->len < 60)) {
- int pad_len = 60 - skb->len;
-
- if (skb_pad(skb, pad_len))
- return true;
- __skb_put(skb, pad_len);
- }
-
- return false;
-}
-
-/* igb_clean_rx_irq -- * packet split */
-static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget)
-{
- struct igb_ring *rx_ring = q_vector->rx.ring;
- struct sk_buff *skb = rx_ring->skb;
- unsigned int total_bytes = 0, total_packets = 0;
- u16 cleaned_count = igb_desc_unused(rx_ring);
-
- do {
- union e1000_adv_rx_desc *rx_desc;
-
- /* return some buffers to hardware, one at a time is too slow */
- if (cleaned_count >= IGB_RX_BUFFER_WRITE) {
- igb_alloc_rx_buffers(rx_ring, cleaned_count);
- cleaned_count = 0;
- }
-
- rx_desc = IGB_RX_DESC(rx_ring, rx_ring->next_to_clean);
-
- if (!igb_test_staterr(rx_desc, E1000_RXD_STAT_DD))
- break;
-
- /*
- * This memory barrier is needed to keep us from reading
- * any other fields out of the rx_desc until we know the
- * RXD_STAT_DD bit is set
- */
- rmb();
-
- /* retrieve a buffer from the ring */
- skb = igb_fetch_rx_buffer(rx_ring, rx_desc, skb);
-
- /* exit if we failed to retrieve a buffer */
- if (!skb)
- break;
-
- cleaned_count++;
-
- /* fetch next buffer in frame if non-eop */
- if (igb_is_non_eop(rx_ring, rx_desc))
- continue;
-
- /* verify the packet layout is correct */
- if (igb_cleanup_headers(rx_ring, rx_desc, skb)) {
- skb = NULL;
- continue;
- }
-
- /* probably a little skewed due to removing CRC */
- total_bytes += skb->len;
-
- /* populate checksum, timestamp, VLAN, and protocol */
- igb_process_skb_fields(rx_ring, rx_desc, skb);
-
-#ifndef IGB_NO_LRO
- if (igb_can_lro(rx_ring, rx_desc, skb))
- igb_lro_receive(q_vector, skb);
- else
-#endif
-#ifdef HAVE_VLAN_RX_REGISTER
- igb_receive_skb(q_vector, skb);
-#else
- napi_gro_receive(&q_vector->napi, skb);
-#endif
-#ifndef NETIF_F_GRO
-
- netdev_ring(rx_ring)->last_rx = jiffies;
-#endif
-
- /* reset skb pointer */
- skb = NULL;
-
- /* update budget accounting */
- total_packets++;
- } while (likely(total_packets < budget));
-
- /* place incomplete frames back on ring for completion */
- rx_ring->skb = skb;
-
- rx_ring->rx_stats.packets += total_packets;
- rx_ring->rx_stats.bytes += total_bytes;
- q_vector->rx.total_packets += total_packets;
- q_vector->rx.total_bytes += total_bytes;
-
- if (cleaned_count)
- igb_alloc_rx_buffers(rx_ring, cleaned_count);
-
-#ifndef IGB_NO_LRO
- igb_lro_flush_all(q_vector);
-
-#endif /* IGB_NO_LRO */
- return total_packets < budget;
-}
-#endif /* CONFIG_IGB_DISABLE_PACKET_SPLIT */
-
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
-static bool igb_alloc_mapped_skb(struct igb_ring *rx_ring,
- struct igb_rx_buffer *bi)
-{
- struct sk_buff *skb = bi->skb;
- dma_addr_t dma = bi->dma;
-
- if (dma)
- return true;
-
- if (likely(!skb)) {
- skb = netdev_alloc_skb_ip_align(netdev_ring(rx_ring),
- rx_ring->rx_buffer_len);
- bi->skb = skb;
- if (!skb) {
- rx_ring->rx_stats.alloc_failed++;
- return false;
- }
-
- /* initialize skb for ring */
- skb_record_rx_queue(skb, ring_queue_index(rx_ring));
- }
-
- dma = dma_map_single(rx_ring->dev, skb->data,
- rx_ring->rx_buffer_len, DMA_FROM_DEVICE);
-
- /* if mapping failed free memory back to system since
- * there isn't much point in holding memory we can't use
- */
- if (dma_mapping_error(rx_ring->dev, dma)) {
- dev_kfree_skb_any(skb);
- bi->skb = NULL;
-
- rx_ring->rx_stats.alloc_failed++;
- return false;
- }
-
- bi->dma = dma;
- return true;
-}
-
-#else /* CONFIG_IGB_DISABLE_PACKET_SPLIT */
-static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
- struct igb_rx_buffer *bi)
-{
- struct page *page = bi->page;
- dma_addr_t dma;
-
- /* since we are recycling buffers we should seldom need to alloc */
- if (likely(page))
- return true;
-
- /* alloc new page for storage */
- page = alloc_page(GFP_ATOMIC | __GFP_COLD);
- if (unlikely(!page)) {
- rx_ring->rx_stats.alloc_failed++;
- return false;
- }
-
- /* map page for use */
- dma = dma_map_page(rx_ring->dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE);
-
- /*
- * if mapping failed free memory back to system since
- * there isn't much point in holding memory we can't use
- */
- if (dma_mapping_error(rx_ring->dev, dma)) {
- __free_page(page);
-
- rx_ring->rx_stats.alloc_failed++;
- return false;
- }
-
- bi->dma = dma;
- bi->page = page;
- bi->page_offset = 0;
-
- return true;
-}
-
-#endif /* CONFIG_IGB_DISABLE_PACKET_SPLIT */
-/**
- * igb_alloc_rx_buffers - Replace used receive buffers; packet split
- * @adapter: address of board private structure
- **/
-void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)
-{
- union e1000_adv_rx_desc *rx_desc;
- struct igb_rx_buffer *bi;
- u16 i = rx_ring->next_to_use;
-
- /* nothing to do */
- if (!cleaned_count)
- return;
-
- rx_desc = IGB_RX_DESC(rx_ring, i);
- bi = &rx_ring->rx_buffer_info[i];
- i -= rx_ring->count;
-
- do {
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- if (!igb_alloc_mapped_skb(rx_ring, bi))
-#else
- if (!igb_alloc_mapped_page(rx_ring, bi))
-#endif /* CONFIG_IGB_DISABLE_PACKET_SPLIT */
- break;
-
- /*
- * Refresh the desc even if buffer_addrs didn't change
- * because each write-back erases this info.
- */
-#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
- rx_desc->read.pkt_addr = cpu_to_le64(bi->dma);
-#else
- rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset);
-#endif
-
- rx_desc++;
- bi++;
- i++;
- if (unlikely(!i)) {
- rx_desc = IGB_RX_DESC(rx_ring, 0);
- bi = rx_ring->rx_buffer_info;
- i -= rx_ring->count;
- }
-
- /* clear the hdr_addr for the next_to_use descriptor */
- rx_desc->read.hdr_addr = 0;
-
- cleaned_count--;
- } while (cleaned_count);
-
- i += rx_ring->count;
-
- if (rx_ring->next_to_use != i) {
- /* record the next descriptor to use */
- rx_ring->next_to_use = i;
-
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
- /* update next to alloc since we have filled the ring */
- rx_ring->next_to_alloc = i;
-
-#endif
- /*
- * Force memory writes to complete before letting h/w
- * know there are new descriptors to fetch. (Only
- * applicable for weak-ordered memory model archs,
- * such as IA-64).
- */
- wmb();
- writel(i, rx_ring->tail);
- }
-}
-
-#ifdef SIOCGMIIPHY
-/**
- * igb_mii_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- **/
-static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct mii_ioctl_data *data = if_mii(ifr);
-
- if (adapter->hw.phy.media_type != e1000_media_type_copper)
- return -EOPNOTSUPP;
-
- switch (cmd) {
- case SIOCGMIIPHY:
- data->phy_id = adapter->hw.phy.addr;
- break;
- case SIOCGMIIREG:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
- &data->val_out))
- return -EIO;
- break;
- case SIOCSMIIREG:
- default:
- return -EOPNOTSUPP;
- }
- return E1000_SUCCESS;
-}
-
-#endif
-/**
- * igb_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- **/
-static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
- switch (cmd) {
-#ifdef SIOCGMIIPHY
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
- case SIOCSMIIREG:
- return igb_mii_ioctl(netdev, ifr, cmd);
-#endif
-#ifdef HAVE_PTP_1588_CLOCK
- case SIOCSHWTSTAMP:
- return igb_ptp_hwtstamp_ioctl(netdev, ifr, cmd);
-#endif /* HAVE_PTP_1588_CLOCK */
-#ifdef ETHTOOL_OPS_COMPAT
- case SIOCETHTOOL:
- return ethtool_ioctl(ifr);
-#endif
- default:
- return -EOPNOTSUPP;
- }
-}
-
-s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
-{
- struct igb_adapter *adapter = hw->back;
- u16 cap_offset;
-
- cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
- if (!cap_offset)
- return -E1000_ERR_CONFIG;
-
- pci_read_config_word(adapter->pdev, cap_offset + reg, value);
-
- return E1000_SUCCESS;
-}
-
-s32 e1000_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
-{
- struct igb_adapter *adapter = hw->back;
- u16 cap_offset;
-
- cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
- if (!cap_offset)
- return -E1000_ERR_CONFIG;
-
- pci_write_config_word(adapter->pdev, cap_offset + reg, *value);
-
- return E1000_SUCCESS;
-}
-
-#ifdef HAVE_VLAN_RX_REGISTER
-static void igb_vlan_mode(struct net_device *netdev, struct vlan_group *vlgrp)
-#else
-void igb_vlan_mode(struct net_device *netdev, u32 features)
-#endif
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl, rctl;
- int i;
-#ifdef HAVE_VLAN_RX_REGISTER
- bool enable = !!vlgrp;
-
- igb_irq_disable(adapter);
-
- adapter->vlgrp = vlgrp;
-
- if (!test_bit(__IGB_DOWN, &adapter->state))
- igb_irq_enable(adapter);
-#else
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
- bool enable = !!(features & NETIF_F_HW_VLAN_CTAG_RX);
-#else
- bool enable = !!(features & NETIF_F_HW_VLAN_RX);
-#endif
-#endif
-
- if (enable) {
- /* enable VLAN tag insert/strip */
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- ctrl |= E1000_CTRL_VME;
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-
- /* Disable CFI check */
- rctl = E1000_READ_REG(hw, E1000_RCTL);
- rctl &= ~E1000_RCTL_CFIEN;
- E1000_WRITE_REG(hw, E1000_RCTL, rctl);
- } else {
- /* disable VLAN tag insert/strip */
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- ctrl &= ~E1000_CTRL_VME;
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
- }
-
-#ifndef CONFIG_IGB_VMDQ_NETDEV
- for (i = 0; i < adapter->vmdq_pools; i++) {
- igb_set_vf_vlan_strip(adapter,
- adapter->vfs_allocated_count + i,
- enable);
- }
-
-#else
- igb_set_vf_vlan_strip(adapter,
- adapter->vfs_allocated_count,
- enable);
-
- for (i = 1; i < adapter->vmdq_pools; i++) {
-#ifdef HAVE_VLAN_RX_REGISTER
- struct igb_vmdq_adapter *vadapter;
- vadapter = netdev_priv(adapter->vmdq_netdev[i-1]);
- enable = !!vadapter->vlgrp;
-#else
- struct net_device *vnetdev;
- vnetdev = adapter->vmdq_netdev[i-1];
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
- enable = !!(vnetdev->features & NETIF_F_HW_VLAN_CTAG_RX);
-#else
- enable = !!(vnetdev->features & NETIF_F_HW_VLAN_RX);
-#endif
-#endif
- igb_set_vf_vlan_strip(adapter,
- adapter->vfs_allocated_count + i,
- enable);
- }
-
-#endif
- igb_rlpml_set(adapter);
-}
-
-#ifdef HAVE_VLAN_PROTOCOL
-static int igb_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
-#elif defined HAVE_INT_NDO_VLAN_RX_ADD_VID
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
-static int igb_vlan_rx_add_vid(struct net_device *netdev,
- __always_unused __be16 proto, u16 vid)
-#else
-static int igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
-#endif
-#else
-static void igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
-#endif
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- int pf_id = adapter->vfs_allocated_count;
-
- /* attempt to add filter to vlvf array */
- igb_vlvf_set(adapter, vid, TRUE, pf_id);
-
- /* add the filter since PF can receive vlans w/o entry in vlvf */
- igb_vfta_set(adapter, vid, TRUE);
-#ifndef HAVE_NETDEV_VLAN_FEATURES
-
- /* Copy feature flags from netdev to the vlan netdev for this vid.
- * This allows things like TSO to bubble down to our vlan device.
- * There is no need to update netdev for vlan 0 (DCB), since it
- * wouldn't has v_netdev.
- */
- if (adapter->vlgrp) {
- struct vlan_group *vlgrp = adapter->vlgrp;
- struct net_device *v_netdev = vlan_group_get_device(vlgrp, vid);
- if (v_netdev) {
- v_netdev->features |= netdev->features;
- vlan_group_set_device(vlgrp, vid, v_netdev);
- }
- }
-#endif
-#ifndef HAVE_VLAN_RX_REGISTER
-
- set_bit(vid, adapter->active_vlans);
-#endif
-#ifdef HAVE_INT_NDO_VLAN_RX_ADD_VID
- return 0;
-#endif
-}
-
-#ifdef HAVE_VLAN_PROTOCOL
-static int igb_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
-#elif defined HAVE_INT_NDO_VLAN_RX_ADD_VID
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
-static int igb_vlan_rx_kill_vid(struct net_device *netdev,
- __always_unused __be16 proto, u16 vid)
-#else
-static int igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
-#endif
-#else
-static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
-#endif
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- int pf_id = adapter->vfs_allocated_count;
- s32 err;
-
-#ifdef HAVE_VLAN_RX_REGISTER
- igb_irq_disable(adapter);
-
- vlan_group_set_device(adapter->vlgrp, vid, NULL);
-
- if (!test_bit(__IGB_DOWN, &adapter->state))
- igb_irq_enable(adapter);
-
-#endif /* HAVE_VLAN_RX_REGISTER */
- /* remove vlan from VLVF table array */
- err = igb_vlvf_set(adapter, vid, FALSE, pf_id);
-
- /* if vid was not present in VLVF just remove it from table */
- if (err)
- igb_vfta_set(adapter, vid, FALSE);
-#ifndef HAVE_VLAN_RX_REGISTER
-
- clear_bit(vid, adapter->active_vlans);
-#endif
-#ifdef HAVE_INT_NDO_VLAN_RX_ADD_VID
- return 0;
-#endif
-}
-
-static void igb_restore_vlan(struct igb_adapter *adapter)
-{
-#ifdef HAVE_VLAN_RX_REGISTER
- igb_vlan_mode(adapter->netdev, adapter->vlgrp);
-
- if (adapter->vlgrp) {
- u16 vid;
- for (vid = 0; vid < VLAN_N_VID; vid++) {
- if (!vlan_group_get_device(adapter->vlgrp, vid))
- continue;
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
- igb_vlan_rx_add_vid(adapter->netdev,
- htons(ETH_P_8021Q), vid);
-#else
- igb_vlan_rx_add_vid(adapter->netdev, vid);
-#endif
- }
- }
-#else
- u16 vid;
-
- igb_vlan_mode(adapter->netdev, adapter->netdev->features);
-
- for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
- igb_vlan_rx_add_vid(adapter->netdev,
- htons(ETH_P_8021Q), vid);
-#else
- igb_vlan_rx_add_vid(adapter->netdev, vid);
-#endif
-#endif
-}
-
-int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
-{
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_mac_info *mac = &adapter->hw.mac;
-
- mac->autoneg = 0;
-
- /* SerDes device's does not support 10Mbps Full/duplex
- * and 100Mbps Half duplex
- */
- if (adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
- switch (spddplx) {
- case SPEED_10 + DUPLEX_HALF:
- case SPEED_10 + DUPLEX_FULL:
- case SPEED_100 + DUPLEX_HALF:
- dev_err(pci_dev_to_dev(pdev),
- "Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
- default:
- break;
- }
- }
-
- switch (spddplx) {
- case SPEED_10 + DUPLEX_HALF:
- mac->forced_speed_duplex = ADVERTISE_10_HALF;
- break;
- case SPEED_10 + DUPLEX_FULL:
- mac->forced_speed_duplex = ADVERTISE_10_FULL;
- break;
- case SPEED_100 + DUPLEX_HALF:
- mac->forced_speed_duplex = ADVERTISE_100_HALF;
- break;
- case SPEED_100 + DUPLEX_FULL:
- mac->forced_speed_duplex = ADVERTISE_100_FULL;
- break;
- case SPEED_1000 + DUPLEX_FULL:
- mac->autoneg = 1;
- adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL;
- break;
- case SPEED_1000 + DUPLEX_HALF: /* not supported */
- default:
- dev_err(pci_dev_to_dev(pdev), "Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
- }
-
- /* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
- adapter->hw.phy.mdix = AUTO_ALL_MODES;
-
- return 0;
-}
-
-static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake,
- bool runtime)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl, rctl, status;
- u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
-#ifdef CONFIG_PM
- int retval = 0;
-#endif
-
- netif_device_detach(netdev);
-
- status = E1000_READ_REG(hw, E1000_STATUS);
- if (status & E1000_STATUS_LU)
- wufc &= ~E1000_WUFC_LNKC;
-
- if (netif_running(netdev))
- __igb_close(netdev, true);
-
- igb_clear_interrupt_scheme(adapter);
-
-#ifdef CONFIG_PM
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-#endif
-
- if (wufc) {
- igb_setup_rctl(adapter);
- igb_set_rx_mode(netdev);
-
- /* turn on all-multi mode if wake on multicast is enabled */
- if (wufc & E1000_WUFC_MC) {
- rctl = E1000_READ_REG(hw, E1000_RCTL);
- rctl |= E1000_RCTL_MPE;
- E1000_WRITE_REG(hw, E1000_RCTL, rctl);
- }
-
- ctrl = E1000_READ_REG(hw, E1000_CTRL);
- /* phy power management enable */
- #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
- ctrl |= E1000_CTRL_ADVD3WUC;
- E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-
- /* Allow time for pending master requests to run */
- e1000_disable_pcie_master(hw);
-
- E1000_WRITE_REG(hw, E1000_WUC, E1000_WUC_PME_EN);
- E1000_WRITE_REG(hw, E1000_WUFC, wufc);
- } else {
- E1000_WRITE_REG(hw, E1000_WUC, 0);
- E1000_WRITE_REG(hw, E1000_WUFC, 0);
- }
-
- *enable_wake = wufc || adapter->en_mng_pt;
- if (!*enable_wake)
- igb_power_down_link(adapter);
- else
- igb_power_up_link(adapter);
-
- /* Release control of h/w to f/w. If f/w is AMT enabled, this
- * would have already happened in close and is redundant. */
- igb_release_hw_control(adapter);
-
- pci_disable_device(pdev);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-#ifdef HAVE_SYSTEM_SLEEP_PM_OPS
-static int igb_suspend(struct device *dev)
-#else
-static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
-#endif /* HAVE_SYSTEM_SLEEP_PM_OPS */
-{
-#ifdef HAVE_SYSTEM_SLEEP_PM_OPS
- struct pci_dev *pdev = to_pci_dev(dev);
-#endif /* HAVE_SYSTEM_SLEEP_PM_OPS */
- int retval;
- bool wake;
-
- retval = __igb_shutdown(pdev, &wake, 0);
- if (retval)
- return retval;
-
- if (wake) {
- pci_prepare_to_sleep(pdev);
- } else {
- pci_wake_from_d3(pdev, false);
- pci_set_power_state(pdev, PCI_D3hot);
- }
-
- return 0;
-}
-
-#ifdef HAVE_SYSTEM_SLEEP_PM_OPS
-static int igb_resume(struct device *dev)
-#else
-static int igb_resume(struct pci_dev *pdev)
-#endif /* HAVE_SYSTEM_SLEEP_PM_OPS */
-{
-#ifdef HAVE_SYSTEM_SLEEP_PM_OPS
- struct pci_dev *pdev = to_pci_dev(dev);
-#endif /* HAVE_SYSTEM_SLEEP_PM_OPS */
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 err;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_save_state(pdev);
-
- err = pci_enable_device_mem(pdev);
- if (err) {
- dev_err(pci_dev_to_dev(pdev),
- "igb: Cannot enable PCI device from suspend\n");
- return err;
- }
- pci_set_master(pdev);
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
-
- if (igb_init_interrupt_scheme(adapter, true)) {
- dev_err(pci_dev_to_dev(pdev), "Unable to allocate memory for queues\n");
- return -ENOMEM;
- }
-
- igb_reset(adapter);
-
- /* let the f/w know that the h/w is now under the control of the
- * driver. */
- igb_get_hw_control(adapter);
-
- E1000_WRITE_REG(hw, E1000_WUS, ~0);
-
- if (netdev->flags & IFF_UP) {
- rtnl_lock();
- err = __igb_open(netdev, true);
- rtnl_unlock();
- if (err)
- return err;
- }
-
- netif_device_attach(netdev);
-
- return 0;
-}
-
-#ifdef CONFIG_PM_RUNTIME
-#ifdef HAVE_SYSTEM_SLEEP_PM_OPS
-static int igb_runtime_idle(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- if (!igb_has_link(adapter))
- pm_schedule_suspend(dev, MSEC_PER_SEC * 5);
-
- return -EBUSY;
-}
-
-static int igb_runtime_suspend(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- int retval;
- bool wake;
-
- retval = __igb_shutdown(pdev, &wake, 1);
- if (retval)
- return retval;
-
- if (wake) {
- pci_prepare_to_sleep(pdev);
- } else {
- pci_wake_from_d3(pdev, false);
- pci_set_power_state(pdev, PCI_D3hot);
- }
-
- return 0;
-}
-
-static int igb_runtime_resume(struct device *dev)
-{
- return igb_resume(dev);
-}
-#endif /* HAVE_SYSTEM_SLEEP_PM_OPS */
-#endif /* CONFIG_PM_RUNTIME */
-#endif /* CONFIG_PM */
-
-#ifdef USE_REBOOT_NOTIFIER
-/* only want to do this for 2.4 kernels? */
-static int igb_notify_reboot(struct notifier_block *nb, unsigned long event,
- void *p)
-{
- struct pci_dev *pdev = NULL;
- bool wake;
-
- switch (event) {
- case SYS_DOWN:
- case SYS_HALT:
- case SYS_POWER_OFF:
- while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
- if (pci_dev_driver(pdev) == &igb_driver) {
- __igb_shutdown(pdev, &wake, 0);
- if (event == SYS_POWER_OFF) {
- pci_wake_from_d3(pdev, wake);
- pci_set_power_state(pdev, PCI_D3hot);
- }
- }
- }
- }
- return NOTIFY_DONE;
-}
-#else
-static void igb_shutdown(struct pci_dev *pdev)
-{
- bool wake = false;
-
- __igb_shutdown(pdev, &wake, 0);
-
- if (system_state == SYSTEM_POWER_OFF) {
- pci_wake_from_d3(pdev, wake);
- pci_set_power_state(pdev, PCI_D3hot);
- }
-}
-#endif /* USE_REBOOT_NOTIFIER */
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void igb_netpoll(struct net_device *netdev)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- struct igb_q_vector *q_vector;
- int i;
-
- for (i = 0; i < adapter->num_q_vectors; i++) {
- q_vector = adapter->q_vector[i];
- if (adapter->msix_entries)
- E1000_WRITE_REG(hw, E1000_EIMC, q_vector->eims_value);
- else
- igb_irq_disable(adapter);
- napi_schedule(&q_vector->napi);
- }
-}
-#endif /* CONFIG_NET_POLL_CONTROLLER */
-
-#ifdef HAVE_PCI_ERS
-#define E1000_DEV_ID_82576_VF 0x10CA
-/**
- * igb_io_error_detected - called when PCI error is detected
- * @pdev: Pointer to PCI device
- * @state: The current pci connection state
- *
- * This function is called after a PCI bus error affecting
- * this device has been detected.
- */
-static pci_ers_result_t igb_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct igb_adapter *adapter = netdev_priv(netdev);
-
-#ifdef CONFIG_PCI_IOV__UNUSED
- struct pci_dev *bdev, *vfdev;
- u32 dw0, dw1, dw2, dw3;
- int vf, pos;
- u16 req_id, pf_func;
-
- if (!(adapter->flags & IGB_FLAG_DETECT_BAD_DMA))
- goto skip_bad_vf_detection;
-
- bdev = pdev->bus->self;
- while (bdev && (pci_pcie_type(bdev) != PCI_EXP_TYPE_ROOT_PORT))
- bdev = bdev->bus->self;
-
- if (!bdev)
- goto skip_bad_vf_detection;
-
- pos = pci_find_ext_capability(bdev, PCI_EXT_CAP_ID_ERR);
- if (!pos)
- goto skip_bad_vf_detection;
-
- pci_read_config_dword(bdev, pos + PCI_ERR_HEADER_LOG, &dw0);
- pci_read_config_dword(bdev, pos + PCI_ERR_HEADER_LOG + 4, &dw1);
- pci_read_config_dword(bdev, pos + PCI_ERR_HEADER_LOG + 8, &dw2);
- pci_read_config_dword(bdev, pos + PCI_ERR_HEADER_LOG + 12, &dw3);
-
- req_id = dw1 >> 16;
- /* On the 82576 if bit 7 of the requestor ID is set then it's a VF */
- if (!(req_id & 0x0080))
- goto skip_bad_vf_detection;
-
- pf_func = req_id & 0x01;
- if ((pf_func & 1) == (pdev->devfn & 1)) {
-
- vf = (req_id & 0x7F) >> 1;
- dev_err(pci_dev_to_dev(pdev),
- "VF %d has caused a PCIe error\n", vf);
- dev_err(pci_dev_to_dev(pdev),
- "TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: "
- "%8.8x\tdw3: %8.8x\n",
- dw0, dw1, dw2, dw3);
-
- /* Find the pci device of the offending VF */
- vfdev = pci_get_device(PCI_VENDOR_ID_INTEL,
- E1000_DEV_ID_82576_VF, NULL);
- while (vfdev) {
- if (vfdev->devfn == (req_id & 0xFF))
- break;
- vfdev = pci_get_device(PCI_VENDOR_ID_INTEL,
- E1000_DEV_ID_82576_VF, vfdev);
- }
- /*
- * There's a slim chance the VF could have been hot plugged,
- * so if it is no longer present we don't need to issue the
- * VFLR. Just clean up the AER in that case.
- */
- if (vfdev) {
- dev_err(pci_dev_to_dev(pdev),
- "Issuing VFLR to VF %d\n", vf);
- pci_write_config_dword(vfdev, 0xA8, 0x00008000);
- }
-
- pci_cleanup_aer_uncorrect_error_status(pdev);
- }
-
- /*
- * Even though the error may have occurred on the other port
- * we still need to increment the vf error reference count for
- * both ports because the I/O resume function will be called
- * for both of them.
- */
- adapter->vferr_refcount++;
-
- return PCI_ERS_RESULT_RECOVERED;
-
-skip_bad_vf_detection:
-#endif /* CONFIG_PCI_IOV */
-
- netif_device_detach(netdev);
-
- if (state == pci_channel_io_perm_failure)
- return PCI_ERS_RESULT_DISCONNECT;
-
- if (netif_running(netdev))
- igb_down(adapter);
- pci_disable_device(pdev);
-
- /* Request a slot slot reset. */
- return PCI_ERS_RESULT_NEED_RESET;
-}
-
-/**
- * igb_io_slot_reset - called after the pci bus has been reset.
- * @pdev: Pointer to PCI device
- *
- * Restart the card from scratch, as if from a cold-boot. Implementation
- * resembles the first-half of the igb_resume routine.
- */
-static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- pci_ers_result_t result;
-
- if (pci_enable_device_mem(pdev)) {
- dev_err(pci_dev_to_dev(pdev),
- "Cannot re-enable PCI device after reset.\n");
- result = PCI_ERS_RESULT_DISCONNECT;
- } else {
- pci_set_master(pdev);
- pci_restore_state(pdev);
- pci_save_state(pdev);
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
-
- schedule_work(&adapter->reset_task);
- E1000_WRITE_REG(hw, E1000_WUS, ~0);
- result = PCI_ERS_RESULT_RECOVERED;
- }
-
- pci_cleanup_aer_uncorrect_error_status(pdev);
-
- return result;
-}
-
-/**
- * igb_io_resume - called when traffic can start flowing again.
- * @pdev: Pointer to PCI device
- *
- * This callback is called when the error recovery driver tells us that
- * its OK to resume normal operation. Implementation resembles the
- * second-half of the igb_resume routine.
- */
-static void igb_io_resume(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct igb_adapter *adapter = netdev_priv(netdev);
-
- if (adapter->vferr_refcount) {
- dev_info(pci_dev_to_dev(pdev), "Resuming after VF err\n");
- adapter->vferr_refcount--;
- return;
- }
-
- if (netif_running(netdev)) {
- if (igb_up(adapter)) {
- dev_err(pci_dev_to_dev(pdev), "igb_up failed after reset\n");
- return;
- }
- }
-
- netif_device_attach(netdev);
-
- /* let the f/w know that the h/w is now under the control of the
- * driver. */
- igb_get_hw_control(adapter);
-}
-
-#endif /* HAVE_PCI_ERS */
-
-int igb_add_mac_filter(struct igb_adapter *adapter, u8 *addr, u16 queue)
-{
- struct e1000_hw *hw = &adapter->hw;
- int i;
-
- if (is_zero_ether_addr(addr))
- return 0;
-
- for (i = 0; i < hw->mac.rar_entry_count; i++) {
- if (adapter->mac_table[i].state & IGB_MAC_STATE_IN_USE)
- continue;
- adapter->mac_table[i].state = (IGB_MAC_STATE_MODIFIED |
- IGB_MAC_STATE_IN_USE);
- memcpy(adapter->mac_table[i].addr, addr, ETH_ALEN);
- adapter->mac_table[i].queue = queue;
- igb_sync_mac_table(adapter);
- return 0;
- }
- return -ENOMEM;
-}
-int igb_del_mac_filter(struct igb_adapter *adapter, u8* addr, u16 queue)
-{
- /* search table for addr, if found, set to 0 and sync */
- int i;
- struct e1000_hw *hw = &adapter->hw;
-
- if (is_zero_ether_addr(addr))
- return 0;
- for (i = 0; i < hw->mac.rar_entry_count; i++) {
- if (ether_addr_equal(addr, adapter->mac_table[i].addr) &&
- adapter->mac_table[i].queue == queue) {
- adapter->mac_table[i].state = IGB_MAC_STATE_MODIFIED;
- memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
- adapter->mac_table[i].queue = 0;
- igb_sync_mac_table(adapter);
- return 0;
- }
- }
- return -ENOMEM;
-}
-static int igb_set_vf_mac(struct igb_adapter *adapter,
- int vf, unsigned char *mac_addr)
-{
- igb_del_mac_filter(adapter, adapter->vf_data[vf].vf_mac_addresses, vf);
- memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
-
- igb_add_mac_filter(adapter, mac_addr, vf);
-
- return 0;
-}
-
-#ifdef IFLA_VF_MAX
-static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- if (!is_valid_ether_addr(mac) || (vf >= adapter->vfs_allocated_count))
- return -EINVAL;
- adapter->vf_data[vf].flags |= IGB_VF_FLAG_PF_SET_MAC;
- dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n", mac, vf);
- dev_info(&adapter->pdev->dev, "Reload the VF driver to make this"
- " change effective.\n");
- if (test_bit(__IGB_DOWN, &adapter->state)) {
- dev_warn(&adapter->pdev->dev, "The VF MAC address has been set,"
- " but the PF device is not up.\n");
- dev_warn(&adapter->pdev->dev, "Bring the PF device up before"
- " attempting to use the VF device.\n");
- }
- return igb_set_vf_mac(adapter, vf, mac);
-}
-
-static int igb_link_mbps(int internal_link_speed)
-{
- switch (internal_link_speed) {
- case SPEED_100:
- return 100;
- case SPEED_1000:
- return 1000;
- case SPEED_2500:
- return 2500;
- default:
- return 0;
- }
-}
-
-static void igb_set_vf_rate_limit(struct e1000_hw *hw, int vf, int tx_rate,
- int link_speed)
-{
- int rf_dec, rf_int;
- u32 bcnrc_val;
-
- if (tx_rate != 0) {
- /* Calculate the rate factor values to set */
- rf_int = link_speed / tx_rate;
- rf_dec = (link_speed - (rf_int * tx_rate));
- rf_dec = (rf_dec * (1<<E1000_RTTBCNRC_RF_INT_SHIFT)) / tx_rate;
-
- bcnrc_val = E1000_RTTBCNRC_RS_ENA;
- bcnrc_val |= ((rf_int<<E1000_RTTBCNRC_RF_INT_SHIFT) &
- E1000_RTTBCNRC_RF_INT_MASK);
- bcnrc_val |= (rf_dec & E1000_RTTBCNRC_RF_DEC_MASK);
- } else {
- bcnrc_val = 0;
- }
-
- E1000_WRITE_REG(hw, E1000_RTTDQSEL, vf); /* vf X uses queue X */
- /*
- * Set global transmit compensation time to the MMW_SIZE in RTTBCNRM
- * register. MMW_SIZE=0x014 if 9728-byte jumbo is supported.
- */
- E1000_WRITE_REG(hw, E1000_RTTBCNRM(0), 0x14);
- E1000_WRITE_REG(hw, E1000_RTTBCNRC, bcnrc_val);
-}
-
-static void igb_check_vf_rate_limit(struct igb_adapter *adapter)
-{
- int actual_link_speed, i;
- bool reset_rate = false;
-
- /* VF TX rate limit was not set */
- if ((adapter->vf_rate_link_speed == 0) ||
- (adapter->hw.mac.type != e1000_82576))
- return;
-
- actual_link_speed = igb_link_mbps(adapter->link_speed);
- if (actual_link_speed != adapter->vf_rate_link_speed) {
- reset_rate = true;
- adapter->vf_rate_link_speed = 0;
- dev_info(&adapter->pdev->dev,
- "Link speed has been changed. VF Transmit rate is disabled\n");
- }
-
- for (i = 0; i < adapter->vfs_allocated_count; i++) {
- if (reset_rate)
- adapter->vf_data[i].tx_rate = 0;
-
- igb_set_vf_rate_limit(&adapter->hw, i,
- adapter->vf_data[i].tx_rate, actual_link_speed);
- }
-}
-
-#ifdef HAVE_VF_MIN_MAX_TXRATE
-static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
- int tx_rate)
-#else /* HAVE_VF_MIN_MAX_TXRATE */
-static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
-#endif /* HAVE_VF_MIN_MAX_TXRATE */
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- int actual_link_speed;
-
- if (hw->mac.type != e1000_82576)
- return -EOPNOTSUPP;
-
-#ifdef HAVE_VF_MIN_MAX_TXRATE
- if (min_tx_rate)
- return -EINVAL;
-#endif /* HAVE_VF_MIN_MAX_TXRATE */
-
- actual_link_speed = igb_link_mbps(adapter->link_speed);
- if ((vf >= adapter->vfs_allocated_count) ||
- (!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) ||
- (tx_rate < 0) || (tx_rate > actual_link_speed))
- return -EINVAL;
-
- adapter->vf_rate_link_speed = actual_link_speed;
- adapter->vf_data[vf].tx_rate = (u16)tx_rate;
- igb_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed);
-
- return 0;
-}
-
-static int igb_ndo_get_vf_config(struct net_device *netdev,
- int vf, struct ifla_vf_info *ivi)
-{
- struct igb_adapter *adapter = netdev_priv(netdev);
- if (vf >= adapter->vfs_allocated_count)
- return -EINVAL;
- ivi->vf = vf;
- memcpy(&ivi->mac, adapter->vf_data[vf].vf_mac_addresses, ETH_ALEN);
-#ifdef HAVE_VF_MIN_MAX_TXRATE
- ivi->max_tx_rate = adapter->vf_data[vf].tx_rate;
- ivi->min_tx_rate = 0;
-#else /* HAVE_VF_MIN_MAX_TXRATE */
- ivi->tx_rate = adapter->vf_data[vf].tx_rate;
-#endif /* HAVE_VF_MIN_MAX_TXRATE */
- ivi->vlan = adapter->vf_data[vf].pf_vlan;
- ivi->qos = adapter->vf_data[vf].pf_qos;
-#ifdef HAVE_VF_SPOOFCHK_CONFIGURE
- ivi->spoofchk = adapter->vf_data[vf].spoofchk_enabled;
-#endif
- return 0;
-}
-#endif
-static void igb_vmm_control(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- int count;
- u32 reg;
-
- switch (hw->mac.type) {
- case e1000_82575:
- default:
- /* replication is not supported for 82575 */
- return;
- case e1000_82576:
- /* notify HW that the MAC is adding vlan tags */
- reg = E1000_READ_REG(hw, E1000_DTXCTL);
- reg |= (E1000_DTXCTL_VLAN_ADDED |
- E1000_DTXCTL_SPOOF_INT);
- E1000_WRITE_REG(hw, E1000_DTXCTL, reg);
- case e1000_82580:
- /* enable replication vlan tag stripping */
- reg = E1000_READ_REG(hw, E1000_RPLOLR);
- reg |= E1000_RPLOLR_STRVLAN;
- E1000_WRITE_REG(hw, E1000_RPLOLR, reg);
- case e1000_i350:
- case e1000_i354:
- /* none of the above registers are supported by i350 */
- break;
- }
-
- /* Enable Malicious Driver Detection */
- if ((adapter->vfs_allocated_count) &&
- (adapter->mdd)) {
- if (hw->mac.type == e1000_i350)
- igb_enable_mdd(adapter);
- }
-
- /* enable replication and loopback support */
- count = adapter->vfs_allocated_count || adapter->vmdq_pools;
- if (adapter->flags & IGB_FLAG_LOOPBACK_ENABLE && count)
- e1000_vmdq_set_loopback_pf(hw, 1);
- e1000_vmdq_set_anti_spoofing_pf(hw,
- adapter->vfs_allocated_count || adapter->vmdq_pools,
- adapter->vfs_allocated_count);
- e1000_vmdq_set_replication_pf(hw, adapter->vfs_allocated_count ||
- adapter->vmdq_pools);
-}
-
-static void igb_init_fw(struct igb_adapter *adapter)
-{
- struct e1000_fw_drv_info fw_cmd;
- struct e1000_hw *hw = &adapter->hw;
- int i;
- u16 mask;
-
- if (hw->mac.type == e1000_i210)
- mask = E1000_SWFW_EEP_SM;
- else
- mask = E1000_SWFW_PHY0_SM;
- /* i211 parts do not support this feature */
- if (hw->mac.type == e1000_i211)
- hw->mac.arc_subsystem_valid = false;
-
- if (!hw->mac.ops.acquire_swfw_sync(hw, mask)) {
- for (i = 0; i <= FW_MAX_RETRIES; i++) {
- E1000_WRITE_REG(hw, E1000_FWSTS, E1000_FWSTS_FWRI);
- fw_cmd.hdr.cmd = FW_CMD_DRV_INFO;
- fw_cmd.hdr.buf_len = FW_CMD_DRV_INFO_LEN;
- fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CMD_RESERVED;
- fw_cmd.port_num = hw->bus.func;
- fw_cmd.drv_version = FW_FAMILY_DRV_VER;
- fw_cmd.hdr.checksum = 0;
- fw_cmd.hdr.checksum = e1000_calculate_checksum((u8 *)&fw_cmd,
- (FW_HDR_LEN +
- fw_cmd.hdr.buf_len));
- e1000_host_interface_command(hw, (u8*)&fw_cmd,
- sizeof(fw_cmd));
- if (fw_cmd.hdr.cmd_or_resp.ret_status == FW_STATUS_SUCCESS)
- break;
- }
- } else
- dev_warn(pci_dev_to_dev(adapter->pdev),
- "Unable to get semaphore, firmware init failed.\n");
- hw->mac.ops.release_swfw_sync(hw, mask);
-}
-
-static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 dmac_thr;
- u16 hwm;
- u32 status;
-
- if (hw->mac.type == e1000_i211)
- return;
-
- if (hw->mac.type > e1000_82580) {
- if (adapter->dmac != IGB_DMAC_DISABLE) {
- u32 reg;
-
- /* force threshold to 0. */
- E1000_WRITE_REG(hw, E1000_DMCTXTH, 0);
-
- /*
- * DMA Coalescing high water mark needs to be greater
- * than the Rx threshold. Set hwm to PBA - max frame
- * size in 16B units, capping it at PBA - 6KB.
- */
- hwm = 64 * pba - adapter->max_frame_size / 16;
- if (hwm < 64 * (pba - 6))
- hwm = 64 * (pba - 6);
- reg = E1000_READ_REG(hw, E1000_FCRTC);
- reg &= ~E1000_FCRTC_RTH_COAL_MASK;
- reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT)
- & E1000_FCRTC_RTH_COAL_MASK);
- E1000_WRITE_REG(hw, E1000_FCRTC, reg);
-
- /*
- * Set the DMA Coalescing Rx threshold to PBA - 2 * max
- * frame size, capping it at PBA - 10KB.
- */
- dmac_thr = pba - adapter->max_frame_size / 512;
- if (dmac_thr < pba - 10)
- dmac_thr = pba - 10;
- reg = E1000_READ_REG(hw, E1000_DMACR);
- reg &= ~E1000_DMACR_DMACTHR_MASK;
- reg |= ((dmac_thr << E1000_DMACR_DMACTHR_SHIFT)
- & E1000_DMACR_DMACTHR_MASK);
-
- /* transition to L0x or L1 if available..*/
- reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK);
-
- /* Check if status is 2.5Gb backplane connection
- * before configuration of watchdog timer, which is
- * in msec values in 12.8usec intervals
- * watchdog timer= msec values in 32usec intervals
- * for non 2.5Gb connection
- */
- if (hw->mac.type == e1000_i354) {
- status = E1000_READ_REG(hw, E1000_STATUS);
- if ((status & E1000_STATUS_2P5_SKU) &&
- (!(status & E1000_STATUS_2P5_SKU_OVER)))
- reg |= ((adapter->dmac * 5) >> 6);
- else
- reg |= ((adapter->dmac) >> 5);
- } else {
- reg |= ((adapter->dmac) >> 5);
- }
-
- /*
- * Disable BMC-to-OS Watchdog enable
- * on devices that support OS-to-BMC
- */
- if (hw->mac.type != e1000_i354)
- reg &= ~E1000_DMACR_DC_BMC2OSW_EN;
- E1000_WRITE_REG(hw, E1000_DMACR, reg);
-
- /* no lower threshold to disable coalescing(smart fifb)-UTRESH=0*/
- E1000_WRITE_REG(hw, E1000_DMCRTRH, 0);
-
- /* This sets the time to wait before requesting
- * transition to low power state to number of usecs
- * needed to receive 1 512 byte frame at gigabit
- * line rate. On i350 device, time to make transition
- * to Lx state is delayed by 4 usec with flush disable
- * bit set to avoid losing mailbox interrupts
- */
- reg = E1000_READ_REG(hw, E1000_DMCTLX);
- if (hw->mac.type == e1000_i350)
- reg |= IGB_DMCTLX_DCFLUSH_DIS;
-
- /* in 2.5Gb connection, TTLX unit is 0.4 usec
- * which is 0x4*2 = 0xA. But delay is still 4 usec
- */
- if (hw->mac.type == e1000_i354) {
- status = E1000_READ_REG(hw, E1000_STATUS);
- if ((status & E1000_STATUS_2P5_SKU) &&
- (!(status & E1000_STATUS_2P5_SKU_OVER)))
- reg |= 0xA;
- else
- reg |= 0x4;
- } else {
- reg |= 0x4;
- }
- E1000_WRITE_REG(hw, E1000_DMCTLX, reg);
-
- /* free space in tx packet buffer to wake from DMA coal */
- E1000_WRITE_REG(hw, E1000_DMCTXTH, (IGB_MIN_TXPBSIZE -
- (IGB_TX_BUF_4096 + adapter->max_frame_size)) >> 6);
-
- /* make low power state decision controlled by DMA coal */
- reg = E1000_READ_REG(hw, E1000_PCIEMISC);
- reg &= ~E1000_PCIEMISC_LX_DECISION;
- E1000_WRITE_REG(hw, E1000_PCIEMISC, reg);
- } /* endif adapter->dmac is not disabled */
- } else if (hw->mac.type == e1000_82580) {
- u32 reg = E1000_READ_REG(hw, E1000_PCIEMISC);
- E1000_WRITE_REG(hw, E1000_PCIEMISC,
- reg & ~E1000_PCIEMISC_LX_DECISION);
- E1000_WRITE_REG(hw, E1000_DMACR, 0);
- }
-}
-
-#ifdef HAVE_I2C_SUPPORT
-/* igb_read_i2c_byte - Reads 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to read
- * @dev_addr: device address
- * @data: value read
- *
- * Performs byte read operation over I2C interface at
- * a specified device address.
- */
-s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data)
-{
- struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw);
- struct i2c_client *this_client = adapter->i2c_client;
- s32 status;
- u16 swfw_mask = 0;
-
- if (!this_client)
- return E1000_ERR_I2C;
-
- swfw_mask = E1000_SWFW_PHY0_SM;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)
- != E1000_SUCCESS)
- return E1000_ERR_SWFW_SYNC;
-
- status = i2c_smbus_read_byte_data(this_client, byte_offset);
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-
- if (status < 0)
- return E1000_ERR_I2C;
- else {
- *data = status;
- return E1000_SUCCESS;
- }
-}
-
-/* igb_write_i2c_byte - Writes 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to write
- * @dev_addr: device address
- * @data: value to write
- *
- * Performs byte write operation over I2C interface at
- * a specified device address.
- */
-s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data)
-{
- struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw);
- struct i2c_client *this_client = adapter->i2c_client;
- s32 status;
- u16 swfw_mask = E1000_SWFW_PHY0_SM;
-
- if (!this_client)
- return E1000_ERR_I2C;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS)
- return E1000_ERR_SWFW_SYNC;
- status = i2c_smbus_write_byte_data(this_client, byte_offset, data);
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-
- if (status)
- return E1000_ERR_I2C;
- else
- return E1000_SUCCESS;
-}
-#endif /* HAVE_I2C_SUPPORT */
-/* igb_main.c */
-
-
-/**
- * igb_probe - Device Initialization Routine
- * @pdev: PCI device information struct
- * @ent: entry in igb_pci_tbl
- *
- * Returns 0 on success, negative on failure
- *
- * igb_probe initializes an adapter identified by a pci_dev structure.
- * The OS initialization, configuring of the adapter private structure,
- * and a hardware reset occur.
- **/
-int igb_kni_probe(struct pci_dev *pdev,
- struct net_device **lad_dev)
-{
- struct net_device *netdev;
- struct igb_adapter *adapter;
- struct e1000_hw *hw;
- u16 eeprom_data = 0;
- u8 pba_str[E1000_PBANUM_LENGTH];
- s32 ret_val;
- static int global_quad_port_a; /* global quad port a indication */
- int i, err, pci_using_dac = 0;
- static int cards_found;
-
- err = pci_enable_device_mem(pdev);
- if (err)
- return err;
-
-#ifdef NO_KNI
- pci_using_dac = 0;
- err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64));
- if (!err) {
- err = dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64));
- if (!err)
- pci_using_dac = 1;
- } else {
- err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32));
- if (err) {
- err = dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32));
- if (err) {
- IGB_ERR("No usable DMA configuration, "
- "aborting\n");
- goto err_dma;
- }
- }
- }
-
-#ifndef HAVE_ASPM_QUIRKS
- /* 82575 requires that the pci-e link partner disable the L0s state */
- switch (pdev->device) {
- case E1000_DEV_ID_82575EB_COPPER:
- case E1000_DEV_ID_82575EB_FIBER_SERDES:
- case E1000_DEV_ID_82575GB_QUAD_COPPER:
- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
- default:
- break;
- }
-
-#endif /* HAVE_ASPM_QUIRKS */
- err = pci_request_selected_regions(pdev,
- pci_select_bars(pdev,
- IORESOURCE_MEM),
- igb_driver_name);
- if (err)
- goto err_pci_reg;
-
- pci_enable_pcie_error_reporting(pdev);
-
- pci_set_master(pdev);
-
- err = -ENOMEM;
-#endif /* NO_KNI */
-#ifdef HAVE_TX_MQ
- netdev = alloc_etherdev_mq(sizeof(struct igb_adapter),
- IGB_MAX_TX_QUEUES);
-#else
- netdev = alloc_etherdev(sizeof(struct igb_adapter));
-#endif /* HAVE_TX_MQ */
- if (!netdev)
- goto err_alloc_etherdev;
-
- SET_MODULE_OWNER(netdev);
- SET_NETDEV_DEV(netdev, &pdev->dev);
-
- //pci_set_drvdata(pdev, netdev);
- adapter = netdev_priv(netdev);
- adapter->netdev = netdev;
- adapter->pdev = pdev;
- hw = &adapter->hw;
- hw->back = adapter;
- adapter->port_num = hw->bus.func;
- adapter->msg_enable = (1 << debug) - 1;
-
-#ifdef HAVE_PCI_ERS
- err = pci_save_state(pdev);
- if (err)
- goto err_ioremap;
-#endif
- err = -EIO;
- hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- if (!hw->hw_addr)
- goto err_ioremap;
-
-#ifdef HAVE_NET_DEVICE_OPS
- netdev->netdev_ops = &igb_netdev_ops;
-#else /* HAVE_NET_DEVICE_OPS */
- netdev->open = &igb_open;
- netdev->stop = &igb_close;
- netdev->get_stats = &igb_get_stats;
-#ifdef HAVE_SET_RX_MODE
- netdev->set_rx_mode = &igb_set_rx_mode;
-#endif
- netdev->set_multicast_list = &igb_set_rx_mode;
- netdev->set_mac_address = &igb_set_mac;
- netdev->change_mtu = &igb_change_mtu;
- netdev->do_ioctl = &igb_ioctl;
-#ifdef HAVE_TX_TIMEOUT
- netdev->tx_timeout = &igb_tx_timeout;
-#endif
- netdev->vlan_rx_register = igb_vlan_mode;
- netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = igb_netpoll;
-#endif
- netdev->hard_start_xmit = &igb_xmit_frame;
-#endif /* HAVE_NET_DEVICE_OPS */
- igb_set_ethtool_ops(netdev);
-#ifdef HAVE_TX_TIMEOUT
- netdev->watchdog_timeo = 5 * HZ;
-#endif
-
- strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
-
- adapter->bd_number = cards_found;
-
- /* setup the private structure */
- err = igb_sw_init(adapter);
- if (err)
- goto err_sw_init;
-
- e1000_get_bus_info(hw);
-
- hw->phy.autoneg_wait_to_complete = FALSE;
- hw->mac.adaptive_ifs = FALSE;
-
- /* Copper options */
- if (hw->phy.media_type == e1000_media_type_copper) {
- hw->phy.mdix = AUTO_ALL_MODES;
- hw->phy.disable_polarity_correction = FALSE;
- hw->phy.ms_type = e1000_ms_hw_default;
- }
-
- if (e1000_check_reset_block(hw))
- dev_info(pci_dev_to_dev(pdev),
- "PHY reset is blocked due to SOL/IDER session.\n");
-
- /*
- * features is initialized to 0 in allocation, it might have bits
- * set by igb_sw_init so we should use an or instead of an
- * assignment.
- */
- netdev->features |= NETIF_F_SG |
- NETIF_F_IP_CSUM |
-#ifdef NETIF_F_IPV6_CSUM
- NETIF_F_IPV6_CSUM |
-#endif
-#ifdef NETIF_F_TSO
- NETIF_F_TSO |
-#ifdef NETIF_F_TSO6
- NETIF_F_TSO6 |
-#endif
-#endif /* NETIF_F_TSO */
-#ifdef NETIF_F_RXHASH
- NETIF_F_RXHASH |
-#endif
- NETIF_F_RXCSUM |
-#ifdef NETIF_F_HW_VLAN_CTAG_RX
- NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HW_VLAN_CTAG_TX;
-#else
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_TX;
-#endif
-
- if (hw->mac.type >= e1000_82576)
- netdev->features |= NETIF_F_SCTP_CSUM;
-
-#ifdef HAVE_NDO_SET_FEATURES
- /* copy netdev features into list of user selectable features */
- netdev->hw_features |= netdev->features;
-#ifndef IGB_NO_LRO
-
- /* give us the option of enabling LRO later */
- netdev->hw_features |= NETIF_F_LRO;
-#endif
-#else
-#ifdef NETIF_F_GRO
-
- /* this is only needed on kernels prior to 2.6.39 */
- netdev->features |= NETIF_F_GRO;
-#endif
-#endif
-
- /* set this bit last since it cannot be part of hw_features */
-#ifdef NETIF_F_HW_VLAN_CTAG_FILTER
- netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
-#else
- netdev->features |= NETIF_F_HW_VLAN_FILTER;
-#endif
-
-#ifdef HAVE_NETDEV_VLAN_FEATURES
- netdev->vlan_features |= NETIF_F_TSO |
- NETIF_F_TSO6 |
- NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM |
- NETIF_F_SG;
-
-#endif
- if (pci_using_dac)
- netdev->features |= NETIF_F_HIGHDMA;
-
-#ifdef NO_KNI
- adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
-#ifdef DEBUG
- if (adapter->dmac != IGB_DMAC_DISABLE)
- printk("%s: DMA Coalescing is enabled..\n", netdev->name);
-#endif
-
- /* before reading the NVM, reset the controller to put the device in a
- * known good starting state */
- e1000_reset_hw(hw);
-#endif /* NO_KNI */
-
- /* make sure the NVM is good */
- if (e1000_validate_nvm_checksum(hw) < 0) {
- dev_err(pci_dev_to_dev(pdev), "The NVM Checksum Is Not"
- " Valid\n");
- err = -EIO;
- goto err_eeprom;
- }
-
- /* copy the MAC address out of the NVM */
- if (e1000_read_mac_addr(hw))
- dev_err(pci_dev_to_dev(pdev), "NVM Read Error\n");
- memcpy(netdev->dev_addr, hw->mac.addr, netdev->addr_len);
-#ifdef ETHTOOL_GPERMADDR
- memcpy(netdev->perm_addr, hw->mac.addr, netdev->addr_len);
-
- if (!is_valid_ether_addr(netdev->perm_addr)) {
-#else
- if (!is_valid_ether_addr(netdev->dev_addr)) {
-#endif
- dev_err(pci_dev_to_dev(pdev), "Invalid MAC Address\n");
- err = -EIO;
- goto err_eeprom;
- }
-
- memcpy(&adapter->mac_table[0].addr, hw->mac.addr, netdev->addr_len);
- adapter->mac_table[0].queue = adapter->vfs_allocated_count;
- adapter->mac_table[0].state = (IGB_MAC_STATE_DEFAULT | IGB_MAC_STATE_IN_USE);
- igb_rar_set(adapter, 0);
-
- /* get firmware version for ethtool -i */
- igb_set_fw_version(adapter);
-
- /* Check if Media Autosense is enabled */
- if (hw->mac.type == e1000_82580)
- igb_init_mas(adapter);
-
-#ifdef NO_KNI
-#ifdef HAVE_TIMER_SETUP
- timer_setup(&adapter->watchdog_timer, &igb_watchdog, 0);
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- timer_setup(&adapter->dma_err_timer, &igb_dma_err_timer, 0);
- timer_setup(&adapter->phy_info_timer, &igb_update_phy_info, 0);
-#else
- setup_timer(&adapter->watchdog_timer, &igb_watchdog,
- (unsigned long) adapter);
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- setup_timer(&adapter->dma_err_timer, &igb_dma_err_timer,
- (unsigned long) adapter);
- setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
- (unsigned long) adapter);
-#endif
-
- INIT_WORK(&adapter->reset_task, igb_reset_task);
- INIT_WORK(&adapter->watchdog_task, igb_watchdog_task);
- if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
- INIT_WORK(&adapter->dma_err_task, igb_dma_err_task);
-#endif
-
- /* Initialize link properties that are user-changeable */
- adapter->fc_autoneg = true;
- hw->mac.autoneg = true;
- hw->phy.autoneg_advertised = 0x2f;
-
- hw->fc.requested_mode = e1000_fc_default;
- hw->fc.current_mode = e1000_fc_default;
-
- e1000_validate_mdi_setting(hw);
-
- /* By default, support wake on port A */
- if (hw->bus.func == 0)
- adapter->flags |= IGB_FLAG_WOL_SUPPORTED;
-
- /* Check the NVM for wake support for non-port A ports */
- if (hw->mac.type >= e1000_82580)
- hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
- NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
- &eeprom_data);
- else if (hw->bus.func == 1)
- e1000_read_nvm(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
-
- if (eeprom_data & IGB_EEPROM_APME)
- adapter->flags |= IGB_FLAG_WOL_SUPPORTED;
-
- /* now that we have the eeprom settings, apply the special cases where
- * the eeprom may be wrong or the board simply won't support wake on
- * lan on a particular port */
- switch (pdev->device) {
- case E1000_DEV_ID_82575GB_QUAD_COPPER:
- adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
- break;
- case E1000_DEV_ID_82575EB_FIBER_SERDES:
- case E1000_DEV_ID_82576_FIBER:
- case E1000_DEV_ID_82576_SERDES:
- /* Wake events only supported on port A for dual fiber
- * regardless of eeprom setting */
- if (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_FUNC_1)
- adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
- break;
- case E1000_DEV_ID_82576_QUAD_COPPER:
- case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
- /* if quad port adapter, disable WoL on all but port A */
- if (global_quad_port_a != 0)
- adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
- else
- adapter->flags |= IGB_FLAG_QUAD_PORT_A;
- /* Reset for multiple quad port adapters */
- if (++global_quad_port_a == 4)
- global_quad_port_a = 0;
- break;
- default:
- /* If the device can't wake, don't set software support */
- if (!device_can_wakeup(&adapter->pdev->dev))
- adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
- break;
- }
-
- /* initialize the wol settings based on the eeprom settings */
- if (adapter->flags & IGB_FLAG_WOL_SUPPORTED)
- adapter->wol |= E1000_WUFC_MAG;
-
- /* Some vendors want WoL disabled by default, but still supported */
- if ((hw->mac.type == e1000_i350) &&
- (pdev->subsystem_vendor == PCI_VENDOR_ID_HP)) {
- adapter->flags |= IGB_FLAG_WOL_SUPPORTED;
- adapter->wol = 0;
- }
-
-#ifdef NO_KNI
- device_set_wakeup_enable(pci_dev_to_dev(adapter->pdev),
- adapter->flags & IGB_FLAG_WOL_SUPPORTED);
-
- /* reset the hardware with the new settings */
- igb_reset(adapter);
- adapter->devrc = 0;
-
-#ifdef HAVE_I2C_SUPPORT
- /* Init the I2C interface */
- err = igb_init_i2c(adapter);
- if (err) {
- dev_err(&pdev->dev, "failed to init i2c interface\n");
- goto err_eeprom;
- }
-#endif /* HAVE_I2C_SUPPORT */
-
- /* let the f/w know that the h/w is now under the control of the
- * driver. */
- igb_get_hw_control(adapter);
-
- strncpy(netdev->name, "eth%d", IFNAMSIZ);
- err = register_netdev(netdev);
- if (err)
- goto err_register;
-
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- err = igb_init_vmdq_netdevs(adapter);
- if (err)
- goto err_register;
-#endif
- /* carrier off reporting is important to ethtool even BEFORE open */
- netif_carrier_off(netdev);
-
-#ifdef IGB_DCA
- if (dca_add_requester(&pdev->dev) == E1000_SUCCESS) {
- adapter->flags |= IGB_FLAG_DCA_ENABLED;
- dev_info(pci_dev_to_dev(pdev), "DCA enabled\n");
- igb_setup_dca(adapter);
- }
-
-#endif
-#ifdef HAVE_PTP_1588_CLOCK
- /* do hw tstamp init after resetting */
- igb_ptp_init(adapter);
-#endif /* HAVE_PTP_1588_CLOCK */
-
-#endif /* NO_KNI */
- dev_info(pci_dev_to_dev(pdev), "Intel(R) Gigabit Ethernet Network Connection\n");
- /* print bus type/speed/width info */
- dev_info(pci_dev_to_dev(pdev), "%s: (PCIe:%s:%s) ",
- netdev->name,
- ((hw->bus.speed == e1000_bus_speed_2500) ? "2.5GT/s" :
- (hw->bus.speed == e1000_bus_speed_5000) ? "5.0GT/s" :
- (hw->mac.type == e1000_i354) ? "integrated" :
- "unknown"),
- ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
- (hw->bus.width == e1000_bus_width_pcie_x2) ? "Width x2" :
- (hw->bus.width == e1000_bus_width_pcie_x1) ? "Width x1" :
- (hw->mac.type == e1000_i354) ? "integrated" :
- "unknown"));
- dev_info(pci_dev_to_dev(pdev), "%s: MAC: ", netdev->name);
- for (i = 0; i < 6; i++)
- printk("%2.2x%c", netdev->dev_addr[i], i == 5 ? '\n' : ':');
-
- ret_val = e1000_read_pba_string(hw, pba_str, E1000_PBANUM_LENGTH);
- if (ret_val)
- strncpy(pba_str, "Unknown", sizeof(pba_str) - 1);
- dev_info(pci_dev_to_dev(pdev), "%s: PBA No: %s\n", netdev->name,
- pba_str);
-
-
- /* Initialize the thermal sensor on i350 devices. */
- if (hw->mac.type == e1000_i350) {
- if (hw->bus.func == 0) {
- u16 ets_word;
-
- /*
- * Read the NVM to determine if this i350 device
- * supports an external thermal sensor.
- */
- e1000_read_nvm(hw, NVM_ETS_CFG, 1, &ets_word);
- if (ets_word != 0x0000 && ets_word != 0xFFFF)
- adapter->ets = true;
- else
- adapter->ets = false;
- }
-#ifdef NO_KNI
-#ifdef IGB_HWMON
-
- igb_sysfs_init(adapter);
-#else
-#ifdef IGB_PROCFS
-
- igb_procfs_init(adapter);
-#endif /* IGB_PROCFS */
-#endif /* IGB_HWMON */
-#endif /* NO_KNI */
- } else {
- adapter->ets = false;
- }
-
- if (hw->phy.media_type == e1000_media_type_copper) {
- switch (hw->mac.type) {
- case e1000_i350:
- case e1000_i210:
- case e1000_i211:
- /* Enable EEE for internal copper PHY devices */
- err = e1000_set_eee_i350(hw);
- if ((!err) &&
- (adapter->flags & IGB_FLAG_EEE))
- adapter->eee_advert =
- MDIO_EEE_100TX | MDIO_EEE_1000T;
- break;
- case e1000_i354:
- if ((E1000_READ_REG(hw, E1000_CTRL_EXT)) &
- (E1000_CTRL_EXT_LINK_MODE_SGMII)) {
- err = e1000_set_eee_i354(hw);
- if ((!err) &&
- (adapter->flags & IGB_FLAG_EEE))
- adapter->eee_advert =
- MDIO_EEE_100TX | MDIO_EEE_1000T;
- }
- break;
- default:
- break;
- }
- }
-
- /* send driver version info to firmware */
- if (hw->mac.type >= e1000_i350)
- igb_init_fw(adapter);
-
-#ifndef IGB_NO_LRO
- if (netdev->features & NETIF_F_LRO)
- dev_info(pci_dev_to_dev(pdev), "Internal LRO is enabled \n");
- else
- dev_info(pci_dev_to_dev(pdev), "LRO is disabled \n");
-#endif
- dev_info(pci_dev_to_dev(pdev),
- "Using %s interrupts. %d rx queue(s), %d tx queue(s)\n",
- adapter->msix_entries ? "MSI-X" :
- (adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy",
- adapter->num_rx_queues, adapter->num_tx_queues);
-
- cards_found++;
- *lad_dev = netdev;
-
- pm_runtime_put_noidle(&pdev->dev);
- return 0;
-
-//err_register:
-// igb_release_hw_control(adapter);
-#ifdef HAVE_I2C_SUPPORT
- memset(&adapter->i2c_adap, 0, sizeof(adapter->i2c_adap));
-#endif /* HAVE_I2C_SUPPORT */
-err_eeprom:
-// if (!e1000_check_reset_block(hw))
-// e1000_phy_hw_reset(hw);
-
- if (hw->flash_address)
- iounmap(hw->flash_address);
-err_sw_init:
-// igb_clear_interrupt_scheme(adapter);
-// igb_reset_sriov_capability(adapter);
- iounmap(hw->hw_addr);
-err_ioremap:
- free_netdev(netdev);
-err_alloc_etherdev:
-// pci_release_selected_regions(pdev,
-// pci_select_bars(pdev, IORESOURCE_MEM));
-//err_pci_reg:
-//err_dma:
- pci_disable_device(pdev);
- return err;
-}
-
-
-void igb_kni_remove(struct pci_dev *pdev)
-{
- pci_disable_device(pdev);
-}
diff --git a/kernel/linux/kni/ethtool/igb/igb_param.c b/kernel/linux/kni/ethtool/igb/igb_param.c
deleted file mode 100644
index 98209a101..000000000
--- a/kernel/linux/kni/ethtool/igb/igb_param.c
+++ /dev/null
@@ -1,832 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-
-#include <linux/netdevice.h>
-
-#include "igb.h"
-
-/* This is the only thing that needs to be changed to adjust the
- * maximum number of ports that the driver can manage.
- */
-
-#define IGB_MAX_NIC 32
-
-#define OPTION_UNSET -1
-#define OPTION_DISABLED 0
-#define OPTION_ENABLED 1
-#define MAX_NUM_LIST_OPTS 15
-
-/* All parameters are treated the same, as an integer array of values.
- * This macro just reduces the need to repeat the same declaration code
- * over and over (plus this helps to avoid typo bugs).
- */
-
-#define IGB_PARAM_INIT { [0 ... IGB_MAX_NIC] = OPTION_UNSET }
-#ifndef module_param_array
-/* Module Parameters are always initialized to -1, so that the driver
- * can tell the difference between no user specified value or the
- * user asking for the default value.
- * The true default values are loaded in when igb_check_options is called.
- *
- * This is a GCC extension to ANSI C.
- * See the item "Labeled Elements in Initializers" in the section
- * "Extensions to the C Language Family" of the GCC documentation.
- */
-
-#define IGB_PARAM(X, desc) \
- static const int X[IGB_MAX_NIC+1] = IGB_PARAM_INIT; \
- MODULE_PARM(X, "1-" __MODULE_STRING(IGB_MAX_NIC) "i"); \
- MODULE_PARM_DESC(X, desc);
-#else
-#define IGB_PARAM(X, desc) \
- static int X[IGB_MAX_NIC+1] = IGB_PARAM_INIT; \
- static unsigned int num_##X; \
- module_param_array_named(X, X, int, &num_##X, 0); \
- MODULE_PARM_DESC(X, desc);
-#endif
-
-/* Interrupt Throttle Rate (interrupts/sec)
- *
- * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative)
- */
-IGB_PARAM(InterruptThrottleRate,
- "Maximum interrupts per second, per vector, (max 100000), default 3=adaptive");
-#define DEFAULT_ITR 3
-#define MAX_ITR 100000
-/* #define MIN_ITR 120 */
-#define MIN_ITR 0
-/* IntMode (Interrupt Mode)
- *
- * Valid Range: 0 - 2
- *
- * Default Value: 2 (MSI-X)
- */
-IGB_PARAM(IntMode, "Change Interrupt Mode (0=Legacy, 1=MSI, 2=MSI-X), default 2");
-#define MAX_INTMODE IGB_INT_MODE_MSIX
-#define MIN_INTMODE IGB_INT_MODE_LEGACY
-
-IGB_PARAM(Node, "set the starting node to allocate memory on, default -1");
-
-/* LLIPort (Low Latency Interrupt TCP Port)
- *
- * Valid Range: 0 - 65535
- *
- * Default Value: 0 (disabled)
- */
-IGB_PARAM(LLIPort, "Low Latency Interrupt TCP Port (0-65535), default 0=off");
-
-#define DEFAULT_LLIPORT 0
-#define MAX_LLIPORT 0xFFFF
-#define MIN_LLIPORT 0
-
-/* LLIPush (Low Latency Interrupt on TCP Push flag)
- *
- * Valid Range: 0, 1
- *
- * Default Value: 0 (disabled)
- */
-IGB_PARAM(LLIPush, "Low Latency Interrupt on TCP Push flag (0,1), default 0=off");
-
-#define DEFAULT_LLIPUSH 0
-#define MAX_LLIPUSH 1
-#define MIN_LLIPUSH 0
-
-/* LLISize (Low Latency Interrupt on Packet Size)
- *
- * Valid Range: 0 - 1500
- *
- * Default Value: 0 (disabled)
- */
-IGB_PARAM(LLISize, "Low Latency Interrupt on Packet Size (0-1500), default 0=off");
-
-#define DEFAULT_LLISIZE 0
-#define MAX_LLISIZE 1500
-#define MIN_LLISIZE 0
-
-/* RSS (Enable RSS multiqueue receive)
- *
- * Valid Range: 0 - 8
- *
- * Default Value: 1
- */
-IGB_PARAM(RSS, "Number of Receive-Side Scaling Descriptor Queues (0-8), default 1, 0=number of cpus");
-
-#define DEFAULT_RSS 1
-#define MAX_RSS 8
-#define MIN_RSS 0
-
-/* VMDQ (Enable VMDq multiqueue receive)
- *
- * Valid Range: 0 - 8
- *
- * Default Value: 0
- */
-IGB_PARAM(VMDQ, "Number of Virtual Machine Device Queues: 0-1 = disable, 2-8 enable, default 0");
-
-#define DEFAULT_VMDQ 0
-#define MAX_VMDQ MAX_RSS
-#define MIN_VMDQ 0
-
-/* max_vfs (Enable SR-IOV VF devices)
- *
- * Valid Range: 0 - 7
- *
- * Default Value: 0
- */
-IGB_PARAM(max_vfs, "Number of Virtual Functions: 0 = disable, 1-7 enable, default 0");
-
-#define DEFAULT_SRIOV 0
-#define MAX_SRIOV 7
-#define MIN_SRIOV 0
-
-/* MDD (Enable Malicious Driver Detection)
- *
- * Only available when SR-IOV is enabled - max_vfs is greater than 0
- *
- * Valid Range: 0, 1
- *
- * Default Value: 1
- */
-IGB_PARAM(MDD, "Malicious Driver Detection (0/1), default 1 = enabled. "
- "Only available when max_vfs is greater than 0");
-
-#ifdef DEBUG
-
-/* Disable Hardware Reset on Tx Hang
- *
- * Valid Range: 0, 1
- *
- * Default Value: 0 (disabled, i.e. h/w will reset)
- */
-IGB_PARAM(DisableHwReset, "Disable reset of hardware on Tx hang");
-
-/* Dump Transmit and Receive buffers
- *
- * Valid Range: 0, 1
- *
- * Default Value: 0
- */
-IGB_PARAM(DumpBuffers, "Dump Tx/Rx buffers on Tx hang or by request");
-
-#endif /* DEBUG */
-
-/* QueuePairs (Enable TX/RX queue pairs for interrupt handling)
- *
- * Valid Range: 0 - 1
- *
- * Default Value: 1
- */
-IGB_PARAM(QueuePairs, "Enable Tx/Rx queue pairs for interrupt handling (0,1), default 1=on");
-
-#define DEFAULT_QUEUE_PAIRS 1
-#define MAX_QUEUE_PAIRS 1
-#define MIN_QUEUE_PAIRS 0
-
-/* Enable/disable EEE (a.k.a. IEEE802.3az)
- *
- * Valid Range: 0, 1
- *
- * Default Value: 1
- */
- IGB_PARAM(EEE, "Enable/disable on parts that support the feature");
-
-/* Enable/disable DMA Coalescing
- *
- * Valid Values: 0(off), 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000,
- * 9000, 10000(msec), 250(usec), 500(usec)
- *
- * Default Value: 0
- */
- IGB_PARAM(DMAC, "Disable or set latency for DMA Coalescing ((0=off, 1000-10000(msec), 250, 500 (usec))");
-
-#ifndef IGB_NO_LRO
-/* Enable/disable Large Receive Offload
- *
- * Valid Values: 0(off), 1(on)
- *
- * Default Value: 0
- */
- IGB_PARAM(LRO, "Large Receive Offload (0,1), default 0=off");
-
-#endif
-struct igb_opt_list {
- int i;
- char *str;
-};
-struct igb_option {
- enum { enable_option, range_option, list_option } type;
- const char *name;
- const char *err;
- int def;
- union {
- struct { /* range_option info */
- int min;
- int max;
- } r;
- struct { /* list_option info */
- int nr;
- struct igb_opt_list *p;
- } l;
- } arg;
-};
-
-static int igb_validate_option(unsigned int *value,
- struct igb_option *opt,
- struct igb_adapter *adapter)
-{
- if (*value == OPTION_UNSET) {
- *value = opt->def;
- return 0;
- }
-
- switch (opt->type) {
- case enable_option:
- switch (*value) {
- case OPTION_ENABLED:
- DPRINTK(PROBE, INFO, "%s Enabled\n", opt->name);
- return 0;
- case OPTION_DISABLED:
- DPRINTK(PROBE, INFO, "%s Disabled\n", opt->name);
- return 0;
- }
- break;
- case range_option:
- if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
- DPRINTK(PROBE, INFO,
- "%s set to %d\n", opt->name, *value);
- return 0;
- }
- break;
- case list_option: {
- int i;
- struct igb_opt_list *ent;
-
- for (i = 0; i < opt->arg.l.nr; i++) {
- ent = &opt->arg.l.p[i];
- if (*value == ent->i) {
- if (ent->str[0] != '\0')
- DPRINTK(PROBE, INFO, "%s\n", ent->str);
- return 0;
- }
- }
- }
- break;
- default:
- BUG();
- }
-
- DPRINTK(PROBE, INFO, "Invalid %s value specified (%d) %s\n",
- opt->name, *value, opt->err);
- *value = opt->def;
- return -1;
-}
-
-/**
- * igb_check_options - Range Checking for Command Line Parameters
- * @adapter: board private structure
- *
- * This routine checks all command line parameters for valid user
- * input. If an invalid value is given, or if no user specified
- * value exists, a default value is used. The final value is stored
- * in a variable in the adapter structure.
- **/
-
-void igb_check_options(struct igb_adapter *adapter)
-{
- int bd = adapter->bd_number;
- struct e1000_hw *hw = &adapter->hw;
-
- if (bd >= IGB_MAX_NIC) {
- DPRINTK(PROBE, NOTICE,
- "Warning: no configuration for board #%d\n", bd);
- DPRINTK(PROBE, NOTICE, "Using defaults for all values\n");
-#ifndef module_param_array
- bd = IGB_MAX_NIC;
-#endif
- }
-
- { /* Interrupt Throttling Rate */
- struct igb_option opt = {
- .type = range_option,
- .name = "Interrupt Throttling Rate (ints/sec)",
- .err = "using default of " __MODULE_STRING(DEFAULT_ITR),
- .def = DEFAULT_ITR,
- .arg = { .r = { .min = MIN_ITR,
- .max = MAX_ITR } }
- };
-
-#ifdef module_param_array
- if (num_InterruptThrottleRate > bd) {
-#endif
- unsigned int itr = InterruptThrottleRate[bd];
-
- switch (itr) {
- case 0:
- DPRINTK(PROBE, INFO, "%s turned off\n",
- opt.name);
- if (hw->mac.type >= e1000_i350)
- adapter->dmac = IGB_DMAC_DISABLE;
- adapter->rx_itr_setting = itr;
- break;
- case 1:
- DPRINTK(PROBE, INFO, "%s set to dynamic mode\n",
- opt.name);
- adapter->rx_itr_setting = itr;
- break;
- case 3:
- DPRINTK(PROBE, INFO,
- "%s set to dynamic conservative mode\n",
- opt.name);
- adapter->rx_itr_setting = itr;
- break;
- default:
- igb_validate_option(&itr, &opt, adapter);
- /* Save the setting, because the dynamic bits
- * change itr. In case of invalid user value,
- * default to conservative mode, else need to
- * clear the lower two bits because they are
- * used as control */
- if (itr == 3) {
- adapter->rx_itr_setting = itr;
- } else {
- adapter->rx_itr_setting = 1000000000 /
- (itr * 256);
- adapter->rx_itr_setting &= ~3;
- }
- break;
- }
-#ifdef module_param_array
- } else {
- adapter->rx_itr_setting = opt.def;
- }
-#endif
- adapter->tx_itr_setting = adapter->rx_itr_setting;
- }
- { /* Interrupt Mode */
- struct igb_option opt = {
- .type = range_option,
- .name = "Interrupt Mode",
- .err = "defaulting to 2 (MSI-X)",
- .def = IGB_INT_MODE_MSIX,
- .arg = { .r = { .min = MIN_INTMODE,
- .max = MAX_INTMODE } }
- };
-
-#ifdef module_param_array
- if (num_IntMode > bd) {
-#endif
- unsigned int int_mode = IntMode[bd];
- igb_validate_option(&int_mode, &opt, adapter);
- adapter->int_mode = int_mode;
-#ifdef module_param_array
- } else {
- adapter->int_mode = opt.def;
- }
-#endif
- }
- { /* Low Latency Interrupt TCP Port */
- struct igb_option opt = {
- .type = range_option,
- .name = "Low Latency Interrupt TCP Port",
- .err = "using default of " __MODULE_STRING(DEFAULT_LLIPORT),
- .def = DEFAULT_LLIPORT,
- .arg = { .r = { .min = MIN_LLIPORT,
- .max = MAX_LLIPORT } }
- };
-
-#ifdef module_param_array
- if (num_LLIPort > bd) {
-#endif
- adapter->lli_port = LLIPort[bd];
- if (adapter->lli_port) {
- igb_validate_option(&adapter->lli_port, &opt,
- adapter);
- } else {
- DPRINTK(PROBE, INFO, "%s turned off\n",
- opt.name);
- }
-#ifdef module_param_array
- } else {
- adapter->lli_port = opt.def;
- }
-#endif
- }
- { /* Low Latency Interrupt on Packet Size */
- struct igb_option opt = {
- .type = range_option,
- .name = "Low Latency Interrupt on Packet Size",
- .err = "using default of " __MODULE_STRING(DEFAULT_LLISIZE),
- .def = DEFAULT_LLISIZE,
- .arg = { .r = { .min = MIN_LLISIZE,
- .max = MAX_LLISIZE } }
- };
-
-#ifdef module_param_array
- if (num_LLISize > bd) {
-#endif
- adapter->lli_size = LLISize[bd];
- if (adapter->lli_size) {
- igb_validate_option(&adapter->lli_size, &opt,
- adapter);
- } else {
- DPRINTK(PROBE, INFO, "%s turned off\n",
- opt.name);
- }
-#ifdef module_param_array
- } else {
- adapter->lli_size = opt.def;
- }
-#endif
- }
- { /* Low Latency Interrupt on TCP Push flag */
- struct igb_option opt = {
- .type = enable_option,
- .name = "Low Latency Interrupt on TCP Push flag",
- .err = "defaulting to Disabled",
- .def = OPTION_DISABLED
- };
-
-#ifdef module_param_array
- if (num_LLIPush > bd) {
-#endif
- unsigned int lli_push = LLIPush[bd];
- igb_validate_option(&lli_push, &opt, adapter);
- adapter->flags |= lli_push ? IGB_FLAG_LLI_PUSH : 0;
-#ifdef module_param_array
- } else {
- adapter->flags |= opt.def ? IGB_FLAG_LLI_PUSH : 0;
- }
-#endif
- }
- { /* SRIOV - Enable SR-IOV VF devices */
- struct igb_option opt = {
- .type = range_option,
- .name = "max_vfs - SR-IOV VF devices",
- .err = "using default of " __MODULE_STRING(DEFAULT_SRIOV),
- .def = DEFAULT_SRIOV,
- .arg = { .r = { .min = MIN_SRIOV,
- .max = MAX_SRIOV } }
- };
-
-#ifdef module_param_array
- if (num_max_vfs > bd) {
-#endif
- adapter->vfs_allocated_count = max_vfs[bd];
- igb_validate_option(&adapter->vfs_allocated_count, &opt, adapter);
-
-#ifdef module_param_array
- } else {
- adapter->vfs_allocated_count = opt.def;
- }
-#endif
- if (adapter->vfs_allocated_count) {
- switch (hw->mac.type) {
- case e1000_82575:
- case e1000_82580:
- case e1000_i210:
- case e1000_i211:
- case e1000_i354:
- adapter->vfs_allocated_count = 0;
- DPRINTK(PROBE, INFO, "SR-IOV option max_vfs not supported.\n");
- default:
- break;
- }
- }
- }
- { /* VMDQ - Enable VMDq multiqueue receive */
- struct igb_option opt = {
- .type = range_option,
- .name = "VMDQ - VMDq multiqueue queue count",
- .err = "using default of " __MODULE_STRING(DEFAULT_VMDQ),
- .def = DEFAULT_VMDQ,
- .arg = { .r = { .min = MIN_VMDQ,
- .max = (MAX_VMDQ - adapter->vfs_allocated_count) } }
- };
- if ((hw->mac.type != e1000_i210) ||
- (hw->mac.type != e1000_i211)) {
-#ifdef module_param_array
- if (num_VMDQ > bd) {
-#endif
- adapter->vmdq_pools = (VMDQ[bd] == 1 ? 0 : VMDQ[bd]);
- if (adapter->vfs_allocated_count && !adapter->vmdq_pools) {
- DPRINTK(PROBE, INFO, "Enabling SR-IOV requires VMDq be set to at least 1\n");
- adapter->vmdq_pools = 1;
- }
- igb_validate_option(&adapter->vmdq_pools, &opt, adapter);
-
-#ifdef module_param_array
- } else {
- if (!adapter->vfs_allocated_count)
- adapter->vmdq_pools = (opt.def == 1 ? 0 : opt.def);
- else
- adapter->vmdq_pools = 1;
- }
-#endif
-#ifdef CONFIG_IGB_VMDQ_NETDEV
- if (hw->mac.type == e1000_82575 && adapter->vmdq_pools) {
- DPRINTK(PROBE, INFO, "VMDq not supported on this part.\n");
- adapter->vmdq_pools = 0;
- }
-#endif
-
- } else {
- DPRINTK(PROBE, INFO, "VMDq option is not supported.\n");
- adapter->vmdq_pools = opt.def;
- }
- }
- { /* RSS - Enable RSS multiqueue receives */
- struct igb_option opt = {
- .type = range_option,
- .name = "RSS - RSS multiqueue receive count",
- .err = "using default of " __MODULE_STRING(DEFAULT_RSS),
- .def = DEFAULT_RSS,
- .arg = { .r = { .min = MIN_RSS,
- .max = MAX_RSS } }
- };
-
- switch (hw->mac.type) {
- case e1000_82575:
-#ifndef CONFIG_IGB_VMDQ_NETDEV
- if (!!adapter->vmdq_pools) {
- if (adapter->vmdq_pools <= 2) {
- if (adapter->vmdq_pools == 2)
- opt.arg.r.max = 3;
- } else {
- opt.arg.r.max = 1;
- }
- } else {
- opt.arg.r.max = 4;
- }
-#else
- opt.arg.r.max = !!adapter->vmdq_pools ? 1 : 4;
-#endif /* CONFIG_IGB_VMDQ_NETDEV */
- break;
- case e1000_i210:
- opt.arg.r.max = 4;
- break;
- case e1000_i211:
- opt.arg.r.max = 2;
- break;
- case e1000_82576:
-#ifndef CONFIG_IGB_VMDQ_NETDEV
- if (!!adapter->vmdq_pools)
- opt.arg.r.max = 2;
- break;
-#endif /* CONFIG_IGB_VMDQ_NETDEV */
- case e1000_82580:
- case e1000_i350:
- case e1000_i354:
- default:
- if (!!adapter->vmdq_pools)
- opt.arg.r.max = 1;
- break;
- }
-
- if (adapter->int_mode != IGB_INT_MODE_MSIX) {
- DPRINTK(PROBE, INFO, "RSS is not supported when in MSI/Legacy Interrupt mode, %s\n",
- opt.err);
- opt.arg.r.max = 1;
- }
-
-#ifdef module_param_array
- if (num_RSS > bd) {
-#endif
- adapter->rss_queues = RSS[bd];
- switch (adapter->rss_queues) {
- case 1:
- break;
- default:
- igb_validate_option(&adapter->rss_queues, &opt, adapter);
- if (adapter->rss_queues)
- break;
- case 0:
- adapter->rss_queues = min_t(u32, opt.arg.r.max, num_online_cpus());
- break;
- }
-#ifdef module_param_array
- } else {
- adapter->rss_queues = opt.def;
- }
-#endif
- }
- { /* QueuePairs - Enable Tx/Rx queue pairs for interrupt handling */
- struct igb_option opt = {
- .type = enable_option,
- .name = "QueuePairs - Tx/Rx queue pairs for interrupt handling",
- .err = "defaulting to Enabled",
- .def = OPTION_ENABLED
- };
-#ifdef module_param_array
- if (num_QueuePairs > bd) {
-#endif
- unsigned int qp = QueuePairs[bd];
- /*
- * We must enable queue pairs if the number of queues
- * exceeds the number of available interrupts. We are
- * limited to 10, or 3 per unallocated vf. On I210 and
- * I211 devices, we are limited to 5 interrupts.
- * However, since I211 only supports 2 queues, we do not
- * need to check and override the user option.
- */
- if (qp == OPTION_DISABLED) {
- if (adapter->rss_queues > 4)
- qp = OPTION_ENABLED;
-
- if (adapter->vmdq_pools > 4)
- qp = OPTION_ENABLED;
-
- if (adapter->rss_queues > 1 &&
- (adapter->vmdq_pools > 3 ||
- adapter->vfs_allocated_count > 6))
- qp = OPTION_ENABLED;
-
- if (hw->mac.type == e1000_i210 &&
- adapter->rss_queues > 2)
- qp = OPTION_ENABLED;
-
- if (qp == OPTION_ENABLED)
- DPRINTK(PROBE, INFO, "Number of queues exceeds available interrupts, %s\n",
- opt.err);
- }
- igb_validate_option(&qp, &opt, adapter);
- adapter->flags |= qp ? IGB_FLAG_QUEUE_PAIRS : 0;
-#ifdef module_param_array
- } else {
- adapter->flags |= opt.def ? IGB_FLAG_QUEUE_PAIRS : 0;
- }
-#endif
- }
- { /* EEE - Enable EEE for capable adapters */
-
- if (hw->mac.type >= e1000_i350) {
- struct igb_option opt = {
- .type = enable_option,
- .name = "EEE Support",
- .err = "defaulting to Enabled",
- .def = OPTION_ENABLED
- };
-#ifdef module_param_array
- if (num_EEE > bd) {
-#endif
- unsigned int eee = EEE[bd];
- igb_validate_option(&eee, &opt, adapter);
- adapter->flags |= eee ? IGB_FLAG_EEE : 0;
- if (eee)
- hw->dev_spec._82575.eee_disable = false;
- else
- hw->dev_spec._82575.eee_disable = true;
-
-#ifdef module_param_array
- } else {
- adapter->flags |= opt.def ? IGB_FLAG_EEE : 0;
- if (adapter->flags & IGB_FLAG_EEE)
- hw->dev_spec._82575.eee_disable = false;
- else
- hw->dev_spec._82575.eee_disable = true;
- }
-#endif
- }
- }
- { /* DMAC - Enable DMA Coalescing for capable adapters */
-
- if (hw->mac.type >= e1000_i350) {
- struct igb_opt_list list [] = {
- { IGB_DMAC_DISABLE, "DMAC Disable"},
- { IGB_DMAC_MIN, "DMAC 250 usec"},
- { IGB_DMAC_500, "DMAC 500 usec"},
- { IGB_DMAC_EN_DEFAULT, "DMAC 1000 usec"},
- { IGB_DMAC_2000, "DMAC 2000 usec"},
- { IGB_DMAC_3000, "DMAC 3000 usec"},
- { IGB_DMAC_4000, "DMAC 4000 usec"},
- { IGB_DMAC_5000, "DMAC 5000 usec"},
- { IGB_DMAC_6000, "DMAC 6000 usec"},
- { IGB_DMAC_7000, "DMAC 7000 usec"},
- { IGB_DMAC_8000, "DMAC 8000 usec"},
- { IGB_DMAC_9000, "DMAC 9000 usec"},
- { IGB_DMAC_MAX, "DMAC 10000 usec"}
- };
- struct igb_option opt = {
- .type = list_option,
- .name = "DMA Coalescing",
- .err = "using default of "__MODULE_STRING(IGB_DMAC_DISABLE),
- .def = IGB_DMAC_DISABLE,
- .arg = { .l = { .nr = 13,
- .p = list
- }
- }
- };
-#ifdef module_param_array
- if (num_DMAC > bd) {
-#endif
- unsigned int dmac = DMAC[bd];
- if (adapter->rx_itr_setting == IGB_DMAC_DISABLE)
- dmac = IGB_DMAC_DISABLE;
- igb_validate_option(&dmac, &opt, adapter);
- switch (dmac) {
- case IGB_DMAC_DISABLE:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_MIN:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_500:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_EN_DEFAULT:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_2000:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_3000:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_4000:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_5000:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_6000:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_7000:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_8000:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_9000:
- adapter->dmac = dmac;
- break;
- case IGB_DMAC_MAX:
- adapter->dmac = dmac;
- break;
- default:
- adapter->dmac = opt.def;
- DPRINTK(PROBE, INFO,
- "Invalid DMAC setting, "
- "resetting DMAC to %d\n", opt.def);
- }
-#ifdef module_param_array
- } else
- adapter->dmac = opt.def;
-#endif
- }
- }
-#ifndef IGB_NO_LRO
- { /* LRO - Enable Large Receive Offload */
- struct igb_option opt = {
- .type = enable_option,
- .name = "LRO - Large Receive Offload",
- .err = "defaulting to Disabled",
- .def = OPTION_DISABLED
- };
- struct net_device *netdev = adapter->netdev;
-#ifdef module_param_array
- if (num_LRO > bd) {
-#endif
- unsigned int lro = LRO[bd];
- igb_validate_option(&lro, &opt, adapter);
- netdev->features |= lro ? NETIF_F_LRO : 0;
-#ifdef module_param_array
- } else if (opt.def == OPTION_ENABLED) {
- netdev->features |= NETIF_F_LRO;
- }
-#endif
- }
-#endif /* IGB_NO_LRO */
- { /* MDD - Enable Malicious Driver Detection. Only available when
- SR-IOV is enabled. */
- struct igb_option opt = {
- .type = enable_option,
- .name = "Malicious Driver Detection",
- .err = "defaulting to 1",
- .def = OPTION_ENABLED,
- .arg = { .r = { .min = OPTION_DISABLED,
- .max = OPTION_ENABLED } }
- };
-
-#ifdef module_param_array
- if (num_MDD > bd) {
-#endif
- adapter->mdd = MDD[bd];
- igb_validate_option((uint *)&adapter->mdd, &opt,
- adapter);
-#ifdef module_param_array
- } else {
- adapter->mdd = opt.def;
- }
-#endif
- }
-}
diff --git a/kernel/linux/kni/ethtool/igb/igb_regtest.h b/kernel/linux/kni/ethtool/igb/igb_regtest.h
deleted file mode 100644
index ec2b86a0e..000000000
--- a/kernel/linux/kni/ethtool/igb/igb_regtest.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/* ethtool register test data */
-struct igb_reg_test {
- u16 reg;
- u16 reg_offset;
- u16 array_len;
- u16 test_type;
- u32 mask;
- u32 write;
-};
-
-/* In the hardware, registers are laid out either singly, in arrays
- * spaced 0x100 bytes apart, or in contiguous tables. We assume
- * most tests take place on arrays or single registers (handled
- * as a single-element array) and special-case the tables.
- * Table tests are always pattern tests.
- *
- * We also make provision for some required setup steps by specifying
- * registers to be written without any read-back testing.
- */
-
-#define PATTERN_TEST 1
-#define SET_READ_TEST 2
-#define WRITE_NO_TEST 3
-#define TABLE32_TEST 4
-#define TABLE64_TEST_LO 5
-#define TABLE64_TEST_HI 6
-
-/* i210 reg test */
-static struct igb_reg_test reg_test_i210[] = {
- { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- /* RDH is read-only for i210, only test RDT. */
- { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0003FFF0, 0x0003FFF0 },
- { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
- { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- { E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
- { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RA, 0, 16, TABLE64_TEST_LO,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RA, 0, 16, TABLE64_TEST_HI,
- 0x900FFFFF, 0xFFFFFFFF },
- { E1000_MTA, 0, 128, TABLE32_TEST,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { 0, 0, 0, 0 }
-};
-
-/* i350 reg test */
-static struct igb_reg_test reg_test_i350[] = {
- { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- /* VET is readonly on i350 */
- { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- { E1000_RDBAL(4), 0x40, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(4), 0x40, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- /* RDH is read-only for i350, only test RDT. */
- { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_RDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
- { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
- { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- { E1000_TDBAL(4), 0x40, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(4), 0x40, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- { E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_TDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
- { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RA, 0, 16, TABLE64_TEST_LO,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RA, 0, 16, TABLE64_TEST_HI,
- 0xC3FFFFFF, 0xFFFFFFFF },
- { E1000_RA2, 0, 16, TABLE64_TEST_LO,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RA2, 0, 16, TABLE64_TEST_HI,
- 0xC3FFFFFF, 0xFFFFFFFF },
- { E1000_MTA, 0, 128, TABLE32_TEST,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { 0, 0, 0, 0 }
-};
-
-/* 82580 reg test */
-static struct igb_reg_test reg_test_82580[] = {
- { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_RDBAL(4), 0x40, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(4), 0x40, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- /* RDH is read-only for 82580, only test RDT. */
- { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_RDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
- { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
- { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_TDBAL(4), 0x40, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(4), 0x40, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_TDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
- { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RA, 0, 16, TABLE64_TEST_LO,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RA, 0, 16, TABLE64_TEST_HI,
- 0x83FFFFFF, 0xFFFFFFFF },
- { E1000_RA2, 0, 8, TABLE64_TEST_LO,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RA2, 0, 8, TABLE64_TEST_HI,
- 0x83FFFFFF, 0xFFFFFFFF },
- { E1000_MTA, 0, 128, TABLE32_TEST,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { 0, 0, 0, 0 }
-};
-
-/* 82576 reg test */
-static struct igb_reg_test reg_test_82576[] = {
- { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_RDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- /* Enable all queues before testing. */
- { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
- { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
- /* RDH is read-only for 82576, only test RDT. */
- { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_RDT(4), 0x40, 12, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
- { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, 0 },
- { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
- { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
- { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_TDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
- { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RA, 0, 16, TABLE64_TEST_LO,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RA, 0, 16, TABLE64_TEST_HI,
- 0x83FFFFFF, 0xFFFFFFFF },
- { E1000_RA2, 0, 8, TABLE64_TEST_LO,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RA2, 0, 8, TABLE64_TEST_HI,
- 0x83FFFFFF, 0xFFFFFFFF },
- { E1000_MTA, 0, 128, TABLE32_TEST,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { 0, 0, 0, 0 }
-};
-
-/* 82575 register test */
-static struct igb_reg_test reg_test_82575[] = {
- { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- /* Enable all four RX queues before testing. */
- { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
- /* RDH is read-only for 82575, only test RDT. */
- { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
- { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
- { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
- { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB3FE, 0x003FFFFB },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB3FE, 0xFFFFFFFF },
- { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_TXCW, 0x100, 1, PATTERN_TEST, 0xC000FFFF, 0x0000FFFF },
- { E1000_RA, 0, 16, TABLE64_TEST_LO,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RA, 0, 16, TABLE64_TEST_HI,
- 0x800FFFFF, 0xFFFFFFFF },
- { E1000_MTA, 0, 128, TABLE32_TEST,
- 0xFFFFFFFF, 0xFFFFFFFF },
- { 0, 0, 0, 0 }
-};
diff --git a/kernel/linux/kni/ethtool/igb/igb_vmdq.c b/kernel/linux/kni/ethtool/igb/igb_vmdq.c
deleted file mode 100644
index cdd807b96..000000000
--- a/kernel/linux/kni/ethtool/igb/igb_vmdq.c
+++ /dev/null
@@ -1,421 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-
-#include <linux/tcp.h>
-
-#include "igb.h"
-#include "igb_vmdq.h"
-#include <linux/if_vlan.h>
-
-#ifdef CONFIG_IGB_VMDQ_NETDEV
-int igb_vmdq_open(struct net_device *dev)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- struct net_device *main_netdev = adapter->netdev;
- int hw_queue = vadapter->rx_ring->queue_index +
- adapter->vfs_allocated_count;
-
- if (test_bit(__IGB_DOWN, &adapter->state)) {
- DPRINTK(DRV, WARNING,
- "Open %s before opening this device.\n",
- main_netdev->name);
- return -EAGAIN;
- }
- netif_carrier_off(dev);
- vadapter->tx_ring->vmdq_netdev = dev;
- vadapter->rx_ring->vmdq_netdev = dev;
- if (is_valid_ether_addr(dev->dev_addr)) {
- igb_del_mac_filter(adapter, dev->dev_addr, hw_queue);
- igb_add_mac_filter(adapter, dev->dev_addr, hw_queue);
- }
- netif_carrier_on(dev);
- return 0;
-}
-
-int igb_vmdq_close(struct net_device *dev)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- int hw_queue = vadapter->rx_ring->queue_index +
- adapter->vfs_allocated_count;
-
- netif_carrier_off(dev);
- igb_del_mac_filter(adapter, dev->dev_addr, hw_queue);
-
- vadapter->tx_ring->vmdq_netdev = NULL;
- vadapter->rx_ring->vmdq_netdev = NULL;
- return 0;
-}
-
-netdev_tx_t igb_vmdq_xmit_frame(struct sk_buff *skb, struct net_device *dev)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
-
- return igb_xmit_frame_ring(skb, vadapter->tx_ring);
-}
-
-struct net_device_stats *igb_vmdq_get_stats(struct net_device *dev)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- struct e1000_hw *hw = &adapter->hw;
- int hw_queue = vadapter->rx_ring->queue_index +
- adapter->vfs_allocated_count;
-
- vadapter->net_stats.rx_packets +=
- E1000_READ_REG(hw, E1000_PFVFGPRC(hw_queue));
- E1000_WRITE_REG(hw, E1000_PFVFGPRC(hw_queue), 0);
- vadapter->net_stats.tx_packets +=
- E1000_READ_REG(hw, E1000_PFVFGPTC(hw_queue));
- E1000_WRITE_REG(hw, E1000_PFVFGPTC(hw_queue), 0);
- vadapter->net_stats.rx_bytes +=
- E1000_READ_REG(hw, E1000_PFVFGORC(hw_queue));
- E1000_WRITE_REG(hw, E1000_PFVFGORC(hw_queue), 0);
- vadapter->net_stats.tx_bytes +=
- E1000_READ_REG(hw, E1000_PFVFGOTC(hw_queue));
- E1000_WRITE_REG(hw, E1000_PFVFGOTC(hw_queue), 0);
- vadapter->net_stats.multicast +=
- E1000_READ_REG(hw, E1000_PFVFMPRC(hw_queue));
- E1000_WRITE_REG(hw, E1000_PFVFMPRC(hw_queue), 0);
- /* only return the current stats */
- return &vadapter->net_stats;
-}
-
-/**
- * igb_write_vm_addr_list - write unicast addresses to RAR table
- * @netdev: network interface device structure
- *
- * Writes unicast address list to the RAR table.
- * Returns: -ENOMEM on failure/insufficient address space
- * 0 on no addresses written
- * X on writing X addresses to the RAR table
- **/
-static int igb_write_vm_addr_list(struct net_device *netdev)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- int count = 0;
- int hw_queue = vadapter->rx_ring->queue_index +
- adapter->vfs_allocated_count;
-
- /* return ENOMEM indicating insufficient memory for addresses */
- if (netdev_uc_count(netdev) > igb_available_rars(adapter))
- return -ENOMEM;
-
- if (!netdev_uc_empty(netdev)) {
-#ifdef NETDEV_HW_ADDR_T_UNICAST
- struct netdev_hw_addr *ha;
-#else
- struct dev_mc_list *ha;
-#endif
- netdev_for_each_uc_addr(ha, netdev) {
-#ifdef NETDEV_HW_ADDR_T_UNICAST
- igb_del_mac_filter(adapter, ha->addr, hw_queue);
- igb_add_mac_filter(adapter, ha->addr, hw_queue);
-#else
- igb_del_mac_filter(adapter, ha->da_addr, hw_queue);
- igb_add_mac_filter(adapter, ha->da_addr, hw_queue);
-#endif
- count++;
- }
- }
- return count;
-}
-
-
-#define E1000_VMOLR_UPE 0x20000000 /* Unicast promiscuous mode */
-void igb_vmdq_set_rx_mode(struct net_device *dev)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- struct e1000_hw *hw = &adapter->hw;
- u32 vmolr, rctl;
- int hw_queue = vadapter->rx_ring->queue_index +
- adapter->vfs_allocated_count;
-
- /* Check for Promiscuous and All Multicast modes */
- vmolr = E1000_READ_REG(hw, E1000_VMOLR(hw_queue));
-
- /* clear the affected bits */
- vmolr &= ~(E1000_VMOLR_UPE | E1000_VMOLR_MPME |
- E1000_VMOLR_ROPE | E1000_VMOLR_ROMPE);
-
- if (dev->flags & IFF_PROMISC) {
- vmolr |= E1000_VMOLR_UPE;
- rctl = E1000_READ_REG(hw, E1000_RCTL);
- rctl |= E1000_RCTL_UPE;
- E1000_WRITE_REG(hw, E1000_RCTL, rctl);
- } else {
- rctl = E1000_READ_REG(hw, E1000_RCTL);
- rctl &= ~E1000_RCTL_UPE;
- E1000_WRITE_REG(hw, E1000_RCTL, rctl);
- if (dev->flags & IFF_ALLMULTI) {
- vmolr |= E1000_VMOLR_MPME;
- } else {
- /*
- * Write addresses to the MTA, if the attempt fails
- * then we should just turn on promiscuous mode so
- * that we can at least receive multicast traffic
- */
- if (igb_write_mc_addr_list(adapter->netdev) != 0)
- vmolr |= E1000_VMOLR_ROMPE;
- }
-#ifdef HAVE_SET_RX_MODE
- /*
- * Write addresses to available RAR registers, if there is not
- * sufficient space to store all the addresses then enable
- * unicast promiscuous mode
- */
- if (igb_write_vm_addr_list(dev) < 0)
- vmolr |= E1000_VMOLR_UPE;
-#endif
- }
- E1000_WRITE_REG(hw, E1000_VMOLR(hw_queue), vmolr);
-
- return;
-}
-
-int igb_vmdq_set_mac(struct net_device *dev, void *p)
-{
- struct sockaddr *addr = p;
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- int hw_queue = vadapter->rx_ring->queue_index +
- adapter->vfs_allocated_count;
-
- igb_del_mac_filter(adapter, dev->dev_addr, hw_queue);
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
- return igb_add_mac_filter(adapter, dev->dev_addr, hw_queue);
-}
-
-int igb_vmdq_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
- struct igb_adapter *adapter = vadapter->real_adapter;
-
- if (adapter->netdev->mtu < new_mtu) {
- DPRINTK(PROBE, INFO,
- "Set MTU on %s to >= %d "
- "before changing MTU on %s\n",
- adapter->netdev->name, new_mtu, dev->name);
- return -EINVAL;
- }
- dev->mtu = new_mtu;
- return 0;
-}
-
-void igb_vmdq_tx_timeout(struct net_device *dev)
-{
- return;
-}
-
-void igb_vmdq_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- struct e1000_hw *hw = &adapter->hw;
- int hw_queue = vadapter->rx_ring->queue_index +
- adapter->vfs_allocated_count;
-
- vadapter->vlgrp = grp;
-
- igb_enable_vlan_tags(adapter);
- E1000_WRITE_REG(hw, E1000_VMVIR(hw_queue), 0);
-
- return;
-}
-void igb_vmdq_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
- struct igb_adapter *adapter = vadapter->real_adapter;
-#ifndef HAVE_NETDEV_VLAN_FEATURES
- struct net_device *v_netdev;
-#endif
- int hw_queue = vadapter->rx_ring->queue_index +
- adapter->vfs_allocated_count;
-
- /* attempt to add filter to vlvf array */
- igb_vlvf_set(adapter, vid, TRUE, hw_queue);
-
-#ifndef HAVE_NETDEV_VLAN_FEATURES
-
- /* Copy feature flags from netdev to the vlan netdev for this vid.
- * This allows things like TSO to bubble down to our vlan device.
- */
- v_netdev = vlan_group_get_device(vadapter->vlgrp, vid);
- v_netdev->features |= adapter->netdev->features;
- vlan_group_set_device(vadapter->vlgrp, vid, v_netdev);
-#endif
-
- return;
-}
-void igb_vmdq_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- int hw_queue = vadapter->rx_ring->queue_index +
- adapter->vfs_allocated_count;
-
- vlan_group_set_device(vadapter->vlgrp, vid, NULL);
- /* remove vlan from VLVF table array */
- igb_vlvf_set(adapter, vid, FALSE, hw_queue);
-
-
- return;
-}
-
-static int igb_vmdq_get_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- struct e1000_hw *hw = &adapter->hw;
- u32 status;
-
- if (hw->phy.media_type == e1000_media_type_copper) {
-
- ecmd->supported = (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full|
- SUPPORTED_Autoneg |
- SUPPORTED_TP);
- ecmd->advertising = ADVERTISED_TP;
-
- if (hw->mac.autoneg == 1) {
- ecmd->advertising |= ADVERTISED_Autoneg;
- /* the e1000 autoneg seems to match ethtool nicely */
- ecmd->advertising |= hw->phy.autoneg_advertised;
- }
-
- ecmd->port = PORT_TP;
- ecmd->phy_address = hw->phy.addr;
- } else {
- ecmd->supported = (SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg);
-
- ecmd->advertising = (ADVERTISED_1000baseT_Full |
- ADVERTISED_FIBRE |
- ADVERTISED_Autoneg);
-
- ecmd->port = PORT_FIBRE;
- }
-
- ecmd->transceiver = XCVR_INTERNAL;
-
- status = E1000_READ_REG(hw, E1000_STATUS);
-
- if (status & E1000_STATUS_LU) {
-
- if ((status & E1000_STATUS_SPEED_1000) ||
- hw->phy.media_type != e1000_media_type_copper)
- ecmd->speed = SPEED_1000;
- else if (status & E1000_STATUS_SPEED_100)
- ecmd->speed = SPEED_100;
- else
- ecmd->speed = SPEED_10;
-
- if ((status & E1000_STATUS_FD) ||
- hw->phy.media_type != e1000_media_type_copper)
- ecmd->duplex = DUPLEX_FULL;
- else
- ecmd->duplex = DUPLEX_HALF;
- } else {
- ecmd->speed = -1;
- ecmd->duplex = -1;
- }
-
- ecmd->autoneg = hw->mac.autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
- return 0;
-}
-
-
-static u32 igb_vmdq_get_msglevel(struct net_device *netdev)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- return adapter->msg_enable;
-}
-
-static void igb_vmdq_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
- struct igb_adapter *adapter = vadapter->real_adapter;
- struct net_device *main_netdev = adapter->netdev;
-
- strncpy(drvinfo->driver, igb_driver_name, 32);
- strncpy(drvinfo->version, igb_driver_version, 32);
-
- strncpy(drvinfo->fw_version, "N/A", 4);
- snprintf(drvinfo->bus_info, 32, "%s VMDQ %d", main_netdev->name,
- vadapter->rx_ring->queue_index);
- drvinfo->n_stats = 0;
- drvinfo->testinfo_len = 0;
- drvinfo->regdump_len = 0;
-}
-
-static void igb_vmdq_get_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
-
- struct igb_ring *tx_ring = vadapter->tx_ring;
- struct igb_ring *rx_ring = vadapter->rx_ring;
-
- ring->rx_max_pending = IGB_MAX_RXD;
- ring->tx_max_pending = IGB_MAX_TXD;
- ring->rx_mini_max_pending = 0;
- ring->rx_jumbo_max_pending = 0;
- ring->rx_pending = rx_ring->count;
- ring->tx_pending = tx_ring->count;
- ring->rx_mini_pending = 0;
- ring->rx_jumbo_pending = 0;
-}
-static u32 igb_vmdq_get_rx_csum(struct net_device *netdev)
-{
- struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
- struct igb_adapter *adapter = vadapter->real_adapter;
-
- return test_bit(IGB_RING_FLAG_RX_CSUM, &adapter->rx_ring[0]->flags);
-}
-
-
-static struct ethtool_ops igb_vmdq_ethtool_ops = {
- .get_settings = igb_vmdq_get_settings,
- .get_drvinfo = igb_vmdq_get_drvinfo,
- .get_link = ethtool_op_get_link,
- .get_ringparam = igb_vmdq_get_ringparam,
- .get_rx_csum = igb_vmdq_get_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_msglevel = igb_vmdq_get_msglevel,
-#ifdef NETIF_F_TSO
- .get_tso = ethtool_op_get_tso,
-#endif
-#ifdef HAVE_ETHTOOL_GET_PERM_ADDR
- .get_perm_addr = ethtool_op_get_perm_addr,
-#endif
-};
-
-void igb_vmdq_set_ethtool_ops(struct net_device *netdev)
-{
- SET_ETHTOOL_OPS(netdev, &igb_vmdq_ethtool_ops);
-}
-
-
-#endif /* CONFIG_IGB_VMDQ_NETDEV */
diff --git a/kernel/linux/kni/ethtool/igb/igb_vmdq.h b/kernel/linux/kni/ethtool/igb/igb_vmdq.h
deleted file mode 100644
index e68c48cfe..000000000
--- a/kernel/linux/kni/ethtool/igb/igb_vmdq.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IGB_VMDQ_H_
-#define _IGB_VMDQ_H_
-
-#ifdef CONFIG_IGB_VMDQ_NETDEV
-int igb_vmdq_open(struct net_device *dev);
-int igb_vmdq_close(struct net_device *dev);
-netdev_tx_t igb_vmdq_xmit_frame(struct sk_buff *skb, struct net_device *dev);
-struct net_device_stats *igb_vmdq_get_stats(struct net_device *dev);
-void igb_vmdq_set_rx_mode(struct net_device *dev);
-int igb_vmdq_set_mac(struct net_device *dev, void *addr);
-int igb_vmdq_change_mtu(struct net_device *dev, int new_mtu);
-void igb_vmdq_tx_timeout(struct net_device *dev);
-void igb_vmdq_vlan_rx_register(struct net_device *dev,
- struct vlan_group *grp);
-void igb_vmdq_vlan_rx_add_vid(struct net_device *dev, unsigned short vid);
-void igb_vmdq_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
-void igb_vmdq_set_ethtool_ops(struct net_device *netdev);
-#endif /* CONFIG_IGB_VMDQ_NETDEV */
-#endif /* _IGB_VMDQ_H_ */
diff --git a/kernel/linux/kni/ethtool/igb/kcompat.h b/kernel/linux/kni/ethtool/igb/kcompat.h
deleted file mode 100644
index ae1b53093..000000000
--- a/kernel/linux/kni/ethtool/igb/kcompat.h
+++ /dev/null
@@ -1,3945 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-2013 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _KCOMPAT_H_
-#define _KCOMPAT_H_
-
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#else
-#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/udp.h>
-#include <linux/mii.h>
-#include <linux/vmalloc.h>
-#include <asm/io.h>
-#include <linux/ethtool.h>
-#include <linux/if_vlan.h>
-
-/* NAPI enable/disable flags here */
-#define NAPI
-
-#define adapter_struct igb_adapter
-#define adapter_q_vector igb_q_vector
-#define NAPI
-
-/* and finally set defines so that the code sees the changes */
-#ifdef NAPI
-#else
-#endif /* NAPI */
-
-/* packet split disable/enable */
-#ifdef DISABLE_PACKET_SPLIT
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
-#define CONFIG_IGB_DISABLE_PACKET_SPLIT
-#endif
-#endif /* DISABLE_PACKET_SPLIT */
-
-/* MSI compatibility code for all kernels and drivers */
-#ifdef DISABLE_PCI_MSI
-#undef CONFIG_PCI_MSI
-#endif
-#ifndef CONFIG_PCI_MSI
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) )
-struct msix_entry {
- u16 vector; /* kernel uses to write allocated vector */
- u16 entry; /* driver uses to specify entry, OS writes */
-};
-#endif
-#undef pci_enable_msi
-#define pci_enable_msi(a) -ENOTSUPP
-#undef pci_disable_msi
-#define pci_disable_msi(a) do {} while (0)
-#undef pci_enable_msix
-#define pci_enable_msix(a, b, c) -ENOTSUPP
-#undef pci_disable_msix
-#define pci_disable_msix(a) do {} while (0)
-#define msi_remove_pci_irq_vectors(a) do {} while (0)
-#endif /* CONFIG_PCI_MSI */
-#ifdef DISABLE_PM
-#undef CONFIG_PM
-#endif
-
-#ifdef DISABLE_NET_POLL_CONTROLLER
-#undef CONFIG_NET_POLL_CONTROLLER
-#endif
-
-#ifndef PMSG_SUSPEND
-#define PMSG_SUSPEND 3
-#endif
-
-/* generic boolean compatibility */
-#undef TRUE
-#undef FALSE
-#define TRUE true
-#define FALSE false
-#ifdef GCC_VERSION
-#if ( GCC_VERSION < 3000 )
-#define _Bool char
-#endif
-#else
-#define _Bool char
-#endif
-
-/* kernels less than 2.4.14 don't have this */
-#ifndef ETH_P_8021Q
-#define ETH_P_8021Q 0x8100
-#endif
-
-#ifndef module_param
-#define module_param(v,t,p) MODULE_PARM(v, "i");
-#endif
-
-#ifndef DMA_64BIT_MASK
-#define DMA_64BIT_MASK 0xffffffffffffffffULL
-#endif
-
-#ifndef DMA_32BIT_MASK
-#define DMA_32BIT_MASK 0x00000000ffffffffULL
-#endif
-
-#ifndef PCI_CAP_ID_EXP
-#define PCI_CAP_ID_EXP 0x10
-#endif
-
-#ifndef PCIE_LINK_STATE_L0S
-#define PCIE_LINK_STATE_L0S 1
-#endif
-#ifndef PCIE_LINK_STATE_L1
-#define PCIE_LINK_STATE_L1 2
-#endif
-
-#ifndef mmiowb
-#ifdef CONFIG_IA64
-#define mmiowb() asm volatile ("mf.a" ::: "memory")
-#else
-#define mmiowb()
-#endif
-#endif
-
-#ifndef SET_NETDEV_DEV
-#define SET_NETDEV_DEV(net, pdev)
-#endif
-
-#if !defined(HAVE_FREE_NETDEV) && ( LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) )
-#define free_netdev(x) kfree(x)
-#endif
-
-#ifdef HAVE_POLL_CONTROLLER
-#define CONFIG_NET_POLL_CONTROLLER
-#endif
-
-#ifndef SKB_DATAREF_SHIFT
-/* if we do not have the infrastructure to detect if skb_header is cloned
- just return false in all cases */
-#define skb_header_cloned(x) 0
-#endif
-
-#ifndef NETIF_F_GSO
-#define gso_size tso_size
-#define gso_segs tso_segs
-#endif
-
-#ifndef NETIF_F_GRO
-#define vlan_gro_receive(_napi, _vlgrp, _vlan, _skb) \
- vlan_hwaccel_receive_skb(_skb, _vlgrp, _vlan)
-#define napi_gro_receive(_napi, _skb) netif_receive_skb(_skb)
-#endif
-
-#ifndef NETIF_F_SCTP_CSUM
-#define NETIF_F_SCTP_CSUM 0
-#endif
-
-#ifndef NETIF_F_LRO
-#define NETIF_F_LRO (1 << 15)
-#endif
-
-#ifndef NETIF_F_NTUPLE
-#define NETIF_F_NTUPLE (1 << 27)
-#endif
-
-#ifndef IPPROTO_SCTP
-#define IPPROTO_SCTP 132
-#endif
-
-#ifndef CHECKSUM_PARTIAL
-#define CHECKSUM_PARTIAL CHECKSUM_HW
-#define CHECKSUM_COMPLETE CHECKSUM_HW
-#endif
-
-#ifndef __read_mostly
-#define __read_mostly
-#endif
-
-#ifndef MII_RESV1
-#define MII_RESV1 0x17 /* Reserved... */
-#endif
-
-#ifndef unlikely
-#define unlikely(_x) _x
-#define likely(_x) _x
-#endif
-
-#ifndef WARN_ON
-#define WARN_ON(x)
-#endif
-
-#ifndef PCI_DEVICE
-#define PCI_DEVICE(vend,dev) \
- .vendor = (vend), .device = (dev), \
- .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-#endif
-
-#ifndef node_online
-#define node_online(node) ((node) == 0)
-#endif
-
-#ifndef num_online_cpus
-#define num_online_cpus() smp_num_cpus
-#endif
-
-#ifndef cpu_online
-#define cpu_online(cpuid) test_bit((cpuid), &cpu_online_map)
-#endif
-
-#ifndef _LINUX_RANDOM_H
-#include <linux/random.h>
-#endif
-
-#ifndef DECLARE_BITMAP
-#ifndef BITS_TO_LONGS
-#define BITS_TO_LONGS(bits) (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
-#endif
-#define DECLARE_BITMAP(name,bits) long name[BITS_TO_LONGS(bits)]
-#endif
-
-#ifndef VLAN_HLEN
-#define VLAN_HLEN 4
-#endif
-
-#ifndef VLAN_ETH_HLEN
-#define VLAN_ETH_HLEN 18
-#endif
-
-#ifndef VLAN_ETH_FRAME_LEN
-#define VLAN_ETH_FRAME_LEN 1518
-#endif
-
-#if !defined(IXGBE_DCA) && !defined(IGB_DCA)
-#define dca_get_tag(b) 0
-#define dca_add_requester(a) -1
-#define dca_remove_requester(b) do { } while(0)
-#define DCA_PROVIDER_ADD 0x0001
-#define DCA_PROVIDER_REMOVE 0x0002
-#endif
-
-#ifndef DCA_GET_TAG_TWO_ARGS
-#define dca3_get_tag(a,b) dca_get_tag(b)
-#endif
-
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-#if defined(__i386__) || defined(__x86_64__)
-#define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-#endif
-#endif
-
-/* taken from 2.6.24 definition in linux/kernel.h */
-#ifndef IS_ALIGNED
-#define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0)
-#endif
-
-#ifdef IS_ENABLED
-#undef IS_ENABLED
-#undef __ARG_PLACEHOLDER_1
-#undef config_enabled
-#undef _config_enabled
-#undef __config_enabled
-#undef ___config_enabled
-#endif
-
-#define __ARG_PLACEHOLDER_1 0,
-#define config_enabled(cfg) _config_enabled(cfg)
-#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value)
-#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0)
-#define ___config_enabled(__ignored, val, ...) val
-
-#define IS_ENABLED(option) \
- (config_enabled(option) || config_enabled(option##_MODULE))
-
-#if !defined(NETIF_F_HW_VLAN_TX) && !defined(NETIF_F_HW_VLAN_CTAG_TX)
-struct _kc_vlan_ethhdr {
- unsigned char h_dest[ETH_ALEN];
- unsigned char h_source[ETH_ALEN];
- __be16 h_vlan_proto;
- __be16 h_vlan_TCI;
- __be16 h_vlan_encapsulated_proto;
-};
-#define vlan_ethhdr _kc_vlan_ethhdr
-struct _kc_vlan_hdr {
- __be16 h_vlan_TCI;
- __be16 h_vlan_encapsulated_proto;
-};
-#define vlan_hdr _kc_vlan_hdr
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) )
-#define vlan_tx_tag_present(_skb) 0
-#define vlan_tx_tag_get(_skb) 0
-#endif
-#endif /* NETIF_F_HW_VLAN_TX && NETIF_F_HW_VLAN_CTAG_TX */
-
-#ifndef VLAN_PRIO_SHIFT
-#define VLAN_PRIO_SHIFT 13
-#endif
-
-
-#ifndef __GFP_COLD
-#define __GFP_COLD 0
-#endif
-
-#ifndef __GFP_COMP
-#define __GFP_COMP 0
-#endif
-
-/*****************************************************************************/
-/* Installations with ethtool version without eeprom, adapter id, or statistics
- * support */
-
-#ifndef ETH_GSTRING_LEN
-#define ETH_GSTRING_LEN 32
-#endif
-
-#ifndef ETHTOOL_GSTATS
-#define ETHTOOL_GSTATS 0x1d
-#undef ethtool_drvinfo
-#define ethtool_drvinfo k_ethtool_drvinfo
-struct k_ethtool_drvinfo {
- u32 cmd;
- char driver[32];
- char version[32];
- char fw_version[32];
- char bus_info[32];
- char reserved1[32];
- char reserved2[16];
- u32 n_stats;
- u32 testinfo_len;
- u32 eedump_len;
- u32 regdump_len;
-};
-
-struct ethtool_stats {
- u32 cmd;
- u32 n_stats;
- u64 data[0];
-};
-#endif /* ETHTOOL_GSTATS */
-
-#ifndef ETHTOOL_PHYS_ID
-#define ETHTOOL_PHYS_ID 0x1c
-#endif /* ETHTOOL_PHYS_ID */
-
-#ifndef ETHTOOL_GSTRINGS
-#define ETHTOOL_GSTRINGS 0x1b
-enum ethtool_stringset {
- ETH_SS_TEST = 0,
- ETH_SS_STATS,
-};
-struct ethtool_gstrings {
- u32 cmd; /* ETHTOOL_GSTRINGS */
- u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/
- u32 len; /* number of strings in the string set */
- u8 data[0];
-};
-#endif /* ETHTOOL_GSTRINGS */
-
-#ifndef ETHTOOL_TEST
-#define ETHTOOL_TEST 0x1a
-enum ethtool_test_flags {
- ETH_TEST_FL_OFFLINE = (1 << 0),
- ETH_TEST_FL_FAILED = (1 << 1),
-};
-struct ethtool_test {
- u32 cmd;
- u32 flags;
- u32 reserved;
- u32 len;
- u64 data[0];
-};
-#endif /* ETHTOOL_TEST */
-
-#ifndef ETHTOOL_GEEPROM
-#define ETHTOOL_GEEPROM 0xb
-#undef ETHTOOL_GREGS
-struct ethtool_eeprom {
- u32 cmd;
- u32 magic;
- u32 offset;
- u32 len;
- u8 data[0];
-};
-
-struct ethtool_value {
- u32 cmd;
- u32 data;
-};
-#endif /* ETHTOOL_GEEPROM */
-
-#ifndef ETHTOOL_GLINK
-#define ETHTOOL_GLINK 0xa
-#endif /* ETHTOOL_GLINK */
-
-#ifndef ETHTOOL_GWOL
-#define ETHTOOL_GWOL 0x5
-#define ETHTOOL_SWOL 0x6
-#define SOPASS_MAX 6
-struct ethtool_wolinfo {
- u32 cmd;
- u32 supported;
- u32 wolopts;
- u8 sopass[SOPASS_MAX]; /* SecureOn(tm) password */
-};
-#endif /* ETHTOOL_GWOL */
-
-#ifndef ETHTOOL_GREGS
-#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers */
-#define ethtool_regs _kc_ethtool_regs
-/* for passing big chunks of data */
-struct _kc_ethtool_regs {
- u32 cmd;
- u32 version; /* driver-specific, indicates different chips/revs */
- u32 len; /* bytes */
- u8 data[0];
-};
-#endif /* ETHTOOL_GREGS */
-
-#ifndef ETHTOOL_GMSGLVL
-#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */
-#endif
-#ifndef ETHTOOL_SMSGLVL
-#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */
-#endif
-#ifndef ETHTOOL_NWAY_RST
-#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv */
-#endif
-#ifndef ETHTOOL_GLINK
-#define ETHTOOL_GLINK 0x0000000a /* Get link status */
-#endif
-#ifndef ETHTOOL_GEEPROM
-#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */
-#endif
-#ifndef ETHTOOL_SEEPROM
-#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */
-#endif
-#ifndef ETHTOOL_GCOALESCE
-#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */
-/* for configuring coalescing parameters of chip */
-#define ethtool_coalesce _kc_ethtool_coalesce
-struct _kc_ethtool_coalesce {
- u32 cmd; /* ETHTOOL_{G,S}COALESCE */
-
- /* How many usecs to delay an RX interrupt after
- * a packet arrives. If 0, only rx_max_coalesced_frames
- * is used.
- */
- u32 rx_coalesce_usecs;
-
- /* How many packets to delay an RX interrupt after
- * a packet arrives. If 0, only rx_coalesce_usecs is
- * used. It is illegal to set both usecs and max frames
- * to zero as this would cause RX interrupts to never be
- * generated.
- */
- u32 rx_max_coalesced_frames;
-
- /* Same as above two parameters, except that these values
- * apply while an IRQ is being serviced by the host. Not
- * all cards support this feature and the values are ignored
- * in that case.
- */
- u32 rx_coalesce_usecs_irq;
- u32 rx_max_coalesced_frames_irq;
-
- /* How many usecs to delay a TX interrupt after
- * a packet is sent. If 0, only tx_max_coalesced_frames
- * is used.
- */
- u32 tx_coalesce_usecs;
-
- /* How many packets to delay a TX interrupt after
- * a packet is sent. If 0, only tx_coalesce_usecs is
- * used. It is illegal to set both usecs and max frames
- * to zero as this would cause TX interrupts to never be
- * generated.
- */
- u32 tx_max_coalesced_frames;
-
- /* Same as above two parameters, except that these values
- * apply while an IRQ is being serviced by the host. Not
- * all cards support this feature and the values are ignored
- * in that case.
- */
- u32 tx_coalesce_usecs_irq;
- u32 tx_max_coalesced_frames_irq;
-
- /* How many usecs to delay in-memory statistics
- * block updates. Some drivers do not have an in-memory
- * statistic block, and in such cases this value is ignored.
- * This value must not be zero.
- */
- u32 stats_block_coalesce_usecs;
-
- /* Adaptive RX/TX coalescing is an algorithm implemented by
- * some drivers to improve latency under low packet rates and
- * improve throughput under high packet rates. Some drivers
- * only implement one of RX or TX adaptive coalescing. Anything
- * not implemented by the driver causes these values to be
- * silently ignored.
- */
- u32 use_adaptive_rx_coalesce;
- u32 use_adaptive_tx_coalesce;
-
- /* When the packet rate (measured in packets per second)
- * is below pkt_rate_low, the {rx,tx}_*_low parameters are
- * used.
- */
- u32 pkt_rate_low;
- u32 rx_coalesce_usecs_low;
- u32 rx_max_coalesced_frames_low;
- u32 tx_coalesce_usecs_low;
- u32 tx_max_coalesced_frames_low;
-
- /* When the packet rate is below pkt_rate_high but above
- * pkt_rate_low (both measured in packets per second) the
- * normal {rx,tx}_* coalescing parameters are used.
- */
-
- /* When the packet rate is (measured in packets per second)
- * is above pkt_rate_high, the {rx,tx}_*_high parameters are
- * used.
- */
- u32 pkt_rate_high;
- u32 rx_coalesce_usecs_high;
- u32 rx_max_coalesced_frames_high;
- u32 tx_coalesce_usecs_high;
- u32 tx_max_coalesced_frames_high;
-
- /* How often to do adaptive coalescing packet rate sampling,
- * measured in seconds. Must not be zero.
- */
- u32 rate_sample_interval;
-};
-#endif /* ETHTOOL_GCOALESCE */
-
-#ifndef ETHTOOL_SCOALESCE
-#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */
-#endif
-#ifndef ETHTOOL_GRINGPARAM
-#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */
-/* for configuring RX/TX ring parameters */
-#define ethtool_ringparam _kc_ethtool_ringparam
-struct _kc_ethtool_ringparam {
- u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */
-
- /* Read only attributes. These indicate the maximum number
- * of pending RX/TX ring entries the driver will allow the
- * user to set.
- */
- u32 rx_max_pending;
- u32 rx_mini_max_pending;
- u32 rx_jumbo_max_pending;
- u32 tx_max_pending;
-
- /* Values changeable by the user. The valid values are
- * in the range 1 to the "*_max_pending" counterpart above.
- */
- u32 rx_pending;
- u32 rx_mini_pending;
- u32 rx_jumbo_pending;
- u32 tx_pending;
-};
-#endif /* ETHTOOL_GRINGPARAM */
-
-#ifndef ETHTOOL_SRINGPARAM
-#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */
-#endif
-#ifndef ETHTOOL_GPAUSEPARAM
-#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */
-/* for configuring link flow control parameters */
-#define ethtool_pauseparam _kc_ethtool_pauseparam
-struct _kc_ethtool_pauseparam {
- u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */
-
- /* If the link is being auto-negotiated (via ethtool_cmd.autoneg
- * being true) the user may set 'autoneg' here non-zero to have the
- * pause parameters be auto-negotiated too. In such a case, the
- * {rx,tx}_pause values below determine what capabilities are
- * advertised.
- *
- * If 'autoneg' is zero or the link is not being auto-negotiated,
- * then {rx,tx}_pause force the driver to use/not-use pause
- * flow control.
- */
- u32 autoneg;
- u32 rx_pause;
- u32 tx_pause;
-};
-#endif /* ETHTOOL_GPAUSEPARAM */
-
-#ifndef ETHTOOL_SPAUSEPARAM
-#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */
-#endif
-#ifndef ETHTOOL_GRXCSUM
-#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_SRXCSUM
-#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_GTXCSUM
-#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_STXCSUM
-#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_GSG
-#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable
- * (ethtool_value) */
-#endif
-#ifndef ETHTOOL_SSG
-#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable
- * (ethtool_value). */
-#endif
-#ifndef ETHTOOL_TEST
-#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */
-#endif
-#ifndef ETHTOOL_GSTRINGS
-#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */
-#endif
-#ifndef ETHTOOL_PHYS_ID
-#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */
-#endif
-#ifndef ETHTOOL_GSTATS
-#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
-#endif
-#ifndef ETHTOOL_GTSO
-#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_STSO
-#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */
-#endif
-
-#ifndef ETHTOOL_BUSINFO_LEN
-#define ETHTOOL_BUSINFO_LEN 32
-#endif
-
-#ifndef RHEL_RELEASE_VERSION
-#define RHEL_RELEASE_VERSION(a,b) (((a) << 8) + (b))
-#endif
-#ifndef AX_RELEASE_VERSION
-#define AX_RELEASE_VERSION(a,b) (((a) << 8) + (b))
-#endif
-
-#ifndef AX_RELEASE_CODE
-#define AX_RELEASE_CODE 0
-#endif
-
-#if (AX_RELEASE_CODE && AX_RELEASE_CODE == AX_RELEASE_VERSION(3,0))
-#define RHEL_RELEASE_CODE RHEL_RELEASE_VERSION(5,0)
-#elif (AX_RELEASE_CODE && AX_RELEASE_CODE == AX_RELEASE_VERSION(3,1))
-#define RHEL_RELEASE_CODE RHEL_RELEASE_VERSION(5,1)
-#elif (AX_RELEASE_CODE && AX_RELEASE_CODE == AX_RELEASE_VERSION(3,2))
-#define RHEL_RELEASE_CODE RHEL_RELEASE_VERSION(5,3)
-#endif
-
-#ifndef RHEL_RELEASE_CODE
-/* NOTE: RHEL_RELEASE_* introduced in RHEL4.5 */
-#define RHEL_RELEASE_CODE 0
-#endif
-
-/* SuSE version macro is the same as Linux kernel version */
-#ifndef SLE_VERSION
-#define SLE_VERSION(a,b,c) KERNEL_VERSION(a,b,c)
-#endif
-#ifdef CONFIG_SUSE_KERNEL
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 57))
-/* SLES12SP3 is at least 4.4.57+ based */
-#define SLE_VERSION_CODE SLE_VERSION(12, 3, 0)
-#elif ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,28) )
-/* SLES12 is at least 3.12.28+ based */
-#define SLE_VERSION_CODE SLE_VERSION(12,0,0)
-#elif ((LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,61)) && \
- (LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)))
-/* SLES11 SP3 is at least 3.0.61+ based */
-#define SLE_VERSION_CODE SLE_VERSION(11,3,0)
-#elif ( LINUX_VERSION_CODE == KERNEL_VERSION(2,6,32) )
-/* SLES11 SP1 is 2.6.32 based */
-#define SLE_VERSION_CODE SLE_VERSION(11,1,0)
-#elif ( LINUX_VERSION_CODE == KERNEL_VERSION(2,6,27) )
-/* SLES11 GA is 2.6.27 based */
-#define SLE_VERSION_CODE SLE_VERSION(11,0,0)
-#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(x,y,z) */
-#endif /* CONFIG_SUSE_KERNEL */
-#ifndef SLE_VERSION_CODE
-#define SLE_VERSION_CODE 0
-#endif /* SLE_VERSION_CODE */
-
-/* Ubuntu release and kernel codes must be specified from Makefile */
-#ifndef UBUNTU_RELEASE_VERSION
-#define UBUNTU_RELEASE_VERSION(a,b) (((a) * 100) + (b))
-#endif
-#ifndef UBUNTU_KERNEL_VERSION
-#define UBUNTU_KERNEL_VERSION(a,b,c,abi,upload) (((a) << 40) + ((b) << 32) + ((c) << 24) + ((abi) << 8) + (upload))
-#endif
-#ifndef UBUNTU_RELEASE_CODE
-#define UBUNTU_RELEASE_CODE 0
-#endif
-#ifndef UBUNTU_KERNEL_CODE
-#define UBUNTU_KERNEL_CODE 0
-#endif
-
-#ifdef __KLOCWORK__
-#ifdef ARRAY_SIZE
-#undef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#endif
-#endif /* __KLOCWORK__ */
-
-/*****************************************************************************/
-/* 2.4.3 => 2.4.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) )
-
-/**************************************/
-/* PCI DRIVER API */
-
-#ifndef pci_set_dma_mask
-#define pci_set_dma_mask _kc_pci_set_dma_mask
-extern int _kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask);
-#endif
-
-#ifndef pci_request_regions
-#define pci_request_regions _kc_pci_request_regions
-extern int _kc_pci_request_regions(struct pci_dev *pdev, char *res_name);
-#endif
-
-#ifndef pci_release_regions
-#define pci_release_regions _kc_pci_release_regions
-extern void _kc_pci_release_regions(struct pci_dev *pdev);
-#endif
-
-/**************************************/
-/* NETWORK DRIVER API */
-
-#ifndef alloc_etherdev
-#define alloc_etherdev _kc_alloc_etherdev
-extern struct net_device * _kc_alloc_etherdev(int sizeof_priv);
-#endif
-
-#ifndef is_valid_ether_addr
-#define is_valid_ether_addr _kc_is_valid_ether_addr
-extern int _kc_is_valid_ether_addr(u8 *addr);
-#endif
-
-/**************************************/
-/* MISCELLANEOUS */
-
-#ifndef INIT_TQUEUE
-#define INIT_TQUEUE(_tq, _routine, _data) \
- do { \
- INIT_LIST_HEAD(&(_tq)->list); \
- (_tq)->sync = 0; \
- (_tq)->routine = _routine; \
- (_tq)->data = _data; \
- } while (0)
-#endif
-
-#endif /* 2.4.3 => 2.4.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5) )
-/* Generic MII registers. */
-#define MII_BMCR 0x00 /* Basic mode control register */
-#define MII_BMSR 0x01 /* Basic mode status register */
-#define MII_PHYSID1 0x02 /* PHYS ID 1 */
-#define MII_PHYSID2 0x03 /* PHYS ID 2 */
-#define MII_ADVERTISE 0x04 /* Advertisement control reg */
-#define MII_LPA 0x05 /* Link partner ability reg */
-#define MII_EXPANSION 0x06 /* Expansion register */
-/* Basic mode control register. */
-#define BMCR_FULLDPLX 0x0100 /* Full duplex */
-#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
-/* Basic mode status register. */
-#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
-#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
-#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
-#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
-#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
-#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
-/* Advertisement control register. */
-#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
-#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
- ADVERTISE_100HALF | ADVERTISE_100FULL)
-/* Expansion register for auto-negotiation. */
-#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
-#endif
-
-/*****************************************************************************/
-/* 2.4.6 => 2.4.3 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) )
-
-#ifndef pci_set_power_state
-#define pci_set_power_state _kc_pci_set_power_state
-extern int _kc_pci_set_power_state(struct pci_dev *dev, int state);
-#endif
-
-#ifndef pci_enable_wake
-#define pci_enable_wake _kc_pci_enable_wake
-extern int _kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable);
-#endif
-
-#ifndef pci_disable_device
-#define pci_disable_device _kc_pci_disable_device
-extern void _kc_pci_disable_device(struct pci_dev *pdev);
-#endif
-
-/* PCI PM entry point syntax changed, so don't support suspend/resume */
-#undef CONFIG_PM
-
-#endif /* 2.4.6 => 2.4.3 */
-
-#ifndef HAVE_PCI_SET_MWI
-#define pci_set_mwi(X) pci_write_config_word(X, \
- PCI_COMMAND, adapter->hw.bus.pci_cmd_word | \
- PCI_COMMAND_INVALIDATE);
-#define pci_clear_mwi(X) pci_write_config_word(X, \
- PCI_COMMAND, adapter->hw.bus.pci_cmd_word & \
- ~PCI_COMMAND_INVALIDATE);
-#endif
-
-/*****************************************************************************/
-/* 2.4.10 => 2.4.9 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) )
-
-/**************************************/
-/* MODULE API */
-
-#ifndef MODULE_LICENSE
- #define MODULE_LICENSE(X)
-#endif
-
-/**************************************/
-/* OTHER */
-
-#undef min
-#define min(x,y) ({ \
- const typeof(x) _x = (x); \
- const typeof(y) _y = (y); \
- (void) (&_x == &_y); \
- _x < _y ? _x : _y; })
-
-#undef max
-#define max(x,y) ({ \
- const typeof(x) _x = (x); \
- const typeof(y) _y = (y); \
- (void) (&_x == &_y); \
- _x > _y ? _x : _y; })
-
-#define min_t(type,x,y) ({ \
- type _x = (x); \
- type _y = (y); \
- _x < _y ? _x : _y; })
-
-#define max_t(type,x,y) ({ \
- type _x = (x); \
- type _y = (y); \
- _x > _y ? _x : _y; })
-
-#ifndef list_for_each_safe
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-#endif
-
-#ifndef ____cacheline_aligned_in_smp
-#ifdef CONFIG_SMP
-#define ____cacheline_aligned_in_smp ____cacheline_aligned
-#else
-#define ____cacheline_aligned_in_smp
-#endif /* CONFIG_SMP */
-#endif
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8) )
-extern int _kc_snprintf(char * buf, size_t size, const char *fmt, ...);
-#define snprintf(buf, size, fmt, args...) _kc_snprintf(buf, size, fmt, ##args)
-extern int _kc_vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
-#define vsnprintf(buf, size, fmt, args) _kc_vsnprintf(buf, size, fmt, args)
-#else /* 2.4.8 => 2.4.9 */
-extern int snprintf(char * buf, size_t size, const char *fmt, ...);
-extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
-#endif
-#endif /* 2.4.10 -> 2.4.6 */
-
-
-/*****************************************************************************/
-/* 2.4.12 => 2.4.10 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,12) )
-#ifndef HAVE_NETIF_MSG
-#define HAVE_NETIF_MSG 1
-enum {
- NETIF_MSG_DRV = 0x0001,
- NETIF_MSG_PROBE = 0x0002,
- NETIF_MSG_LINK = 0x0004,
- NETIF_MSG_TIMER = 0x0008,
- NETIF_MSG_IFDOWN = 0x0010,
- NETIF_MSG_IFUP = 0x0020,
- NETIF_MSG_RX_ERR = 0x0040,
- NETIF_MSG_TX_ERR = 0x0080,
- NETIF_MSG_TX_QUEUED = 0x0100,
- NETIF_MSG_INTR = 0x0200,
- NETIF_MSG_TX_DONE = 0x0400,
- NETIF_MSG_RX_STATUS = 0x0800,
- NETIF_MSG_PKTDATA = 0x1000,
- NETIF_MSG_HW = 0x2000,
- NETIF_MSG_WOL = 0x4000,
-};
-
-#define netif_msg_drv(p) ((p)->msg_enable & NETIF_MSG_DRV)
-#define netif_msg_probe(p) ((p)->msg_enable & NETIF_MSG_PROBE)
-#define netif_msg_link(p) ((p)->msg_enable & NETIF_MSG_LINK)
-#define netif_msg_timer(p) ((p)->msg_enable & NETIF_MSG_TIMER)
-#define netif_msg_ifdown(p) ((p)->msg_enable & NETIF_MSG_IFDOWN)
-#define netif_msg_ifup(p) ((p)->msg_enable & NETIF_MSG_IFUP)
-#define netif_msg_rx_err(p) ((p)->msg_enable & NETIF_MSG_RX_ERR)
-#define netif_msg_tx_err(p) ((p)->msg_enable & NETIF_MSG_TX_ERR)
-#define netif_msg_tx_queued(p) ((p)->msg_enable & NETIF_MSG_TX_QUEUED)
-#define netif_msg_intr(p) ((p)->msg_enable & NETIF_MSG_INTR)
-#define netif_msg_tx_done(p) ((p)->msg_enable & NETIF_MSG_TX_DONE)
-#define netif_msg_rx_status(p) ((p)->msg_enable & NETIF_MSG_RX_STATUS)
-#define netif_msg_pktdata(p) ((p)->msg_enable & NETIF_MSG_PKTDATA)
-#endif /* !HAVE_NETIF_MSG */
-#endif /* 2.4.12 => 2.4.10 */
-
-/*****************************************************************************/
-/* 2.4.13 => 2.4.12 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) )
-
-/**************************************/
-/* PCI DMA MAPPING */
-
-#ifndef virt_to_page
- #define virt_to_page(v) (mem_map + (virt_to_phys(v) >> PAGE_SHIFT))
-#endif
-
-#ifndef pci_map_page
-#define pci_map_page _kc_pci_map_page
-extern u64 _kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset, size_t size, int direction);
-#endif
-
-#ifndef pci_unmap_page
-#define pci_unmap_page _kc_pci_unmap_page
-extern void _kc_pci_unmap_page(struct pci_dev *dev, u64 dma_addr, size_t size, int direction);
-#endif
-
-/* pci_set_dma_mask takes dma_addr_t, which is only 32-bits prior to 2.4.13 */
-
-#undef DMA_32BIT_MASK
-#define DMA_32BIT_MASK 0xffffffff
-#undef DMA_64BIT_MASK
-#define DMA_64BIT_MASK 0xffffffff
-
-/**************************************/
-/* OTHER */
-
-#ifndef cpu_relax
-#define cpu_relax() rep_nop()
-#endif
-
-struct vlan_ethhdr {
- unsigned char h_dest[ETH_ALEN];
- unsigned char h_source[ETH_ALEN];
- unsigned short h_vlan_proto;
- unsigned short h_vlan_TCI;
- unsigned short h_vlan_encapsulated_proto;
-};
-#endif /* 2.4.13 => 2.4.12 */
-
-/*****************************************************************************/
-/* 2.4.17 => 2.4.12 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17) )
-
-#ifndef __devexit_p
- #define __devexit_p(x) &(x)
-#endif
-
-#else
- /* For Kernel 3.8 these are not defined - so undefine all */
- #undef __devexit_p
- #undef __devexit
- #undef __devinit
- #undef __devinitdata
- #define __devexit_p(x) &(x)
- #define __devexit
- #define __devinit
- #define __devinitdata
-
-#endif /* 2.4.17 => 2.4.13 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) )
-#define NETIF_MSG_HW 0x2000
-#define NETIF_MSG_WOL 0x4000
-
-#ifndef netif_msg_hw
-#define netif_msg_hw(p) ((p)->msg_enable & NETIF_MSG_HW)
-#endif
-#ifndef netif_msg_wol
-#define netif_msg_wol(p) ((p)->msg_enable & NETIF_MSG_WOL)
-#endif
-#endif /* 2.4.18 */
-
-/*****************************************************************************/
-
-/*****************************************************************************/
-/* 2.4.20 => 2.4.19 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20) )
-
-/* we won't support NAPI on less than 2.4.20 */
-#ifdef NAPI
-#undef NAPI
-#endif
-
-#endif /* 2.4.20 => 2.4.19 */
-
-/*****************************************************************************/
-/* 2.4.22 => 2.4.17 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) )
-#define pci_name(x) ((x)->slot_name)
-
-#ifndef SUPPORTED_10000baseT_Full
-#define SUPPORTED_10000baseT_Full (1 << 12)
-#endif
-#ifndef ADVERTISED_10000baseT_Full
-#define ADVERTISED_10000baseT_Full (1 << 12)
-#endif
-#endif
-
-/*****************************************************************************/
-/* 2.4.22 => 2.4.17 */
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) )
-#ifndef IGB_NO_LRO
-#define IGB_NO_LRO
-#endif
-#endif
-
-/*****************************************************************************/
-/*****************************************************************************/
-/* 2.4.23 => 2.4.22 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) )
-/*****************************************************************************/
-#ifdef NAPI
-#ifndef netif_poll_disable
-#define netif_poll_disable(x) _kc_netif_poll_disable(x)
-static inline void _kc_netif_poll_disable(struct net_device *netdev)
-{
- while (test_and_set_bit(__LINK_STATE_RX_SCHED, &netdev->state)) {
- /* No hurry */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
-}
-#endif
-#ifndef netif_poll_enable
-#define netif_poll_enable(x) _kc_netif_poll_enable(x)
-static inline void _kc_netif_poll_enable(struct net_device *netdev)
-{
- clear_bit(__LINK_STATE_RX_SCHED, &netdev->state);
-}
-#endif
-#endif /* NAPI */
-#ifndef netif_tx_disable
-#define netif_tx_disable(x) _kc_netif_tx_disable(x)
-static inline void _kc_netif_tx_disable(struct net_device *dev)
-{
- spin_lock_bh(&dev->xmit_lock);
- netif_stop_queue(dev);
- spin_unlock_bh(&dev->xmit_lock);
-}
-#endif
-#else /* 2.4.23 => 2.4.22 */
-#define HAVE_SCTP
-#endif /* 2.4.23 => 2.4.22 */
-
-/*****************************************************************************/
-/* 2.6.4 => 2.6.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25) || \
- ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \
- LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) )
-#define ETHTOOL_OPS_COMPAT
-#endif /* 2.6.4 => 2.6.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) )
-#define __user
-#endif /* < 2.4.27 */
-
-/*****************************************************************************/
-/* 2.5.71 => 2.4.x */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,71) )
-#define sk_protocol protocol
-#define pci_get_device pci_find_device
-#endif /* 2.5.70 => 2.4.x */
-
-/*****************************************************************************/
-/* < 2.4.27 or 2.6.0 <= 2.6.5 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) || \
- ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \
- LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ) )
-
-#ifndef netif_msg_init
-#define netif_msg_init _kc_netif_msg_init
-static inline u32 _kc_netif_msg_init(int debug_value, int default_msg_enable_bits)
-{
- /* use default */
- if (debug_value < 0 || debug_value >= (sizeof(u32) * 8))
- return default_msg_enable_bits;
- if (debug_value == 0) /* no output */
- return 0;
- /* set low N bits */
- return (1 << debug_value) -1;
-}
-#endif
-
-#endif /* < 2.4.27 or 2.6.0 <= 2.6.5 */
-/*****************************************************************************/
-#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) || \
- (( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) && \
- ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) )))
-#define netdev_priv(x) x->priv
-#endif
-
-/*****************************************************************************/
-/* <= 2.5.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) )
-#include <linux/rtnetlink.h>
-#undef pci_register_driver
-#define pci_register_driver pci_module_init
-
-/*
- * Most of the dma compat code is copied/modified from the 2.4.37
- * /include/linux/libata-compat.h header file
- */
-/* These definitions mirror those in pci.h, so they can be used
- * interchangeably with their PCI_ counterparts */
-enum dma_data_direction {
- DMA_BIDIRECTIONAL = 0,
- DMA_TO_DEVICE = 1,
- DMA_FROM_DEVICE = 2,
- DMA_NONE = 3,
-};
-
-struct device {
- struct pci_dev pdev;
-};
-
-static inline struct pci_dev *to_pci_dev (struct device *dev)
-{
- return (struct pci_dev *) dev;
-}
-static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
-{
- return (struct device *) pdev;
-}
-
-#define pdev_printk(lvl, pdev, fmt, args...) \
- printk("%s %s: " fmt, lvl, pci_name(pdev), ## args)
-#define dev_err(dev, fmt, args...) \
- pdev_printk(KERN_ERR, to_pci_dev(dev), fmt, ## args)
-#define dev_info(dev, fmt, args...) \
- pdev_printk(KERN_INFO, to_pci_dev(dev), fmt, ## args)
-#define dev_warn(dev, fmt, args...) \
- pdev_printk(KERN_WARNING, to_pci_dev(dev), fmt, ## args)
-#define dev_notice(dev, fmt, args...) \
- pdev_printk(KERN_NOTICE, to_pci_dev(dev), fmt, ## args)
-#define dev_dbg(dev, fmt, args...) \
- pdev_printk(KERN_DEBUG, to_pci_dev(dev), fmt, ## args)
-
-/* NOTE: dangerous! we ignore the 'gfp' argument */
-#define dma_alloc_coherent(dev,sz,dma,gfp) \
- pci_alloc_consistent(to_pci_dev(dev),(sz),(dma))
-#define dma_free_coherent(dev,sz,addr,dma_addr) \
- pci_free_consistent(to_pci_dev(dev),(sz),(addr),(dma_addr))
-
-#define dma_map_page(dev,a,b,c,d) \
- pci_map_page(to_pci_dev(dev),(a),(b),(c),(d))
-#define dma_unmap_page(dev,a,b,c) \
- pci_unmap_page(to_pci_dev(dev),(a),(b),(c))
-
-#define dma_map_single(dev,a,b,c) \
- pci_map_single(to_pci_dev(dev),(a),(b),(c))
-#define dma_unmap_single(dev,a,b,c) \
- pci_unmap_single(to_pci_dev(dev),(a),(b),(c))
-
-#define dma_map_sg(dev, sg, nents, dir) \
- pci_map_sg(to_pci_dev(dev), (sg), (nents), (dir)
-#define dma_unmap_sg(dev, sg, nents, dir) \
- pci_unmap_sg(to_pci_dev(dev), (sg), (nents), (dir)
-
-#define dma_sync_single(dev,a,b,c) \
- pci_dma_sync_single(to_pci_dev(dev),(a),(b),(c))
-
-/* for range just sync everything, that's all the pci API can do */
-#define dma_sync_single_range(dev,addr,off,sz,dir) \
- pci_dma_sync_single(to_pci_dev(dev),(addr),(off)+(sz),(dir))
-
-#define dma_set_mask(dev,mask) \
- pci_set_dma_mask(to_pci_dev(dev),(mask))
-
-/* hlist_* code - double linked lists */
-struct hlist_head {
- struct hlist_node *first;
-};
-
-struct hlist_node {
- struct hlist_node *next, **pprev;
-};
-
-static inline void __hlist_del(struct hlist_node *n)
-{
- struct hlist_node *next = n->next;
- struct hlist_node **pprev = n->pprev;
- *pprev = next;
- if (next)
- next->pprev = pprev;
-}
-
-static inline void hlist_del(struct hlist_node *n)
-{
- __hlist_del(n);
- n->next = NULL;
- n->pprev = NULL;
-}
-
-static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
-{
- struct hlist_node *first = h->first;
- n->next = first;
- if (first)
- first->pprev = &n->next;
- h->first = n;
- n->pprev = &h->first;
-}
-
-static inline int hlist_empty(const struct hlist_head *h)
-{
- return !h->first;
-}
-#define HLIST_HEAD_INIT { .first = NULL }
-#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
-#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
-static inline void INIT_HLIST_NODE(struct hlist_node *h)
-{
- h->next = NULL;
- h->pprev = NULL;
-}
-
-#ifndef might_sleep
-#define might_sleep()
-#endif
-#else
-static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
-{
- return &pdev->dev;
-}
-#endif /* <= 2.5.0 */
-
-/*****************************************************************************/
-/* 2.5.28 => 2.4.23 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) )
-
-#include <linux/tqueue.h>
-#define work_struct tq_struct
-#undef INIT_WORK
-#define INIT_WORK(a,b) INIT_TQUEUE(a,(void (*)(void *))b,a)
-#undef container_of
-#define container_of list_entry
-#define schedule_work schedule_task
-#define flush_scheduled_work flush_scheduled_tasks
-#define cancel_work_sync(x) flush_scheduled_work()
-
-#endif /* 2.5.28 => 2.4.17 */
-
-/*****************************************************************************/
-/* 2.6.0 => 2.5.28 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-#ifndef read_barrier_depends
-#define read_barrier_depends() rmb()
-#endif
-
-#undef get_cpu
-#define get_cpu() smp_processor_id()
-#undef put_cpu
-#define put_cpu() do { } while(0)
-#define MODULE_INFO(version, _version)
-#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
-#define CONFIG_E1000_DISABLE_PACKET_SPLIT 1
-#endif
-#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
-#define CONFIG_IGB_DISABLE_PACKET_SPLIT 1
-#endif
-
-#define dma_set_coherent_mask(dev,mask) 1
-
-#undef dev_put
-#define dev_put(dev) __dev_put(dev)
-
-#ifndef skb_fill_page_desc
-#define skb_fill_page_desc _kc_skb_fill_page_desc
-extern void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size);
-#endif
-
-#undef ALIGN
-#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
-
-#ifndef page_count
-#define page_count(p) atomic_read(&(p)->count)
-#endif
-
-#ifdef MAX_NUMNODES
-#undef MAX_NUMNODES
-#endif
-#define MAX_NUMNODES 1
-
-/* find_first_bit and find_next bit are not defined for most
- * 2.4 kernels (except for the redhat 2.4.21 kernels
- */
-#include <linux/bitops.h>
-#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
-#undef find_next_bit
-#define find_next_bit _kc_find_next_bit
-extern unsigned long _kc_find_next_bit(const unsigned long *addr,
- unsigned long size,
- unsigned long offset);
-#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
-
-
-#ifndef netdev_name
-static inline const char *_kc_netdev_name(const struct net_device *dev)
-{
- if (strchr(dev->name, '%'))
- return "(unregistered net_device)";
- return dev->name;
-}
-#define netdev_name(netdev) _kc_netdev_name(netdev)
-#endif /* netdev_name */
-
-#ifndef strlcpy
-#define strlcpy _kc_strlcpy
-extern size_t _kc_strlcpy(char *dest, const char *src, size_t size);
-#endif /* strlcpy */
-
-#ifndef do_div
-#if BITS_PER_LONG == 64
-# define do_div(n,base) ({ \
- uint32_t __base = (base); \
- uint32_t __rem; \
- __rem = ((uint64_t)(n)) % __base; \
- (n) = ((uint64_t)(n)) / __base; \
- __rem; \
- })
-#elif BITS_PER_LONG == 32
-extern uint32_t _kc__div64_32(uint64_t *dividend, uint32_t divisor);
-# define do_div(n,base) ({ \
- uint32_t __base = (base); \
- uint32_t __rem; \
- if (likely(((n) >> 32) == 0)) { \
- __rem = (uint32_t)(n) % __base; \
- (n) = (uint32_t)(n) / __base; \
- } else \
- __rem = _kc__div64_32(&(n), __base); \
- __rem; \
- })
-#else /* BITS_PER_LONG == ?? */
-# error do_div() does not yet support the C64
-#endif /* BITS_PER_LONG */
-#endif /* do_div */
-
-#ifndef NSEC_PER_SEC
-#define NSEC_PER_SEC 1000000000L
-#endif
-
-#undef HAVE_I2C_SUPPORT
-#else /* 2.6.0 */
-#if IS_ENABLED(CONFIG_I2C_ALGOBIT) && \
- (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(4,9)))
-#define HAVE_I2C_SUPPORT
-#endif /* IS_ENABLED(CONFIG_I2C_ALGOBIT) */
-
-#endif /* 2.6.0 => 2.5.28 */
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) )
-#define dma_pool pci_pool
-#define dma_pool_destroy pci_pool_destroy
-#define dma_pool_alloc pci_pool_alloc
-#define dma_pool_free pci_pool_free
-
-#define dma_pool_create(name,dev,size,align,allocation) \
- pci_pool_create((name),to_pci_dev(dev),(size),(align),(allocation))
-#endif /* < 2.6.3 */
-
-/*****************************************************************************/
-/* 2.6.4 => 2.6.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) )
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif /* 2.6.4 => 2.6.0 */
-
-/*****************************************************************************/
-/* 2.6.5 => 2.6.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) )
-#define dma_sync_single_for_cpu dma_sync_single
-#define dma_sync_single_for_device dma_sync_single
-#define dma_sync_single_range_for_cpu dma_sync_single_range
-#define dma_sync_single_range_for_device dma_sync_single_range
-#ifndef pci_dma_mapping_error
-#define pci_dma_mapping_error _kc_pci_dma_mapping_error
-static inline int _kc_pci_dma_mapping_error(dma_addr_t dma_addr)
-{
- return dma_addr == 0;
-}
-#endif
-#endif /* 2.6.5 => 2.6.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) )
-extern int _kc_scnprintf(char * buf, size_t size, const char *fmt, ...);
-#define scnprintf(buf, size, fmt, args...) _kc_scnprintf(buf, size, fmt, ##args)
-#endif /* < 2.6.4 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,6) )
-/* taken from 2.6 include/linux/bitmap.h */
-#undef bitmap_zero
-#define bitmap_zero _kc_bitmap_zero
-static inline void _kc_bitmap_zero(unsigned long *dst, int nbits)
-{
- if (nbits <= BITS_PER_LONG)
- *dst = 0UL;
- else {
- int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
- memset(dst, 0, len);
- }
-}
-#define random_ether_addr _kc_random_ether_addr
-static inline void _kc_random_ether_addr(u8 *addr)
-{
- get_random_bytes(addr, ETH_ALEN);
- addr[0] &= 0xfe; /* clear multicast */
- addr[0] |= 0x02; /* set local assignment */
-}
-#define page_to_nid(x) 0
-
-#endif /* < 2.6.6 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) )
-#undef if_mii
-#define if_mii _kc_if_mii
-static inline struct mii_ioctl_data *_kc_if_mii(struct ifreq *rq)
-{
- return (struct mii_ioctl_data *) &rq->ifr_ifru;
-}
-
-#ifndef __force
-#define __force
-#endif
-#endif /* < 2.6.7 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) )
-#ifndef PCI_EXP_DEVCTL
-#define PCI_EXP_DEVCTL 8
-#endif
-#ifndef PCI_EXP_DEVCTL_CERE
-#define PCI_EXP_DEVCTL_CERE 0x0001
-#endif
-#define PCI_EXP_FLAGS 2 /* Capabilities register */
-#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */
-#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
-#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
-#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
-#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
-#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
-#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
-#define PCI_EXP_DEVCAP 4 /* Device capabilities */
-#define PCI_EXP_DEVSTA 10 /* Device Status */
-#define msleep(x) do { set_current_state(TASK_UNINTERRUPTIBLE); \
- schedule_timeout((x * HZ)/1000 + 2); \
- } while (0)
-
-#endif /* < 2.6.8 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
-#include <net/dsfield.h>
-#define __iomem
-
-#ifndef kcalloc
-#define kcalloc(n, size, flags) _kc_kzalloc(((n) * (size)), flags)
-extern void *_kc_kzalloc(size_t size, int flags);
-#endif
-#define MSEC_PER_SEC 1000L
-static inline unsigned int _kc_jiffies_to_msecs(const unsigned long j)
-{
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
- return (MSEC_PER_SEC / HZ) * j;
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
- return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
-#else
- return (j * MSEC_PER_SEC) / HZ;
-#endif
-}
-static inline unsigned long _kc_msecs_to_jiffies(const unsigned int m)
-{
- if (m > _kc_jiffies_to_msecs(MAX_JIFFY_OFFSET))
- return MAX_JIFFY_OFFSET;
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
- return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
- return m * (HZ / MSEC_PER_SEC);
-#else
- return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC;
-#endif
-}
-
-#define msleep_interruptible _kc_msleep_interruptible
-static inline unsigned long _kc_msleep_interruptible(unsigned int msecs)
-{
- unsigned long timeout = _kc_msecs_to_jiffies(msecs) + 1;
-
- while (timeout && !signal_pending(current)) {
- __set_current_state(TASK_INTERRUPTIBLE);
- timeout = schedule_timeout(timeout);
- }
- return _kc_jiffies_to_msecs(timeout);
-}
-
-/* Basic mode control register. */
-#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
-
-#ifndef __le16
-#define __le16 u16
-#endif
-#ifndef __le32
-#define __le32 u32
-#endif
-#ifndef __le64
-#define __le64 u64
-#endif
-#ifndef __be16
-#define __be16 u16
-#endif
-#ifndef __be32
-#define __be32 u32
-#endif
-#ifndef __be64
-#define __be64 u64
-#endif
-
-static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
-{
- return (struct vlan_ethhdr *)skb->mac.raw;
-}
-
-/* Wake-On-Lan options. */
-#define WAKE_PHY (1 << 0)
-#define WAKE_UCAST (1 << 1)
-#define WAKE_MCAST (1 << 2)
-#define WAKE_BCAST (1 << 3)
-#define WAKE_ARP (1 << 4)
-#define WAKE_MAGIC (1 << 5)
-#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
-
-#define skb_header_pointer _kc_skb_header_pointer
-static inline void *_kc_skb_header_pointer(const struct sk_buff *skb,
- int offset, int len, void *buffer)
-{
- int hlen = skb_headlen(skb);
-
- if (hlen - offset >= len)
- return skb->data + offset;
-
-#ifdef MAX_SKB_FRAGS
- if (skb_copy_bits(skb, offset, buffer, len) < 0)
- return NULL;
-
- return buffer;
-#else
- return NULL;
-#endif
-
-#ifndef NETDEV_TX_OK
-#define NETDEV_TX_OK 0
-#endif
-#ifndef NETDEV_TX_BUSY
-#define NETDEV_TX_BUSY 1
-#endif
-#ifndef NETDEV_TX_LOCKED
-#define NETDEV_TX_LOCKED -1
-#endif
-}
-
-#ifndef __bitwise
-#define __bitwise
-#endif
-#endif /* < 2.6.9 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
-#ifdef module_param_array_named
-#undef module_param_array_named
-#define module_param_array_named(name, array, type, nump, perm) \
- static struct kparam_array __param_arr_##name \
- = { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type, \
- sizeof(array[0]), array }; \
- module_param_call(name, param_array_set, param_array_get, \
- &__param_arr_##name, perm)
-#endif /* module_param_array_named */
-/*
- * num_online is broken for all < 2.6.10 kernels. This is needed to support
- * Node module parameter of ixgbe.
- */
-#undef num_online_nodes
-#define num_online_nodes(n) 1
-extern DECLARE_BITMAP(_kcompat_node_online_map, MAX_NUMNODES);
-#undef node_online_map
-#define node_online_map _kcompat_node_online_map
-#define pci_get_class pci_find_class
-#endif /* < 2.6.10 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
-#define PCI_D0 0
-#define PCI_D1 1
-#define PCI_D2 2
-#define PCI_D3hot 3
-#define PCI_D3cold 4
-typedef int pci_power_t;
-#define pci_choose_state(pdev,state) state
-#define PMSG_SUSPEND 3
-#define PCI_EXP_LNKCTL 16
-
-#undef NETIF_F_LLTX
-
-#ifndef ARCH_HAS_PREFETCH
-#define prefetch(X)
-#endif
-
-#ifndef NET_IP_ALIGN
-#define NET_IP_ALIGN 2
-#endif
-
-#define KC_USEC_PER_SEC 1000000L
-#define usecs_to_jiffies _kc_usecs_to_jiffies
-static inline unsigned int _kc_jiffies_to_usecs(const unsigned long j)
-{
-#if HZ <= KC_USEC_PER_SEC && !(KC_USEC_PER_SEC % HZ)
- return (KC_USEC_PER_SEC / HZ) * j;
-#elif HZ > KC_USEC_PER_SEC && !(HZ % KC_USEC_PER_SEC)
- return (j + (HZ / KC_USEC_PER_SEC) - 1)/(HZ / KC_USEC_PER_SEC);
-#else
- return (j * KC_USEC_PER_SEC) / HZ;
-#endif
-}
-static inline unsigned long _kc_usecs_to_jiffies(const unsigned int m)
-{
- if (m > _kc_jiffies_to_usecs(MAX_JIFFY_OFFSET))
- return MAX_JIFFY_OFFSET;
-#if HZ <= KC_USEC_PER_SEC && !(KC_USEC_PER_SEC % HZ)
- return (m + (KC_USEC_PER_SEC / HZ) - 1) / (KC_USEC_PER_SEC / HZ);
-#elif HZ > KC_USEC_PER_SEC && !(HZ % KC_USEC_PER_SEC)
- return m * (HZ / KC_USEC_PER_SEC);
-#else
- return (m * HZ + KC_USEC_PER_SEC - 1) / KC_USEC_PER_SEC;
-#endif
-}
-
-#define PCI_EXP_LNKCAP 12 /* Link Capabilities */
-#define PCI_EXP_LNKSTA 18 /* Link Status */
-#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
-#define PCI_EXP_SLTCTL 24 /* Slot Control */
-#define PCI_EXP_SLTSTA 26 /* Slot Status */
-#define PCI_EXP_RTCTL 28 /* Root Control */
-#define PCI_EXP_RTCAP 30 /* Root Capabilities */
-#define PCI_EXP_RTSTA 32 /* Root Status */
-#endif /* < 2.6.11 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) )
-#include <linux/reboot.h>
-#define USE_REBOOT_NOTIFIER
-
-/* Generic MII registers. */
-#define MII_CTRL1000 0x09 /* 1000BASE-T control */
-#define MII_STAT1000 0x0a /* 1000BASE-T status */
-/* Advertisement control register. */
-#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
-#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymmetric pause */
-/* Link partner ability register. */
-#define LPA_PAUSE_CAP 0x0400 /* Can pause */
-#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
-/* 1000BASE-T Control register */
-#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
-#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
-/* 1000BASE-T Status register */
-#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
-#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
-
-#ifndef is_zero_ether_addr
-#define is_zero_ether_addr _kc_is_zero_ether_addr
-static inline int _kc_is_zero_ether_addr(const u8 *addr)
-{
- return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
-}
-#endif /* is_zero_ether_addr */
-#ifndef is_multicast_ether_addr
-#define is_multicast_ether_addr _kc_is_multicast_ether_addr
-static inline int _kc_is_multicast_ether_addr(const u8 *addr)
-{
- return addr[0] & 0x01;
-}
-#endif /* is_multicast_ether_addr */
-#endif /* < 2.6.12 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
-#ifndef kstrdup
-#define kstrdup _kc_kstrdup
-extern char *_kc_kstrdup(const char *s, unsigned int gfp);
-#endif
-#endif /* < 2.6.13 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) )
-#define pm_message_t u32
-#ifndef kzalloc
-#define kzalloc _kc_kzalloc
-extern void *_kc_kzalloc(size_t size, int flags);
-#endif
-
-/* Generic MII registers. */
-#define MII_ESTATUS 0x0f /* Extended Status */
-/* Basic mode status register. */
-#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
-/* Extended status register. */
-#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
-#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
-
-#define SUPPORTED_Pause (1 << 13)
-#define SUPPORTED_Asym_Pause (1 << 14)
-#define ADVERTISED_Pause (1 << 13)
-#define ADVERTISED_Asym_Pause (1 << 14)
-
-#if (!(RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(4,3)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0))))
-#if ((LINUX_VERSION_CODE == KERNEL_VERSION(2,6,9)) && !defined(gfp_t))
-#define gfp_t unsigned
-#else
-typedef unsigned gfp_t;
-#endif
-#endif /* !RHEL4.3->RHEL5.0 */
-
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) )
-#ifdef CONFIG_X86_64
-#define dma_sync_single_range_for_cpu(dev, addr, off, sz, dir) \
- dma_sync_single_for_cpu((dev), (addr), (off) + (sz), (dir))
-#define dma_sync_single_range_for_device(dev, addr, off, sz, dir) \
- dma_sync_single_for_device((dev), (addr), (off) + (sz), (dir))
-#endif
-#endif
-#endif /* < 2.6.14 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) )
-#ifndef vmalloc_node
-#define vmalloc_node(a,b) vmalloc(a)
-#endif /* vmalloc_node*/
-
-#define setup_timer(_timer, _function, _data) \
-do { \
- (_timer)->function = _function; \
- (_timer)->data = _data; \
- init_timer(_timer); \
-} while (0)
-#ifndef device_can_wakeup
-#define device_can_wakeup(dev) (1)
-#endif
-#ifndef device_set_wakeup_enable
-#define device_set_wakeup_enable(dev, val) do{}while(0)
-#endif
-#ifndef device_init_wakeup
-#define device_init_wakeup(dev,val) do {} while (0)
-#endif
-static inline unsigned _kc_compare_ether_addr(const u8 *addr1, const u8 *addr2)
-{
- const u16 *a = (const u16 *) addr1;
- const u16 *b = (const u16 *) addr2;
-
- return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
-}
-#undef compare_ether_addr
-#define compare_ether_addr(addr1, addr2) _kc_compare_ether_addr(addr1, addr2)
-#endif /* < 2.6.15 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) )
-#undef DEFINE_MUTEX
-#define DEFINE_MUTEX(x) DECLARE_MUTEX(x)
-#define mutex_lock(x) down_interruptible(x)
-#define mutex_unlock(x) up(x)
-
-#ifndef ____cacheline_internodealigned_in_smp
-#ifdef CONFIG_SMP
-#define ____cacheline_internodealigned_in_smp ____cacheline_aligned_in_smp
-#else
-#define ____cacheline_internodealigned_in_smp
-#endif /* CONFIG_SMP */
-#endif /* ____cacheline_internodealigned_in_smp */
-#undef HAVE_PCI_ERS
-#else /* 2.6.16 and above */
-#undef HAVE_PCI_ERS
-#define HAVE_PCI_ERS
-#if ( SLE_VERSION_CODE && SLE_VERSION_CODE == SLE_VERSION(10,4,0) )
-#ifdef device_can_wakeup
-#undef device_can_wakeup
-#endif /* device_can_wakeup */
-#define device_can_wakeup(dev) 1
-#endif /* SLE_VERSION(10,4,0) */
-#endif /* < 2.6.16 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) )
-#ifndef dev_notice
-#define dev_notice(dev, fmt, args...) \
- dev_printk(KERN_NOTICE, dev, fmt, ## args)
-#endif
-
-#ifndef first_online_node
-#define first_online_node 0
-#endif
-#ifndef NET_SKB_PAD
-#define NET_SKB_PAD 16
-#endif
-#endif /* < 2.6.17 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) )
-
-#ifndef IRQ_HANDLED
-#define irqreturn_t void
-#define IRQ_HANDLED
-#define IRQ_NONE
-#endif
-
-#ifndef IRQF_PROBE_SHARED
-#ifdef SA_PROBEIRQ
-#define IRQF_PROBE_SHARED SA_PROBEIRQ
-#else
-#define IRQF_PROBE_SHARED 0
-#endif
-#endif
-
-#ifndef IRQF_SHARED
-#define IRQF_SHARED SA_SHIRQ
-#endif
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#endif
-
-#ifndef FIELD_SIZEOF
-#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
-#endif
-
-#ifndef skb_is_gso
-#ifdef NETIF_F_TSO
-#define skb_is_gso _kc_skb_is_gso
-static inline int _kc_skb_is_gso(const struct sk_buff *skb)
-{
- return skb_shinfo(skb)->gso_size;
-}
-#else
-#define skb_is_gso(a) 0
-#endif
-#endif
-
-#ifndef resource_size_t
-#define resource_size_t unsigned long
-#endif
-
-#ifdef skb_pad
-#undef skb_pad
-#endif
-#define skb_pad(x,y) _kc_skb_pad(x, y)
-int _kc_skb_pad(struct sk_buff *skb, int pad);
-#ifdef skb_padto
-#undef skb_padto
-#endif
-#define skb_padto(x,y) _kc_skb_padto(x, y)
-static inline int _kc_skb_padto(struct sk_buff *skb, unsigned int len)
-{
- unsigned int size = skb->len;
- if(likely(size >= len))
- return 0;
- return _kc_skb_pad(skb, len - size);
-}
-
-#ifndef DECLARE_PCI_UNMAP_ADDR
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- u32 LEN_NAME
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-#endif /* DECLARE_PCI_UNMAP_ADDR */
-#endif /* < 2.6.18 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) )
-
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,0)))
-#define i_private u.generic_ip
-#endif /* >= RHEL 5.0 */
-
-#ifndef DIV_ROUND_UP
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-#endif
-#ifndef __ALIGN_MASK
-#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
-#endif
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) )
-#if (!((RHEL_RELEASE_CODE && \
- ((RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(4,4) && \
- RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0)) || \
- (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,0))))))
-typedef irqreturn_t (*irq_handler_t)(int, void*, struct pt_regs *);
-#endif
-#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,0))
-#undef CONFIG_INET_LRO
-#undef CONFIG_INET_LRO_MODULE
-#ifdef IXGBE_FCOE
-#undef CONFIG_FCOE
-#undef CONFIG_FCOE_MODULE
-#endif /* IXGBE_FCOE */
-#endif
-typedef irqreturn_t (*new_handler_t)(int, void*);
-static inline irqreturn_t _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id)
-#else /* 2.4.x */
-typedef void (*irq_handler_t)(int, void*, struct pt_regs *);
-typedef void (*new_handler_t)(int, void*);
-static inline int _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id)
-#endif /* >= 2.5.x */
-{
- irq_handler_t new_handler = (irq_handler_t) handler;
- return request_irq(irq, new_handler, flags, devname, dev_id);
-}
-
-#undef request_irq
-#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
-/* 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
-#define PCI_CONFIG_SPACE_LEN 64
-#define PCIE_LINK_STATUS 0x12
-#define pci_config_space_ich8lan() do {} while(0)
-#undef pci_save_state
-extern int _kc_pci_save_state(struct pci_dev *);
-#define pci_save_state(pdev) _kc_pci_save_state(pdev)
-#undef pci_restore_state
-extern void _kc_pci_restore_state(struct pci_dev *);
-#define pci_restore_state(pdev) _kc_pci_restore_state(pdev)
-#endif /* !(RHEL_RELEASE_CODE >= RHEL 5.4) */
-
-#ifdef HAVE_PCI_ERS
-#undef free_netdev
-extern void _kc_free_netdev(struct net_device *);
-#define free_netdev(netdev) _kc_free_netdev(netdev)
-#endif
-static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
-{
- return 0;
-}
-#define pci_disable_pcie_error_reporting(dev) do {} while (0)
-#define pci_cleanup_aer_uncorrect_error_status(dev) do {} while (0)
-
-extern void *_kc_kmemdup(const void *src, size_t len, unsigned gfp);
-#define kmemdup(src, len, gfp) _kc_kmemdup(src, len, gfp)
-#ifndef bool
-#define bool _Bool
-#define true 1
-#define false 0
-#endif
-#else /* 2.6.19 */
-#include <linux/aer.h>
-#include <linux/string.h>
-#endif /* < 2.6.19 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) )
-#undef INIT_WORK
-#define INIT_WORK(_work, _func) \
-do { \
- INIT_LIST_HEAD(&(_work)->entry); \
- (_work)->pending = 0; \
- (_work)->func = (void (*)(void *))_func; \
- (_work)->data = _work; \
- init_timer(&(_work)->timer); \
-} while (0)
-#endif
-
-#ifndef PCI_VDEVICE
-#define PCI_VDEVICE(ven, dev) \
- PCI_VENDOR_ID_##ven, (dev), \
- PCI_ANY_ID, PCI_ANY_ID, 0, 0
-#endif
-
-#ifndef PCI_VENDOR_ID_INTEL
-#define PCI_VENDOR_ID_INTEL 0x8086
-#endif
-
-#ifndef round_jiffies
-#define round_jiffies(x) x
-#endif
-
-#define csum_offset csum
-
-#define HAVE_EARLY_VMALLOC_NODE
-#define dev_to_node(dev) -1
-#undef set_dev_node
-/* remove compiler warning with b=b, for unused variable */
-#define set_dev_node(a, b) do { (b) = (b); } while(0)
-
-#if (!(RHEL_RELEASE_CODE && \
- (((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(4,7)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0))) || \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,6)))) && \
- !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(10,2,0)))
-typedef __u16 __bitwise __sum16;
-typedef __u32 __bitwise __wsum;
-#endif
-
-#if (!(RHEL_RELEASE_CODE && \
- (((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(4,7)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0))) || \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,4)))) && \
- !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(10,2,0)))
-static inline __wsum csum_unfold(__sum16 n)
-{
- return (__force __wsum)n;
-}
-#endif
-
-#else /* < 2.6.20 */
-#define HAVE_DEVICE_NUMA_NODE
-#endif /* < 2.6.20 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) )
-#define to_net_dev(class) container_of(class, struct net_device, class_dev)
-#define NETDEV_CLASS_DEV
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5)))
-#define vlan_group_get_device(vg, id) (vg->vlan_devices[id])
-#define vlan_group_set_device(vg, id, dev) \
- do { \
- if (vg) vg->vlan_devices[id] = dev; \
- } while (0)
-#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5)) */
-#define pci_channel_offline(pdev) (pdev->error_state && \
- pdev->error_state != pci_channel_io_normal)
-#define pci_request_selected_regions(pdev, bars, name) \
- pci_request_regions(pdev, name)
-#define pci_release_selected_regions(pdev, bars) pci_release_regions(pdev);
-
-#ifndef __aligned
-#define __aligned(x) __attribute__((aligned(x)))
-#endif
-
-extern struct pci_dev *_kc_netdev_to_pdev(struct net_device *netdev);
-#define netdev_to_dev(netdev) \
- pci_dev_to_dev(_kc_netdev_to_pdev(netdev))
-#else
-static inline struct device *netdev_to_dev(struct net_device *netdev)
-{
- return &netdev->dev;
-}
-
-#endif /* < 2.6.21 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) )
-#define tcp_hdr(skb) (skb->h.th)
-#define tcp_hdrlen(skb) (skb->h.th->doff << 2)
-#define skb_transport_offset(skb) (skb->h.raw - skb->data)
-#define skb_transport_header(skb) (skb->h.raw)
-#define ipv6_hdr(skb) (skb->nh.ipv6h)
-#define ip_hdr(skb) (skb->nh.iph)
-#define skb_network_offset(skb) (skb->nh.raw - skb->data)
-#define skb_network_header(skb) (skb->nh.raw)
-#define skb_tail_pointer(skb) skb->tail
-#define skb_reset_tail_pointer(skb) \
- do { \
- skb->tail = skb->data; \
- } while (0)
-#define skb_set_tail_pointer(skb, offset) \
- do { \
- skb->tail = skb->data + offset; \
- } while (0)
-#define skb_copy_to_linear_data(skb, from, len) \
- memcpy(skb->data, from, len)
-#define skb_copy_to_linear_data_offset(skb, offset, from, len) \
- memcpy(skb->data + offset, from, len)
-#define skb_network_header_len(skb) (skb->h.raw - skb->nh.raw)
-#define pci_register_driver pci_module_init
-#define skb_mac_header(skb) skb->mac.raw
-
-#ifdef NETIF_F_MULTI_QUEUE
-#ifndef alloc_etherdev_mq
-#define alloc_etherdev_mq(_a, _b) alloc_etherdev(_a)
-#endif
-#endif /* NETIF_F_MULTI_QUEUE */
-
-#ifndef ETH_FCS_LEN
-#define ETH_FCS_LEN 4
-#endif
-#define cancel_work_sync(x) flush_scheduled_work()
-#ifndef udp_hdr
-#define udp_hdr _udp_hdr
-static inline struct udphdr *_udp_hdr(const struct sk_buff *skb)
-{
- return (struct udphdr *)skb_transport_header(skb);
-}
-#endif
-
-#ifdef cpu_to_be16
-#undef cpu_to_be16
-#endif
-#define cpu_to_be16(x) __constant_htons(x)
-
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,1)))
-enum {
- DUMP_PREFIX_NONE,
- DUMP_PREFIX_ADDRESS,
- DUMP_PREFIX_OFFSET
-};
-#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,1)) */
-#ifndef hex_asc
-#define hex_asc(x) "0123456789abcdef"[x]
-#endif
-#include <linux/ctype.h>
-extern void _kc_print_hex_dump(const char *level, const char *prefix_str,
- int prefix_type, int rowsize, int groupsize,
- const void *buf, size_t len, bool ascii);
-#define print_hex_dump(lvl, s, t, r, g, b, l, a) \
- _kc_print_hex_dump(lvl, s, t, r, g, b, l, a)
-#ifndef ADVERTISED_2500baseX_Full
-#define ADVERTISED_2500baseX_Full (1 << 15)
-#endif
-#ifndef SUPPORTED_2500baseX_Full
-#define SUPPORTED_2500baseX_Full (1 << 15)
-#endif
-
-#ifdef HAVE_I2C_SUPPORT
-#include <linux/i2c.h>
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5)))
-struct i2c_board_info {
- char driver_name[KOBJ_NAME_LEN];
- char type[I2C_NAME_SIZE];
- unsigned short flags;
- unsigned short addr;
- void *platform_data;
-};
-#define I2C_BOARD_INFO(driver, dev_addr) .driver_name = (driver),\
- .addr = (dev_addr)
-#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5)) */
-#define i2c_new_device(adap, info) _kc_i2c_new_device(adap, info)
-extern struct i2c_client *
-_kc_i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
-#endif /* HAVE_I2C_SUPPORT */
-
-#else /* 2.6.22 */
-#define ETH_TYPE_TRANS_SETS_DEV
-#define HAVE_NETDEV_STATS_IN_NETDEV
-#endif /* < 2.6.22 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) )
-#undef SET_MODULE_OWNER
-#define SET_MODULE_OWNER(dev) do { } while (0)
-#endif /* > 2.6.22 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) )
-#define netif_subqueue_stopped(_a, _b) 0
-#ifndef PTR_ALIGN
-#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
-#endif
-
-#ifndef CONFIG_PM_SLEEP
-#define CONFIG_PM_SLEEP CONFIG_PM
-#endif
-
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) )
-#define HAVE_ETHTOOL_GET_PERM_ADDR
-#endif /* 2.6.14 through 2.6.22 */
-#endif /* < 2.6.23 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) )
-#ifndef ETH_FLAG_LRO
-#define ETH_FLAG_LRO NETIF_F_LRO
-#endif
-
-/* if GRO is supported then the napi struct must already exist */
-#ifndef NETIF_F_GRO
-/* NAPI API changes in 2.6.24 break everything */
-struct napi_struct {
- /* used to look up the real NAPI polling routine */
- int (*poll)(struct napi_struct *, int);
- struct net_device *dev;
- int weight;
-};
-#endif
-
-#ifdef NAPI
-extern int __kc_adapter_clean(struct net_device *, int *);
-extern struct net_device *napi_to_poll_dev(const struct napi_struct *napi);
-#define netif_napi_add(_netdev, _napi, _poll, _weight) \
- do { \
- struct napi_struct *__napi = (_napi); \
- struct net_device *poll_dev = napi_to_poll_dev(__napi); \
- poll_dev->poll = &(__kc_adapter_clean); \
- poll_dev->priv = (_napi); \
- poll_dev->weight = (_weight); \
- set_bit(__LINK_STATE_RX_SCHED, &poll_dev->state); \
- set_bit(__LINK_STATE_START, &poll_dev->state);\
- dev_hold(poll_dev); \
- __napi->poll = &(_poll); \
- __napi->weight = (_weight); \
- __napi->dev = (_netdev); \
- } while (0)
-#define netif_napi_del(_napi) \
- do { \
- struct net_device *poll_dev = napi_to_poll_dev(_napi); \
- WARN_ON(!test_bit(__LINK_STATE_RX_SCHED, &poll_dev->state)); \
- dev_put(poll_dev); \
- memset(poll_dev, 0, sizeof(struct net_device));\
- } while (0)
-#define napi_schedule_prep(_napi) \
- (netif_running((_napi)->dev) && netif_rx_schedule_prep(napi_to_poll_dev(_napi)))
-#define napi_schedule(_napi) \
- do { \
- if (napi_schedule_prep(_napi)) \
- __netif_rx_schedule(napi_to_poll_dev(_napi)); \
- } while (0)
-#define napi_enable(_napi) netif_poll_enable(napi_to_poll_dev(_napi))
-#define napi_disable(_napi) netif_poll_disable(napi_to_poll_dev(_napi))
-#ifdef CONFIG_SMP
-static inline void napi_synchronize(const struct napi_struct *n)
-{
- struct net_device *dev = napi_to_poll_dev(n);
-
- while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
- /* No hurry. */
- msleep(1);
- }
-}
-#else
-#define napi_synchronize(n) barrier()
-#endif /* CONFIG_SMP */
-#define __napi_schedule(_napi) __netif_rx_schedule(napi_to_poll_dev(_napi))
-#ifndef NETIF_F_GRO
-#define napi_complete(_napi) netif_rx_complete(napi_to_poll_dev(_napi))
-#else
-#define napi_complete(_napi) \
- do { \
- napi_gro_flush(_napi); \
- netif_rx_complete(napi_to_poll_dev(_napi)); \
- } while (0)
-#endif /* NETIF_F_GRO */
-#else /* NAPI */
-#define netif_napi_add(_netdev, _napi, _poll, _weight) \
- do { \
- struct napi_struct *__napi = _napi; \
- _netdev->poll = &(_poll); \
- _netdev->weight = (_weight); \
- __napi->poll = &(_poll); \
- __napi->weight = (_weight); \
- __napi->dev = (_netdev); \
- } while (0)
-#define netif_napi_del(_a) do {} while (0)
-#endif /* NAPI */
-
-#undef dev_get_by_name
-#define dev_get_by_name(_a, _b) dev_get_by_name(_b)
-#define __netif_subqueue_stopped(_a, _b) netif_subqueue_stopped(_a, _b)
-#ifndef DMA_BIT_MASK
-#define DMA_BIT_MASK(n) (((n) == 64) ? DMA_64BIT_MASK : ((1ULL<<(n))-1))
-#endif
-
-#ifdef NETIF_F_TSO6
-#define skb_is_gso_v6 _kc_skb_is_gso_v6
-static inline int _kc_skb_is_gso_v6(const struct sk_buff *skb)
-{
- return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;
-}
-#endif /* NETIF_F_TSO6 */
-
-#ifndef KERN_CONT
-#define KERN_CONT ""
-#endif
-#ifndef pr_err
-#define pr_err(fmt, arg...) \
- printk(KERN_ERR fmt, ##arg)
-#endif
-#else /* < 2.6.24 */
-#define HAVE_ETHTOOL_GET_SSET_COUNT
-#define HAVE_NETDEV_NAPI_LIST
-#endif /* < 2.6.24 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24) )
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) )
-#include <linux/pm_qos_params.h>
-#else /* >= 3.2.0 */
-#include <linux/pm_qos.h>
-#endif /* else >= 3.2.0 */
-#endif /* > 2.6.24 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) )
-#define PM_QOS_CPU_DMA_LATENCY 1
-
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) )
-#include <linux/latency.h>
-#define PM_QOS_DEFAULT_VALUE INFINITE_LATENCY
-#define pm_qos_add_requirement(pm_qos_class, name, value) \
- set_acceptable_latency(name, value)
-#define pm_qos_remove_requirement(pm_qos_class, name) \
- remove_acceptable_latency(name)
-#define pm_qos_update_requirement(pm_qos_class, name, value) \
- modify_acceptable_latency(name, value)
-#else
-#define PM_QOS_DEFAULT_VALUE -1
-#define pm_qos_add_requirement(pm_qos_class, name, value)
-#define pm_qos_remove_requirement(pm_qos_class, name)
-#define pm_qos_update_requirement(pm_qos_class, name, value) { \
- if (value != PM_QOS_DEFAULT_VALUE) { \
- printk(KERN_WARNING "%s: unable to set PM QoS requirement\n", \
- pci_name(adapter->pdev)); \
- } \
-}
-
-#endif /* > 2.6.18 */
-
-#define pci_enable_device_mem(pdev) pci_enable_device(pdev)
-
-#ifndef DEFINE_PCI_DEVICE_TABLE
-#define DEFINE_PCI_DEVICE_TABLE(_table) struct pci_device_id _table[]
-#endif /* DEFINE_PCI_DEVICE_TABLE */
-
-
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) )
-#ifndef IGB_PROCFS
-#define IGB_PROCFS
-#endif /* IGB_PROCFS */
-#endif /* >= 2.6.0 */
-
-#else /* < 2.6.25 */
-
-
-#if IS_ENABLED(CONFIG_HWMON)
-#ifndef IGB_HWMON
-#define IGB_HWMON
-#endif /* IGB_HWMON */
-#endif /* CONFIG_HWMON */
-
-#endif /* < 2.6.25 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) )
-#ifndef clamp_t
-#define clamp_t(type, val, min, max) ({ \
- type __val = (val); \
- type __min = (min); \
- type __max = (max); \
- __val = __val < __min ? __min : __val; \
- __val > __max ? __max : __val; })
-#endif /* clamp_t */
-#undef kzalloc_node
-#define kzalloc_node(_size, _flags, _node) kzalloc(_size, _flags)
-
-extern void _kc_pci_disable_link_state(struct pci_dev *dev, int state);
-#define pci_disable_link_state(p, s) _kc_pci_disable_link_state(p, s)
-#else /* < 2.6.26 */
-#include <linux/pci-aspm.h>
-#define HAVE_NETDEV_VLAN_FEATURES
-#ifndef PCI_EXP_LNKCAP_ASPMS
-#define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */
-#endif /* PCI_EXP_LNKCAP_ASPMS */
-#endif /* < 2.6.26 */
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) )
-static inline void _kc_ethtool_cmd_speed_set(struct ethtool_cmd *ep,
- __u32 speed)
-{
- ep->speed = (__u16)speed;
- /* ep->speed_hi = (__u16)(speed >> 16); */
-}
-#define ethtool_cmd_speed_set _kc_ethtool_cmd_speed_set
-
-static inline __u32 _kc_ethtool_cmd_speed(struct ethtool_cmd *ep)
-{
- /* no speed_hi before 2.6.27, and probably no need for it yet */
- return (__u32)ep->speed;
-}
-#define ethtool_cmd_speed _kc_ethtool_cmd_speed
-
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) )
-#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) && defined(CONFIG_PM))
-#define ANCIENT_PM 1
-#elif ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) && \
- (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) && \
- defined(CONFIG_PM_SLEEP))
-#define NEWER_PM 1
-#endif
-#if defined(ANCIENT_PM) || defined(NEWER_PM)
-#undef device_set_wakeup_enable
-#define device_set_wakeup_enable(dev, val) \
- do { \
- u16 pmc = 0; \
- int pm = pci_find_capability(adapter->pdev, PCI_CAP_ID_PM); \
- if (pm) { \
- pci_read_config_word(adapter->pdev, pm + PCI_PM_PMC, \
- &pmc); \
- } \
- (dev)->power.can_wakeup = !!(pmc >> 11); \
- (dev)->power.should_wakeup = (val && (pmc >> 11)); \
- } while (0)
-#endif /* 2.6.15-2.6.22 and CONFIG_PM or 2.6.23-2.6.25 and CONFIG_PM_SLEEP */
-#endif /* 2.6.15 through 2.6.27 */
-#ifndef netif_napi_del
-#define netif_napi_del(_a) do {} while (0)
-#ifdef NAPI
-#ifdef CONFIG_NETPOLL
-#undef netif_napi_del
-#define netif_napi_del(_a) list_del(&(_a)->dev_list);
-#endif
-#endif
-#endif /* netif_napi_del */
-#ifdef dma_mapping_error
-#undef dma_mapping_error
-#endif
-#define dma_mapping_error(dev, dma_addr) pci_dma_mapping_error(dma_addr)
-
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
-#define HAVE_TX_MQ
-#endif
-
-#ifdef HAVE_TX_MQ
-extern void _kc_netif_tx_stop_all_queues(struct net_device *);
-extern void _kc_netif_tx_wake_all_queues(struct net_device *);
-extern void _kc_netif_tx_start_all_queues(struct net_device *);
-#define netif_tx_stop_all_queues(a) _kc_netif_tx_stop_all_queues(a)
-#define netif_tx_wake_all_queues(a) _kc_netif_tx_wake_all_queues(a)
-#define netif_tx_start_all_queues(a) _kc_netif_tx_start_all_queues(a)
-#undef netif_stop_subqueue
-#define netif_stop_subqueue(_ndev,_qi) do { \
- if (netif_is_multiqueue((_ndev))) \
- netif_stop_subqueue((_ndev), (_qi)); \
- else \
- netif_stop_queue((_ndev)); \
- } while (0)
-#undef netif_start_subqueue
-#define netif_start_subqueue(_ndev,_qi) do { \
- if (netif_is_multiqueue((_ndev))) \
- netif_start_subqueue((_ndev), (_qi)); \
- else \
- netif_start_queue((_ndev)); \
- } while (0)
-#else /* HAVE_TX_MQ */
-#define netif_tx_stop_all_queues(a) netif_stop_queue(a)
-#define netif_tx_wake_all_queues(a) netif_wake_queue(a)
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) )
-#define netif_tx_start_all_queues(a) netif_start_queue(a)
-#else
-#define netif_tx_start_all_queues(a) do {} while (0)
-#endif
-#define netif_stop_subqueue(_ndev,_qi) netif_stop_queue((_ndev))
-#define netif_start_subqueue(_ndev,_qi) netif_start_queue((_ndev))
-#endif /* HAVE_TX_MQ */
-#ifndef NETIF_F_MULTI_QUEUE
-#define NETIF_F_MULTI_QUEUE 0
-#define netif_is_multiqueue(a) 0
-#define netif_wake_subqueue(a, b)
-#endif /* NETIF_F_MULTI_QUEUE */
-
-#ifndef __WARN_printf
-extern void __kc_warn_slowpath(const char *file, const int line,
- const char *fmt, ...) __attribute__((format(printf, 3, 4)));
-#define __WARN_printf(arg...) __kc_warn_slowpath(__FILE__, __LINE__, arg)
-#endif /* __WARN_printf */
-
-#ifndef WARN
-#define WARN(condition, format...) ({ \
- int __ret_warn_on = !!(condition); \
- if (unlikely(__ret_warn_on)) \
- __WARN_printf(format); \
- unlikely(__ret_warn_on); \
-})
-#endif /* WARN */
-#undef HAVE_IXGBE_DEBUG_FS
-#undef HAVE_IGB_DEBUG_FS
-#else /* < 2.6.27 */
-#define HAVE_TX_MQ
-#define HAVE_NETDEV_SELECT_QUEUE
-#ifdef CONFIG_DEBUG_FS
-#define HAVE_IXGBE_DEBUG_FS
-#define HAVE_IGB_DEBUG_FS
-#endif /* CONFIG_DEBUG_FS */
-#endif /* < 2.6.27 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) )
-#define pci_ioremap_bar(pdev, bar) ioremap(pci_resource_start(pdev, bar), \
- pci_resource_len(pdev, bar))
-#define pci_wake_from_d3 _kc_pci_wake_from_d3
-#define pci_prepare_to_sleep _kc_pci_prepare_to_sleep
-extern int _kc_pci_wake_from_d3(struct pci_dev *dev, bool enable);
-extern int _kc_pci_prepare_to_sleep(struct pci_dev *dev);
-#define netdev_alloc_page(a) alloc_page(GFP_ATOMIC)
-#ifndef __skb_queue_head_init
-static inline void __kc_skb_queue_head_init(struct sk_buff_head *list)
-{
- list->prev = list->next = (struct sk_buff *)list;
- list->qlen = 0;
-}
-#define __skb_queue_head_init(_q) __kc_skb_queue_head_init(_q)
-#endif
-
-#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */
-#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
-
-#endif /* < 2.6.28 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) )
-#ifndef swap
-#define swap(a, b) \
- do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
-#endif
-#define pci_request_selected_regions_exclusive(pdev, bars, name) \
- pci_request_selected_regions(pdev, bars, name)
-#ifndef CONFIG_NR_CPUS
-#define CONFIG_NR_CPUS 1
-#endif /* CONFIG_NR_CPUS */
-#ifndef pcie_aspm_enabled
-#define pcie_aspm_enabled() (1)
-#endif /* pcie_aspm_enabled */
-
-#define PCI_EXP_SLTSTA_PDS 0x0040 /* Presence Detect State */
-
-#ifndef pci_clear_master
-extern void _kc_pci_clear_master(struct pci_dev *dev);
-#define pci_clear_master(dev) _kc_pci_clear_master(dev)
-#endif
-
-#ifndef PCI_EXP_LNKCTL_ASPMC
-#define PCI_EXP_LNKCTL_ASPMC 0x0003 /* ASPM Control */
-#endif
-#else /* < 2.6.29 */
-#ifndef HAVE_NET_DEVICE_OPS
-#define HAVE_NET_DEVICE_OPS
-#endif
-#ifdef CONFIG_DCB
-#define HAVE_PFC_MODE_ENABLE
-#endif /* CONFIG_DCB */
-#endif /* < 2.6.29 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) )
-#define skb_rx_queue_recorded(a) false
-#define skb_get_rx_queue(a) 0
-#define skb_record_rx_queue(a, b) do {} while (0)
-#define skb_tx_hash(n, s) ___kc_skb_tx_hash((n), (s), (n)->real_num_tx_queues)
-#ifndef CONFIG_PCI_IOV
-#undef pci_enable_sriov
-#define pci_enable_sriov(a, b) -ENOTSUPP
-#undef pci_disable_sriov
-#define pci_disable_sriov(a) do {} while (0)
-#endif /* CONFIG_PCI_IOV */
-#ifndef pr_cont
-#define pr_cont(fmt, ...) \
- printk(KERN_CONT fmt, ##__VA_ARGS__)
-#endif /* pr_cont */
-static inline void _kc_synchronize_irq(unsigned int a)
-{
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) )
- synchronize_irq();
-#else /* < 2.5.28 */
- synchronize_irq(a);
-#endif /* < 2.5.28 */
-}
-#undef synchronize_irq
-#define synchronize_irq(a) _kc_synchronize_irq(a)
-
-#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */
-
-#else /* < 2.6.30 */
-#define HAVE_ASPM_QUIRKS
-#endif /* < 2.6.30 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) )
-#define ETH_P_1588 0x88F7
-#define ETH_P_FIP 0x8914
-#ifndef netdev_uc_count
-#define netdev_uc_count(dev) ((dev)->uc_count)
-#endif
-#ifndef netdev_for_each_uc_addr
-#define netdev_for_each_uc_addr(uclist, dev) \
- for (uclist = dev->uc_list; uclist; uclist = uclist->next)
-#endif
-#ifndef PORT_OTHER
-#define PORT_OTHER 0xff
-#endif
-#ifndef MDIO_PHY_ID_PRTAD
-#define MDIO_PHY_ID_PRTAD 0x03e0
-#endif
-#ifndef MDIO_PHY_ID_DEVAD
-#define MDIO_PHY_ID_DEVAD 0x001f
-#endif
-#ifndef skb_dst
-#define skb_dst(s) ((s)->dst)
-#endif
-
-#ifndef SUPPORTED_1000baseKX_Full
-#define SUPPORTED_1000baseKX_Full (1 << 17)
-#endif
-#ifndef SUPPORTED_10000baseKX4_Full
-#define SUPPORTED_10000baseKX4_Full (1 << 18)
-#endif
-#ifndef SUPPORTED_10000baseKR_Full
-#define SUPPORTED_10000baseKR_Full (1 << 19)
-#endif
-
-#ifndef ADVERTISED_1000baseKX_Full
-#define ADVERTISED_1000baseKX_Full (1 << 17)
-#endif
-#ifndef ADVERTISED_10000baseKX4_Full
-#define ADVERTISED_10000baseKX4_Full (1 << 18)
-#endif
-#ifndef ADVERTISED_10000baseKR_Full
-#define ADVERTISED_10000baseKR_Full (1 << 19)
-#endif
-
-#else /* < 2.6.31 */
-#ifndef HAVE_NETDEV_STORAGE_ADDRESS
-#define HAVE_NETDEV_STORAGE_ADDRESS
-#endif
-#ifndef HAVE_NETDEV_HW_ADDR
-#define HAVE_NETDEV_HW_ADDR
-#endif
-#ifndef HAVE_TRANS_START_IN_QUEUE
-#define HAVE_TRANS_START_IN_QUEUE
-#endif
-#ifndef HAVE_INCLUDE_LINUX_MDIO_H
-#define HAVE_INCLUDE_LINUX_MDIO_H
-#endif
-#endif /* < 2.6.31 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) )
-#undef netdev_tx_t
-#define netdev_tx_t int
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef NETIF_F_FCOE_MTU
-#define NETIF_F_FCOE_MTU (1 << 26)
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-static inline int _kc_pm_runtime_get_sync()
-{
- return 1;
-}
-#define pm_runtime_get_sync(dev) _kc_pm_runtime_get_sync()
-#else /* 2.6.0 => 2.6.32 */
-static inline int _kc_pm_runtime_get_sync(struct device *dev)
-{
- return 1;
-}
-#ifndef pm_runtime_get_sync
-#define pm_runtime_get_sync(dev) _kc_pm_runtime_get_sync(dev)
-#endif
-#endif /* 2.6.0 => 2.6.32 */
-#ifndef pm_runtime_put
-#define pm_runtime_put(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_put_sync
-#define pm_runtime_put_sync(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_resume
-#define pm_runtime_resume(dev) do {} while (0)
-#endif
-#ifndef pm_schedule_suspend
-#define pm_schedule_suspend(dev, t) do {} while (0)
-#endif
-#ifndef pm_runtime_set_suspended
-#define pm_runtime_set_suspended(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_disable
-#define pm_runtime_disable(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_put_noidle
-#define pm_runtime_put_noidle(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_set_active
-#define pm_runtime_set_active(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_enable
-#define pm_runtime_enable(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_get_noresume
-#define pm_runtime_get_noresume(dev) do {} while (0)
-#endif
-#else /* < 2.6.32 */
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef HAVE_NETDEV_OPS_FCOE_ENABLE
-#define HAVE_NETDEV_OPS_FCOE_ENABLE
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-#ifdef CONFIG_DCB
-#ifndef HAVE_DCBNL_OPS_GETAPP
-#define HAVE_DCBNL_OPS_GETAPP
-#endif
-#endif /* CONFIG_DCB */
-#include <linux/pm_runtime.h>
-/* IOV bad DMA target work arounds require at least this kernel rev support */
-#define HAVE_PCIE_TYPE
-#endif /* < 2.6.32 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) )
-#ifndef pci_pcie_cap
-#define pci_pcie_cap(pdev) pci_find_capability(pdev, PCI_CAP_ID_EXP)
-#endif
-#ifndef IPV4_FLOW
-#define IPV4_FLOW 0x10
-#endif /* IPV4_FLOW */
-#ifndef IPV6_FLOW
-#define IPV6_FLOW 0x11
-#endif /* IPV6_FLOW */
-/* Features back-ported to RHEL6 or SLES11 SP1 after 2.6.32 */
-#if ( (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)) || \
- (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,1,0)) )
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef HAVE_NETDEV_OPS_FCOE_GETWWN
-#define HAVE_NETDEV_OPS_FCOE_GETWWN
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-#endif /* RHEL6 or SLES11 SP1 */
-#ifndef __percpu
-#define __percpu
-#endif /* __percpu */
-#ifndef PORT_DA
-#define PORT_DA PORT_OTHER
-#endif
-#ifndef PORT_NONE
-#define PORT_NONE PORT_OTHER
-#endif
-
-#if ((RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,3)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0))))
-#if !defined(CONFIG_X86_32) && !defined(CONFIG_NEED_DMA_MAP_STATE)
-#undef DEFINE_DMA_UNMAP_ADDR
-#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME
-#undef DEFINE_DMA_UNMAP_LEN
-#define DEFINE_DMA_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME
-#undef dma_unmap_addr
-#define dma_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
-#undef dma_unmap_addr_set
-#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
-#undef dma_unmap_len
-#define dma_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
-#undef dma_unmap_len_set
-#define dma_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
-#endif /* CONFIG_X86_64 && !CONFIG_NEED_DMA_MAP_STATE */
-#endif /* RHEL_RELEASE_CODE */
-
-#if (!(RHEL_RELEASE_CODE && \
- (((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,8)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,0))) || \
- ((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,1)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0))))))
-static inline bool pci_is_pcie(struct pci_dev *dev)
-{
- return !!pci_pcie_cap(dev);
-}
-#endif /* RHEL_RELEASE_CODE */
-
-#ifndef __always_unused
-#define __always_unused __attribute__((__unused__))
-#endif
-#ifndef __maybe_unused
-#define __maybe_unused __attribute__((__unused__))
-#endif
-
-#if (!(RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,2))))
-#define sk_tx_queue_get(_sk) (-1)
-#define sk_tx_queue_set(_sk, _tx_queue) do {} while(0)
-#endif /* !(RHEL >= 6.2) */
-
-#if (RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,4)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)))
-#define HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT
-#define HAVE_ETHTOOL_SET_PHYS_ID
-#define HAVE_ETHTOOL_GET_TS_INFO
-#endif /* RHEL >= 6.4 && RHEL < 7.0 */
-
-#if (RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,5)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)))
-#define HAVE_RHEL6_NETDEV_OPS_EXT_FDB
-#endif /* RHEL >= 6.5 && RHEL < 7.0 */
-
-#else /* < 2.6.33 */
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef HAVE_NETDEV_OPS_FCOE_GETWWN
-#define HAVE_NETDEV_OPS_FCOE_GETWWN
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-#endif /* < 2.6.33 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) )
-#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,0))
-#ifndef pci_num_vf
-#define pci_num_vf(pdev) _kc_pci_num_vf(pdev)
-extern int _kc_pci_num_vf(struct pci_dev *dev);
-#endif
-#endif /* RHEL_RELEASE_CODE */
-
-#ifndef ETH_FLAG_NTUPLE
-#define ETH_FLAG_NTUPLE NETIF_F_NTUPLE
-#endif
-
-#ifndef netdev_mc_count
-#define netdev_mc_count(dev) ((dev)->mc_count)
-#endif
-#ifndef netdev_mc_empty
-#define netdev_mc_empty(dev) (netdev_mc_count(dev) == 0)
-#endif
-#ifndef netdev_for_each_mc_addr
-#define netdev_for_each_mc_addr(mclist, dev) \
- for (mclist = dev->mc_list; mclist; mclist = mclist->next)
-#endif
-#ifndef netdev_uc_count
-#define netdev_uc_count(dev) ((dev)->uc.count)
-#endif
-#ifndef netdev_uc_empty
-#define netdev_uc_empty(dev) (netdev_uc_count(dev) == 0)
-#endif
-#ifndef netdev_for_each_uc_addr
-#define netdev_for_each_uc_addr(ha, dev) \
- list_for_each_entry(ha, &dev->uc.list, list)
-#endif
-#ifndef dma_set_coherent_mask
-#define dma_set_coherent_mask(dev,mask) \
- pci_set_consistent_dma_mask(to_pci_dev(dev),(mask))
-#endif
-#ifndef pci_dev_run_wake
-#define pci_dev_run_wake(pdev) (0)
-#endif
-
-/* netdev logging taken from include/linux/netdevice.h */
-#ifndef netdev_name
-static inline const char *_kc_netdev_name(const struct net_device *dev)
-{
- if (dev->reg_state != NETREG_REGISTERED)
- return "(unregistered net_device)";
- return dev->name;
-}
-#define netdev_name(netdev) _kc_netdev_name(netdev)
-#endif /* netdev_name */
-
-#undef netdev_printk
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-#define netdev_printk(level, netdev, format, args...) \
-do { \
- struct pci_dev *pdev = _kc_netdev_to_pdev(netdev); \
- printk(level "%s: " format, pci_name(pdev), ##args); \
-} while(0)
-#elif ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) )
-#define netdev_printk(level, netdev, format, args...) \
-do { \
- struct pci_dev *pdev = _kc_netdev_to_pdev(netdev); \
- struct device *dev = pci_dev_to_dev(pdev); \
- dev_printk(level, dev, "%s: " format, \
- netdev_name(netdev), ##args); \
-} while(0)
-#else /* 2.6.21 => 2.6.34 */
-#define netdev_printk(level, netdev, format, args...) \
- dev_printk(level, (netdev)->dev.parent, \
- "%s: " format, \
- netdev_name(netdev), ##args)
-#endif /* <2.6.0 <2.6.21 <2.6.34 */
-#undef netdev_emerg
-#define netdev_emerg(dev, format, args...) \
- netdev_printk(KERN_EMERG, dev, format, ##args)
-#undef netdev_alert
-#define netdev_alert(dev, format, args...) \
- netdev_printk(KERN_ALERT, dev, format, ##args)
-#undef netdev_crit
-#define netdev_crit(dev, format, args...) \
- netdev_printk(KERN_CRIT, dev, format, ##args)
-#undef netdev_err
-#define netdev_err(dev, format, args...) \
- netdev_printk(KERN_ERR, dev, format, ##args)
-#undef netdev_warn
-#define netdev_warn(dev, format, args...) \
- netdev_printk(KERN_WARNING, dev, format, ##args)
-#undef netdev_notice
-#define netdev_notice(dev, format, args...) \
- netdev_printk(KERN_NOTICE, dev, format, ##args)
-#undef netdev_info
-#define netdev_info(dev, format, args...) \
- netdev_printk(KERN_INFO, dev, format, ##args)
-#undef netdev_dbg
-#if defined(DEBUG)
-#define netdev_dbg(__dev, format, args...) \
- netdev_printk(KERN_DEBUG, __dev, format, ##args)
-#elif defined(CONFIG_DYNAMIC_DEBUG)
-#define netdev_dbg(__dev, format, args...) \
-do { \
- dynamic_dev_dbg((__dev)->dev.parent, "%s: " format, \
- netdev_name(__dev), ##args); \
-} while (0)
-#else /* DEBUG */
-#define netdev_dbg(__dev, format, args...) \
-({ \
- if (0) \
- netdev_printk(KERN_DEBUG, __dev, format, ##args); \
- 0; \
-})
-#endif /* DEBUG */
-
-#undef netif_printk
-#define netif_printk(priv, type, level, dev, fmt, args...) \
-do { \
- if (netif_msg_##type(priv)) \
- netdev_printk(level, (dev), fmt, ##args); \
-} while (0)
-
-#undef netif_emerg
-#define netif_emerg(priv, type, dev, fmt, args...) \
- netif_level(emerg, priv, type, dev, fmt, ##args)
-#undef netif_alert
-#define netif_alert(priv, type, dev, fmt, args...) \
- netif_level(alert, priv, type, dev, fmt, ##args)
-#undef netif_crit
-#define netif_crit(priv, type, dev, fmt, args...) \
- netif_level(crit, priv, type, dev, fmt, ##args)
-#undef netif_err
-#define netif_err(priv, type, dev, fmt, args...) \
- netif_level(err, priv, type, dev, fmt, ##args)
-#undef netif_warn
-#define netif_warn(priv, type, dev, fmt, args...) \
- netif_level(warn, priv, type, dev, fmt, ##args)
-#undef netif_notice
-#define netif_notice(priv, type, dev, fmt, args...) \
- netif_level(notice, priv, type, dev, fmt, ##args)
-#undef netif_info
-#define netif_info(priv, type, dev, fmt, args...) \
- netif_level(info, priv, type, dev, fmt, ##args)
-#undef netif_dbg
-#define netif_dbg(priv, type, dev, fmt, args...) \
- netif_level(dbg, priv, type, dev, fmt, ##args)
-
-#ifdef SET_SYSTEM_SLEEP_PM_OPS
-#define HAVE_SYSTEM_SLEEP_PM_OPS
-#endif
-
-#ifndef for_each_set_bit
-#define for_each_set_bit(bit, addr, size) \
- for ((bit) = find_first_bit((addr), (size)); \
- (bit) < (size); \
- (bit) = find_next_bit((addr), (size), (bit) + 1))
-#endif /* for_each_set_bit */
-
-#ifndef DEFINE_DMA_UNMAP_ADDR
-#define DEFINE_DMA_UNMAP_ADDR DECLARE_PCI_UNMAP_ADDR
-#define DEFINE_DMA_UNMAP_LEN DECLARE_PCI_UNMAP_LEN
-#define dma_unmap_addr pci_unmap_addr
-#define dma_unmap_addr_set pci_unmap_addr_set
-#define dma_unmap_len pci_unmap_len
-#define dma_unmap_len_set pci_unmap_len_set
-#endif /* DEFINE_DMA_UNMAP_ADDR */
-
-#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,3))
-#ifdef IGB_HWMON
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-#define sysfs_attr_init(attr) \
- do { \
- static struct lock_class_key __key; \
- (attr)->key = &__key; \
- } while (0)
-#else
-#define sysfs_attr_init(attr) do {} while (0)
-#endif /* CONFIG_DEBUG_LOCK_ALLOC */
-#endif /* IGB_HWMON */
-#endif /* RHEL_RELEASE_CODE */
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-static inline bool _kc_pm_runtime_suspended()
-{
- return false;
-}
-#define pm_runtime_suspended(dev) _kc_pm_runtime_suspended()
-#else /* 2.6.0 => 2.6.34 */
-static inline bool _kc_pm_runtime_suspended(struct device *dev)
-{
- return false;
-}
-#ifndef pm_runtime_suspended
-#define pm_runtime_suspended(dev) _kc_pm_runtime_suspended(dev)
-#endif
-#endif /* 2.6.0 => 2.6.34 */
-
-#else /* < 2.6.34 */
-#define HAVE_SYSTEM_SLEEP_PM_OPS
-#ifndef HAVE_SET_RX_MODE
-#define HAVE_SET_RX_MODE
-#endif
-
-#endif /* < 2.6.34 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) )
-
-ssize_t _kc_simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
- const void __user *from, size_t count);
-#define simple_write_to_buffer _kc_simple_write_to_buffer
-
-#ifndef numa_node_id
-#define numa_node_id() 0
-#endif
-#ifdef HAVE_TX_MQ
-#include <net/sch_generic.h>
-#ifndef CONFIG_NETDEVICES_MULTIQUEUE
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)))
-void _kc_netif_set_real_num_tx_queues(struct net_device *, unsigned int);
-#define netif_set_real_num_tx_queues _kc_netif_set_real_num_tx_queues
-#endif /* !(RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)) */
-#else /* CONFIG_NETDEVICES_MULTI_QUEUE */
-#define netif_set_real_num_tx_queues(_netdev, _count) \
- do { \
- (_netdev)->egress_subqueue_count = _count; \
- } while (0)
-#endif /* CONFIG_NETDEVICES_MULTI_QUEUE */
-#else /* HAVE_TX_MQ */
-#define netif_set_real_num_tx_queues(_netdev, _count) do {} while(0)
-#endif /* HAVE_TX_MQ */
-#ifndef ETH_FLAG_RXHASH
-#define ETH_FLAG_RXHASH (1<<28)
-#endif /* ETH_FLAG_RXHASH */
-#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0))
-#define HAVE_IRQ_AFFINITY_HINT
-#endif
-#else /* < 2.6.35 */
-#define HAVE_PM_QOS_REQUEST_LIST
-#define HAVE_IRQ_AFFINITY_HINT
-#endif /* < 2.6.35 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) )
-extern int _kc_ethtool_op_set_flags(struct net_device *, u32, u32);
-#define ethtool_op_set_flags _kc_ethtool_op_set_flags
-extern u32 _kc_ethtool_op_get_flags(struct net_device *);
-#define ethtool_op_get_flags _kc_ethtool_op_get_flags
-
-#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-#ifdef NET_IP_ALIGN
-#undef NET_IP_ALIGN
-#endif
-#define NET_IP_ALIGN 0
-#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
-
-#ifdef NET_SKB_PAD
-#undef NET_SKB_PAD
-#endif
-
-#if (L1_CACHE_BYTES > 32)
-#define NET_SKB_PAD L1_CACHE_BYTES
-#else
-#define NET_SKB_PAD 32
-#endif
-
-static inline struct sk_buff *_kc_netdev_alloc_skb_ip_align(struct net_device *dev,
- unsigned int length)
-{
- struct sk_buff *skb;
-
- skb = alloc_skb(length + NET_SKB_PAD + NET_IP_ALIGN, GFP_ATOMIC);
- if (skb) {
-#if (NET_IP_ALIGN + NET_SKB_PAD)
- skb_reserve(skb, NET_IP_ALIGN + NET_SKB_PAD);
-#endif
- skb->dev = dev;
- }
- return skb;
-}
-
-#ifdef netdev_alloc_skb_ip_align
-#undef netdev_alloc_skb_ip_align
-#endif
-#define netdev_alloc_skb_ip_align(n, l) _kc_netdev_alloc_skb_ip_align(n, l)
-
-#undef netif_level
-#define netif_level(level, priv, type, dev, fmt, args...) \
-do { \
- if (netif_msg_##type(priv)) \
- netdev_##level(dev, fmt, ##args); \
-} while (0)
-
-#undef usleep_range
-#define usleep_range(min, max) msleep(DIV_ROUND_UP(min, 1000))
-
-#define u64_stats_update_begin(a) do { } while(0)
-#define u64_stats_update_end(a) do { } while(0)
-#define u64_stats_fetch_begin(a) do { } while(0)
-#define u64_stats_fetch_retry_bh(a) (0)
-#define u64_stats_fetch_begin_bh(a) (0)
-
-#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,1))
-#define HAVE_8021P_SUPPORT
-#endif
-
-#else /* < 2.6.36 */
-
-
-#define HAVE_PM_QOS_REQUEST_ACTIVE
-#define HAVE_8021P_SUPPORT
-#define HAVE_NDO_GET_STATS64
-#endif /* < 2.6.36 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) )
-#ifndef netif_set_real_num_rx_queues
-static inline int __kc_netif_set_real_num_rx_queues(struct net_device *dev,
- unsigned int rxq)
-{
- return 0;
-}
-#define netif_set_real_num_rx_queues(dev, rxq) \
- __kc_netif_set_real_num_rx_queues((dev), (rxq))
-#endif
-#ifndef ETHTOOL_RXNTUPLE_ACTION_CLEAR
-#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2)
-#endif
-#ifndef VLAN_N_VID
-#define VLAN_N_VID VLAN_GROUP_ARRAY_LEN
-#endif /* VLAN_N_VID */
-#ifndef ETH_FLAG_TXVLAN
-#define ETH_FLAG_TXVLAN (1 << 7)
-#endif /* ETH_FLAG_TXVLAN */
-#ifndef ETH_FLAG_RXVLAN
-#define ETH_FLAG_RXVLAN (1 << 8)
-#endif /* ETH_FLAG_RXVLAN */
-
-static inline void _kc_skb_checksum_none_assert(struct sk_buff *skb)
-{
- WARN_ON(skb->ip_summed != CHECKSUM_NONE);
-}
-#define skb_checksum_none_assert(skb) _kc_skb_checksum_none_assert(skb)
-
-static inline void *_kc_vzalloc_node(unsigned long size, int node)
-{
- void *addr = vmalloc_node(size, node);
- if (addr)
- memset(addr, 0, size);
- return addr;
-}
-#define vzalloc_node(_size, _node) _kc_vzalloc_node(_size, _node)
-
-static inline void *_kc_vzalloc(unsigned long size)
-{
- void *addr = vmalloc(size);
- if (addr)
- memset(addr, 0, size);
- return addr;
-}
-#define vzalloc(_size) _kc_vzalloc(_size)
-
-#ifndef vlan_get_protocol
-static inline __be16 __kc_vlan_get_protocol(const struct sk_buff *skb)
-{
- if (vlan_tx_tag_present(skb) ||
- skb->protocol != cpu_to_be16(ETH_P_8021Q))
- return skb->protocol;
-
- if (skb_headlen(skb) < sizeof(struct vlan_ethhdr))
- return 0;
-
- return ((struct vlan_ethhdr*)skb->data)->h_vlan_encapsulated_proto;
-}
-#define vlan_get_protocol(_skb) __kc_vlan_get_protocol(_skb)
-#endif
-#ifdef HAVE_HW_TIME_STAMP
-#define SKBTX_HW_TSTAMP (1 << 0)
-#define SKBTX_IN_PROGRESS (1 << 2)
-#define SKB_SHARED_TX_IS_UNION
-#endif
-
-#ifndef device_wakeup_enable
-#define device_wakeup_enable(dev) device_set_wakeup_enable(dev, true)
-#endif
-
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,4,18) )
-#ifndef HAVE_VLAN_RX_REGISTER
-#define HAVE_VLAN_RX_REGISTER
-#endif
-#endif /* > 2.4.18 */
-#endif /* < 2.6.37 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) )
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) )
-#define skb_checksum_start_offset(skb) skb_transport_offset(skb)
-#else /* 2.6.22 -> 2.6.37 */
-static inline int _kc_skb_checksum_start_offset(const struct sk_buff *skb)
-{
- return skb->csum_start - skb_headroom(skb);
-}
-#define skb_checksum_start_offset(skb) _kc_skb_checksum_start_offset(skb)
-#endif /* 2.6.22 -> 2.6.37 */
-#ifdef CONFIG_DCB
-#ifndef IEEE_8021QAZ_MAX_TCS
-#define IEEE_8021QAZ_MAX_TCS 8
-#endif
-#ifndef DCB_CAP_DCBX_HOST
-#define DCB_CAP_DCBX_HOST 0x01
-#endif
-#ifndef DCB_CAP_DCBX_LLD_MANAGED
-#define DCB_CAP_DCBX_LLD_MANAGED 0x02
-#endif
-#ifndef DCB_CAP_DCBX_VER_CEE
-#define DCB_CAP_DCBX_VER_CEE 0x04
-#endif
-#ifndef DCB_CAP_DCBX_VER_IEEE
-#define DCB_CAP_DCBX_VER_IEEE 0x08
-#endif
-#ifndef DCB_CAP_DCBX_STATIC
-#define DCB_CAP_DCBX_STATIC 0x10
-#endif
-#endif /* CONFIG_DCB */
-#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,2))
-#define CONFIG_XPS
-#endif /* RHEL_RELEASE_VERSION(6,2) */
-#endif /* < 2.6.38 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) )
-#ifndef NETIF_F_RXCSUM
-#define NETIF_F_RXCSUM (1 << 29)
-#endif
-#ifndef skb_queue_reverse_walk_safe
-#define skb_queue_reverse_walk_safe(queue, skb, tmp) \
- for (skb = (queue)->prev, tmp = skb->prev; \
- skb != (struct sk_buff *)(queue); \
- skb = tmp, tmp = skb->prev)
-#endif
-#else /* < 2.6.39 */
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef HAVE_NETDEV_OPS_FCOE_DDP_TARGET
-#define HAVE_NETDEV_OPS_FCOE_DDP_TARGET
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-#ifndef HAVE_MQPRIO
-#define HAVE_MQPRIO
-#endif
-#ifndef HAVE_SETUP_TC
-#define HAVE_SETUP_TC
-#endif
-#ifdef CONFIG_DCB
-#ifndef HAVE_DCBNL_IEEE
-#define HAVE_DCBNL_IEEE
-#endif
-#endif /* CONFIG_DCB */
-#ifndef HAVE_NDO_SET_FEATURES
-#define HAVE_NDO_SET_FEATURES
-#endif
-#endif /* < 2.6.39 */
-
-/*****************************************************************************/
-/* use < 2.6.40 because of a Fedora 15 kernel update where they
- * updated the kernel version to 2.6.40.x and they back-ported 3.0 features
- * like set_phys_id for ethtool.
- */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,40) )
-#ifdef ETHTOOL_GRXRINGS
-#ifndef FLOW_EXT
-#define FLOW_EXT 0x80000000
-union _kc_ethtool_flow_union {
- struct ethtool_tcpip4_spec tcp_ip4_spec;
- struct ethtool_usrip4_spec usr_ip4_spec;
- __u8 hdata[60];
-};
-struct _kc_ethtool_flow_ext {
- __be16 vlan_etype;
- __be16 vlan_tci;
- __be32 data[2];
-};
-struct _kc_ethtool_rx_flow_spec {
- __u32 flow_type;
- union _kc_ethtool_flow_union h_u;
- struct _kc_ethtool_flow_ext h_ext;
- union _kc_ethtool_flow_union m_u;
- struct _kc_ethtool_flow_ext m_ext;
- __u64 ring_cookie;
- __u32 location;
-};
-#define ethtool_rx_flow_spec _kc_ethtool_rx_flow_spec
-#endif /* FLOW_EXT */
-#endif
-
-#define pci_disable_link_state_locked pci_disable_link_state
-
-#ifndef PCI_LTR_VALUE_MASK
-#define PCI_LTR_VALUE_MASK 0x000003ff
-#endif
-#ifndef PCI_LTR_SCALE_MASK
-#define PCI_LTR_SCALE_MASK 0x00001c00
-#endif
-#ifndef PCI_LTR_SCALE_SHIFT
-#define PCI_LTR_SCALE_SHIFT 10
-#endif
-
-#else /* < 2.6.40 */
-#define HAVE_ETHTOOL_SET_PHYS_ID
-#endif /* < 2.6.40 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) )
-#define USE_LEGACY_PM_SUPPORT
-#endif /* < 3.0.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) )
-#ifndef __netdev_alloc_skb_ip_align
-#define __netdev_alloc_skb_ip_align(d,l,_g) netdev_alloc_skb_ip_align(d,l)
-#endif /* __netdev_alloc_skb_ip_align */
-#define dcb_ieee_setapp(dev, app) dcb_setapp(dev, app)
-#define dcb_ieee_delapp(dev, app) 0
-#define dcb_ieee_getapp_mask(dev, app) (1 << app->priority)
-
-/* 1000BASE-T Control register */
-#define CTL1000_AS_MASTER 0x0800
-#define CTL1000_ENABLE_MASTER 0x1000
-
-#else /* < 3.1.0 */
-#ifndef HAVE_DCBNL_IEEE_DELAPP
-#define HAVE_DCBNL_IEEE_DELAPP
-#endif
-#endif /* < 3.1.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) )
-#ifdef ETHTOOL_GRXRINGS
-#define HAVE_ETHTOOL_GET_RXNFC_VOID_RULE_LOCS
-#endif /* ETHTOOL_GRXRINGS */
-
-#ifndef skb_frag_size
-#define skb_frag_size(frag) _kc_skb_frag_size(frag)
-static inline unsigned int _kc_skb_frag_size(const skb_frag_t *frag)
-{
- return frag->size;
-}
-#endif /* skb_frag_size */
-
-#ifndef skb_frag_size_sub
-#define skb_frag_size_sub(frag, delta) _kc_skb_frag_size_sub(frag, delta)
-static inline void _kc_skb_frag_size_sub(skb_frag_t *frag, int delta)
-{
- frag->size -= delta;
-}
-#endif /* skb_frag_size_sub */
-
-#ifndef skb_frag_page
-#define skb_frag_page(frag) _kc_skb_frag_page(frag)
-static inline struct page *_kc_skb_frag_page(const skb_frag_t *frag)
-{
- return frag->page;
-}
-#endif /* skb_frag_page */
-
-#ifndef skb_frag_address
-#define skb_frag_address(frag) _kc_skb_frag_address(frag)
-static inline void *_kc_skb_frag_address(const skb_frag_t *frag)
-{
- return page_address(skb_frag_page(frag)) + frag->page_offset;
-}
-#endif /* skb_frag_address */
-
-#ifndef skb_frag_dma_map
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) )
-#include <linux/dma-mapping.h>
-#endif
-#define skb_frag_dma_map(dev,frag,offset,size,dir) \
- _kc_skb_frag_dma_map(dev,frag,offset,size,dir)
-static inline dma_addr_t _kc_skb_frag_dma_map(struct device *dev,
- const skb_frag_t *frag,
- size_t offset, size_t size,
- enum dma_data_direction dir)
-{
- return dma_map_page(dev, skb_frag_page(frag),
- frag->page_offset + offset, size, dir);
-}
-#endif /* skb_frag_dma_map */
-
-#ifndef __skb_frag_unref
-#define __skb_frag_unref(frag) __kc_skb_frag_unref(frag)
-static inline void __kc_skb_frag_unref(skb_frag_t *frag)
-{
- put_page(skb_frag_page(frag));
-}
-#endif /* __skb_frag_unref */
-
-#ifndef SPEED_UNKNOWN
-#define SPEED_UNKNOWN -1
-#endif
-#ifndef DUPLEX_UNKNOWN
-#define DUPLEX_UNKNOWN 0xff
-#endif
-#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,3))
-#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED
-#define HAVE_PCI_DEV_FLAGS_ASSIGNED
-#endif
-#endif
-#else /* < 3.2.0 */
-#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED
-#define HAVE_PCI_DEV_FLAGS_ASSIGNED
-#define HAVE_VF_SPOOFCHK_CONFIGURE
-#endif
-#endif /* < 3.2.0 */
-
-#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE == RHEL_RELEASE_VERSION(6,2))
-#undef ixgbe_get_netdev_tc_txq
-#define ixgbe_get_netdev_tc_txq(dev, tc) (&netdev_extended(dev)->qos_data.tc_to_txq[tc])
-#endif
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) )
-typedef u32 kni_netdev_features_t;
-#undef PCI_EXP_TYPE_RC_EC
-#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
-#ifndef CONFIG_BQL
-#define netdev_tx_completed_queue(_q, _p, _b) do {} while (0)
-#define netdev_completed_queue(_n, _p, _b) do {} while (0)
-#define netdev_tx_sent_queue(_q, _b) do {} while (0)
-#define netdev_sent_queue(_n, _b) do {} while (0)
-#define netdev_tx_reset_queue(_q) do {} while (0)
-#define netdev_reset_queue(_n) do {} while (0)
-#endif
-#else /* ! < 3.3.0 */
-typedef netdev_features_t kni_netdev_features_t;
-#define HAVE_INT_NDO_VLAN_RX_ADD_VID
-#ifdef ETHTOOL_SRXNTUPLE
-#undef ETHTOOL_SRXNTUPLE
-#endif
-#endif /* < 3.3.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) )
-#ifndef NETIF_F_RXFCS
-#define NETIF_F_RXFCS 0
-#endif /* NETIF_F_RXFCS */
-#ifndef NETIF_F_RXALL
-#define NETIF_F_RXALL 0
-#endif /* NETIF_F_RXALL */
-
-#if !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0))
-#define NUMTCS_RETURNS_U8
-
-int _kc_simple_open(struct inode *inode, struct file *file);
-#define simple_open _kc_simple_open
-#endif /* !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0)) */
-
-
-#ifndef skb_add_rx_frag
-#define skb_add_rx_frag _kc_skb_add_rx_frag
-extern void _kc_skb_add_rx_frag(struct sk_buff *, int, struct page *,
- int, int, unsigned int);
-#endif
-#ifdef NET_ADDR_RANDOM
-#define eth_hw_addr_random(N) do { \
- random_ether_addr(N->dev_addr); \
- N->addr_assign_type |= NET_ADDR_RANDOM; \
- } while (0)
-#else /* NET_ADDR_RANDOM */
-#define eth_hw_addr_random(N) random_ether_addr(N->dev_addr)
-#endif /* NET_ADDR_RANDOM */
-#else /* < 3.4.0 */
-#include <linux/kconfig.h>
-#endif /* >= 3.4.0 */
-
-/*****************************************************************************/
-#if defined(E1000E_PTP) || defined(IGB_PTP) || defined(IXGBE_PTP) || defined(I40E_PTP)
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) ) && IS_ENABLED(CONFIG_PTP_1588_CLOCK)
-#define HAVE_PTP_1588_CLOCK
-#else
-#error Cannot enable PTP Hardware Clock support due to a pre-3.0 kernel version or CONFIG_PTP_1588_CLOCK not enabled in the kernel
-#endif /* > 3.0.0 && IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
-#endif /* E1000E_PTP || IGB_PTP || IXGBE_PTP || I40E_PTP */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) )
-#define skb_tx_timestamp(skb) do {} while (0)
-static inline bool __kc_ether_addr_equal(const u8 *addr1, const u8 *addr2)
-{
- return !compare_ether_addr(addr1, addr2);
-}
-#define ether_addr_equal(_addr1, _addr2) __kc_ether_addr_equal((_addr1),(_addr2))
-#else
-#define HAVE_FDB_OPS
-#define HAVE_ETHTOOL_GET_TS_INFO
-#endif /* < 3.5.0 */
-
-/*****************************************************************************/
-#include <linux/mdio.h>
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) )
-#define PCI_EXP_LNKCAP2 44 /* Link Capability 2 */
-
-#ifndef MDIO_EEE_100TX
-#define MDIO_EEE_100TX 0x0002 /* 100TX EEE cap */
-#endif
-#ifndef MDIO_EEE_1000T
-#define MDIO_EEE_1000T 0x0004 /* 1000T EEE cap */
-#endif
-#ifndef MDIO_EEE_10GT
-#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */
-#endif
-#ifndef MDIO_EEE_1000KX
-#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */
-#endif
-#ifndef MDIO_EEE_10GKX4
-#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */
-#endif
-#ifndef MDIO_EEE_10GKR
-#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */
-#endif
-#endif /* < 3.6.0 */
-
-/******************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) )
-#ifndef ADVERTISED_40000baseKR4_Full
-/* these defines were all added in one commit, so should be safe
- * to trigger activiation on one define
- */
-#define SUPPORTED_40000baseKR4_Full (1 << 23)
-#define SUPPORTED_40000baseCR4_Full (1 << 24)
-#define SUPPORTED_40000baseSR4_Full (1 << 25)
-#define SUPPORTED_40000baseLR4_Full (1 << 26)
-#define ADVERTISED_40000baseKR4_Full (1 << 23)
-#define ADVERTISED_40000baseCR4_Full (1 << 24)
-#define ADVERTISED_40000baseSR4_Full (1 << 25)
-#define ADVERTISED_40000baseLR4_Full (1 << 26)
-#endif
-
-/**
- * mmd_eee_cap_to_ethtool_sup_t
- * @eee_cap: value of the MMD EEE Capability register
- *
- * A small helper function that translates MMD EEE Capability (3.20) bits
- * to ethtool supported settings.
- */
-static inline u32 __kc_mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap)
-{
- u32 supported = 0;
-
- if (eee_cap & MDIO_EEE_100TX)
- supported |= SUPPORTED_100baseT_Full;
- if (eee_cap & MDIO_EEE_1000T)
- supported |= SUPPORTED_1000baseT_Full;
- if (eee_cap & MDIO_EEE_10GT)
- supported |= SUPPORTED_10000baseT_Full;
- if (eee_cap & MDIO_EEE_1000KX)
- supported |= SUPPORTED_1000baseKX_Full;
- if (eee_cap & MDIO_EEE_10GKX4)
- supported |= SUPPORTED_10000baseKX4_Full;
- if (eee_cap & MDIO_EEE_10GKR)
- supported |= SUPPORTED_10000baseKR_Full;
-
- return supported;
-}
-#define mmd_eee_cap_to_ethtool_sup_t(eee_cap) \
- __kc_mmd_eee_cap_to_ethtool_sup_t(eee_cap)
-
-/**
- * mmd_eee_adv_to_ethtool_adv_t
- * @eee_adv: value of the MMD EEE Advertisement/Link Partner Ability registers
- *
- * A small helper function that translates the MMD EEE Advertisement (7.60)
- * and MMD EEE Link Partner Ability (7.61) bits to ethtool advertisement
- * settings.
- */
-static inline u32 __kc_mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv)
-{
- u32 adv = 0;
-
- if (eee_adv & MDIO_EEE_100TX)
- adv |= ADVERTISED_100baseT_Full;
- if (eee_adv & MDIO_EEE_1000T)
- adv |= ADVERTISED_1000baseT_Full;
- if (eee_adv & MDIO_EEE_10GT)
- adv |= ADVERTISED_10000baseT_Full;
- if (eee_adv & MDIO_EEE_1000KX)
- adv |= ADVERTISED_1000baseKX_Full;
- if (eee_adv & MDIO_EEE_10GKX4)
- adv |= ADVERTISED_10000baseKX4_Full;
- if (eee_adv & MDIO_EEE_10GKR)
- adv |= ADVERTISED_10000baseKR_Full;
-
- return adv;
-}
-#define mmd_eee_adv_to_ethtool_adv_t(eee_adv) \
- __kc_mmd_eee_adv_to_ethtool_adv_t(eee_adv)
-
-/**
- * ethtool_adv_to_mmd_eee_adv_t
- * @adv: the ethtool advertisement settings
- *
- * A small helper function that translates ethtool advertisement settings
- * to EEE advertisements for the MMD EEE Advertisement (7.60) and
- * MMD EEE Link Partner Ability (7.61) registers.
- */
-static inline u16 __kc_ethtool_adv_to_mmd_eee_adv_t(u32 adv)
-{
- u16 reg = 0;
-
- if (adv & ADVERTISED_100baseT_Full)
- reg |= MDIO_EEE_100TX;
- if (adv & ADVERTISED_1000baseT_Full)
- reg |= MDIO_EEE_1000T;
- if (adv & ADVERTISED_10000baseT_Full)
- reg |= MDIO_EEE_10GT;
- if (adv & ADVERTISED_1000baseKX_Full)
- reg |= MDIO_EEE_1000KX;
- if (adv & ADVERTISED_10000baseKX4_Full)
- reg |= MDIO_EEE_10GKX4;
- if (adv & ADVERTISED_10000baseKR_Full)
- reg |= MDIO_EEE_10GKR;
-
- return reg;
-}
-#define ethtool_adv_to_mmd_eee_adv_t(adv) \
- __kc_ethtool_adv_to_mmd_eee_adv_t(adv)
-
-#ifndef pci_pcie_type
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) )
-static inline u8 pci_pcie_type(struct pci_dev *pdev)
-{
- int pos;
- u16 reg16;
-
- pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (!pos)
- BUG();
- pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16);
- return (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
-}
-#else /* < 2.6.24 */
-#define pci_pcie_type(x) (x)->pcie_type
-#endif /* < 2.6.24 */
-#endif /* pci_pcie_type */
-
-#define ptp_clock_register(caps, args...) ptp_clock_register(caps)
-
-#ifndef PCI_EXP_LNKSTA2
-int __kc_pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val);
-#define pcie_capability_read_word(d,p,v) __kc_pcie_capability_read_word(d,p,v)
-int __kc_pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val);
-#define pcie_capability_write_word(d,p,v) __kc_pcie_capability_write_word(d,p,v)
-int __kc_pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
- u16 clear, u16 set);
-#define pcie_capability_clear_and_set_word(d,p,c,s) \
- __kc_pcie_capability_clear_and_set_word(d,p,c,s)
-
-#define PCI_EXP_LNKSTA2 50 /* Link Status 2 */
-
-static inline int pcie_capability_clear_word(struct pci_dev *dev, int pos,
- u16 clear)
-{
- return __kc_pcie_capability_clear_and_set_word(dev, pos, clear, 0);
-}
-#endif /* !PCI_EXP_LNKSTA2 */
-
-#if (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0))
-#define USE_CONST_DEV_UC_CHAR
-#endif
-
-#else /* >= 3.7.0 */
-#define HAVE_CONST_STRUCT_PCI_ERROR_HANDLERS
-#define USE_CONST_DEV_UC_CHAR
-#endif /* >= 3.7.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) )
-#ifndef PCI_EXP_LNKCTL_ASPM_L0S
-#define PCI_EXP_LNKCTL_ASPM_L0S 0x01 /* L0s Enable */
-#endif
-#ifndef PCI_EXP_LNKCTL_ASPM_L1
-#define PCI_EXP_LNKCTL_ASPM_L1 0x02 /* L1 Enable */
-#endif
-#define HAVE_CONFIG_HOTPLUG
-/* Reserved Ethernet Addresses per IEEE 802.1Q */
-static const u8 eth_reserved_addr_base[ETH_ALEN] __aligned(2) = {
- 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
-#if !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0)) &&\
- !(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,5))
-static inline bool is_link_local_ether_addr(const u8 *addr)
-{
- __be16 *a = (__be16 *)addr;
- static const __be16 *b = (const __be16 *)eth_reserved_addr_base;
- static const __be16 m = cpu_to_be16(0xfff0);
-
- return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0;
-}
-#endif /* !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,3,0)) */
-#else /* >= 3.8.0 */
-#ifndef __devinit
-#define __devinit
-#define HAVE_ENCAP_CSUM_OFFLOAD
-#endif
-
-#ifndef __devinitdata
-#define __devinitdata
-#endif
-
-#ifndef __devexit
-#define __devexit
-#endif
-
-#ifndef __devexit_p
-#define __devexit_p
-#endif
-
-#ifndef HAVE_SRIOV_CONFIGURE
-#define HAVE_SRIOV_CONFIGURE
-#endif
-
-#define HAVE_BRIDGE_ATTRIBS
-#ifndef BRIDGE_MODE_VEB
-#define BRIDGE_MODE_VEB 0 /* Default loopback mode */
-#endif /* BRIDGE_MODE_VEB */
-#ifndef BRIDGE_MODE_VEPA
-#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */
-#endif /* BRIDGE_MODE_VEPA */
-#endif /* >= 3.8.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) )
-
-#undef hlist_entry
-#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
-
-#undef hlist_entry_safe
-#define hlist_entry_safe(ptr, type, member) \
- (ptr) ? hlist_entry(ptr, type, member) : NULL
-
-#undef hlist_for_each_entry
-#define hlist_for_each_entry(pos, head, member) \
- for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member); \
- pos; \
- pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
-
-#undef hlist_for_each_entry_safe
-#define hlist_for_each_entry_safe(pos, n, head, member) \
- for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); \
- pos && ({ n = pos->member.next; 1; }); \
- pos = hlist_entry_safe(n, typeof(*pos), member))
-
-#ifdef CONFIG_XPS
-extern int __kc_netif_set_xps_queue(struct net_device *, struct cpumask *, u16);
-#define netif_set_xps_queue(_dev, _mask, _idx) __kc_netif_set_xps_queue((_dev), (_mask), (_idx))
-#else /* CONFIG_XPS */
-#define netif_set_xps_queue(_dev, _mask, _idx) do {} while (0)
-#endif /* CONFIG_XPS */
-
-#ifdef HAVE_NETDEV_SELECT_QUEUE
-#define _kc_hashrnd 0xd631614b /* not so random hash salt */
-extern u16 __kc_netdev_pick_tx(struct net_device *dev, struct sk_buff *skb);
-#define __netdev_pick_tx __kc_netdev_pick_tx
-#endif /* HAVE_NETDEV_SELECT_QUEUE */
-#else
-#define HAVE_BRIDGE_FILTER
-#define USE_DEFAULT_FDB_DEL_DUMP
-#endif /* < 3.9.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) )
-#ifdef CONFIG_PCI_IOV
-extern int __kc_pci_vfs_assigned(struct pci_dev *dev);
-#else
-static inline int __kc_pci_vfs_assigned(struct pci_dev *dev)
-{
- return 0;
-}
-#endif
-#define pci_vfs_assigned(dev) __kc_pci_vfs_assigned(dev)
-
-#ifndef VLAN_TX_COOKIE_MAGIC
-static inline struct sk_buff *__kc__vlan_hwaccel_put_tag(struct sk_buff *skb,
- u16 vlan_tci)
-{
-#ifdef VLAN_TAG_PRESENT
- vlan_tci |= VLAN_TAG_PRESENT;
-#endif
- skb->vlan_tci = vlan_tci;
- return skb;
-}
-#define __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci) \
- __kc__vlan_hwaccel_put_tag(skb, vlan_tci)
-#endif
-
-#else /* >= 3.10.0 */
-#define HAVE_ENCAP_TSO_OFFLOAD
-#endif /* >= 3.10.0 */
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) )
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,6)))
-#if (!(UBUNTU_KERNEL_CODE >= UBUNTU_KERNEL_VERSION(3,13,0,30,0) \
- && (UBUNTU_RELEASE_CODE == UBUNTU_RELEASE_VERSION(12,4) \
- || UBUNTU_RELEASE_CODE == UBUNTU_RELEASE_VERSION(14,4))))
-#if (!(SLE_VERSION_CODE == SLE_VERSION(12,0,0)))
-#ifdef NETIF_F_RXHASH
-#define PKT_HASH_TYPE_L3 0
-static inline void
-skb_set_hash(struct sk_buff *skb, __u32 hash, __always_unused int type)
-{
- skb->rxhash = hash;
-}
-#endif /* NETIF_F_RXHASH */
-#endif /* < SLES12 */
-#endif /* < 3.13.0-30.54 (Ubuntu 14.04) */
-#endif /* < RHEL7 */
-#endif /* < 3.14.0 */
-
-#if (( LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) ) \
- || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2) ))
-#undef SET_ETHTOOL_OPS
-#define SET_ETHTOOL_OPS(netdev, ops) ((netdev)->ethtool_ops = (ops))
-#define HAVE_VF_MIN_MAX_TXRATE 1
-#endif /* >= 3.16.0 */
-
-#if (( LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) ) \
- || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2) ))
-#define HAVE_NDO_DFLT_BRIDGE_ADD_MASK
-#if ( RHEL_RELEASE_CODE != RHEL_RELEASE_VERSION(7,2) )
-#define HAVE_NDO_FDB_ADD_VID
-#endif /* !RHEL 7.2 */
-#endif /* >= 3.19.0 */
-
-#if (( LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) ) \
- || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,2) ))
-/* vlan_tx_xx functions got renamed to skb_vlan */
-#define vlan_tx_tag_get skb_vlan_tag_get
-#define vlan_tx_tag_present skb_vlan_tag_present
-#if ( RHEL_RELEASE_CODE != RHEL_RELEASE_VERSION(7,2) )
-#define HAVE_NDO_BRIDGE_SET_DEL_LINK_FLAGS
-#endif /* !RHEL 7.2 */
-#endif /* 4.0.0 */
-
-#if (( LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) ) \
- || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) ))
-/* ndo_bridge_getlink adds new nlflags parameter */
-#define HAVE_NDO_BRIDGE_GETLINK_NLFLAGS
-#endif /* >= 4.1.0 */
-
-#if (( LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0) ) \
- || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,4) ))
-/* ndo_bridge_getlink adds new filter_mask and vlan_fill parameters */
-#define HAVE_NDO_BRIDGE_GETLINK_FILTER_MASK_VLAN_FILL
-#endif /* >= 4.2.0 */
-
-/*
- * vlan_tx_tag_* macros renamed to skb_vlan_tag_* (Linux commit: df8a39defad4)
- * For older kernels backported this commit, need to use renamed functions.
- * This fix is specific to RedHat/CentOS kernels.
- */
-#if (defined(RHEL_RELEASE_CODE) && \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6, 8)) && \
- (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)))
-#define vlan_tx_tag_get skb_vlan_tag_get
-#define vlan_tx_tag_present skb_vlan_tag_present
-#endif
-
-#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) || \
- (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(12, 3, 0)) || \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 4)))
-#define HAVE_VF_VLAN_PROTO
-#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 4))
-/* In RHEL/Centos 7.4, the "new" version of ndo_set_vf_vlan
- * is in the struct net_device_ops_extended */
-#define ndo_set_vf_vlan extended.ndo_set_vf_vlan
-#endif
-#endif
-
-#if (defined(RHEL_RELEASE_CODE) && \
- (RHEL_RELEASE_VERSION(7, 5) <= RHEL_RELEASE_CODE))
-#define ndo_change_mtu ndo_change_mtu_rh74
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
-#define HAVE_PCI_ENABLE_MSIX
-#endif
-
-#if defined(timer_setup) && defined(from_timer)
-#define HAVE_TIMER_SETUP
-#endif
-
-#endif /* _KCOMPAT_H_ */
diff --git a/kernel/linux/kni/ethtool/igb/meson.build b/kernel/linux/kni/ethtool/igb/meson.build
deleted file mode 100644
index 2f796ac0b..000000000
--- a/kernel/linux/kni/ethtool/igb/meson.build
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
-
-kni_igb_sources = files(
- 'e1000_82575.c',
- 'e1000_api.c',
- 'e1000_i210.c',
- 'e1000_mac.c',
- 'e1000_manage.c',
- 'e1000_mbx.c',
- 'e1000_nvm.c',
- 'e1000_phy.c',
- 'igb_ethtool.c',
- 'igb_main.c',
- 'igb_param.c',
- 'igb_vmdq.c')
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe.h
deleted file mode 100644
index cc15ec6ab..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe.h
+++ /dev/null
@@ -1,912 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_H_
-#define _IXGBE_H_
-
-#ifndef IXGBE_NO_LRO
-#include <net/tcp.h>
-#endif
-
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#ifdef HAVE_IRQ_AFFINITY_HINT
-#include <linux/cpumask.h>
-#endif /* HAVE_IRQ_AFFINITY_HINT */
-#include <linux/vmalloc.h>
-
-#ifdef SIOCETHTOOL
-#include <linux/ethtool.h>
-#endif
-#ifdef NETIF_F_HW_VLAN_TX
-#include <linux/if_vlan.h>
-#endif
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
-#define IXGBE_DCA
-#include <linux/dca.h>
-#endif
-#include "ixgbe_dcb.h"
-
-#include "kcompat.h"
-
-#ifdef HAVE_SCTP
-#include <linux/sctp.h>
-#endif
-
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#define IXGBE_FCOE
-#include "ixgbe_fcoe.h"
-#endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */
-
-#if defined(CONFIG_PTP_1588_CLOCK) || defined(CONFIG_PTP_1588_CLOCK_MODULE)
-#define HAVE_IXGBE_PTP
-#endif
-
-#include "ixgbe_api.h"
-
-#define PFX "ixgbe: "
-#define DPRINTK(nlevel, klevel, fmt, args...) \
- ((void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
- printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
- __func__ , ## args)))
-
-/* TX/RX descriptor defines */
-#define IXGBE_DEFAULT_TXD 512
-#define IXGBE_DEFAULT_TX_WORK 256
-#define IXGBE_MAX_TXD 4096
-#define IXGBE_MIN_TXD 64
-
-#define IXGBE_DEFAULT_RXD 512
-#define IXGBE_DEFAULT_RX_WORK 256
-#define IXGBE_MAX_RXD 4096
-#define IXGBE_MIN_RXD 64
-
-
-/* flow control */
-#define IXGBE_MIN_FCRTL 0x40
-#define IXGBE_MAX_FCRTL 0x7FF80
-#define IXGBE_MIN_FCRTH 0x600
-#define IXGBE_MAX_FCRTH 0x7FFF0
-#define IXGBE_DEFAULT_FCPAUSE 0xFFFF
-#define IXGBE_MIN_FCPAUSE 0
-#define IXGBE_MAX_FCPAUSE 0xFFFF
-
-/* Supported Rx Buffer Sizes */
-#define IXGBE_RXBUFFER_512 512 /* Used for packet split */
-#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT
-#define IXGBE_RXBUFFER_1536 1536
-#define IXGBE_RXBUFFER_2K 2048
-#define IXGBE_RXBUFFER_3K 3072
-#define IXGBE_RXBUFFER_4K 4096
-#define IXGBE_RXBUFFER_7K 7168
-#define IXGBE_RXBUFFER_8K 8192
-#define IXGBE_RXBUFFER_15K 15360
-#endif /* CONFIG_IXGBE_DISABLE_PACKET_SPLIT */
-#define IXGBE_MAX_RXBUFFER 16384 /* largest size for single descriptor */
-
-/*
- * NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN mans we
- * reserve 2 more, and skb_shared_info adds an additional 384 bytes more,
- * this adds up to 512 bytes of extra data meaning the smallest allocation
- * we could have is 1K.
- * i.e. RXBUFFER_512 --> size-1024 slab
- */
-#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_512
-
-#define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
-
-/* How many Rx Buffers do we bundle into one write to the hardware ? */
-#define IXGBE_RX_BUFFER_WRITE 16 /* Must be power of 2 */
-
-#define IXGBE_TX_FLAGS_CSUM (u32)(1)
-#define IXGBE_TX_FLAGS_HW_VLAN (u32)(1 << 1)
-#define IXGBE_TX_FLAGS_SW_VLAN (u32)(1 << 2)
-#define IXGBE_TX_FLAGS_TSO (u32)(1 << 3)
-#define IXGBE_TX_FLAGS_IPV4 (u32)(1 << 4)
-#define IXGBE_TX_FLAGS_FCOE (u32)(1 << 5)
-#define IXGBE_TX_FLAGS_FSO (u32)(1 << 6)
-#define IXGBE_TX_FLAGS_TXSW (u32)(1 << 7)
-#define IXGBE_TX_FLAGS_TSTAMP (u32)(1 << 8)
-#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000
-#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000
-#define IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT 29
-#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
-
-#define IXGBE_MAX_RX_DESC_POLL 10
-
-#define IXGBE_MAX_VF_MC_ENTRIES 30
-#define IXGBE_MAX_VF_FUNCTIONS 64
-#define IXGBE_MAX_VFTA_ENTRIES 128
-#define MAX_EMULATION_MAC_ADDRS 16
-#define IXGBE_MAX_PF_MACVLANS 15
-#define IXGBE_82599_VF_DEVICE_ID 0x10ED
-#define IXGBE_X540_VF_DEVICE_ID 0x1515
-
-#ifdef CONFIG_PCI_IOV
-#define VMDQ_P(p) ((p) + adapter->num_vfs)
-#else
-#define VMDQ_P(p) (p)
-#endif
-
-#define UPDATE_VF_COUNTER_32bit(reg, last_counter, counter) \
- { \
- u32 current_counter = IXGBE_READ_REG(hw, reg); \
- if (current_counter < last_counter) \
- counter += 0x100000000LL; \
- last_counter = current_counter; \
- counter &= 0xFFFFFFFF00000000LL; \
- counter |= current_counter; \
- }
-
-#define UPDATE_VF_COUNTER_36bit(reg_lsb, reg_msb, last_counter, counter) \
- { \
- u64 current_counter_lsb = IXGBE_READ_REG(hw, reg_lsb); \
- u64 current_counter_msb = IXGBE_READ_REG(hw, reg_msb); \
- u64 current_counter = (current_counter_msb << 32) | \
- current_counter_lsb; \
- if (current_counter < last_counter) \
- counter += 0x1000000000LL; \
- last_counter = current_counter; \
- counter &= 0xFFFFFFF000000000LL; \
- counter |= current_counter; \
- }
-
-struct vf_stats {
- u64 gprc;
- u64 gorc;
- u64 gptc;
- u64 gotc;
- u64 mprc;
-};
-
-struct vf_data_storage {
- unsigned char vf_mac_addresses[ETH_ALEN];
- u16 vf_mc_hashes[IXGBE_MAX_VF_MC_ENTRIES];
- u16 num_vf_mc_hashes;
- u16 default_vf_vlan_id;
- u16 vlans_enabled;
- bool clear_to_send;
- struct vf_stats vfstats;
- struct vf_stats last_vfstats;
- struct vf_stats saved_rst_vfstats;
- bool pf_set_mac;
- u16 pf_vlan; /* When set, guest VLAN config not allowed. */
- u16 pf_qos;
- u16 tx_rate;
- u16 vlan_count;
- u8 spoofchk_enabled;
- struct pci_dev *vfdev;
-};
-
-struct vf_macvlans {
- struct list_head l;
- int vf;
- bool free;
- bool is_macvlan;
- u8 vf_macvlan[ETH_ALEN];
-};
-
-#ifndef IXGBE_NO_LRO
-#define IXGBE_LRO_MAX 32 /*Maximum number of LRO descriptors*/
-#define IXGBE_LRO_GLOBAL 10
-
-struct ixgbe_lro_stats {
- u32 flushed;
- u32 coal;
-};
-
-/*
- * ixgbe_lro_header - header format to be aggregated by LRO
- * @iph: IP header without options
- * @tcp: TCP header
- * @ts: Optional TCP timestamp data in TCP options
- *
- * This structure relies on the check above that verifies that the header
- * is IPv4 and does not contain any options.
- */
-struct ixgbe_lrohdr {
- struct iphdr iph;
- struct tcphdr th;
- __be32 ts[0];
-};
-
-struct ixgbe_lro_list {
- struct sk_buff_head active;
- struct ixgbe_lro_stats stats;
-};
-
-#endif /* IXGBE_NO_LRO */
-#define IXGBE_MAX_TXD_PWR 14
-#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR)
-
-/* Tx Descriptors needed, worst case */
-#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IXGBE_MAX_DATA_PER_TXD)
-#ifdef MAX_SKB_FRAGS
-#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4)
-#else
-#define DESC_NEEDED 4
-#endif
-
-/* wrapper around a pointer to a socket buffer,
- * so a DMA handle can be stored along with the buffer */
-struct ixgbe_tx_buffer {
- union ixgbe_adv_tx_desc *next_to_watch;
- unsigned long time_stamp;
- struct sk_buff *skb;
- unsigned int bytecount;
- unsigned short gso_segs;
- __be16 protocol;
- DEFINE_DMA_UNMAP_ADDR(dma);
- DEFINE_DMA_UNMAP_LEN(len);
- u32 tx_flags;
-};
-
-struct ixgbe_rx_buffer {
- struct sk_buff *skb;
- dma_addr_t dma;
-#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT
- struct page *page;
- unsigned int page_offset;
-#endif
-};
-
-struct ixgbe_queue_stats {
- u64 packets;
- u64 bytes;
-};
-
-struct ixgbe_tx_queue_stats {
- u64 restart_queue;
- u64 tx_busy;
- u64 tx_done_old;
-};
-
-struct ixgbe_rx_queue_stats {
- u64 rsc_count;
- u64 rsc_flush;
- u64 non_eop_descs;
- u64 alloc_rx_page_failed;
- u64 alloc_rx_buff_failed;
- u64 csum_err;
-};
-
-enum ixgbe_ring_state_t {
- __IXGBE_TX_FDIR_INIT_DONE,
- __IXGBE_TX_DETECT_HANG,
- __IXGBE_HANG_CHECK_ARMED,
- __IXGBE_RX_RSC_ENABLED,
-#ifndef HAVE_NDO_SET_FEATURES
- __IXGBE_RX_CSUM_ENABLED,
-#endif
- __IXGBE_RX_CSUM_UDP_ZERO_ERR,
-#ifdef IXGBE_FCOE
- __IXGBE_RX_FCOE_BUFSZ,
-#endif
-};
-
-#define check_for_tx_hang(ring) \
- test_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
-#define set_check_for_tx_hang(ring) \
- set_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
-#define clear_check_for_tx_hang(ring) \
- clear_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
-#ifndef IXGBE_NO_HW_RSC
-#define ring_is_rsc_enabled(ring) \
- test_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
-#else
-#define ring_is_rsc_enabled(ring) false
-#endif
-#define set_ring_rsc_enabled(ring) \
- set_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
-#define clear_ring_rsc_enabled(ring) \
- clear_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
-#define netdev_ring(ring) (ring->netdev)
-#define ring_queue_index(ring) (ring->queue_index)
-
-
-struct ixgbe_ring {
- struct ixgbe_ring *next; /* pointer to next ring in q_vector */
- struct ixgbe_q_vector *q_vector; /* backpointer to host q_vector */
- struct net_device *netdev; /* netdev ring belongs to */
- struct device *dev; /* device for DMA mapping */
- void *desc; /* descriptor ring memory */
- union {
- struct ixgbe_tx_buffer *tx_buffer_info;
- struct ixgbe_rx_buffer *rx_buffer_info;
- };
- unsigned long state;
- u8 __iomem *tail;
- dma_addr_t dma; /* phys. address of descriptor ring */
- unsigned int size; /* length in bytes */
-
- u16 count; /* amount of descriptors */
-
- u8 queue_index; /* needed for multiqueue queue management */
- u8 reg_idx; /* holds the special value that gets
- * the hardware register offset
- * associated with this ring, which is
- * different for DCB and RSS modes
- */
- u16 next_to_use;
- u16 next_to_clean;
-
- union {
-#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT
- u16 rx_buf_len;
-#else
- u16 next_to_alloc;
-#endif
- struct {
- u8 atr_sample_rate;
- u8 atr_count;
- };
- };
-
- u8 dcb_tc;
- struct ixgbe_queue_stats stats;
- union {
- struct ixgbe_tx_queue_stats tx_stats;
- struct ixgbe_rx_queue_stats rx_stats;
- };
-} ____cacheline_internodealigned_in_smp;
-
-enum ixgbe_ring_f_enum {
- RING_F_NONE = 0,
- RING_F_VMDQ, /* SR-IOV uses the same ring feature */
- RING_F_RSS,
- RING_F_FDIR,
-#ifdef IXGBE_FCOE
- RING_F_FCOE,
-#endif /* IXGBE_FCOE */
- RING_F_ARRAY_SIZE /* must be last in enum set */
-};
-
-#define IXGBE_MAX_DCB_INDICES 8
-#define IXGBE_MAX_RSS_INDICES 16
-#define IXGBE_MAX_VMDQ_INDICES 64
-#define IXGBE_MAX_FDIR_INDICES 64
-#ifdef IXGBE_FCOE
-#define IXGBE_MAX_FCOE_INDICES 8
-#define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES)
-#define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES)
-#else
-#define MAX_RX_QUEUES IXGBE_MAX_FDIR_INDICES
-#define MAX_TX_QUEUES IXGBE_MAX_FDIR_INDICES
-#endif /* IXGBE_FCOE */
-struct ixgbe_ring_feature {
- int indices;
- int mask;
-};
-
-#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT
-/*
- * FCoE requires that all Rx buffers be over 2200 bytes in length. Since
- * this is twice the size of a half page we need to double the page order
- * for FCoE enabled Rx queues.
- */
-#if defined(IXGBE_FCOE) && (PAGE_SIZE < 8192)
-static inline unsigned int ixgbe_rx_pg_order(struct ixgbe_ring *ring)
-{
- return test_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state) ? 1 : 0;
-}
-#else
-#define ixgbe_rx_pg_order(_ring) 0
-#endif
-#define ixgbe_rx_pg_size(_ring) (PAGE_SIZE << ixgbe_rx_pg_order(_ring))
-#define ixgbe_rx_bufsz(_ring) ((PAGE_SIZE / 2) << ixgbe_rx_pg_order(_ring))
-
-#endif
-struct ixgbe_ring_container {
- struct ixgbe_ring *ring; /* pointer to linked list of rings */
- unsigned int total_bytes; /* total bytes processed this int */
- unsigned int total_packets; /* total packets processed this int */
- u16 work_limit; /* total work allowed per interrupt */
- u8 count; /* total number of rings in vector */
- u8 itr; /* current ITR setting for ring */
-};
-
-/* iterator for handling rings in ring container */
-#define ixgbe_for_each_ring(pos, head) \
- for (pos = (head).ring; pos != NULL; pos = pos->next)
-
-#define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \
- ? 8 : 1)
-#define MAX_TX_PACKET_BUFFERS MAX_RX_PACKET_BUFFERS
-
-/* MAX_MSIX_Q_VECTORS of these are allocated,
- * but we only use one per queue-specific vector.
- */
-struct ixgbe_q_vector {
- struct ixgbe_adapter *adapter;
- int cpu; /* CPU for DCA */
- u16 v_idx; /* index of q_vector within array, also used for
- * finding the bit in EICR and friends that
- * represents the vector for this ring */
- u16 itr; /* Interrupt throttle rate written to EITR */
- struct ixgbe_ring_container rx, tx;
-
-#ifdef CONFIG_IXGBE_NAPI
- struct napi_struct napi;
-#endif
-#ifndef HAVE_NETDEV_NAPI_LIST
- struct net_device poll_dev;
-#endif
-#ifdef HAVE_IRQ_AFFINITY_HINT
- cpumask_t affinity_mask;
-#endif
-#ifndef IXGBE_NO_LRO
- struct ixgbe_lro_list lrolist; /* LRO list for queue vector*/
-#endif
- int numa_node;
- char name[IFNAMSIZ + 9];
-
- /* for dynamic allocation of rings associated with this q_vector */
- struct ixgbe_ring ring[0] ____cacheline_internodealigned_in_smp;
-};
-
-/*
- * microsecond values for various ITR rates shifted by 2 to fit itr register
- * with the first 3 bits reserved 0
- */
-#define IXGBE_MIN_RSC_ITR 24
-#define IXGBE_100K_ITR 40
-#define IXGBE_20K_ITR 200
-#define IXGBE_16K_ITR 248
-#define IXGBE_10K_ITR 400
-#define IXGBE_8K_ITR 500
-
-/* ixgbe_test_staterr - tests bits in Rx descriptor status and error fields */
-static inline __le32 ixgbe_test_staterr(union ixgbe_adv_rx_desc *rx_desc,
- const u32 stat_err_bits)
-{
- return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits);
-}
-
-/* ixgbe_desc_unused - calculate if we have unused descriptors */
-static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
-{
- u16 ntc = ring->next_to_clean;
- u16 ntu = ring->next_to_use;
-
- return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
-}
-
-#define IXGBE_RX_DESC(R, i) \
- (&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
-#define IXGBE_TX_DESC(R, i) \
- (&(((union ixgbe_adv_tx_desc *)((R)->desc))[i]))
-#define IXGBE_TX_CTXTDESC(R, i) \
- (&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i]))
-
-#define IXGBE_MAX_JUMBO_FRAME_SIZE 16128
-#ifdef IXGBE_FCOE
-/* use 3K as the baby jumbo frame size for FCoE */
-#define IXGBE_FCOE_JUMBO_FRAME_SIZE 3072
-#endif /* IXGBE_FCOE */
-
-#define TCP_TIMER_VECTOR 0
-#define OTHER_VECTOR 1
-#define NON_Q_VECTORS (OTHER_VECTOR + TCP_TIMER_VECTOR)
-
-#define IXGBE_MAX_MSIX_Q_VECTORS_82599 64
-#define IXGBE_MAX_MSIX_Q_VECTORS_82598 16
-
-struct ixgbe_mac_addr {
- u8 addr[ETH_ALEN];
- u16 queue;
- u16 state; /* bitmask */
-};
-#define IXGBE_MAC_STATE_DEFAULT 0x1
-#define IXGBE_MAC_STATE_MODIFIED 0x2
-#define IXGBE_MAC_STATE_IN_USE 0x4
-
-#ifdef IXGBE_PROCFS
-struct ixgbe_therm_proc_data {
- struct ixgbe_hw *hw;
- struct ixgbe_thermal_diode_data *sensor_data;
-};
-
-#endif /* IXGBE_PROCFS */
-
-/*
- * Only for array allocations in our adapter struct. On 82598, there will be
- * unused entries in the array, but that's not a big deal. Also, in 82599,
- * we can actually assign 64 queue vectors based on our extended-extended
- * interrupt registers. This is different than 82598, which is limited to 16.
- */
-#define MAX_MSIX_Q_VECTORS IXGBE_MAX_MSIX_Q_VECTORS_82599
-#define MAX_MSIX_COUNT IXGBE_MAX_MSIX_VECTORS_82599
-
-#define MIN_MSIX_Q_VECTORS 1
-#define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS)
-
-/* default to trying for four seconds */
-#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
-
-/* board specific private data structure */
-struct ixgbe_adapter {
-#ifdef NETIF_F_HW_VLAN_TX
-#ifdef HAVE_VLAN_RX_REGISTER
- struct vlan_group *vlgrp; /* must be first, see ixgbe_receive_skb */
-#else
- unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
-#endif
-#endif /* NETIF_F_HW_VLAN_TX */
- /* OS defined structs */
- struct net_device *netdev;
- struct pci_dev *pdev;
-
- unsigned long state;
-
- /* Some features need tri-state capability,
- * thus the additional *_CAPABLE flags.
- */
- u32 flags;
-#define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 0)
-#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 1)
-#define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 2)
-#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 3)
-#ifndef IXGBE_NO_LLI
-#define IXGBE_FLAG_LLI_PUSH (u32)(1 << 4)
-#endif
-#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 8)
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
-#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 9)
-#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 10)
-#define IXGBE_FLAG_DCA_ENABLED_DATA (u32)(1 << 11)
-#else
-#define IXGBE_FLAG_DCA_ENABLED (u32)0
-#define IXGBE_FLAG_DCA_CAPABLE (u32)0
-#define IXGBE_FLAG_DCA_ENABLED_DATA (u32)0
-#endif
-#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 12)
-#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 13)
-#define IXGBE_FLAG_DCB_CAPABLE (u32)(1 << 14)
-#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 15)
-#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 16)
-#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 18)
-#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 19)
-#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 20)
-#define IXGBE_FLAG_NEED_LINK_CONFIG (u32)(1 << 21)
-#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 22)
-#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 23)
-#ifdef IXGBE_FCOE
-#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 24)
-#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 25)
-#endif /* IXGBE_FCOE */
-#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 26)
-#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 27)
-#define IXGBE_FLAG_SRIOV_REPLICATION_ENABLE (u32)(1 << 28)
-#define IXGBE_FLAG_SRIOV_L2SWITCH_ENABLE (u32)(1 << 29)
-#define IXGBE_FLAG_SRIOV_L2LOOPBACK_ENABLE (u32)(1 << 30)
-#define IXGBE_FLAG_RX_BB_CAPABLE (u32)(1 << 31)
-
- u32 flags2;
-#ifndef IXGBE_NO_HW_RSC
-#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
-#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
-#else
-#define IXGBE_FLAG2_RSC_CAPABLE 0
-#define IXGBE_FLAG2_RSC_ENABLED 0
-#endif
-#define IXGBE_FLAG2_VMDQ_DEFAULT_OVERRIDE (u32)(1 << 2)
-#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 4)
-#define IXGBE_FLAG2_TEMP_SENSOR_EVENT (u32)(1 << 5)
-#define IXGBE_FLAG2_SEARCH_FOR_SFP (u32)(1 << 6)
-#define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 7)
-#define IXGBE_FLAG2_RESET_REQUESTED (u32)(1 << 8)
-#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 9)
-#define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP (u32)(1 << 10)
-#define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP (u32)(1 << 11)
-#define IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED (u32)(1 << 12)
-
- /* Tx fast path data */
- int num_tx_queues;
- u16 tx_itr_setting;
- u16 tx_work_limit;
-
- /* Rx fast path data */
- int num_rx_queues;
- u16 rx_itr_setting;
- u16 rx_work_limit;
-
- /* TX */
- struct ixgbe_ring *tx_ring[MAX_TX_QUEUES] ____cacheline_aligned_in_smp;
-
- u64 restart_queue;
- u64 lsc_int;
- u32 tx_timeout_count;
-
- /* RX */
- struct ixgbe_ring *rx_ring[MAX_RX_QUEUES];
- int num_rx_pools; /* == num_rx_queues in 82598 */
- int num_rx_queues_per_pool; /* 1 if 82598, can be many if 82599 */
- u64 hw_csum_rx_error;
- u64 hw_rx_no_dma_resources;
- u64 rsc_total_count;
- u64 rsc_total_flush;
- u64 non_eop_descs;
-#ifndef CONFIG_IXGBE_NAPI
- u64 rx_dropped_backlog; /* count drops from rx intr handler */
-#endif
- u32 alloc_rx_page_failed;
- u32 alloc_rx_buff_failed;
-
- struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
-
-#ifdef HAVE_DCBNL_IEEE
- struct ieee_pfc *ixgbe_ieee_pfc;
- struct ieee_ets *ixgbe_ieee_ets;
-#endif
- struct ixgbe_dcb_config dcb_cfg;
- struct ixgbe_dcb_config temp_dcb_cfg;
- u8 dcb_set_bitmap;
- u8 dcbx_cap;
-#ifndef HAVE_MQPRIO
- u8 tc;
-#endif
- enum ixgbe_fc_mode last_lfc_mode;
-
- int num_msix_vectors;
- int max_msix_q_vectors; /* true count of q_vectors for device */
- struct ixgbe_ring_feature ring_feature[RING_F_ARRAY_SIZE];
- struct msix_entry *msix_entries;
-
-#ifndef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats net_stats;
-#endif
-#ifndef IXGBE_NO_LRO
- struct ixgbe_lro_stats lro_stats;
-#endif
-
-#ifdef ETHTOOL_TEST
- u32 test_icr;
- struct ixgbe_ring test_tx_ring;
- struct ixgbe_ring test_rx_ring;
-#endif
-
- /* structs defined in ixgbe_hw.h */
- struct ixgbe_hw hw;
- u16 msg_enable;
- struct ixgbe_hw_stats stats;
-#ifndef IXGBE_NO_LLI
- u32 lli_port;
- u32 lli_size;
- u32 lli_etype;
- u32 lli_vlan_pri;
-#endif /* IXGBE_NO_LLI */
-
- u32 *config_space;
- u64 tx_busy;
- unsigned int tx_ring_count;
- unsigned int rx_ring_count;
-
- u32 link_speed;
- bool link_up;
- unsigned long link_check_timeout;
-
- struct timer_list service_timer;
- struct work_struct service_task;
-
- struct hlist_head fdir_filter_list;
- unsigned long fdir_overflow; /* number of times ATR was backed off */
- union ixgbe_atr_input fdir_mask;
- int fdir_filter_count;
- u32 fdir_pballoc;
- u32 atr_sample_rate;
- spinlock_t fdir_perfect_lock;
-
-#ifdef IXGBE_FCOE
- struct ixgbe_fcoe fcoe;
-#endif /* IXGBE_FCOE */
- u32 wol;
-
- u16 bd_number;
-
- char eeprom_id[32];
- u16 eeprom_cap;
- bool netdev_registered;
- u32 interrupt_event;
-#ifdef HAVE_ETHTOOL_SET_PHYS_ID
- u32 led_reg;
-#endif
-
- DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);
- unsigned int num_vfs;
- struct vf_data_storage *vfinfo;
- int vf_rate_link_speed;
- struct vf_macvlans vf_mvs;
- struct vf_macvlans *mv_list;
-#ifdef CONFIG_PCI_IOV
- u32 timer_event_accumulator;
- u32 vferr_refcount;
-#endif
- struct ixgbe_mac_addr *mac_table;
-#ifdef IXGBE_SYSFS
- struct kobject *info_kobj;
- struct kobject *therm_kobj[IXGBE_MAX_SENSORS];
-#else /* IXGBE_SYSFS */
-#ifdef IXGBE_PROCFS
- struct proc_dir_entry *eth_dir;
- struct proc_dir_entry *info_dir;
- struct proc_dir_entry *therm_dir[IXGBE_MAX_SENSORS];
- struct ixgbe_therm_proc_data therm_data[IXGBE_MAX_SENSORS];
-#endif /* IXGBE_PROCFS */
-#endif /* IXGBE_SYSFS */
-};
-
-struct ixgbe_fdir_filter {
- struct hlist_node fdir_node;
- union ixgbe_atr_input filter;
- u16 sw_idx;
- u16 action;
-};
-
-enum ixgbe_state_t {
- __IXGBE_TESTING,
- __IXGBE_RESETTING,
- __IXGBE_DOWN,
- __IXGBE_SERVICE_SCHED,
- __IXGBE_IN_SFP_INIT,
-};
-
-struct ixgbe_cb {
-#ifdef CONFIG_IXGBE_DISABLE_PACKET_SPLIT
- union { /* Union defining head/tail partner */
- struct sk_buff *head;
- struct sk_buff *tail;
- };
-#endif
- dma_addr_t dma;
-#ifndef IXGBE_NO_LRO
- __be32 tsecr; /* timestamp echo response */
- u32 tsval; /* timestamp value in host order */
- u32 next_seq; /* next expected sequence number */
- u16 free; /* 65521 minus total size */
- u16 mss; /* size of data portion of packet */
-#endif /* IXGBE_NO_LRO */
-#ifdef HAVE_VLAN_RX_REGISTER
- u16 vid; /* VLAN tag */
-#endif
- u16 append_cnt; /* number of skb's appended */
-#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT
- bool page_released;
-#endif
-};
-#define IXGBE_CB(skb) ((struct ixgbe_cb *)(skb)->cb)
-
-#ifdef IXGBE_SYSFS
-void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter);
-int ixgbe_sysfs_init(struct ixgbe_adapter *adapter);
-#endif /* IXGBE_SYSFS */
-#ifdef IXGBE_PROCFS
-void ixgbe_procfs_exit(struct ixgbe_adapter *adapter);
-int ixgbe_procfs_init(struct ixgbe_adapter *adapter);
-int ixgbe_procfs_topdir_init(void);
-void ixgbe_procfs_topdir_exit(void);
-#endif /* IXGBE_PROCFS */
-
-extern struct dcbnl_rtnl_ops dcbnl_ops;
-extern int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max);
-
-extern u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 index);
-
-/* needed by ixgbe_main.c */
-extern int ixgbe_validate_mac_addr(u8 *mc_addr);
-extern void ixgbe_check_options(struct ixgbe_adapter *adapter);
-extern void ixgbe_assign_netdev_ops(struct net_device *netdev);
-
-/* needed by ixgbe_ethtool.c */
-extern char ixgbe_driver_name[];
-extern const char ixgbe_driver_version[];
-
-extern void ixgbe_up(struct ixgbe_adapter *adapter);
-extern void ixgbe_down(struct ixgbe_adapter *adapter);
-extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
-extern void ixgbe_reset(struct ixgbe_adapter *adapter);
-extern void ixgbe_set_ethtool_ops(struct net_device *netdev);
-extern int ixgbe_setup_rx_resources(struct ixgbe_ring *);
-extern int ixgbe_setup_tx_resources(struct ixgbe_ring *);
-extern void ixgbe_free_rx_resources(struct ixgbe_ring *);
-extern void ixgbe_free_tx_resources(struct ixgbe_ring *);
-extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,
- struct ixgbe_ring *);
-extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,
- struct ixgbe_ring *);
-extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
-extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
-extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
-extern bool ixgbe_is_ixgbe(struct pci_dev *pcidev);
-extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *,
- struct ixgbe_adapter *,
- struct ixgbe_ring *);
-extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *,
- struct ixgbe_tx_buffer *);
-extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16);
-extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *);
-extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *);
-extern void ixgbe_set_rx_mode(struct net_device *netdev);
-extern int ixgbe_write_mc_addr_list(struct net_device *netdev);
-extern int ixgbe_setup_tc(struct net_device *dev, u8 tc);
-#ifdef IXGBE_FCOE
-extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32);
-#endif /* IXGBE_FCOE */
-extern void ixgbe_do_reset(struct net_device *netdev);
-extern void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector);
-extern void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *);
-extern void ixgbe_vlan_stripping_enable(struct ixgbe_adapter *adapter);
-extern void ixgbe_vlan_stripping_disable(struct ixgbe_adapter *adapter);
-#ifdef ETHTOOL_OPS_COMPAT
-extern int ethtool_ioctl(struct ifreq *ifr);
-#endif
-
-#ifdef IXGBE_FCOE
-extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter);
-extern int ixgbe_fso(struct ixgbe_ring *tx_ring,
- struct ixgbe_tx_buffer *first,
- u8 *hdr_len);
-extern void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter);
-extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
- union ixgbe_adv_rx_desc *rx_desc,
- struct sk_buff *skb);
-extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
- struct scatterlist *sgl, unsigned int sgc);
-#ifdef HAVE_NETDEV_OPS_FCOE_DDP_TARGET
-extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid,
- struct scatterlist *sgl, unsigned int sgc);
-#endif /* HAVE_NETDEV_OPS_FCOE_DDP_TARGET */
-extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid);
-#ifdef HAVE_NETDEV_OPS_FCOE_ENABLE
-extern int ixgbe_fcoe_enable(struct net_device *netdev);
-extern int ixgbe_fcoe_disable(struct net_device *netdev);
-#endif /* HAVE_NETDEV_OPS_FCOE_ENABLE */
-#ifdef CONFIG_DCB
-#ifdef HAVE_DCBNL_OPS_GETAPP
-extern u8 ixgbe_fcoe_getapp(struct net_device *netdev);
-#endif /* HAVE_DCBNL_OPS_GETAPP */
-extern u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up);
-#endif /* CONFIG_DCB */
-#ifdef HAVE_NETDEV_OPS_FCOE_GETWWN
-extern int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type);
-#endif
-#endif /* IXGBE_FCOE */
-
-#ifdef CONFIG_DCB
-#ifdef HAVE_DCBNL_IEEE
-s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max_frame);
-#endif /* HAVE_DCBNL_IEEE */
-#endif /* CONFIG_DCB */
-
-extern void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring);
-#ifndef ETHTOOL_GLINKSETTINGS
-extern int ixgbe_get_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd);
-#endif
-extern int ixgbe_write_uc_addr_list(struct ixgbe_adapter *adapter,
- struct net_device *netdev, unsigned int vfn);
-extern void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter);
-extern int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
- u8 *addr, u16 queue);
-extern int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
- u8 *addr, u16 queue);
-extern int ixgbe_available_rars(struct ixgbe_adapter *adapter);
-#ifndef HAVE_VLAN_RX_REGISTER
-extern void ixgbe_vlan_mode(struct net_device *, u32);
-#endif
-#ifndef ixgbe_get_netdev_tc_txq
-#define ixgbe_get_netdev_tc_txq(dev, tc) (&dev->tc_to_txq[tc])
-#endif
-extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter);
-#endif /* _IXGBE_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.c b/kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.c
deleted file mode 100644
index 242de671e..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.c
+++ /dev/null
@@ -1,1281 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "ixgbe_type.h"
-#include "ixgbe_82598.h"
-#include "ixgbe_api.h"
-#include "ixgbe_common.h"
-#include "ixgbe_phy.h"
-
-static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *autoneg);
-static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
- bool autoneg_wait_to_complete);
-static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed, bool *link_up,
- bool link_up_wait_to_complete);
-static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
-static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
-static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
-static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
-static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
- u32 headroom, int strategy);
-
-/**
- * ixgbe_set_pcie_completion_timeout - set pci-e completion timeout
- * @hw: pointer to the HW structure
- *
- * The defaults for 82598 should be in the range of 50us to 50ms,
- * however the hardware default for these parts is 500us to 1ms which is less
- * than the 10ms recommended by the pci-e spec. To address this we need to
- * increase the value to either 10ms to 250ms for capability version 1 config,
- * or 16ms to 55ms for version 2.
- **/
-void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
-{
- u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR);
- u16 pcie_devctl2;
-
- /* only take action if timeout value is defaulted to 0 */
- if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK)
- goto out;
-
- /*
- * if capababilities version is type 1 we can write the
- * timeout of 10ms to 250ms through the GCR register
- */
- if (!(gcr & IXGBE_GCR_CAP_VER2)) {
- gcr |= IXGBE_GCR_CMPL_TMOUT_10ms;
- goto out;
- }
-
- /*
- * for version 2 capabilities we need to write the config space
- * directly in order to set the completion timeout value for
- * 16ms to 55ms
- */
- pcie_devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2);
- pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms;
- IXGBE_WRITE_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2);
-out:
- /* disable completion timeout resend */
- gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND;
- IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr);
-}
-
-/**
- * ixgbe_init_ops_82598 - Inits func ptrs and MAC type
- * @hw: pointer to hardware structure
- *
- * Initialize the function pointers and assign the MAC type for 82598.
- * Does not touch the hardware.
- **/
-s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
-{
- struct ixgbe_mac_info *mac = &hw->mac;
- struct ixgbe_phy_info *phy = &hw->phy;
- s32 ret_val;
-
- ret_val = ixgbe_init_phy_ops_generic(hw);
- ret_val = ixgbe_init_ops_generic(hw);
-
- /* PHY */
- phy->ops.init = &ixgbe_init_phy_ops_82598;
-
- /* MAC */
- mac->ops.start_hw = &ixgbe_start_hw_82598;
- mac->ops.reset_hw = &ixgbe_reset_hw_82598;
- mac->ops.get_media_type = &ixgbe_get_media_type_82598;
- mac->ops.get_supported_physical_layer =
- &ixgbe_get_supported_physical_layer_82598;
- mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82598;
- mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82598;
- mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie_82598;
-
- /* RAR, Multicast, VLAN */
- mac->ops.set_vmdq = &ixgbe_set_vmdq_82598;
- mac->ops.clear_vmdq = &ixgbe_clear_vmdq_82598;
- mac->ops.set_vfta = &ixgbe_set_vfta_82598;
- mac->ops.set_vlvf = NULL;
- mac->ops.clear_vfta = &ixgbe_clear_vfta_82598;
-
- /* Flow Control */
- mac->ops.fc_enable = &ixgbe_fc_enable_82598;
-
- mac->mcft_size = 128;
- mac->vft_size = 128;
- mac->num_rar_entries = 16;
- mac->rx_pb_size = 512;
- mac->max_tx_queues = 32;
- mac->max_rx_queues = 64;
- mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw);
-
- /* SFP+ Module */
- phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598;
-
- /* Link */
- mac->ops.check_link = &ixgbe_check_mac_link_82598;
- mac->ops.setup_link = &ixgbe_setup_mac_link_82598;
- mac->ops.flap_tx_laser = NULL;
- mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82598;
- mac->ops.setup_rxpba = &ixgbe_set_rxpba_82598;
-
- /* Manageability interface */
- mac->ops.set_fw_drv_ver = NULL;
-
- return ret_val;
-}
-
-/**
- * ixgbe_init_phy_ops_82598 - PHY/SFP specific init
- * @hw: pointer to hardware structure
- *
- * Initialize any function pointers that were not able to be
- * set during init_shared_code because the PHY/SFP type was
- * not known. Perform the SFP init if necessary.
- *
- **/
-s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
-{
- struct ixgbe_mac_info *mac = &hw->mac;
- struct ixgbe_phy_info *phy = &hw->phy;
- s32 ret_val = 0;
- u16 list_offset, data_offset;
-
- /* Identify the PHY */
- phy->ops.identify(hw);
-
- /* Overwrite the link function pointers if copper PHY */
- if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
- mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
- mac->ops.get_link_capabilities =
- &ixgbe_get_copper_link_capabilities_generic;
- }
-
- switch (hw->phy.type) {
- case ixgbe_phy_tn:
- phy->ops.setup_link = &ixgbe_setup_phy_link_tnx;
- phy->ops.check_link = &ixgbe_check_phy_link_tnx;
- phy->ops.get_firmware_version =
- &ixgbe_get_phy_firmware_version_tnx;
- break;
- case ixgbe_phy_nl:
- phy->ops.reset = &ixgbe_reset_phy_nl;
-
- /* Call SFP+ identify routine to get the SFP+ module type */
- ret_val = phy->ops.identify_sfp(hw);
- if (ret_val != 0)
- goto out;
- else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) {
- ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
- }
-
- /* Check to see if SFP+ module is supported */
- ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
- &list_offset,
- &data_offset);
- if (ret_val != 0) {
- ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
- }
- break;
- default:
- break;
- }
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx
- * @hw: pointer to hardware structure
- *
- * Starts the hardware using the generic start_hw function.
- * Disables relaxed ordering Then set pcie completion timeout
- *
- **/
-s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
-{
- u32 regval;
- u32 i;
- s32 ret_val = 0;
-
- ret_val = ixgbe_start_hw_generic(hw);
-
- /* Disable relaxed ordering */
- for (i = 0; ((i < hw->mac.max_tx_queues) &&
- (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
- regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
- regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
- }
-
- for (i = 0; ((i < hw->mac.max_rx_queues) &&
- (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
- regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
- regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
- IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
- IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
- }
-
- /* set the completion timeout for interface */
- if (ret_val == 0)
- ixgbe_set_pcie_completion_timeout(hw);
-
- return ret_val;
-}
-
-/**
- * ixgbe_get_link_capabilities_82598 - Determines link capabilities
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @autoneg: boolean auto-negotiation value
- *
- * Determines the link capabilities by reading the AUTOC register.
- **/
-static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *autoneg)
-{
- s32 status = 0;
- u32 autoc = 0;
-
- /*
- * Determine link capabilities based on the stored value of AUTOC,
- * which represents EEPROM defaults. If AUTOC value has not been
- * stored, use the current register value.
- */
- if (hw->mac.orig_link_settings_stored)
- autoc = hw->mac.orig_autoc;
- else
- autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-
- switch (autoc & IXGBE_AUTOC_LMS_MASK) {
- case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- *autoneg = false;
- break;
-
- case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
- *speed = IXGBE_LINK_SPEED_10GB_FULL;
- *autoneg = false;
- break;
-
- case IXGBE_AUTOC_LMS_1G_AN:
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- *autoneg = true;
- break;
-
- case IXGBE_AUTOC_LMS_KX4_AN:
- case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
- *speed = IXGBE_LINK_SPEED_UNKNOWN;
- if (autoc & IXGBE_AUTOC_KX4_SUPP)
- *speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (autoc & IXGBE_AUTOC_KX_SUPP)
- *speed |= IXGBE_LINK_SPEED_1GB_FULL;
- *autoneg = true;
- break;
-
- default:
- status = IXGBE_ERR_LINK_SETUP;
- break;
- }
-
- return status;
-}
-
-/**
- * ixgbe_get_media_type_82598 - Determines media type
- * @hw: pointer to hardware structure
- *
- * Returns the media type (fiber, copper, backplane)
- **/
-static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
-{
- enum ixgbe_media_type media_type;
-
- /* Detect if there is a copper PHY attached. */
- switch (hw->phy.type) {
- case ixgbe_phy_cu_unknown:
- case ixgbe_phy_tn:
- media_type = ixgbe_media_type_copper;
- goto out;
- default:
- break;
- }
-
- /* Media type for I82598 is based on device ID */
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82598:
- case IXGBE_DEV_ID_82598_BX:
- /* Default device ID is mezzanine card KX/KX4 */
- media_type = ixgbe_media_type_backplane;
- break;
- case IXGBE_DEV_ID_82598AF_DUAL_PORT:
- case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
- case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
- case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
- case IXGBE_DEV_ID_82598EB_XF_LR:
- case IXGBE_DEV_ID_82598EB_SFP_LOM:
- media_type = ixgbe_media_type_fiber;
- break;
- case IXGBE_DEV_ID_82598EB_CX4:
- case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
- media_type = ixgbe_media_type_cx4;
- break;
- case IXGBE_DEV_ID_82598AT:
- case IXGBE_DEV_ID_82598AT2:
- media_type = ixgbe_media_type_copper;
- break;
- default:
- media_type = ixgbe_media_type_unknown;
- break;
- }
-out:
- return media_type;
-}
-
-/**
- * ixgbe_fc_enable_82598 - Enable flow control
- * @hw: pointer to hardware structure
- *
- * Enable flow control according to the current settings.
- **/
-s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
-{
- s32 ret_val = 0;
- u32 fctrl_reg;
- u32 rmcs_reg;
- u32 reg;
- u32 fcrtl, fcrth;
- u32 link_speed = 0;
- int i;
- bool link_up;
-
- /* Validate the water mark configuration */
- if (!hw->fc.pause_time) {
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
-
- /* Low water mark of zero causes XOFF floods */
- for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
- if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
- hw->fc.high_water[i]) {
- if (!hw->fc.low_water[i] ||
- hw->fc.low_water[i] >= hw->fc.high_water[i]) {
- hw_dbg(hw, "Invalid water mark configuration\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
- }
- }
-
- /*
- * On 82598 having Rx FC on causes resets while doing 1G
- * so if it's on turn it off once we know link_speed. For
- * more details see 82598 Specification update.
- */
- hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
- if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
- switch (hw->fc.requested_mode) {
- case ixgbe_fc_full:
- hw->fc.requested_mode = ixgbe_fc_tx_pause;
- break;
- case ixgbe_fc_rx_pause:
- hw->fc.requested_mode = ixgbe_fc_none;
- break;
- default:
- /* no change */
- break;
- }
- }
-
- /* Negotiate the fc mode to use */
- ixgbe_fc_autoneg(hw);
-
- /* Disable any previous flow control settings */
- fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
-
- rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
- rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
-
- /*
- * The possible values of fc.current_mode are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames,
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but
- * we do not support receiving pause frames).
- * 3: Both Rx and Tx flow control (symmetric) are enabled.
- * other: Invalid.
- */
- switch (hw->fc.current_mode) {
- case ixgbe_fc_none:
- /*
- * Flow control is disabled by software override or autoneg.
- * The code below will actually disable it in the HW.
- */
- break;
- case ixgbe_fc_rx_pause:
- /*
- * Rx Flow control is enabled and Tx Flow control is
- * disabled by software override. Since there really
- * isn't a way to advertise that we are capable of RX
- * Pause ONLY, we will advertise that we support both
- * symmetric and asymmetric Rx PAUSE. Later, we will
- * disable the adapter's ability to send PAUSE frames.
- */
- fctrl_reg |= IXGBE_FCTRL_RFCE;
- break;
- case ixgbe_fc_tx_pause:
- /*
- * Tx Flow control is enabled, and Rx Flow control is
- * disabled by software override.
- */
- rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
- break;
- case ixgbe_fc_full:
- /* Flow control (both Rx and Tx) is enabled by SW override. */
- fctrl_reg |= IXGBE_FCTRL_RFCE;
- rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
- break;
- default:
- hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = IXGBE_ERR_CONFIG;
- goto out;
- break;
- }
-
- /* Set 802.3x based flow control settings. */
- fctrl_reg |= IXGBE_FCTRL_DPF;
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
- IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
-
- /* Set up and enable Rx high/low water mark thresholds, enable XON. */
- for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
- if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
- hw->fc.high_water[i]) {
- fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
- fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
- } else {
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
- }
-
- }
-
- /* Configure pause time (2 TCs per register) */
- reg = hw->fc.pause_time * 0x00010001;
- for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
-
- /* Configure flow control refresh threshold value */
- IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_start_mac_link_82598 - Configures MAC link settings
- * @hw: pointer to hardware structure
- *
- * Configures link settings based on values in the ixgbe_hw struct.
- * Restarts the link. Performs autonegotiation if needed.
- **/
-static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
- bool autoneg_wait_to_complete)
-{
- u32 autoc_reg;
- u32 links_reg;
- u32 i;
- s32 status = 0;
-
- /* Restart link */
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- autoc_reg |= IXGBE_AUTOC_AN_RESTART;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-
- /* Only poll for autoneg to complete if specified to do so */
- if (autoneg_wait_to_complete) {
- if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
- IXGBE_AUTOC_LMS_KX4_AN ||
- (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
- IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
- links_reg = 0; /* Just in case Autoneg time = 0 */
- for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
- links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
- if (links_reg & IXGBE_LINKS_KX_AN_COMP)
- break;
- msleep(100);
- }
- if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
- status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
- hw_dbg(hw, "Autonegotiation did not complete.\n");
- }
- }
- }
-
- /* Add delay to filter out noises during initial link setup */
- msleep(50);
-
- return status;
-}
-
-/**
- * ixgbe_validate_link_ready - Function looks for phy link
- * @hw: pointer to hardware structure
- *
- * Function indicates success when phy link is available. If phy is not ready
- * within 5 seconds of MAC indicating link, the function returns error.
- **/
-static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw)
-{
- u32 timeout;
- u16 an_reg;
-
- if (hw->device_id != IXGBE_DEV_ID_82598AT2)
- return 0;
-
- for (timeout = 0;
- timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) {
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg);
-
- if ((an_reg & IXGBE_MII_AUTONEG_COMPLETE) &&
- (an_reg & IXGBE_MII_AUTONEG_LINK_UP))
- break;
-
- msleep(100);
- }
-
- if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) {
- hw_dbg(hw, "Link was indicated but link is down\n");
- return IXGBE_ERR_LINK_SETUP;
- }
-
- return 0;
-}
-
-/**
- * ixgbe_check_mac_link_82598 - Get link/speed status
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @link_up: true is link is up, false otherwise
- * @link_up_wait_to_complete: bool used to wait for link up or not
- *
- * Reads the links register to determine if link is up and the current speed
- **/
-static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed, bool *link_up,
- bool link_up_wait_to_complete)
-{
- u32 links_reg;
- u32 i;
- u16 link_reg, adapt_comp_reg;
-
- /*
- * SERDES PHY requires us to read link status from undocumented
- * register 0xC79F. Bit 0 set indicates link is up/ready; clear
- * indicates link down. OxC00C is read to check that the XAUI lanes
- * are active. Bit 0 clear indicates active; set indicates inactive.
- */
- if (hw->phy.type == ixgbe_phy_nl) {
- hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
- hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
- hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV,
- &adapt_comp_reg);
- if (link_up_wait_to_complete) {
- for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
- if ((link_reg & 1) &&
- ((adapt_comp_reg & 1) == 0)) {
- *link_up = true;
- break;
- } else {
- *link_up = false;
- }
- msleep(100);
- hw->phy.ops.read_reg(hw, 0xC79F,
- IXGBE_TWINAX_DEV,
- &link_reg);
- hw->phy.ops.read_reg(hw, 0xC00C,
- IXGBE_TWINAX_DEV,
- &adapt_comp_reg);
- }
- } else {
- if ((link_reg & 1) && ((adapt_comp_reg & 1) == 0))
- *link_up = true;
- else
- *link_up = false;
- }
-
- if (*link_up == false)
- goto out;
- }
-
- links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
- if (link_up_wait_to_complete) {
- for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
- if (links_reg & IXGBE_LINKS_UP) {
- *link_up = true;
- break;
- } else {
- *link_up = false;
- }
- msleep(100);
- links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
- }
- } else {
- if (links_reg & IXGBE_LINKS_UP)
- *link_up = true;
- else
- *link_up = false;
- }
-
- if (links_reg & IXGBE_LINKS_SPEED)
- *speed = IXGBE_LINK_SPEED_10GB_FULL;
- else
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
-
- if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == true) &&
- (ixgbe_validate_link_ready(hw) != 0))
- *link_up = false;
-
-out:
- return 0;
-}
-
-/**
- * ixgbe_setup_mac_link_82598 - Set MAC link speed
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- * @autoneg_wait_to_complete: true when waiting for completion is needed
- *
- * Set the link speed in the AUTOC register and restarts link.
- **/
-static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
- bool autoneg_wait_to_complete)
-{
- s32 status = 0;
- ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
- u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- u32 autoc = curr_autoc;
- u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
-
- /* Check to see if speed passed in is supported. */
- ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
- speed &= link_capabilities;
-
- if (speed == IXGBE_LINK_SPEED_UNKNOWN)
- status = IXGBE_ERR_LINK_SETUP;
-
- /* Set KX4/KX support according to speed requested */
- else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
- link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
- autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
- if (speed & IXGBE_LINK_SPEED_10GB_FULL)
- autoc |= IXGBE_AUTOC_KX4_SUPP;
- if (speed & IXGBE_LINK_SPEED_1GB_FULL)
- autoc |= IXGBE_AUTOC_KX_SUPP;
- if (autoc != curr_autoc)
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
- }
-
- if (status == 0) {
- /*
- * Setup and restart the link based on the new values in
- * ixgbe_hw This will write the AUTOC register based on the new
- * stored values
- */
- status = ixgbe_start_mac_link_82598(hw,
- autoneg_wait_to_complete);
- }
-
- return status;
-}
-
-
-/**
- * ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- * @autoneg_wait_to_complete: true if waiting is needed to complete
- *
- * Sets the link speed in the AUTOC register in the MAC and restarts link.
- **/
-static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete)
-{
- s32 status;
-
- /* Setup the PHY according to input speed */
- status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
- autoneg_wait_to_complete);
- /* Set up MAC */
- ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
-
- return status;
-}
-
-/**
- * ixgbe_reset_hw_82598 - Performs hardware reset
- * @hw: pointer to hardware structure
- *
- * Resets the hardware by resetting the transmit and receive units, masks and
- * clears all interrupts, performing a PHY reset, and performing a link (MAC)
- * reset.
- **/
-static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- s32 phy_status = 0;
- u32 ctrl;
- u32 gheccr;
- u32 i;
- u32 autoc;
- u8 analog_val;
-
- /* Call adapter stop to disable tx/rx and clear interrupts */
- status = hw->mac.ops.stop_adapter(hw);
- if (status != 0)
- goto reset_hw_out;
-
- /*
- * Power up the Atlas Tx lanes if they are currently powered down.
- * Atlas Tx lanes are powered down for MAC loopback tests, but
- * they are not automatically restored on reset.
- */
- hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
- if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) {
- /* Enable Tx Atlas so packets can be transmitted again */
- hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
- &analog_val);
- analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN;
- hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
- analog_val);
-
- hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
- &analog_val);
- analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
- hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
- analog_val);
-
- hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
- &analog_val);
- analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
- hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
- analog_val);
-
- hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
- &analog_val);
- analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
- hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
- analog_val);
- }
-
- /* Reset PHY */
- if (hw->phy.reset_disable == false) {
- /* PHY ops must be identified and initialized prior to reset */
-
- /* Init PHY and function pointers, perform SFP setup */
- phy_status = hw->phy.ops.init(hw);
- if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto reset_hw_out;
- if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
- goto mac_reset_top;
-
- hw->phy.ops.reset(hw);
- }
-
-mac_reset_top:
- /*
- * Issue global reset to the MAC. This needs to be a SW reset.
- * If link reset is used, it might reset the MAC when mng is using it
- */
- ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST;
- IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
- IXGBE_WRITE_FLUSH(hw);
-
- /* Poll for reset bit to self-clear indicating reset is complete */
- for (i = 0; i < 10; i++) {
- udelay(1);
- ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
- if (!(ctrl & IXGBE_CTRL_RST))
- break;
- }
- if (ctrl & IXGBE_CTRL_RST) {
- status = IXGBE_ERR_RESET_FAILED;
- hw_dbg(hw, "Reset polling failed to complete.\n");
- }
-
- msleep(50);
-
- /*
- * Double resets are required for recovery from certain error
- * conditions. Between resets, it is necessary to stall to allow time
- * for any pending HW events to complete.
- */
- if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
- hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
- goto mac_reset_top;
- }
-
- gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR);
- gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6));
- IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
-
- /*
- * Store the original AUTOC value if it has not been
- * stored off yet. Otherwise restore the stored original
- * AUTOC value since the reset operation sets back to deaults.
- */
- autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- if (hw->mac.orig_link_settings_stored == false) {
- hw->mac.orig_autoc = autoc;
- hw->mac.orig_link_settings_stored = true;
- } else if (autoc != hw->mac.orig_autoc) {
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
- }
-
- /* Store the permanent mac address */
- hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
-
- /*
- * Store MAC address from RAR0, clear receive address registers, and
- * clear the multicast table
- */
- hw->mac.ops.init_rx_addrs(hw);
-
-reset_hw_out:
- if (phy_status != 0)
- status = phy_status;
-
- return status;
-}
-
-/**
- * ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address
- * @hw: pointer to hardware struct
- * @rar: receive address register index to associate with a VMDq index
- * @vmdq: VMDq set index
- **/
-s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
-{
- u32 rar_high;
- u32 rar_entries = hw->mac.num_rar_entries;
-
- /* Make sure we are using a valid rar index range */
- if (rar >= rar_entries) {
- hw_dbg(hw, "RAR index %d is out of range.\n", rar);
- return IXGBE_ERR_INVALID_ARGUMENT;
- }
-
- rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
- rar_high &= ~IXGBE_RAH_VIND_MASK;
- rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK);
- IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
- return 0;
-}
-
-/**
- * ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address
- * @hw: pointer to hardware struct
- * @rar: receive address register index to associate with a VMDq index
- * @vmdq: VMDq clear index (not used in 82598, but elsewhere)
- **/
-static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
-{
- u32 rar_high;
- u32 rar_entries = hw->mac.num_rar_entries;
-
-
- /* Make sure we are using a valid rar index range */
- if (rar >= rar_entries) {
- hw_dbg(hw, "RAR index %d is out of range.\n", rar);
- return IXGBE_ERR_INVALID_ARGUMENT;
- }
-
- rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
- if (rar_high & IXGBE_RAH_VIND_MASK) {
- rar_high &= ~IXGBE_RAH_VIND_MASK;
- IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
- }
-
- return 0;
-}
-
-/**
- * ixgbe_set_vfta_82598 - Set VLAN filter table
- * @hw: pointer to hardware structure
- * @vlan: VLAN id to write to VLAN filter
- * @vind: VMDq output index that maps queue to VLAN id in VFTA
- * @vlan_on: boolean flag to turn on/off VLAN in VFTA
- *
- * Turn on/off specified VLAN in the VLAN filter table.
- **/
-s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
- bool vlan_on)
-{
- u32 regindex;
- u32 bitindex;
- u32 bits;
- u32 vftabyte;
-
- if (vlan > 4095)
- return IXGBE_ERR_PARAM;
-
- /* Determine 32-bit word position in array */
- regindex = (vlan >> 5) & 0x7F; /* upper seven bits */
-
- /* Determine the location of the (VMD) queue index */
- vftabyte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
- bitindex = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */
-
- /* Set the nibble for VMD queue index */
- bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex));
- bits &= (~(0x0F << bitindex));
- bits |= (vind << bitindex);
- IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits);
-
- /* Determine the location of the bit for this VLAN id */
- bitindex = vlan & 0x1F; /* lower five bits */
-
- bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
- if (vlan_on)
- /* Turn on this VLAN id */
- bits |= (1 << bitindex);
- else
- /* Turn off this VLAN id */
- bits &= ~(1 << bitindex);
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
-
- return 0;
-}
-
-/**
- * ixgbe_clear_vfta_82598 - Clear VLAN filter table
- * @hw: pointer to hardware structure
- *
- * Clears the VLAN filer table, and the VMDq index associated with the filter
- **/
-static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
-{
- u32 offset;
- u32 vlanbyte;
-
- for (offset = 0; offset < hw->mac.vft_size; offset++)
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
-
- for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
- for (offset = 0; offset < hw->mac.vft_size; offset++)
- IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
- 0);
-
- return 0;
-}
-
-/**
- * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
- * @hw: pointer to hardware structure
- * @reg: analog register to read
- * @val: read value
- *
- * Performs read operation to Atlas analog register specified.
- **/
-s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val)
-{
- u32 atlas_ctl;
-
- IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
- IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
- IXGBE_WRITE_FLUSH(hw);
- udelay(10);
- atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
- *val = (u8)atlas_ctl;
-
- return 0;
-}
-
-/**
- * ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register
- * @hw: pointer to hardware structure
- * @reg: atlas register to write
- * @val: value to write
- *
- * Performs write operation to Atlas analog register specified.
- **/
-s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
-{
- u32 atlas_ctl;
-
- atlas_ctl = (reg << 8) | val;
- IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
- IXGBE_WRITE_FLUSH(hw);
- udelay(10);
-
- return 0;
-}
-
-/**
- * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
- * @hw: pointer to hardware structure
- * @byte_offset: EEPROM byte offset to read
- * @eeprom_data: value read
- *
- * Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
- **/
-s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
- u8 *eeprom_data)
-{
- s32 status = 0;
- u16 sfp_addr = 0;
- u16 sfp_data = 0;
- u16 sfp_stat = 0;
- u32 i;
-
- if (hw->phy.type == ixgbe_phy_nl) {
- /*
- * NetLogic phy SDA/SCL registers are at addresses 0xC30A to
- * 0xC30D. These registers are used to talk to the SFP+
- * module's EEPROM through the SDA/SCL (I2C) interface.
- */
- sfp_addr = (IXGBE_I2C_EEPROM_DEV_ADDR << 8) + byte_offset;
- sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
- hw->phy.ops.write_reg(hw,
- IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- sfp_addr);
-
- /* Poll status */
- for (i = 0; i < 100; i++) {
- hw->phy.ops.read_reg(hw,
- IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &sfp_stat);
- sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
- if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
- break;
- msleep(10);
- }
-
- if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) {
- hw_dbg(hw, "EEPROM read did not pass.\n");
- status = IXGBE_ERR_SFP_NOT_PRESENT;
- goto out;
- }
-
- /* Read data */
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
-
- *eeprom_data = (u8)(sfp_data >> 8);
- } else {
- status = IXGBE_ERR_PHY;
- goto out;
- }
-
-out:
- return status;
-}
-
-/**
- * ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
- * @hw: pointer to hardware structure
- *
- * Determines physical layer capabilities of the current configuration.
- **/
-u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
-{
- u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
- u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
- u16 ext_ability = 0;
-
- hw->phy.ops.identify(hw);
-
- /* Copper PHY must be checked before AUTOC LMS to determine correct
- * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
- switch (hw->phy.type) {
- case ixgbe_phy_tn:
- case ixgbe_phy_cu_unknown:
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
- if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
- if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
- if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
- physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
- goto out;
- default:
- break;
- }
-
- switch (autoc & IXGBE_AUTOC_LMS_MASK) {
- case IXGBE_AUTOC_LMS_1G_AN:
- case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
- if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
- else
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
- break;
- case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
- if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
- else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
- else /* XAUI */
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- break;
- case IXGBE_AUTOC_LMS_KX4_AN:
- case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
- if (autoc & IXGBE_AUTOC_KX_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
- if (autoc & IXGBE_AUTOC_KX4_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
- break;
- default:
- break;
- }
-
- if (hw->phy.type == ixgbe_phy_nl) {
- hw->phy.ops.identify_sfp(hw);
-
- switch (hw->phy.sfp_type) {
- case ixgbe_sfp_type_da_cu:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
- break;
- case ixgbe_sfp_type_sr:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- break;
- case ixgbe_sfp_type_lr:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- break;
- default:
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- break;
- }
- }
-
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
- break;
- case IXGBE_DEV_ID_82598AF_DUAL_PORT:
- case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
- case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- break;
- case IXGBE_DEV_ID_82598EB_XF_LR:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- break;
- default:
- break;
- }
-
-out:
- return physical_layer;
-}
-
-/**
- * ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
- * port devices.
- * @hw: pointer to the HW structure
- *
- * Calls common function and corrects issue with some single port devices
- * that enable LAN1 but not LAN0.
- **/
-void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw)
-{
- struct ixgbe_bus_info *bus = &hw->bus;
- u16 pci_gen = 0;
- u16 pci_ctrl2 = 0;
-
- ixgbe_set_lan_id_multi_port_pcie(hw);
-
- /* check if LAN0 is disabled */
- hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen);
- if ((pci_gen != 0) && (pci_gen != 0xFFFF)) {
-
- hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2);
-
- /* if LAN0 is completely disabled force function to 0 */
- if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) &&
- !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) &&
- !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) {
-
- bus->func = 0;
- }
- }
-}
-
-/**
- * ixgbe_set_rxpba_82598 - Initialize RX packet buffer
- * @hw: pointer to hardware structure
- * @num_pb: number of packet buffers to allocate
- * @headroom: reserve n KB of headroom
- * @strategy: packet buffer allocation strategy
- **/
-static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
- u32 headroom, int strategy)
-{
- u32 rxpktsize = IXGBE_RXPBSIZE_64KB;
- u8 i = 0;
-
- if (!num_pb)
- return;
-
- /* Setup Rx packet buffer sizes */
- switch (strategy) {
- case PBA_STRATEGY_WEIGHTED:
- /* Setup the first four at 80KB */
- rxpktsize = IXGBE_RXPBSIZE_80KB;
- for (; i < 4; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
- /* Setup the last four at 48KB...don't re-init i */
- rxpktsize = IXGBE_RXPBSIZE_48KB;
- /* Fall Through */
- case PBA_STRATEGY_EQUAL:
- default:
- /* Divide the remaining Rx packet buffer evenly among the TCs */
- for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
- break;
- }
-
- /* Setup Tx packet buffer sizes */
- for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++)
- IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), IXGBE_TXPBSIZE_40KB);
-
- return;
-}
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.h
deleted file mode 100644
index 9a8c670a7..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_82598_H_
-#define _IXGBE_82598_H_
-
-u32 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw);
-s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw);
-s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw);
-s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
-s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on);
-s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val);
-s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val);
-s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
- u8 *eeprom_data);
-u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw);
-s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw);
-void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw);
-void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw);
-#endif /* _IXGBE_82598_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.c b/kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.c
deleted file mode 100644
index 3f1591230..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.c
+++ /dev/null
@@ -1,2299 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "ixgbe_type.h"
-#include "ixgbe_82599.h"
-#include "ixgbe_api.h"
-#include "ixgbe_common.h"
-#include "ixgbe_phy.h"
-
-static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
-static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
-static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
- u16 offset, u16 *data);
-static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data);
-static s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data);
-static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data);
-
-void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
-{
- struct ixgbe_mac_info *mac = &hw->mac;
-
- /* enable the laser control functions for SFP+ fiber */
- if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) {
- mac->ops.disable_tx_laser =
- &ixgbe_disable_tx_laser_multispeed_fiber;
- mac->ops.enable_tx_laser =
- &ixgbe_enable_tx_laser_multispeed_fiber;
- mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber;
-
- } else {
- mac->ops.disable_tx_laser = NULL;
- mac->ops.enable_tx_laser = NULL;
- mac->ops.flap_tx_laser = NULL;
- }
-
- if (hw->phy.multispeed_fiber) {
- /* Set up dual speed SFP+ support */
- mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
- } else {
- if ((ixgbe_get_media_type(hw) == ixgbe_media_type_backplane) &&
- (hw->phy.smart_speed == ixgbe_smart_speed_auto ||
- hw->phy.smart_speed == ixgbe_smart_speed_on) &&
- !ixgbe_verify_lesm_fw_enabled_82599(hw)) {
- mac->ops.setup_link = &ixgbe_setup_mac_link_smartspeed;
- } else {
- mac->ops.setup_link = &ixgbe_setup_mac_link_82599;
- }
- }
-}
-
-/**
- * ixgbe_init_phy_ops_82599 - PHY/SFP specific init
- * @hw: pointer to hardware structure
- *
- * Initialize any function pointers that were not able to be
- * set during init_shared_code because the PHY/SFP type was
- * not known. Perform the SFP init if necessary.
- *
- **/
-s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
-{
- struct ixgbe_mac_info *mac = &hw->mac;
- struct ixgbe_phy_info *phy = &hw->phy;
- s32 ret_val = 0;
- u32 esdp;
-
- if (hw->device_id == IXGBE_DEV_ID_82599_QSFP_SF_QP) {
- /* Store flag indicating I2C bus access control unit. */
- hw->phy.qsfp_shared_i2c_bus = TRUE;
-
- /* Initialize access to QSFP+ I2C bus */
- esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
- esdp |= IXGBE_ESDP_SDP0_DIR;
- esdp &= ~IXGBE_ESDP_SDP1_DIR;
- esdp &= ~IXGBE_ESDP_SDP0;
- esdp &= ~IXGBE_ESDP_SDP0_NATIVE;
- esdp &= ~IXGBE_ESDP_SDP1_NATIVE;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
- IXGBE_WRITE_FLUSH(hw);
-
- phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_82599;
- phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_82599;
- }
- /* Identify the PHY or SFP module */
- ret_val = phy->ops.identify(hw);
- if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto init_phy_ops_out;
-
- /* Setup function pointers based on detected SFP module and speeds */
- ixgbe_init_mac_link_ops_82599(hw);
- if (hw->phy.sfp_type != ixgbe_sfp_type_unknown)
- hw->phy.ops.reset = NULL;
-
- /* If copper media, overwrite with copper function pointers */
- if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
- mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
- mac->ops.get_link_capabilities =
- &ixgbe_get_copper_link_capabilities_generic;
- }
-
- /* Set necessary function pointers based on phy type */
- switch (hw->phy.type) {
- case ixgbe_phy_tn:
- phy->ops.setup_link = &ixgbe_setup_phy_link_tnx;
- phy->ops.check_link = &ixgbe_check_phy_link_tnx;
- phy->ops.get_firmware_version =
- &ixgbe_get_phy_firmware_version_tnx;
- break;
- default:
- break;
- }
-init_phy_ops_out:
- return ret_val;
-}
-
-s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
-{
- s32 ret_val = 0;
- u32 reg_anlp1 = 0;
- u32 i = 0;
- u16 list_offset, data_offset, data_value;
-
- if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
- ixgbe_init_mac_link_ops_82599(hw);
-
- hw->phy.ops.reset = NULL;
-
- ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
- &data_offset);
- if (ret_val != 0)
- goto setup_sfp_out;
-
- /* PHY config will finish before releasing the semaphore */
- ret_val = hw->mac.ops.acquire_swfw_sync(hw,
- IXGBE_GSSR_MAC_CSR_SM);
- if (ret_val != 0) {
- ret_val = IXGBE_ERR_SWFW_SYNC;
- goto setup_sfp_out;
- }
-
- hw->eeprom.ops.read(hw, ++data_offset, &data_value);
- while (data_value != 0xffff) {
- IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
- IXGBE_WRITE_FLUSH(hw);
- hw->eeprom.ops.read(hw, ++data_offset, &data_value);
- }
-
- /* Release the semaphore */
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
- /* Delay obtaining semaphore again to allow FW access */
- msleep(hw->eeprom.semaphore_delay);
-
- /* Now restart DSP by setting Restart_AN and clearing LMS */
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
- IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) |
- IXGBE_AUTOC_AN_RESTART));
-
- /* Wait for AN to leave state 0 */
- for (i = 0; i < 10; i++) {
- msleep(4);
- reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
- if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
- break;
- }
- if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) {
- hw_dbg(hw, "sfp module setup not complete\n");
- ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
- goto setup_sfp_out;
- }
-
- /* Restart DSP by setting Restart_AN and return to SFI mode */
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
- IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL |
- IXGBE_AUTOC_AN_RESTART));
- }
-
-setup_sfp_out:
- return ret_val;
-}
-
-/**
- * ixgbe_init_ops_82599 - Inits func ptrs and MAC type
- * @hw: pointer to hardware structure
- *
- * Initialize the function pointers and assign the MAC type for 82599.
- * Does not touch the hardware.
- **/
-
-s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
-{
- struct ixgbe_mac_info *mac = &hw->mac;
- struct ixgbe_phy_info *phy = &hw->phy;
- struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
- s32 ret_val;
-
- ixgbe_init_phy_ops_generic(hw);
- ret_val = ixgbe_init_ops_generic(hw);
-
- /* PHY */
- phy->ops.identify = &ixgbe_identify_phy_82599;
- phy->ops.init = &ixgbe_init_phy_ops_82599;
-
- /* MAC */
- mac->ops.reset_hw = &ixgbe_reset_hw_82599;
- mac->ops.get_media_type = &ixgbe_get_media_type_82599;
- mac->ops.get_supported_physical_layer =
- &ixgbe_get_supported_physical_layer_82599;
- mac->ops.disable_sec_rx_path = &ixgbe_disable_sec_rx_path_generic;
- mac->ops.enable_sec_rx_path = &ixgbe_enable_sec_rx_path_generic;
- mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_82599;
- mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82599;
- mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82599;
- mac->ops.start_hw = &ixgbe_start_hw_82599;
- mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic;
- mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_generic;
- mac->ops.get_device_caps = &ixgbe_get_device_caps_generic;
- mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic;
- mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic;
-
- /* RAR, Multicast, VLAN */
- mac->ops.set_vmdq = &ixgbe_set_vmdq_generic;
- mac->ops.set_vmdq_san_mac = &ixgbe_set_vmdq_san_mac_generic;
- mac->ops.clear_vmdq = &ixgbe_clear_vmdq_generic;
- mac->ops.insert_mac_addr = &ixgbe_insert_mac_addr_generic;
- mac->rar_highwater = 1;
- mac->ops.set_vfta = &ixgbe_set_vfta_generic;
- mac->ops.set_vlvf = &ixgbe_set_vlvf_generic;
- mac->ops.clear_vfta = &ixgbe_clear_vfta_generic;
- mac->ops.init_uta_tables = &ixgbe_init_uta_tables_generic;
- mac->ops.setup_sfp = &ixgbe_setup_sfp_modules_82599;
- mac->ops.set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing;
- mac->ops.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing;
-
- /* Link */
- mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82599;
- mac->ops.check_link = &ixgbe_check_mac_link_generic;
- mac->ops.setup_rxpba = &ixgbe_set_rxpba_generic;
- ixgbe_init_mac_link_ops_82599(hw);
-
- mac->mcft_size = 128;
- mac->vft_size = 128;
- mac->num_rar_entries = 128;
- mac->rx_pb_size = 512;
- mac->max_tx_queues = 128;
- mac->max_rx_queues = 128;
- mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw);
-
- mac->arc_subsystem_valid = (IXGBE_READ_REG(hw, IXGBE_FWSM) &
- IXGBE_FWSM_MODE_MASK) ? true : false;
-
- //hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
-
- /* EEPROM */
- eeprom->ops.read = &ixgbe_read_eeprom_82599;
- eeprom->ops.read_buffer = &ixgbe_read_eeprom_buffer_82599;
-
- /* Manageability interface */
- mac->ops.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic;
-
- mac->ops.get_thermal_sensor_data =
- &ixgbe_get_thermal_sensor_data_generic;
- mac->ops.init_thermal_sensor_thresh =
- &ixgbe_init_thermal_sensor_thresh_generic;
-
- return ret_val;
-}
-
-/**
- * ixgbe_get_link_capabilities_82599 - Determines link capabilities
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @negotiation: true when autoneg or autotry is enabled
- *
- * Determines the link capabilities by reading the AUTOC register.
- **/
-s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *negotiation)
-{
- s32 status = 0;
- u32 autoc = 0;
-
- /* Check if 1G SFP module. */
- if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = true;
- goto out;
- }
-
- /*
- * Determine link capabilities based on the stored value of AUTOC,
- * which represents EEPROM defaults. If AUTOC value has not
- * been stored, use the current register values.
- */
- if (hw->mac.orig_link_settings_stored)
- autoc = hw->mac.orig_autoc;
- else
- autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-
- switch (autoc & IXGBE_AUTOC_LMS_MASK) {
- case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = false;
- break;
-
- case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
- *speed = IXGBE_LINK_SPEED_10GB_FULL;
- *negotiation = false;
- break;
-
- case IXGBE_AUTOC_LMS_1G_AN:
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = true;
- break;
-
- case IXGBE_AUTOC_LMS_10G_SERIAL:
- *speed = IXGBE_LINK_SPEED_10GB_FULL;
- *negotiation = false;
- break;
-
- case IXGBE_AUTOC_LMS_KX4_KX_KR:
- case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
- *speed = IXGBE_LINK_SPEED_UNKNOWN;
- if (autoc & IXGBE_AUTOC_KR_SUPP)
- *speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (autoc & IXGBE_AUTOC_KX4_SUPP)
- *speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (autoc & IXGBE_AUTOC_KX_SUPP)
- *speed |= IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = true;
- break;
-
- case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
- *speed = IXGBE_LINK_SPEED_100_FULL;
- if (autoc & IXGBE_AUTOC_KR_SUPP)
- *speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (autoc & IXGBE_AUTOC_KX4_SUPP)
- *speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (autoc & IXGBE_AUTOC_KX_SUPP)
- *speed |= IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = true;
- break;
-
- case IXGBE_AUTOC_LMS_SGMII_1G_100M:
- *speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
- *negotiation = false;
- break;
-
- default:
- status = IXGBE_ERR_LINK_SETUP;
- goto out;
- break;
- }
-
- if (hw->phy.multispeed_fiber) {
- *speed |= IXGBE_LINK_SPEED_10GB_FULL |
- IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = true;
- }
-
-out:
- return status;
-}
-
-/**
- * ixgbe_get_media_type_82599 - Get media type
- * @hw: pointer to hardware structure
- *
- * Returns the media type (fiber, copper, backplane)
- **/
-enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
-{
- enum ixgbe_media_type media_type;
-
- /* Detect if there is a copper PHY attached. */
- switch (hw->phy.type) {
- case ixgbe_phy_cu_unknown:
- case ixgbe_phy_tn:
- media_type = ixgbe_media_type_copper;
- goto out;
- default:
- break;
- }
-
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82599_KX4:
- case IXGBE_DEV_ID_82599_KX4_MEZZ:
- case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
- case IXGBE_DEV_ID_82599_KR:
- case IXGBE_DEV_ID_82599_BACKPLANE_FCOE:
- case IXGBE_DEV_ID_82599_XAUI_LOM:
- /* Default device ID is mezzanine card KX/KX4 */
- media_type = ixgbe_media_type_backplane;
- break;
- case IXGBE_DEV_ID_82599_SFP:
- case IXGBE_DEV_ID_82599_SFP_FCOE:
- case IXGBE_DEV_ID_82599_SFP_EM:
- case IXGBE_DEV_ID_82599_SFP_SF2:
- case IXGBE_DEV_ID_82599EN_SFP:
- media_type = ixgbe_media_type_fiber;
- break;
- case IXGBE_DEV_ID_82599_CX4:
- media_type = ixgbe_media_type_cx4;
- break;
- case IXGBE_DEV_ID_82599_T3_LOM:
- media_type = ixgbe_media_type_copper;
- break;
- case IXGBE_DEV_ID_82599_LS:
- media_type = ixgbe_media_type_fiber_lco;
- break;
- case IXGBE_DEV_ID_82599_QSFP_SF_QP:
- media_type = ixgbe_media_type_fiber_qsfp;
- break;
- default:
- media_type = ixgbe_media_type_unknown;
- break;
- }
-out:
- return media_type;
-}
-
-/**
- * ixgbe_start_mac_link_82599 - Setup MAC link settings
- * @hw: pointer to hardware structure
- * @autoneg_wait_to_complete: true when waiting for completion is needed
- *
- * Configures link settings based on values in the ixgbe_hw struct.
- * Restarts the link. Performs autonegotiation if needed.
- **/
-s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
- bool autoneg_wait_to_complete)
-{
- u32 autoc_reg;
- u32 links_reg = 0;
- u32 i;
- s32 status = 0;
-
- /* Restart link */
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- autoc_reg |= IXGBE_AUTOC_AN_RESTART;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-
- /* Only poll for autoneg to complete if specified to do so */
- if (autoneg_wait_to_complete) {
- if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
- IXGBE_AUTOC_LMS_KX4_KX_KR ||
- (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
- IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
- (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
- IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
- for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
- links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
- if (links_reg & IXGBE_LINKS_KX_AN_COMP)
- break;
- msleep(100);
- }
- if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
- status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
- hw_dbg(hw, "Autoneg did not complete.\n");
- }
- }
- }
-
- /* Add delay to filter out noises during initial link setup */
- msleep(50);
-
- return status;
-}
-
-/**
- * ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser
- * @hw: pointer to hardware structure
- *
- * The base drivers may require better control over SFP+ module
- * PHY states. This includes selectively shutting down the Tx
- * laser on the PHY, effectively halting physical link.
- **/
-void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
-{
- u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
-
- /* Disable tx laser; allow 100us to go dark per spec */
- esdp_reg |= IXGBE_ESDP_SDP3;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- IXGBE_WRITE_FLUSH(hw);
- udelay(100);
-}
-
-/**
- * ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser
- * @hw: pointer to hardware structure
- *
- * The base drivers may require better control over SFP+ module
- * PHY states. This includes selectively turning on the Tx
- * laser on the PHY, effectively starting physical link.
- **/
-void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
-{
- u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
-
- /* Enable tx laser; allow 100ms to light up */
- esdp_reg &= ~IXGBE_ESDP_SDP3;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- IXGBE_WRITE_FLUSH(hw);
- msleep(100);
-}
-
-/**
- * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser
- * @hw: pointer to hardware structure
- *
- * When the driver changes the link speeds that it can support,
- * it sets autotry_restart to true to indicate that we need to
- * initiate a new autotry session with the link partner. To do
- * so, we set the speed then disable and re-enable the tx laser, to
- * alert the link partner that it also needs to restart autotry on its
- * end. This is consistent with true clause 37 autoneg, which also
- * involves a loss of signal.
- **/
-void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
-{
- if (hw->mac.autotry_restart) {
- ixgbe_disable_tx_laser_multispeed_fiber(hw);
- ixgbe_enable_tx_laser_multispeed_fiber(hw);
- hw->mac.autotry_restart = false;
- }
-}
-
-/**
- * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- * @autoneg_wait_to_complete: true when waiting for completion is needed
- *
- * Set the link speed in the AUTOC register and restarts link.
- **/
-s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
- bool autoneg_wait_to_complete)
-{
- s32 status = 0;
- ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
- ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
- u32 speedcnt = 0;
- u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
- u32 i = 0;
- bool link_up = false;
- bool negotiation;
-
- /* Mask off requested but non-supported speeds */
- status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
- if (status != 0)
- return status;
-
- speed &= link_speed;
-
- /*
- * Try each speed one by one, highest priority first. We do this in
- * software because 10gb fiber doesn't support speed autonegotiation.
- */
- if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
- speedcnt++;
- highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
-
- /* If we already have link at this speed, just jump out */
- status = ixgbe_check_link(hw, &link_speed, &link_up, false);
- if (status != 0)
- return status;
-
- if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
- goto out;
-
- /* Set the module link speed */
- esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- IXGBE_WRITE_FLUSH(hw);
-
- /* Allow module to change analog characteristics (1G->10G) */
- msleep(40);
-
- status = ixgbe_setup_mac_link_82599(hw,
- IXGBE_LINK_SPEED_10GB_FULL,
- autoneg,
- autoneg_wait_to_complete);
- if (status != 0)
- return status;
-
- /* Flap the tx laser if it has not already been done */
- ixgbe_flap_tx_laser(hw);
-
- /*
- * Wait for the controller to acquire link. Per IEEE 802.3ap,
- * Section 73.10.2, we may have to wait up to 500ms if KR is
- * attempted. 82599 uses the same timing for 10g SFI.
- */
- for (i = 0; i < 5; i++) {
- /* Wait for the link partner to also set speed */
- msleep(100);
-
- /* If we have link, just jump out */
- status = ixgbe_check_link(hw, &link_speed,
- &link_up, false);
- if (status != 0)
- return status;
-
- if (link_up)
- goto out;
- }
- }
-
- if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
- speedcnt++;
- if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
- highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
-
- /* If we already have link at this speed, just jump out */
- status = ixgbe_check_link(hw, &link_speed, &link_up, false);
- if (status != 0)
- return status;
-
- if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
- goto out;
-
- /* Set the module link speed */
- esdp_reg &= ~IXGBE_ESDP_SDP5;
- esdp_reg |= IXGBE_ESDP_SDP5_DIR;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- IXGBE_WRITE_FLUSH(hw);
-
- /* Allow module to change analog characteristics (10G->1G) */
- msleep(40);
-
- status = ixgbe_setup_mac_link_82599(hw,
- IXGBE_LINK_SPEED_1GB_FULL,
- autoneg,
- autoneg_wait_to_complete);
- if (status != 0)
- return status;
-
- /* Flap the tx laser if it has not already been done */
- ixgbe_flap_tx_laser(hw);
-
- /* Wait for the link partner to also set speed */
- msleep(100);
-
- /* If we have link, just jump out */
- status = ixgbe_check_link(hw, &link_speed, &link_up, false);
- if (status != 0)
- return status;
-
- if (link_up)
- goto out;
- }
-
- /*
- * We didn't get link. Configure back to the highest speed we tried,
- * (if there was more than one). We call ourselves back with just the
- * single highest speed that the user requested.
- */
- if (speedcnt > 1)
- status = ixgbe_setup_mac_link_multispeed_fiber(hw,
- highest_link_speed, autoneg, autoneg_wait_to_complete);
-
-out:
- /* Set autoneg_advertised value based on input link speed */
- hw->phy.autoneg_advertised = 0;
-
- if (speed & IXGBE_LINK_SPEED_10GB_FULL)
- hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
-
- if (speed & IXGBE_LINK_SPEED_1GB_FULL)
- hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
-
- return status;
-}
-
-/**
- * ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- * @autoneg_wait_to_complete: true when waiting for completion is needed
- *
- * Implements the Intel SmartSpeed algorithm.
- **/
-s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
- bool autoneg_wait_to_complete)
-{
- s32 status = 0;
- ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
- s32 i, j;
- bool link_up = false;
- u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-
- /* Set autoneg_advertised value based on input link speed */
- hw->phy.autoneg_advertised = 0;
-
- if (speed & IXGBE_LINK_SPEED_10GB_FULL)
- hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
-
- if (speed & IXGBE_LINK_SPEED_1GB_FULL)
- hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
-
- if (speed & IXGBE_LINK_SPEED_100_FULL)
- hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
-
- /*
- * Implement Intel SmartSpeed algorithm. SmartSpeed will reduce the
- * autoneg advertisement if link is unable to be established at the
- * highest negotiated rate. This can sometimes happen due to integrity
- * issues with the physical media connection.
- */
-
- /* First, try to get link with full advertisement */
- hw->phy.smart_speed_active = false;
- for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
- status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
- autoneg_wait_to_complete);
- if (status != 0)
- goto out;
-
- /*
- * Wait for the controller to acquire link. Per IEEE 802.3ap,
- * Section 73.10.2, we may have to wait up to 500ms if KR is
- * attempted, or 200ms if KX/KX4/BX/BX4 is attempted, per
- * Table 9 in the AN MAS.
- */
- for (i = 0; i < 5; i++) {
- msleep(100);
-
- /* If we have link, just jump out */
- status = ixgbe_check_link(hw, &link_speed, &link_up,
- false);
- if (status != 0)
- goto out;
-
- if (link_up)
- goto out;
- }
- }
-
- /*
- * We didn't get link. If we advertised KR plus one of KX4/KX
- * (or BX4/BX), then disable KR and try again.
- */
- if (((autoc_reg & IXGBE_AUTOC_KR_SUPP) == 0) ||
- ((autoc_reg & IXGBE_AUTOC_KX4_KX_SUPP_MASK) == 0))
- goto out;
-
- /* Turn SmartSpeed on to disable KR support */
- hw->phy.smart_speed_active = true;
- status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
- autoneg_wait_to_complete);
- if (status != 0)
- goto out;
-
- /*
- * Wait for the controller to acquire link. 600ms will allow for
- * the AN link_fail_inhibit_timer as well for multiple cycles of
- * parallel detect, both 10g and 1g. This allows for the maximum
- * connect attempts as defined in the AN MAS table 73-7.
- */
- for (i = 0; i < 6; i++) {
- msleep(100);
-
- /* If we have link, just jump out */
- status = ixgbe_check_link(hw, &link_speed, &link_up, false);
- if (status != 0)
- goto out;
-
- if (link_up)
- goto out;
- }
-
- /* We didn't get link. Turn SmartSpeed back off. */
- hw->phy.smart_speed_active = false;
- status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
- autoneg_wait_to_complete);
-
-out:
- if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL))
- hw_dbg(hw, "Smartspeed has downgraded the link speed "
- "from the maximum advertised\n");
- return status;
-}
-
-/**
- * ixgbe_setup_mac_link_82599 - Set MAC link speed
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- * @autoneg_wait_to_complete: true when waiting for completion is needed
- *
- * Set the link speed in the AUTOC register and restarts link.
- **/
-s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
- bool autoneg_wait_to_complete)
-{
- s32 status = 0;
- u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
- u32 start_autoc = autoc;
- u32 orig_autoc = 0;
- u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
- u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
- u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
- u32 links_reg = 0;
- u32 i;
- ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
-
- /* Check to see if speed passed in is supported. */
- status = ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
- if (status != 0)
- goto out;
-
- speed &= link_capabilities;
-
- if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
- status = IXGBE_ERR_LINK_SETUP;
- goto out;
- }
-
- /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
- if (hw->mac.orig_link_settings_stored)
- orig_autoc = hw->mac.orig_autoc;
- else
- orig_autoc = autoc;
-
- if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
- link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
- link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
- /* Set KX4/KX/KR support according to speed requested */
- autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
- if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
- if (orig_autoc & IXGBE_AUTOC_KX4_SUPP)
- autoc |= IXGBE_AUTOC_KX4_SUPP;
- if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) &&
- (hw->phy.smart_speed_active == false))
- autoc |= IXGBE_AUTOC_KR_SUPP;
- }
- if (speed & IXGBE_LINK_SPEED_1GB_FULL)
- autoc |= IXGBE_AUTOC_KX_SUPP;
- } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) &&
- (link_mode == IXGBE_AUTOC_LMS_1G_LINK_NO_AN ||
- link_mode == IXGBE_AUTOC_LMS_1G_AN)) {
- /* Switch from 1G SFI to 10G SFI if requested */
- if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
- (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)) {
- autoc &= ~IXGBE_AUTOC_LMS_MASK;
- autoc |= IXGBE_AUTOC_LMS_10G_SERIAL;
- }
- } else if ((pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI) &&
- (link_mode == IXGBE_AUTOC_LMS_10G_SERIAL)) {
- /* Switch from 10G SFI to 1G SFI if requested */
- if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
- (pma_pmd_1g == IXGBE_AUTOC_1G_SFI)) {
- autoc &= ~IXGBE_AUTOC_LMS_MASK;
- if (autoneg)
- autoc |= IXGBE_AUTOC_LMS_1G_AN;
- else
- autoc |= IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
- }
- }
-
- if (autoc != start_autoc) {
- /* Restart link */
- autoc |= IXGBE_AUTOC_AN_RESTART;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
-
- /* Only poll for autoneg to complete if specified to do so */
- if (autoneg_wait_to_complete) {
- if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
- link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
- link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
- for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
- links_reg =
- IXGBE_READ_REG(hw, IXGBE_LINKS);
- if (links_reg & IXGBE_LINKS_KX_AN_COMP)
- break;
- msleep(100);
- }
- if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
- status =
- IXGBE_ERR_AUTONEG_NOT_COMPLETE;
- hw_dbg(hw, "Autoneg did not complete.\n");
- }
- }
- }
-
- /* Add delay to filter out noises during initial link setup */
- msleep(50);
- }
-
-out:
- return status;
-}
-
-/**
- * ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- * @autoneg_wait_to_complete: true if waiting is needed to complete
- *
- * Restarts link on PHY and MAC based on settings passed in.
- **/
-static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete)
-{
- s32 status;
-
- /* Setup the PHY according to input speed */
- status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
- autoneg_wait_to_complete);
- /* Set up MAC */
- ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete);
-
- return status;
-}
-
-/**
- * ixgbe_reset_hw_82599 - Perform hardware reset
- * @hw: pointer to hardware structure
- *
- * Resets the hardware by resetting the transmit and receive units, masks
- * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
- * reset.
- **/
-s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
-{
-// ixgbe_link_speed link_speed;
- s32 status = 0;
-// u32 ctrl, i, autoc, autoc2;
-// bool link_up = false;
-
-#if 0
- /* Call adapter stop to disable tx/rx and clear interrupts */
- status = hw->mac.ops.stop_adapter(hw);
- if (status != 0)
- goto reset_hw_out;
-
- /* flush pending Tx transactions */
- ixgbe_clear_tx_pending(hw);
-
- /* PHY ops must be identified and initialized prior to reset */
-
- /* Identify PHY and related function pointers */
- status = hw->phy.ops.init(hw);
-
- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto reset_hw_out;
-
- /* Setup SFP module if there is one present. */
- if (hw->phy.sfp_setup_needed) {
- status = hw->mac.ops.setup_sfp(hw);
- hw->phy.sfp_setup_needed = false;
- }
-
- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto reset_hw_out;
-
- /* Reset PHY */
- if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
- hw->phy.ops.reset(hw);
-
-mac_reset_top:
- /*
- * Issue global reset to the MAC. Needs to be SW reset if link is up.
- * If link reset is used when link is up, it might reset the PHY when
- * mng is using it. If link is down or the flag to force full link
- * reset is set, then perform link reset.
- */
- ctrl = IXGBE_CTRL_LNK_RST;
- if (!hw->force_full_reset) {
- hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
- if (link_up)
- ctrl = IXGBE_CTRL_RST;
- }
-
- ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
- IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
- IXGBE_WRITE_FLUSH(hw);
-
- /* Poll for reset bit to self-clear indicating reset is complete */
- for (i = 0; i < 10; i++) {
- udelay(1);
- ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
- if (!(ctrl & IXGBE_CTRL_RST_MASK))
- break;
- }
-
- if (ctrl & IXGBE_CTRL_RST_MASK) {
- status = IXGBE_ERR_RESET_FAILED;
- hw_dbg(hw, "Reset polling failed to complete.\n");
- }
-
- msleep(50);
-
- /*
- * Double resets are required for recovery from certain error
- * conditions. Between resets, it is necessary to stall to allow time
- * for any pending HW events to complete.
- */
- if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
- hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
- goto mac_reset_top;
- }
-
- /*
- * Store the original AUTOC/AUTOC2 values if they have not been
- * stored off yet. Otherwise restore the stored original
- * values since the reset operation sets back to defaults.
- */
- autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
- if (hw->mac.orig_link_settings_stored == false) {
- hw->mac.orig_autoc = autoc;
- hw->mac.orig_autoc2 = autoc2;
- hw->mac.orig_link_settings_stored = true;
- } else {
- if (autoc != hw->mac.orig_autoc)
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
- IXGBE_AUTOC_AN_RESTART));
-
- if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
- (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
- autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK;
- autoc2 |= (hw->mac.orig_autoc2 &
- IXGBE_AUTOC2_UPPER_MASK);
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
- }
- }
-#endif
-
- /* Store the permanent mac address */
- hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
-
- /*
- * Store MAC address from RAR0, clear receive address registers, and
- * clear the multicast table. Also reset num_rar_entries to 128,
- * since we modify this value when programming the SAN MAC address.
- */
- hw->mac.num_rar_entries = 128;
- hw->mac.ops.init_rx_addrs(hw);
-
- /* Store the permanent SAN mac address */
- hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
-
- /* Add the SAN MAC address to the RAR only if it's a valid address */
- if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
- hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
- hw->mac.san_addr, 0, IXGBE_RAH_AV);
-
- /* Save the SAN MAC RAR index */
- hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
-
- /* Reserve the last RAR for the SAN MAC address */
- hw->mac.num_rar_entries--;
- }
-
- /* Store the alternative WWNN/WWPN prefix */
- hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
- &hw->mac.wwpn_prefix);
-
-//reset_hw_out:
- return status;
-}
-
-/**
- * ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables.
- * @hw: pointer to hardware structure
- **/
-s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
-{
- int i;
- u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
- fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE;
-
- /*
- * Before starting reinitialization process,
- * FDIRCMD.CMD must be zero.
- */
- for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
- if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
- IXGBE_FDIRCMD_CMD_MASK))
- break;
- udelay(10);
- }
- if (i >= IXGBE_FDIRCMD_CMD_POLL) {
- hw_dbg(hw, "Flow Director previous command isn't complete, "
- "aborting table re-initialization.\n");
- return IXGBE_ERR_FDIR_REINIT_FAILED;
- }
-
- IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
- IXGBE_WRITE_FLUSH(hw);
- /*
- * 82599 adapters flow director init flow cannot be restarted,
- * Workaround 82599 silicon errata by performing the following steps
- * before re-writing the FDIRCTRL control register with the same value.
- * - write 1 to bit 8 of FDIRCMD register &
- * - write 0 to bit 8 of FDIRCMD register
- */
- IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
- (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) |
- IXGBE_FDIRCMD_CLEARHT));
- IXGBE_WRITE_FLUSH(hw);
- IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
- (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
- ~IXGBE_FDIRCMD_CLEARHT));
- IXGBE_WRITE_FLUSH(hw);
- /*
- * Clear FDIR Hash register to clear any leftover hashes
- * waiting to be programmed.
- */
- IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, 0x00);
- IXGBE_WRITE_FLUSH(hw);
-
- IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
- IXGBE_WRITE_FLUSH(hw);
-
- /* Poll init-done after we write FDIRCTRL register */
- for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
- if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
- IXGBE_FDIRCTRL_INIT_DONE)
- break;
- udelay(10);
- }
- if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
- hw_dbg(hw, "Flow Director Signature poll time exceeded!\n");
- return IXGBE_ERR_FDIR_REINIT_FAILED;
- }
-
- /* Clear FDIR statistics registers (read to clear) */
- IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT);
- IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT);
- IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
- IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
- IXGBE_READ_REG(hw, IXGBE_FDIRLEN);
-
- return 0;
-}
-
-/**
- * ixgbe_fdir_enable_82599 - Initialize Flow Director control registers
- * @hw: pointer to hardware structure
- * @fdirctrl: value to write to flow director control register
- **/
-static void ixgbe_fdir_enable_82599(struct ixgbe_hw *hw, u32 fdirctrl)
-{
- int i;
-
- /* Prime the keys for hashing */
- IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, IXGBE_ATR_BUCKET_HASH_KEY);
- IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, IXGBE_ATR_SIGNATURE_HASH_KEY);
-
- /*
- * Poll init-done after we write the register. Estimated times:
- * 10G: PBALLOC = 11b, timing is 60us
- * 1G: PBALLOC = 11b, timing is 600us
- * 100M: PBALLOC = 11b, timing is 6ms
- *
- * Multiple these timings by 4 if under full Rx load
- *
- * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
- * 1 msec per poll time. If we're at line rate and drop to 100M, then
- * this might not finish in our poll time, but we can live with that
- * for now.
- */
- IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
- IXGBE_WRITE_FLUSH(hw);
- for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
- if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
- IXGBE_FDIRCTRL_INIT_DONE)
- break;
- msleep(1);
- }
-
- if (i >= IXGBE_FDIR_INIT_DONE_POLL)
- hw_dbg(hw, "Flow Director poll time exceeded!\n");
-}
-
-/**
- * ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters
- * @hw: pointer to hardware structure
- * @fdirctrl: value to write to flow director control register, initially
- * contains just the value of the Rx packet buffer allocation
- **/
-s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl)
-{
- /*
- * Continue setup of fdirctrl register bits:
- * Move the flexible bytes to use the ethertype - shift 6 words
- * Set the maximum length per hash bucket to 0xA filters
- * Send interrupt when 64 filters are left
- */
- fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) |
- (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) |
- (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT);
-
- /* write hashes and fdirctrl register, poll for completion */
- ixgbe_fdir_enable_82599(hw, fdirctrl);
-
- return 0;
-}
-
-/**
- * ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters
- * @hw: pointer to hardware structure
- * @fdirctrl: value to write to flow director control register, initially
- * contains just the value of the Rx packet buffer allocation
- **/
-s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl)
-{
- /*
- * Continue setup of fdirctrl register bits:
- * Turn perfect match filtering on
- * Report hash in RSS field of Rx wb descriptor
- * Initialize the drop queue
- * Move the flexible bytes to use the ethertype - shift 6 words
- * Set the maximum length per hash bucket to 0xA filters
- * Send interrupt when 64 (0x4 * 16) filters are left
- */
- fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH |
- IXGBE_FDIRCTRL_REPORT_STATUS |
- (IXGBE_FDIR_DROP_QUEUE << IXGBE_FDIRCTRL_DROP_Q_SHIFT) |
- (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) |
- (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) |
- (4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT);
-
- /* write hashes and fdirctrl register, poll for completion */
- ixgbe_fdir_enable_82599(hw, fdirctrl);
-
- return 0;
-}
-
-/*
- * These defines allow us to quickly generate all of the necessary instructions
- * in the function below by simply calling out IXGBE_COMPUTE_SIG_HASH_ITERATION
- * for values 0 through 15
- */
-#define IXGBE_ATR_COMMON_HASH_KEY \
- (IXGBE_ATR_BUCKET_HASH_KEY & IXGBE_ATR_SIGNATURE_HASH_KEY)
-#define IXGBE_COMPUTE_SIG_HASH_ITERATION(_n) \
-do { \
- u32 n = (_n); \
- if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << n)) \
- common_hash ^= lo_hash_dword >> n; \
- else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \
- bucket_hash ^= lo_hash_dword >> n; \
- else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << n)) \
- sig_hash ^= lo_hash_dword << (16 - n); \
- if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << (n + 16))) \
- common_hash ^= hi_hash_dword >> n; \
- else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \
- bucket_hash ^= hi_hash_dword >> n; \
- else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << (n + 16))) \
- sig_hash ^= hi_hash_dword << (16 - n); \
-} while (0);
-
-/**
- * ixgbe_atr_compute_sig_hash_82599 - Compute the signature hash
- * @stream: input bitstream to compute the hash on
- *
- * This function is almost identical to the function above but contains
- * several optomizations such as unwinding all of the loops, letting the
- * compiler work out all of the conditional ifs since the keys are static
- * defines, and computing two keys at once since the hashed dword stream
- * will be the same for both keys.
- **/
-u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
- union ixgbe_atr_hash_dword common)
-{
- u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
- u32 sig_hash = 0, bucket_hash = 0, common_hash = 0;
-
- /* record the flow_vm_vlan bits as they are a key part to the hash */
- flow_vm_vlan = IXGBE_NTOHL(input.dword);
-
- /* generate common hash dword */
- hi_hash_dword = IXGBE_NTOHL(common.dword);
-
- /* low dword is word swapped version of common */
- lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16);
-
- /* apply flow ID/VM pool/VLAN ID bits to hash words */
- hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16);
-
- /* Process bits 0 and 16 */
- IXGBE_COMPUTE_SIG_HASH_ITERATION(0);
-
- /*
- * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to
- * delay this because bit 0 of the stream should not be processed
- * so we do not add the vlan until after bit 0 was processed
- */
- lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16);
-
- /* Process remaining 30 bit of the key */
- IXGBE_COMPUTE_SIG_HASH_ITERATION(1);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(2);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(3);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(4);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(5);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(6);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(7);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(8);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(9);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(10);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(11);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(12);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(13);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(14);
- IXGBE_COMPUTE_SIG_HASH_ITERATION(15);
-
- /* combine common_hash result with signature and bucket hashes */
- bucket_hash ^= common_hash;
- bucket_hash &= IXGBE_ATR_HASH_MASK;
-
- sig_hash ^= common_hash << 16;
- sig_hash &= IXGBE_ATR_HASH_MASK << 16;
-
- /* return completed signature hash */
- return sig_hash ^ bucket_hash;
-}
-
-/**
- * ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter
- * @hw: pointer to hardware structure
- * @input: unique input dword
- * @common: compressed common input dword
- * @queue: queue index to direct traffic to
- **/
-s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_hash_dword input,
- union ixgbe_atr_hash_dword common,
- u8 queue)
-{
- u64 fdirhashcmd;
- u32 fdircmd;
-
- /*
- * Get the flow_type in order to program FDIRCMD properly
- * lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6
- */
- switch (input.formatted.flow_type) {
- case IXGBE_ATR_FLOW_TYPE_TCPV4:
- case IXGBE_ATR_FLOW_TYPE_UDPV4:
- case IXGBE_ATR_FLOW_TYPE_SCTPV4:
- case IXGBE_ATR_FLOW_TYPE_TCPV6:
- case IXGBE_ATR_FLOW_TYPE_UDPV6:
- case IXGBE_ATR_FLOW_TYPE_SCTPV6:
- break;
- default:
- hw_dbg(hw, " Error on flow type input\n");
- return IXGBE_ERR_CONFIG;
- }
-
- /* configure FDIRCMD register */
- fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
- IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
- fdircmd |= input.formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
- fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
-
- /*
- * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits
- * is for FDIRCMD. Then do a 64-bit register write from FDIRHASH.
- */
- fdirhashcmd = (u64)fdircmd << 32;
- fdirhashcmd |= ixgbe_atr_compute_sig_hash_82599(input, common);
- IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd);
-
- hw_dbg(hw, "Tx Queue=%x hash=%x\n", queue, (u32)fdirhashcmd);
-
- return 0;
-}
-
-#define IXGBE_COMPUTE_BKT_HASH_ITERATION(_n) \
-do { \
- u32 n = (_n); \
- if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \
- bucket_hash ^= lo_hash_dword >> n; \
- if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \
- bucket_hash ^= hi_hash_dword >> n; \
-} while (0);
-
-/**
- * ixgbe_atr_compute_perfect_hash_82599 - Compute the perfect filter hash
- * @atr_input: input bitstream to compute the hash on
- * @input_mask: mask for the input bitstream
- *
- * This function serves two main purposes. First it applys the input_mask
- * to the atr_input resulting in a cleaned up atr_input data stream.
- * Secondly it computes the hash and stores it in the bkt_hash field at
- * the end of the input byte stream. This way it will be available for
- * future use without needing to recompute the hash.
- **/
-void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
- union ixgbe_atr_input *input_mask)
-{
-
- u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
- u32 bucket_hash = 0;
-
- /* Apply masks to input data */
- input->dword_stream[0] &= input_mask->dword_stream[0];
- input->dword_stream[1] &= input_mask->dword_stream[1];
- input->dword_stream[2] &= input_mask->dword_stream[2];
- input->dword_stream[3] &= input_mask->dword_stream[3];
- input->dword_stream[4] &= input_mask->dword_stream[4];
- input->dword_stream[5] &= input_mask->dword_stream[5];
- input->dword_stream[6] &= input_mask->dword_stream[6];
- input->dword_stream[7] &= input_mask->dword_stream[7];
- input->dword_stream[8] &= input_mask->dword_stream[8];
- input->dword_stream[9] &= input_mask->dword_stream[9];
- input->dword_stream[10] &= input_mask->dword_stream[10];
-
- /* record the flow_vm_vlan bits as they are a key part to the hash */
- flow_vm_vlan = IXGBE_NTOHL(input->dword_stream[0]);
-
- /* generate common hash dword */
- hi_hash_dword = IXGBE_NTOHL(input->dword_stream[1] ^
- input->dword_stream[2] ^
- input->dword_stream[3] ^
- input->dword_stream[4] ^
- input->dword_stream[5] ^
- input->dword_stream[6] ^
- input->dword_stream[7] ^
- input->dword_stream[8] ^
- input->dword_stream[9] ^
- input->dword_stream[10]);
-
- /* low dword is word swapped version of common */
- lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16);
-
- /* apply flow ID/VM pool/VLAN ID bits to hash words */
- hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16);
-
- /* Process bits 0 and 16 */
- IXGBE_COMPUTE_BKT_HASH_ITERATION(0);
-
- /*
- * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to
- * delay this because bit 0 of the stream should not be processed
- * so we do not add the vlan until after bit 0 was processed
- */
- lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16);
-
- /* Process remaining 30 bit of the key */
- IXGBE_COMPUTE_BKT_HASH_ITERATION(1);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(2);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(3);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(4);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(5);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(6);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(7);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(8);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(9);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(10);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(11);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(12);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(13);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(14);
- IXGBE_COMPUTE_BKT_HASH_ITERATION(15);
-
- /*
- * Limit hash to 13 bits since max bucket count is 8K.
- * Store result at the end of the input stream.
- */
- input->formatted.bkt_hash = bucket_hash & 0x1FFF;
-}
-
-/**
- * ixgbe_get_fdirtcpm_82599 - generate a tcp port from atr_input_masks
- * @input_mask: mask to be bit swapped
- *
- * The source and destination port masks for flow director are bit swapped
- * in that bit 15 effects bit 0, 14 effects 1, 13, 2 etc. In order to
- * generate a correctly swapped value we need to bit swap the mask and that
- * is what is accomplished by this function.
- **/
-static u32 ixgbe_get_fdirtcpm_82599(union ixgbe_atr_input *input_mask)
-{
- u32 mask = IXGBE_NTOHS(input_mask->formatted.dst_port);
- mask <<= IXGBE_FDIRTCPM_DPORTM_SHIFT;
- mask |= IXGBE_NTOHS(input_mask->formatted.src_port);
- mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1);
- mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2);
- mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4);
- return ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8);
-}
-
-/*
- * These two macros are meant to address the fact that we have registers
- * that are either all or in part big-endian. As a result on big-endian
- * systems we will end up byte swapping the value to little-endian before
- * it is byte swapped again and written to the hardware in the original
- * big-endian format.
- */
-#define IXGBE_STORE_AS_BE32(_value) \
- (((u32)(_value) >> 24) | (((u32)(_value) & 0x00FF0000) >> 8) | \
- (((u32)(_value) & 0x0000FF00) << 8) | ((u32)(_value) << 24))
-
-#define IXGBE_WRITE_REG_BE32(a, reg, value) \
- IXGBE_WRITE_REG((a), (reg), IXGBE_STORE_AS_BE32(IXGBE_NTOHL(value)))
-
-#define IXGBE_STORE_AS_BE16(_value) \
- IXGBE_NTOHS(((u16)(_value) >> 8) | ((u16)(_value) << 8))
-
-s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_input *input_mask)
-{
- /* mask IPv6 since it is currently not supported */
- u32 fdirm = IXGBE_FDIRM_DIPv6;
- u32 fdirtcpm;
-
- /*
- * Program the relevant mask registers. If src/dst_port or src/dst_addr
- * are zero, then assume a full mask for that field. Also assume that
- * a VLAN of 0 is unspecified, so mask that out as well. L4type
- * cannot be masked out in this implementation.
- *
- * This also assumes IPv4 only. IPv6 masking isn't supported at this
- * point in time.
- */
-
- /* verify bucket hash is cleared on hash generation */
- if (input_mask->formatted.bkt_hash)
- hw_dbg(hw, " bucket hash should always be 0 in mask\n");
-
- /* Program FDIRM and verify partial masks */
- switch (input_mask->formatted.vm_pool & 0x7F) {
- case 0x0:
- fdirm |= IXGBE_FDIRM_POOL;
- case 0x7F:
- break;
- default:
- hw_dbg(hw, " Error on vm pool mask\n");
- return IXGBE_ERR_CONFIG;
- }
-
- switch (input_mask->formatted.flow_type & IXGBE_ATR_L4TYPE_MASK) {
- case 0x0:
- fdirm |= IXGBE_FDIRM_L4P;
- if (input_mask->formatted.dst_port ||
- input_mask->formatted.src_port) {
- hw_dbg(hw, " Error on src/dst port mask\n");
- return IXGBE_ERR_CONFIG;
- }
- case IXGBE_ATR_L4TYPE_MASK:
- break;
- default:
- hw_dbg(hw, " Error on flow type mask\n");
- return IXGBE_ERR_CONFIG;
- }
-
- switch (IXGBE_NTOHS(input_mask->formatted.vlan_id) & 0xEFFF) {
- case 0x0000:
- /* mask VLAN ID, fall through to mask VLAN priority */
- fdirm |= IXGBE_FDIRM_VLANID;
- case 0x0FFF:
- /* mask VLAN priority */
- fdirm |= IXGBE_FDIRM_VLANP;
- break;
- case 0xE000:
- /* mask VLAN ID only, fall through */
- fdirm |= IXGBE_FDIRM_VLANID;
- case 0xEFFF:
- /* no VLAN fields masked */
- break;
- default:
- hw_dbg(hw, " Error on VLAN mask\n");
- return IXGBE_ERR_CONFIG;
- }
-
- switch (input_mask->formatted.flex_bytes & 0xFFFF) {
- case 0x0000:
- /* Mask Flex Bytes, fall through */
- fdirm |= IXGBE_FDIRM_FLEX;
- case 0xFFFF:
- break;
- default:
- hw_dbg(hw, " Error on flexible byte mask\n");
- return IXGBE_ERR_CONFIG;
- }
-
- /* Now mask VM pool and destination IPv6 - bits 5 and 2 */
- IXGBE_WRITE_REG(hw, IXGBE_FDIRM, fdirm);
-
- /* store the TCP/UDP port masks, bit reversed from port layout */
- fdirtcpm = ixgbe_get_fdirtcpm_82599(input_mask);
-
- /* write both the same so that UDP and TCP use the same mask */
- IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm);
- IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm);
-
- /* store source and destination IP masks (big-enian) */
- IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M,
- ~input_mask->formatted.src_ip[0]);
- IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M,
- ~input_mask->formatted.dst_ip[0]);
-
- return 0;
-}
-
-s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_input *input,
- u16 soft_id, u8 queue)
-{
- u32 fdirport, fdirvlan, fdirhash, fdircmd;
-
- /* currently IPv6 is not supported, must be programmed with 0 */
- IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(0),
- input->formatted.src_ip[0]);
- IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(1),
- input->formatted.src_ip[1]);
- IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIPv6(2),
- input->formatted.src_ip[2]);
-
- /* record the source address (big-endian) */
- IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, input->formatted.src_ip[0]);
-
- /* record the first 32 bits of the destination address (big-endian) */
- IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPDA, input->formatted.dst_ip[0]);
-
- /* record source and destination port (little-endian)*/
- fdirport = IXGBE_NTOHS(input->formatted.dst_port);
- fdirport <<= IXGBE_FDIRPORT_DESTINATION_SHIFT;
- fdirport |= IXGBE_NTOHS(input->formatted.src_port);
- IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, fdirport);
-
- /* record vlan (little-endian) and flex_bytes(big-endian) */
- fdirvlan = IXGBE_STORE_AS_BE16(input->formatted.flex_bytes);
- fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT;
- fdirvlan |= IXGBE_NTOHS(input->formatted.vlan_id);
- IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, fdirvlan);
-
- /* configure FDIRHASH register */
- fdirhash = input->formatted.bkt_hash;
- fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT;
- IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
-
- /*
- * flush all previous writes to make certain registers are
- * programmed prior to issuing the command
- */
- IXGBE_WRITE_FLUSH(hw);
-
- /* configure FDIRCMD register */
- fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
- IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
- if (queue == IXGBE_FDIR_DROP_QUEUE)
- fdircmd |= IXGBE_FDIRCMD_DROP;
- fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
- fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
- fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT;
-
- IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
-
- return 0;
-}
-
-s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_input *input,
- u16 soft_id)
-{
- u32 fdirhash;
- u32 fdircmd = 0;
- u32 retry_count;
- s32 err = 0;
-
- /* configure FDIRHASH register */
- fdirhash = input->formatted.bkt_hash;
- fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT;
- IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
-
- /* flush hash to HW */
- IXGBE_WRITE_FLUSH(hw);
-
- /* Query if filter is present */
- IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT);
-
- for (retry_count = 10; retry_count; retry_count--) {
- /* allow 10us for query to process */
- udelay(10);
- /* verify query completed successfully */
- fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD);
- if (!(fdircmd & IXGBE_FDIRCMD_CMD_MASK))
- break;
- }
-
- if (!retry_count)
- err = IXGBE_ERR_FDIR_REINIT_FAILED;
-
- /* if filter exists in hardware then remove it */
- if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) {
- IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
- IXGBE_WRITE_FLUSH(hw);
- IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
- IXGBE_FDIRCMD_CMD_REMOVE_FLOW);
- }
-
- return err;
-}
-
-/**
- * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter
- * @hw: pointer to hardware structure
- * @input: input bitstream
- * @input_mask: mask for the input bitstream
- * @soft_id: software index for the filters
- * @queue: queue index to direct traffic to
- *
- * Note that the caller to this function must lock before calling, since the
- * hardware writes must be protected from one another.
- **/
-s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_input *input,
- union ixgbe_atr_input *input_mask,
- u16 soft_id, u8 queue)
-{
- s32 err = IXGBE_ERR_CONFIG;
-
- /*
- * Check flow_type formatting, and bail out before we touch the hardware
- * if there's a configuration issue
- */
- switch (input->formatted.flow_type) {
- case IXGBE_ATR_FLOW_TYPE_IPV4:
- input_mask->formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK;
- if (input->formatted.dst_port || input->formatted.src_port) {
- hw_dbg(hw, " Error on src/dst port\n");
- return IXGBE_ERR_CONFIG;
- }
- break;
- case IXGBE_ATR_FLOW_TYPE_SCTPV4:
- if (input->formatted.dst_port || input->formatted.src_port) {
- hw_dbg(hw, " Error on src/dst port\n");
- return IXGBE_ERR_CONFIG;
- }
- case IXGBE_ATR_FLOW_TYPE_TCPV4:
- case IXGBE_ATR_FLOW_TYPE_UDPV4:
- input_mask->formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK |
- IXGBE_ATR_L4TYPE_MASK;
- break;
- default:
- hw_dbg(hw, " Error on flow type input\n");
- return err;
- }
-
- /* program input mask into the HW */
- err = ixgbe_fdir_set_input_mask_82599(hw, input_mask);
- if (err)
- return err;
-
- /* apply mask and compute/store hash */
- ixgbe_atr_compute_perfect_hash_82599(input, input_mask);
-
- /* program filters to filter memory */
- return ixgbe_fdir_write_perfect_filter_82599(hw, input,
- soft_id, queue);
-}
-
-/**
- * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
- * @hw: pointer to hardware structure
- * @reg: analog register to read
- * @val: read value
- *
- * Performs read operation to Omer analog register specified.
- **/
-s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
-{
- u32 core_ctl;
-
- IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD |
- (reg << 8));
- IXGBE_WRITE_FLUSH(hw);
- udelay(10);
- core_ctl = IXGBE_READ_REG(hw, IXGBE_CORECTL);
- *val = (u8)core_ctl;
-
- return 0;
-}
-
-/**
- * ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register
- * @hw: pointer to hardware structure
- * @reg: atlas register to write
- * @val: value to write
- *
- * Performs write operation to Omer analog register specified.
- **/
-s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
-{
- u32 core_ctl;
-
- core_ctl = (reg << 8) | val;
- IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl);
- IXGBE_WRITE_FLUSH(hw);
- udelay(10);
-
- return 0;
-}
-
-/**
- * ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
- * @hw: pointer to hardware structure
- *
- * Starts the hardware using the generic start_hw function
- * and the generation start_hw function.
- * Then performs revision-specific operations, if any.
- **/
-s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
-{
- s32 ret_val = 0;
-
- ret_val = ixgbe_start_hw_generic(hw);
- if (ret_val != 0)
- goto out;
-
- ret_val = ixgbe_start_hw_gen2(hw);
- if (ret_val != 0)
- goto out;
-
- /* We need to run link autotry after the driver loads */
- hw->mac.autotry_restart = true;
-
- if (ret_val == 0)
- ret_val = ixgbe_verify_fw_version_82599(hw);
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_identify_phy_82599 - Get physical layer module
- * @hw: pointer to hardware structure
- *
- * Determines the physical layer module found on the current adapter.
- * If PHY already detected, maintains current PHY type in hw struct,
- * otherwise executes the PHY detection routine.
- **/
-s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
-{
- s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
-
- /* Detect PHY if not unknown - returns success if already detected. */
- status = ixgbe_identify_phy_generic(hw);
- if (status != 0) {
- /* 82599 10GBASE-T requires an external PHY */
- if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper)
- goto out;
- else
- status = ixgbe_identify_module_generic(hw);
- }
-
- /* Set PHY type none if no PHY detected */
- if (hw->phy.type == ixgbe_phy_unknown) {
- hw->phy.type = ixgbe_phy_none;
- status = 0;
- }
-
- /* Return error if SFP module has been detected but is not supported */
- if (hw->phy.type == ixgbe_phy_sfp_unsupported)
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
-
-out:
- return status;
-}
-
-/**
- * ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
- * @hw: pointer to hardware structure
- *
- * Determines physical layer capabilities of the current configuration.
- **/
-u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
-{
- u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
- u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
- u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
- u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
- u16 ext_ability = 0;
- u8 comp_codes_10g = 0;
- u8 comp_codes_1g = 0;
-
- hw->phy.ops.identify(hw);
-
- switch (hw->phy.type) {
- case ixgbe_phy_tn:
- case ixgbe_phy_cu_unknown:
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
- if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
- if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
- if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
- physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
- goto out;
- default:
- break;
- }
-
- switch (autoc & IXGBE_AUTOC_LMS_MASK) {
- case IXGBE_AUTOC_LMS_1G_AN:
- case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
- if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) {
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX |
- IXGBE_PHYSICAL_LAYER_1000BASE_BX;
- goto out;
- } else
- /* SFI mode so read SFP module */
- goto sfp_check;
- break;
- case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
- if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
- else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
- else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_XAUI)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_XAUI;
- goto out;
- break;
- case IXGBE_AUTOC_LMS_10G_SERIAL:
- if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) {
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR;
- goto out;
- } else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)
- goto sfp_check;
- break;
- case IXGBE_AUTOC_LMS_KX4_KX_KR:
- case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
- if (autoc & IXGBE_AUTOC_KX_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
- if (autoc & IXGBE_AUTOC_KX4_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
- if (autoc & IXGBE_AUTOC_KR_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR;
- goto out;
- break;
- default:
- goto out;
- break;
- }
-
-sfp_check:
- /* SFP check must be done last since DA modules are sometimes used to
- * test KR mode - we need to id KR mode correctly before SFP module.
- * Call identify_sfp because the pluggable module may have changed */
- hw->phy.ops.identify_sfp(hw);
- if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
- goto out;
-
- switch (hw->phy.type) {
- case ixgbe_phy_sfp_passive_tyco:
- case ixgbe_phy_sfp_passive_unknown:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
- break;
- case ixgbe_phy_sfp_ftl_active:
- case ixgbe_phy_sfp_active_unknown:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA;
- break;
- case ixgbe_phy_sfp_avago:
- case ixgbe_phy_sfp_ftl:
- case ixgbe_phy_sfp_intel:
- case ixgbe_phy_sfp_unknown:
- hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g);
- hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
- if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
- else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE)
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_SX;
- break;
- default:
- break;
- }
-
-out:
- return physical_layer;
-}
-
-/**
- * ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
- * @hw: pointer to hardware structure
- * @regval: register value to write to RXCTRL
- *
- * Enables the Rx DMA unit for 82599
- **/
-s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
-{
-
- /*
- * Workaround for 82599 silicon errata when enabling the Rx datapath.
- * If traffic is incoming before we enable the Rx unit, it could hang
- * the Rx DMA unit. Therefore, make sure the security engine is
- * completely disabled prior to enabling the Rx unit.
- */
-
- hw->mac.ops.disable_sec_rx_path(hw);
-
- IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
-
- hw->mac.ops.enable_sec_rx_path(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_verify_fw_version_82599 - verify fw version for 82599
- * @hw: pointer to hardware structure
- *
- * Verifies that installed the firmware version is 0.6 or higher
- * for SFI devices. All 82599 SFI devices should have version 0.6 or higher.
- *
- * Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or
- * if the FW version is not supported.
- **/
-static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
-{
- s32 status = IXGBE_ERR_EEPROM_VERSION;
- u16 fw_offset, fw_ptp_cfg_offset;
- u16 fw_version = 0;
-
- /* firmware check is only necessary for SFI devices */
- if (hw->phy.media_type != ixgbe_media_type_fiber) {
- status = 0;
- goto fw_version_out;
- }
-
- /* get the offset to the Firmware Module block */
- hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
-
- if ((fw_offset == 0) || (fw_offset == 0xFFFF))
- goto fw_version_out;
-
- /* get the offset to the Pass Through Patch Configuration block */
- hw->eeprom.ops.read(hw, (fw_offset +
- IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR),
- &fw_ptp_cfg_offset);
-
- if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF))
- goto fw_version_out;
-
- /* get the firmware version */
- hw->eeprom.ops.read(hw, (fw_ptp_cfg_offset +
- IXGBE_FW_PATCH_VERSION_4), &fw_version);
-
- if (fw_version > 0x5)
- status = 0;
-
-fw_version_out:
- return status;
-}
-
-/**
- * ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state.
- * @hw: pointer to hardware structure
- *
- * Returns true if the LESM FW module is present and enabled. Otherwise
- * returns false. Smart Speed must be disabled if LESM FW module is enabled.
- **/
-bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
-{
- bool lesm_enabled = false;
- u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;
- s32 status;
-
- /* get the offset to the Firmware Module block */
- status = hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
-
- if ((status != 0) ||
- (fw_offset == 0) || (fw_offset == 0xFFFF))
- goto out;
-
- /* get the offset to the LESM Parameters block */
- status = hw->eeprom.ops.read(hw, (fw_offset +
- IXGBE_FW_LESM_PARAMETERS_PTR),
- &fw_lesm_param_offset);
-
- if ((status != 0) ||
- (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF))
- goto out;
-
- /* get the lesm state word */
- status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset +
- IXGBE_FW_LESM_STATE_1),
- &fw_lesm_state);
-
- if ((status == 0) &&
- (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED))
- lesm_enabled = true;
-
-out:
- return lesm_enabled;
-}
-
-/**
- * ixgbe_read_eeprom_buffer_82599 - Read EEPROM word(s) using
- * fastest available method
- *
- * @hw: pointer to hardware structure
- * @offset: offset of word in EEPROM to read
- * @words: number of words
- * @data: word(s) read from the EEPROM
- *
- * Retrieves 16 bit word(s) read from EEPROM
- **/
-static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
- s32 ret_val = IXGBE_ERR_CONFIG;
-
- /*
- * If EEPROM is detected and can be addressed using 14 bits,
- * use EERD otherwise use bit bang
- */
- if ((eeprom->type == ixgbe_eeprom_spi) &&
- (offset + (words - 1) <= IXGBE_EERD_MAX_ADDR))
- ret_val = ixgbe_read_eerd_buffer_generic(hw, offset, words,
- data);
- else
- ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset,
- words,
- data);
-
- return ret_val;
-}
-
-/**
- * ixgbe_read_eeprom_82599 - Read EEPROM word using
- * fastest available method
- *
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @data: word read from the EEPROM
- *
- * Reads a 16 bit word from the EEPROM
- **/
-static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
- u16 offset, u16 *data)
-{
- struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
- s32 ret_val = IXGBE_ERR_CONFIG;
-
- /*
- * If EEPROM is detected and can be addressed using 14 bits,
- * use EERD otherwise use bit bang
- */
- if ((eeprom->type == ixgbe_eeprom_spi) &&
- (offset <= IXGBE_EERD_MAX_ADDR))
- ret_val = ixgbe_read_eerd_generic(hw, offset, data);
- else
- ret_val = ixgbe_read_eeprom_bit_bang_generic(hw, offset, data);
-
- return ret_val;
-}
-
-/**
- * ixgbe_read_i2c_byte_82599 - Reads 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to read
- * @data: value read
- *
- * Performs byte read operation to SFP module's EEPROM over I2C interface at
- * a specified device address.
- **/
-static s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data)
-{
- u32 esdp;
- s32 status;
- s32 timeout = 200;
-
- if (hw->phy.qsfp_shared_i2c_bus == TRUE) {
- /* Acquire I2C bus ownership. */
- esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
- esdp |= IXGBE_ESDP_SDP0;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
- IXGBE_WRITE_FLUSH(hw);
-
- while (timeout) {
- esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
- if (esdp & IXGBE_ESDP_SDP1)
- break;
-
- msleep(5);
- timeout--;
- }
-
- if (!timeout) {
- hw_dbg(hw, "Driver can't access resource,"
- " acquiring I2C bus timeout.\n");
- status = IXGBE_ERR_I2C;
- goto release_i2c_access;
- }
- }
-
- status = ixgbe_read_i2c_byte_generic(hw, byte_offset, dev_addr, data);
-
-release_i2c_access:
-
- if (hw->phy.qsfp_shared_i2c_bus == TRUE) {
- /* Release I2C bus ownership. */
- esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
- esdp &= ~IXGBE_ESDP_SDP0;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
- IXGBE_WRITE_FLUSH(hw);
- }
-
- return status;
-}
-
-/**
- * ixgbe_write_i2c_byte_82599 - Writes 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to write
- * @data: value to write
- *
- * Performs byte write operation to SFP module's EEPROM over I2C interface at
- * a specified device address.
- **/
-static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data)
-{
- u32 esdp;
- s32 status;
- s32 timeout = 200;
-
- if (hw->phy.qsfp_shared_i2c_bus == TRUE) {
- /* Acquire I2C bus ownership. */
- esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
- esdp |= IXGBE_ESDP_SDP0;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
- IXGBE_WRITE_FLUSH(hw);
-
- while (timeout) {
- esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
- if (esdp & IXGBE_ESDP_SDP1)
- break;
-
- msleep(5);
- timeout--;
- }
-
- if (!timeout) {
- hw_dbg(hw, "Driver can't access resource,"
- " acquiring I2C bus timeout.\n");
- status = IXGBE_ERR_I2C;
- goto release_i2c_access;
- }
- }
-
- status = ixgbe_write_i2c_byte_generic(hw, byte_offset, dev_addr, data);
-
-release_i2c_access:
-
- if (hw->phy.qsfp_shared_i2c_bus == TRUE) {
- /* Release I2C bus ownership. */
- esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
- esdp &= ~IXGBE_ESDP_SDP0;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
- IXGBE_WRITE_FLUSH(hw);
- }
-
- return status;
-}
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.h
deleted file mode 100644
index 0305ed732..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_82599_H_
-#define _IXGBE_82599_H_
-
-s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed, bool *autoneg);
-enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw);
-void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
-void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
-void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
-s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
- bool autoneg_wait_to_complete);
-s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
- bool autoneg_wait_to_complete);
-s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
- bool autoneg_wait_to_complete);
-s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool autoneg_wait_to_complete);
-s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw);
-void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw);
-s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
-s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
-s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
-s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw);
-s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
-s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw);
-u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
-s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval);
-bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
-#endif /* _IXGBE_82599_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_api.c b/kernel/linux/kni/ethtool/ixgbe/ixgbe_api.c
deleted file mode 100644
index 1be4c64ff..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_api.c
+++ /dev/null
@@ -1,1142 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "ixgbe_api.h"
-#include "ixgbe_common.h"
-
-/**
- * ixgbe_init_shared_code - Initialize the shared code
- * @hw: pointer to hardware structure
- *
- * This will assign function pointers and assign the MAC type and PHY code.
- * Does not touch the hardware. This function must be called prior to any
- * other function in the shared code. The ixgbe_hw structure should be
- * memset to 0 prior to calling this function. The following fields in
- * hw structure should be filled in prior to calling this function:
- * hw_addr, back, device_id, vendor_id, subsystem_device_id,
- * subsystem_vendor_id, and revision_id
- **/
-s32 ixgbe_init_shared_code(struct ixgbe_hw *hw)
-{
- s32 status;
-
- /*
- * Set the mac type
- */
- ixgbe_set_mac_type(hw);
-
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- status = ixgbe_init_ops_82598(hw);
- break;
- case ixgbe_mac_82599EB:
- status = ixgbe_init_ops_82599(hw);
- break;
- case ixgbe_mac_X540:
- status = ixgbe_init_ops_X540(hw);
- break;
- default:
- status = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
- break;
- }
-
- return status;
-}
-
-/**
- * ixgbe_set_mac_type - Sets MAC type
- * @hw: pointer to the HW structure
- *
- * This function sets the mac type of the adapter based on the
- * vendor ID and device ID stored in the hw structure.
- **/
-s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
-{
- s32 ret_val = 0;
-
- if (hw->vendor_id == IXGBE_INTEL_VENDOR_ID) {
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82598:
- case IXGBE_DEV_ID_82598_BX:
- case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
- case IXGBE_DEV_ID_82598AF_DUAL_PORT:
- case IXGBE_DEV_ID_82598AT:
- case IXGBE_DEV_ID_82598AT2:
- case IXGBE_DEV_ID_82598EB_CX4:
- case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
- case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
- case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
- case IXGBE_DEV_ID_82598EB_XF_LR:
- case IXGBE_DEV_ID_82598EB_SFP_LOM:
- hw->mac.type = ixgbe_mac_82598EB;
- break;
- case IXGBE_DEV_ID_82599_KX4:
- case IXGBE_DEV_ID_82599_KX4_MEZZ:
- case IXGBE_DEV_ID_82599_XAUI_LOM:
- case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
- case IXGBE_DEV_ID_82599_KR:
- case IXGBE_DEV_ID_82599_SFP:
- case IXGBE_DEV_ID_82599_BACKPLANE_FCOE:
- case IXGBE_DEV_ID_82599_SFP_FCOE:
- case IXGBE_DEV_ID_82599_SFP_EM:
- case IXGBE_DEV_ID_82599_SFP_SF2:
- case IXGBE_DEV_ID_82599_QSFP_SF_QP:
- case IXGBE_DEV_ID_82599EN_SFP:
- case IXGBE_DEV_ID_82599_CX4:
- case IXGBE_DEV_ID_82599_LS:
- case IXGBE_DEV_ID_82599_T3_LOM:
- hw->mac.type = ixgbe_mac_82599EB;
- break;
- case IXGBE_DEV_ID_X540T:
- hw->mac.type = ixgbe_mac_X540;
- break;
- default:
- ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
- break;
- }
- } else {
- ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
- }
-
- hw_dbg(hw, "ixgbe_set_mac_type found mac: %d, returns: %d\n",
- hw->mac.type, ret_val);
- return ret_val;
-}
-
-/**
- * ixgbe_init_hw - Initialize the hardware
- * @hw: pointer to hardware structure
- *
- * Initialize the hardware by resetting and then starting the hardware
- **/
-s32 ixgbe_init_hw(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.init_hw, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_reset_hw - Performs a hardware reset
- * @hw: pointer to hardware structure
- *
- * Resets the hardware by resetting the transmit and receive units, masks and
- * clears all interrupts, performs a PHY reset, and performs a MAC reset
- **/
-s32 ixgbe_reset_hw(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.reset_hw, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_start_hw - Prepares hardware for Rx/Tx
- * @hw: pointer to hardware structure
- *
- * Starts the hardware by filling the bus info structure and media type,
- * clears all on chip counters, initializes receive address registers,
- * multicast table, VLAN filter table, calls routine to setup link and
- * flow control settings, and leaves transmit and receive units disabled
- * and uninitialized.
- **/
-s32 ixgbe_start_hw(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.start_hw, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_clear_hw_cntrs - Clear hardware counters
- * @hw: pointer to hardware structure
- *
- * Clears all hardware statistics counters by reading them from the hardware
- * Statistics counters are clear on read.
- **/
-s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.clear_hw_cntrs, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_media_type - Get media type
- * @hw: pointer to hardware structure
- *
- * Returns the media type (fiber, copper, backplane)
- **/
-enum ixgbe_media_type ixgbe_get_media_type(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_media_type, (hw),
- ixgbe_media_type_unknown);
-}
-
-/**
- * ixgbe_get_mac_addr - Get MAC address
- * @hw: pointer to hardware structure
- * @mac_addr: Adapter MAC address
- *
- * Reads the adapter's MAC address from the first Receive Address Register
- * (RAR0) A reset of the adapter must have been performed prior to calling
- * this function in order for the MAC address to have been loaded from the
- * EEPROM into RAR0
- **/
-s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_mac_addr,
- (hw, mac_addr), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_san_mac_addr - Get SAN MAC address
- * @hw: pointer to hardware structure
- * @san_mac_addr: SAN MAC address
- *
- * Reads the SAN MAC address from the EEPROM, if it's available. This is
- * per-port, so set_lan_id() must be called before reading the addresses.
- **/
-s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_san_mac_addr,
- (hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_set_san_mac_addr - Write a SAN MAC address
- * @hw: pointer to hardware structure
- * @san_mac_addr: SAN MAC address
- *
- * Writes A SAN MAC address to the EEPROM.
- **/
-s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr)
-{
- return ixgbe_call_func(hw, hw->mac.ops.set_san_mac_addr,
- (hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_device_caps - Get additional device capabilities
- * @hw: pointer to hardware structure
- * @device_caps: the EEPROM word for device capabilities
- *
- * Reads the extra device capabilities from the EEPROM
- **/
-s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_device_caps,
- (hw, device_caps), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_wwn_prefix - Get alternative WWNN/WWPN prefix from the EEPROM
- * @hw: pointer to hardware structure
- * @wwnn_prefix: the alternative WWNN prefix
- * @wwpn_prefix: the alternative WWPN prefix
- *
- * This function will read the EEPROM from the alternative SAN MAC address
- * block to check the support for the alternative WWNN/WWPN prefix support.
- **/
-s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix,
- u16 *wwpn_prefix)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_wwn_prefix,
- (hw, wwnn_prefix, wwpn_prefix),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_fcoe_boot_status - Get FCOE boot status from EEPROM
- * @hw: pointer to hardware structure
- * @bs: the fcoe boot status
- *
- * This function will read the FCOE boot status from the iSCSI FCOE block
- **/
-s32 ixgbe_get_fcoe_boot_status(struct ixgbe_hw *hw, u16 *bs)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_fcoe_boot_status,
- (hw, bs),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_bus_info - Set PCI bus info
- * @hw: pointer to hardware structure
- *
- * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure
- **/
-s32 ixgbe_get_bus_info(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_bus_info, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_num_of_tx_queues - Get Tx queues
- * @hw: pointer to hardware structure
- *
- * Returns the number of transmit queues for the given adapter.
- **/
-u32 ixgbe_get_num_of_tx_queues(struct ixgbe_hw *hw)
-{
- return hw->mac.max_tx_queues;
-}
-
-/**
- * ixgbe_get_num_of_rx_queues - Get Rx queues
- * @hw: pointer to hardware structure
- *
- * Returns the number of receive queues for the given adapter.
- **/
-u32 ixgbe_get_num_of_rx_queues(struct ixgbe_hw *hw)
-{
- return hw->mac.max_rx_queues;
-}
-
-/**
- * ixgbe_stop_adapter - Disable Rx/Tx units
- * @hw: pointer to hardware structure
- *
- * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
- * disables transmit and receive units. The adapter_stopped flag is used by
- * the shared code and drivers to determine if the adapter is in a stopped
- * state and should not touch the hardware.
- **/
-s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.stop_adapter, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_read_pba_string - Reads part number string from EEPROM
- * @hw: pointer to hardware structure
- * @pba_num: stores the part number string from the EEPROM
- * @pba_num_size: part number string buffer length
- *
- * Reads the part number string from the EEPROM.
- **/
-s32 ixgbe_read_pba_string(struct ixgbe_hw *hw, u8 *pba_num, u32 pba_num_size)
-{
- return ixgbe_read_pba_string_generic(hw, pba_num, pba_num_size);
-}
-
-/**
- * ixgbe_identify_phy - Get PHY type
- * @hw: pointer to hardware structure
- *
- * Determines the physical layer module found on the current adapter.
- **/
-s32 ixgbe_identify_phy(struct ixgbe_hw *hw)
-{
- s32 status = 0;
-
- if (hw->phy.type == ixgbe_phy_unknown) {
- status = ixgbe_call_func(hw, hw->phy.ops.identify, (hw),
- IXGBE_NOT_IMPLEMENTED);
- }
-
- return status;
-}
-
-/**
- * ixgbe_reset_phy - Perform a PHY reset
- * @hw: pointer to hardware structure
- **/
-s32 ixgbe_reset_phy(struct ixgbe_hw *hw)
-{
- s32 status = 0;
-
- if (hw->phy.type == ixgbe_phy_unknown) {
- if (ixgbe_identify_phy(hw) != 0)
- status = IXGBE_ERR_PHY;
- }
-
- if (status == 0) {
- status = ixgbe_call_func(hw, hw->phy.ops.reset, (hw),
- IXGBE_NOT_IMPLEMENTED);
- }
- return status;
-}
-
-/**
- * ixgbe_get_phy_firmware_version -
- * @hw: pointer to hardware structure
- * @firmware_version: pointer to firmware version
- **/
-s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw, u16 *firmware_version)
-{
- s32 status = 0;
-
- status = ixgbe_call_func(hw, hw->phy.ops.get_firmware_version,
- (hw, firmware_version),
- IXGBE_NOT_IMPLEMENTED);
- return status;
-}
-
-/**
- * ixgbe_read_phy_reg - Read PHY register
- * @hw: pointer to hardware structure
- * @reg_addr: 32 bit address of PHY register to read
- * @phy_data: Pointer to read data from PHY register
- *
- * Reads a value from a specified PHY register
- **/
-s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
- u16 *phy_data)
-{
- if (hw->phy.id == 0)
- ixgbe_identify_phy(hw);
-
- return ixgbe_call_func(hw, hw->phy.ops.read_reg, (hw, reg_addr,
- device_type, phy_data), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_write_phy_reg - Write PHY register
- * @hw: pointer to hardware structure
- * @reg_addr: 32 bit PHY register to write
- * @phy_data: Data to write to the PHY register
- *
- * Writes a value to specified PHY register
- **/
-s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
- u16 phy_data)
-{
- if (hw->phy.id == 0)
- ixgbe_identify_phy(hw);
-
- return ixgbe_call_func(hw, hw->phy.ops.write_reg, (hw, reg_addr,
- device_type, phy_data), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_setup_phy_link - Restart PHY autoneg
- * @hw: pointer to hardware structure
- *
- * Restart autonegotiation and PHY and waits for completion.
- **/
-s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->phy.ops.setup_link, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_check_phy_link - Determine link and speed status
- * @hw: pointer to hardware structure
- *
- * Reads a PHY register to determine if link is up and the current speed for
- * the PHY.
- **/
-s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
- bool *link_up)
-{
- return ixgbe_call_func(hw, hw->phy.ops.check_link, (hw, speed,
- link_up), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_setup_phy_link_speed - Set auto advertise
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- *
- * Sets the auto advertised capabilities
- **/
-s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete)
-{
- return ixgbe_call_func(hw, hw->phy.ops.setup_link_speed, (hw, speed,
- autoneg, autoneg_wait_to_complete),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_check_link - Get link and speed status
- * @hw: pointer to hardware structure
- *
- * Reads the links register to determine if link is up and the current speed
- **/
-s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
- bool *link_up, bool link_up_wait_to_complete)
-{
- return ixgbe_call_func(hw, hw->mac.ops.check_link, (hw, speed,
- link_up, link_up_wait_to_complete),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_disable_tx_laser - Disable Tx laser
- * @hw: pointer to hardware structure
- *
- * If the driver needs to disable the laser on SFI optics.
- **/
-void ixgbe_disable_tx_laser(struct ixgbe_hw *hw)
-{
- if (hw->mac.ops.disable_tx_laser)
- hw->mac.ops.disable_tx_laser(hw);
-}
-
-/**
- * ixgbe_enable_tx_laser - Enable Tx laser
- * @hw: pointer to hardware structure
- *
- * If the driver needs to enable the laser on SFI optics.
- **/
-void ixgbe_enable_tx_laser(struct ixgbe_hw *hw)
-{
- if (hw->mac.ops.enable_tx_laser)
- hw->mac.ops.enable_tx_laser(hw);
-}
-
-/**
- * ixgbe_flap_tx_laser - flap Tx laser to start autotry process
- * @hw: pointer to hardware structure
- *
- * When the driver changes the link speeds that it can support then
- * flap the tx laser to alert the link partner to start autotry
- * process on its end.
- **/
-void ixgbe_flap_tx_laser(struct ixgbe_hw *hw)
-{
- if (hw->mac.ops.flap_tx_laser)
- hw->mac.ops.flap_tx_laser(hw);
-}
-
-/**
- * ixgbe_setup_link - Set link speed
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- *
- * Configures link settings. Restarts the link.
- * Performs autonegotiation if needed.
- **/
-s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete)
-{
- return ixgbe_call_func(hw, hw->mac.ops.setup_link, (hw, speed,
- autoneg, autoneg_wait_to_complete),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_link_capabilities - Returns link capabilities
- * @hw: pointer to hardware structure
- *
- * Determines the link capabilities of the current configuration.
- **/
-s32 ixgbe_get_link_capabilities(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
- bool *autoneg)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_link_capabilities, (hw,
- speed, autoneg), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_led_on - Turn on LEDs
- * @hw: pointer to hardware structure
- * @index: led number to turn on
- *
- * Turns on the software controllable LEDs.
- **/
-s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
-{
- return ixgbe_call_func(hw, hw->mac.ops.led_on, (hw, index),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_led_off - Turn off LEDs
- * @hw: pointer to hardware structure
- * @index: led number to turn off
- *
- * Turns off the software controllable LEDs.
- **/
-s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
-{
- return ixgbe_call_func(hw, hw->mac.ops.led_off, (hw, index),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_blink_led_start - Blink LEDs
- * @hw: pointer to hardware structure
- * @index: led number to blink
- *
- * Blink LED based on index.
- **/
-s32 ixgbe_blink_led_start(struct ixgbe_hw *hw, u32 index)
-{
- return ixgbe_call_func(hw, hw->mac.ops.blink_led_start, (hw, index),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_blink_led_stop - Stop blinking LEDs
- * @hw: pointer to hardware structure
- *
- * Stop blinking LED based on index.
- **/
-s32 ixgbe_blink_led_stop(struct ixgbe_hw *hw, u32 index)
-{
- return ixgbe_call_func(hw, hw->mac.ops.blink_led_stop, (hw, index),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_init_eeprom_params - Initialize EEPROM parameters
- * @hw: pointer to hardware structure
- *
- * Initializes the EEPROM parameters ixgbe_eeprom_info within the
- * ixgbe_hw struct in order to set up EEPROM access.
- **/
-s32 ixgbe_init_eeprom_params(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->eeprom.ops.init_params, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-
-/**
- * ixgbe_write_eeprom - Write word to EEPROM
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be written to
- * @data: 16 bit word to be written to the EEPROM
- *
- * Writes 16 bit value to EEPROM. If ixgbe_eeprom_update_checksum is not
- * called after this function, the EEPROM will most likely contain an
- * invalid checksum.
- **/
-s32 ixgbe_write_eeprom(struct ixgbe_hw *hw, u16 offset, u16 data)
-{
- return ixgbe_call_func(hw, hw->eeprom.ops.write, (hw, offset, data),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_write_eeprom_buffer - Write word(s) to EEPROM
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be written to
- * @data: 16 bit word(s) to be written to the EEPROM
- * @words: number of words
- *
- * Writes 16 bit word(s) to EEPROM. If ixgbe_eeprom_update_checksum is not
- * called after this function, the EEPROM will most likely contain an
- * invalid checksum.
- **/
-s32 ixgbe_write_eeprom_buffer(struct ixgbe_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- return ixgbe_call_func(hw, hw->eeprom.ops.write_buffer,
- (hw, offset, words, data),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_read_eeprom - Read word from EEPROM
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be read
- * @data: read 16 bit value from EEPROM
- *
- * Reads 16 bit value from EEPROM
- **/
-s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data)
-{
- return ixgbe_call_func(hw, hw->eeprom.ops.read, (hw, offset, data),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_read_eeprom_buffer - Read word(s) from EEPROM
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be read
- * @data: read 16 bit word(s) from EEPROM
- * @words: number of words
- *
- * Reads 16 bit word(s) from EEPROM
- **/
-s32 ixgbe_read_eeprom_buffer(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- return ixgbe_call_func(hw, hw->eeprom.ops.read_buffer,
- (hw, offset, words, data),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_validate_eeprom_checksum - Validate EEPROM checksum
- * @hw: pointer to hardware structure
- * @checksum_val: calculated checksum
- *
- * Performs checksum calculation and validates the EEPROM checksum
- **/
-s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
-{
- return ixgbe_call_func(hw, hw->eeprom.ops.validate_checksum,
- (hw, checksum_val), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_eeprom_update_checksum - Updates the EEPROM checksum
- * @hw: pointer to hardware structure
- **/
-s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->eeprom.ops.update_checksum, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_insert_mac_addr - Find a RAR for this mac address
- * @hw: pointer to hardware structure
- * @addr: Address to put into receive address register
- * @vmdq: VMDq pool to assign
- *
- * Puts an ethernet address into a receive address register, or
- * finds the rar that it is already in; adds to the pool list
- **/
-s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
-{
- return ixgbe_call_func(hw, hw->mac.ops.insert_mac_addr,
- (hw, addr, vmdq),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_set_rar - Set Rx address register
- * @hw: pointer to hardware structure
- * @index: Receive address register to write
- * @addr: Address to put into receive address register
- * @vmdq: VMDq "set"
- * @enable_addr: set flag that address is active
- *
- * Puts an ethernet address into a receive address register.
- **/
-s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
- u32 enable_addr)
-{
- return ixgbe_call_func(hw, hw->mac.ops.set_rar, (hw, index, addr, vmdq,
- enable_addr), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_clear_rar - Clear Rx address register
- * @hw: pointer to hardware structure
- * @index: Receive address register to write
- *
- * Puts an ethernet address into a receive address register.
- **/
-s32 ixgbe_clear_rar(struct ixgbe_hw *hw, u32 index)
-{
- return ixgbe_call_func(hw, hw->mac.ops.clear_rar, (hw, index),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_set_vmdq - Associate a VMDq index with a receive address
- * @hw: pointer to hardware structure
- * @rar: receive address register index to associate with VMDq index
- * @vmdq: VMDq set or pool index
- **/
-s32 ixgbe_set_vmdq(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
-{
- return ixgbe_call_func(hw, hw->mac.ops.set_vmdq, (hw, rar, vmdq),
- IXGBE_NOT_IMPLEMENTED);
-
-}
-
-/**
- * ixgbe_set_vmdq_san_mac - Associate VMDq index 127 with a receive address
- * @hw: pointer to hardware structure
- * @vmdq: VMDq default pool index
- **/
-s32 ixgbe_set_vmdq_san_mac(struct ixgbe_hw *hw, u32 vmdq)
-{
- return ixgbe_call_func(hw, hw->mac.ops.set_vmdq_san_mac,
- (hw, vmdq), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_clear_vmdq - Disassociate a VMDq index from a receive address
- * @hw: pointer to hardware structure
- * @rar: receive address register index to disassociate with VMDq index
- * @vmdq: VMDq set or pool index
- **/
-s32 ixgbe_clear_vmdq(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
-{
- return ixgbe_call_func(hw, hw->mac.ops.clear_vmdq, (hw, rar, vmdq),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_init_rx_addrs - Initializes receive address filters.
- * @hw: pointer to hardware structure
- *
- * Places the MAC address in receive address register 0 and clears the rest
- * of the receive address registers. Clears the multicast table. Assumes
- * the receiver is in reset when the routine is called.
- **/
-s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.init_rx_addrs, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_num_rx_addrs - Returns the number of RAR entries.
- * @hw: pointer to hardware structure
- **/
-u32 ixgbe_get_num_rx_addrs(struct ixgbe_hw *hw)
-{
- return hw->mac.num_rar_entries;
-}
-
-/**
- * ixgbe_update_uc_addr_list - Updates the MAC's list of secondary addresses
- * @hw: pointer to hardware structure
- * @addr_list: the list of new multicast addresses
- * @addr_count: number of addresses
- * @func: iterator function to walk the multicast address list
- *
- * The given list replaces any existing list. Clears the secondary addrs from
- * receive address registers. Uses unused receive address registers for the
- * first secondary addresses, and falls back to promiscuous mode as needed.
- **/
-s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
- u32 addr_count, ixgbe_mc_addr_itr func)
-{
- return ixgbe_call_func(hw, hw->mac.ops.update_uc_addr_list, (hw,
- addr_list, addr_count, func),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_update_mc_addr_list - Updates the MAC's list of multicast addresses
- * @hw: pointer to hardware structure
- * @mc_addr_list: the list of new multicast addresses
- * @mc_addr_count: number of addresses
- * @func: iterator function to walk the multicast address list
- *
- * The given list replaces any existing list. Clears the MC addrs from receive
- * address registers and the multicast table. Uses unused receive address
- * registers for the first multicast addresses, and hashes the rest into the
- * multicast table.
- **/
-s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, ixgbe_mc_addr_itr func,
- bool clear)
-{
- return ixgbe_call_func(hw, hw->mac.ops.update_mc_addr_list, (hw,
- mc_addr_list, mc_addr_count, func, clear),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_enable_mc - Enable multicast address in RAR
- * @hw: pointer to hardware structure
- *
- * Enables multicast address in RAR and the use of the multicast hash table.
- **/
-s32 ixgbe_enable_mc(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.enable_mc, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_disable_mc - Disable multicast address in RAR
- * @hw: pointer to hardware structure
- *
- * Disables multicast address in RAR and the use of the multicast hash table.
- **/
-s32 ixgbe_disable_mc(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.disable_mc, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_clear_vfta - Clear VLAN filter table
- * @hw: pointer to hardware structure
- *
- * Clears the VLAN filer table, and the VMDq index associated with the filter
- **/
-s32 ixgbe_clear_vfta(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.clear_vfta, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_set_vfta - Set VLAN filter table
- * @hw: pointer to hardware structure
- * @vlan: VLAN id to write to VLAN filter
- * @vind: VMDq output index that maps queue to VLAN id in VFTA
- * @vlan_on: boolean flag to turn on/off VLAN in VFTA
- *
- * Turn on/off specified VLAN in the VLAN filter table.
- **/
-s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on)
-{
- return ixgbe_call_func(hw, hw->mac.ops.set_vfta, (hw, vlan, vind,
- vlan_on), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_set_vlvf - Set VLAN Pool Filter
- * @hw: pointer to hardware structure
- * @vlan: VLAN id to write to VLAN filter
- * @vind: VMDq output index that maps queue to VLAN id in VFVFB
- * @vlan_on: boolean flag to turn on/off VLAN in VFVF
- * @vfta_changed: pointer to boolean flag which indicates whether VFTA
- * should be changed
- *
- * Turn on/off specified bit in VLVF table.
- **/
-s32 ixgbe_set_vlvf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on,
- bool *vfta_changed)
-{
- return ixgbe_call_func(hw, hw->mac.ops.set_vlvf, (hw, vlan, vind,
- vlan_on, vfta_changed), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_fc_enable - Enable flow control
- * @hw: pointer to hardware structure
- *
- * Configures the flow control settings based on SW configuration.
- **/
-s32 ixgbe_fc_enable(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.fc_enable, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_set_fw_drv_ver - Try to send the driver version number FW
- * @hw: pointer to hardware structure
- * @maj: driver major number to be sent to firmware
- * @min: driver minor number to be sent to firmware
- * @build: driver build number to be sent to firmware
- * @ver: driver version number to be sent to firmware
- **/
-s32 ixgbe_set_fw_drv_ver(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build,
- u8 ver)
-{
- return ixgbe_call_func(hw, hw->mac.ops.set_fw_drv_ver, (hw, maj, min,
- build, ver), IXGBE_NOT_IMPLEMENTED);
-}
-
-
-/**
- * ixgbe_get_thermal_sensor_data - Gathers thermal sensor data
- * @hw: pointer to hardware structure
- *
- * Updates the temperatures in mac.thermal_sensor_data
- **/
-s32 ixgbe_get_thermal_sensor_data(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_thermal_sensor_data, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds
- * @hw: pointer to hardware structure
- *
- * Inits the thermal sensor thresholds according to the NVM map
- **/
-s32 ixgbe_init_thermal_sensor_thresh(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.init_thermal_sensor_thresh, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-/**
- * ixgbe_read_analog_reg8 - Reads 8 bit analog register
- * @hw: pointer to hardware structure
- * @reg: analog register to read
- * @val: read value
- *
- * Performs write operation to analog register specified.
- **/
-s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val)
-{
- return ixgbe_call_func(hw, hw->mac.ops.read_analog_reg8, (hw, reg,
- val), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_write_analog_reg8 - Writes 8 bit analog register
- * @hw: pointer to hardware structure
- * @reg: analog register to write
- * @val: value to write
- *
- * Performs write operation to Atlas analog register specified.
- **/
-s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val)
-{
- return ixgbe_call_func(hw, hw->mac.ops.write_analog_reg8, (hw, reg,
- val), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_init_uta_tables - Initializes Unicast Table Arrays.
- * @hw: pointer to hardware structure
- *
- * Initializes the Unicast Table Arrays to zero on device load. This
- * is part of the Rx init addr execution path.
- **/
-s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.init_uta_tables, (hw),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_read_i2c_byte - Reads 8 bit word over I2C at specified device address
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to read
- * @data: value read
- *
- * Performs byte read operation to SFP module's EEPROM over I2C interface.
- **/
-s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
- u8 *data)
-{
- return ixgbe_call_func(hw, hw->phy.ops.read_i2c_byte, (hw, byte_offset,
- dev_addr, data), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_write_i2c_byte - Writes 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to write
- * @data: value to write
- *
- * Performs byte write operation to SFP module's EEPROM over I2C interface
- * at a specified device address.
- **/
-s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
- u8 data)
-{
- return ixgbe_call_func(hw, hw->phy.ops.write_i2c_byte, (hw, byte_offset,
- dev_addr, data), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_write_i2c_eeprom - Writes 8 bit EEPROM word over I2C interface
- * @hw: pointer to hardware structure
- * @byte_offset: EEPROM byte offset to write
- * @eeprom_data: value to write
- *
- * Performs byte write operation to SFP module's EEPROM over I2C interface.
- **/
-s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw,
- u8 byte_offset, u8 eeprom_data)
-{
- return ixgbe_call_func(hw, hw->phy.ops.write_i2c_eeprom,
- (hw, byte_offset, eeprom_data),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_read_i2c_eeprom - Reads 8 bit EEPROM word over I2C interface
- * @hw: pointer to hardware structure
- * @byte_offset: EEPROM byte offset to read
- * @eeprom_data: value read
- *
- * Performs byte read operation to SFP module's EEPROM over I2C interface.
- **/
-s32 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data)
-{
- return ixgbe_call_func(hw, hw->phy.ops.read_i2c_eeprom,
- (hw, byte_offset, eeprom_data),
- IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_get_supported_physical_layer - Returns physical layer type
- * @hw: pointer to hardware structure
- *
- * Determines physical layer capabilities of the current configuration.
- **/
-u32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.get_supported_physical_layer,
- (hw), IXGBE_PHYSICAL_LAYER_UNKNOWN);
-}
-
-/**
- * ixgbe_enable_rx_dma - Enables Rx DMA unit, dependent on device specifics
- * @hw: pointer to hardware structure
- * @regval: bitfield to write to the Rx DMA register
- *
- * Enables the Rx DMA unit of the device.
- **/
-s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval)
-{
- return ixgbe_call_func(hw, hw->mac.ops.enable_rx_dma,
- (hw, regval), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_disable_sec_rx_path - Stops the receive data path
- * @hw: pointer to hardware structure
- *
- * Stops the receive data path.
- **/
-s32 ixgbe_disable_sec_rx_path(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.disable_sec_rx_path,
- (hw), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_enable_sec_rx_path - Enables the receive data path
- * @hw: pointer to hardware structure
- *
- * Enables the receive data path.
- **/
-s32 ixgbe_enable_sec_rx_path(struct ixgbe_hw *hw)
-{
- return ixgbe_call_func(hw, hw->mac.ops.enable_sec_rx_path,
- (hw), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_acquire_swfw_semaphore - Acquire SWFW semaphore
- * @hw: pointer to hardware structure
- * @mask: Mask to specify which semaphore to acquire
- *
- * Acquires the SWFW semaphore through SW_FW_SYNC register for the specified
- * function (CSR, PHY0, PHY1, EEPROM, Flash)
- **/
-s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u16 mask)
-{
- return ixgbe_call_func(hw, hw->mac.ops.acquire_swfw_sync,
- (hw, mask), IXGBE_NOT_IMPLEMENTED);
-}
-
-/**
- * ixgbe_release_swfw_semaphore - Release SWFW semaphore
- * @hw: pointer to hardware structure
- * @mask: Mask to specify which semaphore to release
- *
- * Releases the SWFW semaphore through SW_FW_SYNC register for the specified
- * function (CSR, PHY0, PHY1, EEPROM, Flash)
- **/
-void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u16 mask)
-{
- if (hw->mac.ops.release_swfw_sync)
- hw->mac.ops.release_swfw_sync(hw, mask);
-}
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_api.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_api.h
deleted file mode 100644
index 11247a0b6..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_api.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_API_H_
-#define _IXGBE_API_H_
-
-#include "ixgbe_type.h"
-
-s32 ixgbe_init_shared_code(struct ixgbe_hw *hw);
-
-extern s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw);
-extern s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw);
-extern s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw);
-
-s32 ixgbe_set_mac_type(struct ixgbe_hw *hw);
-s32 ixgbe_init_hw(struct ixgbe_hw *hw);
-s32 ixgbe_reset_hw(struct ixgbe_hw *hw);
-s32 ixgbe_start_hw(struct ixgbe_hw *hw);
-s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw);
-enum ixgbe_media_type ixgbe_get_media_type(struct ixgbe_hw *hw);
-s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr);
-s32 ixgbe_get_bus_info(struct ixgbe_hw *hw);
-u32 ixgbe_get_num_of_tx_queues(struct ixgbe_hw *hw);
-u32 ixgbe_get_num_of_rx_queues(struct ixgbe_hw *hw);
-s32 ixgbe_stop_adapter(struct ixgbe_hw *hw);
-s32 ixgbe_read_pba_string(struct ixgbe_hw *hw, u8 *pba_num, u32 pba_num_size);
-
-s32 ixgbe_identify_phy(struct ixgbe_hw *hw);
-s32 ixgbe_reset_phy(struct ixgbe_hw *hw);
-s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
- u16 *phy_data);
-s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
- u16 phy_data);
-
-s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw);
-s32 ixgbe_check_phy_link(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *link_up);
-s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
-void ixgbe_disable_tx_laser(struct ixgbe_hw *hw);
-void ixgbe_enable_tx_laser(struct ixgbe_hw *hw);
-void ixgbe_flap_tx_laser(struct ixgbe_hw *hw);
-s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool autoneg_wait_to_complete);
-s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
- bool *link_up, bool link_up_wait_to_complete);
-s32 ixgbe_get_link_capabilities(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
- bool *autoneg);
-s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_blink_led_start(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_blink_led_stop(struct ixgbe_hw *hw, u32 index);
-
-s32 ixgbe_init_eeprom_params(struct ixgbe_hw *hw);
-s32 ixgbe_write_eeprom(struct ixgbe_hw *hw, u16 offset, u16 data);
-s32 ixgbe_write_eeprom_buffer(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data);
-s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data);
-s32 ixgbe_read_eeprom_buffer(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data);
-
-s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val);
-s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw);
-
-s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
-s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
- u32 enable_addr);
-s32 ixgbe_clear_rar(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_set_vmdq(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
-s32 ixgbe_set_vmdq_san_mac(struct ixgbe_hw *hw, u32 vmdq);
-s32 ixgbe_clear_vmdq(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
-s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw);
-u32 ixgbe_get_num_rx_addrs(struct ixgbe_hw *hw);
-s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
- u32 addr_count, ixgbe_mc_addr_itr func);
-s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, ixgbe_mc_addr_itr func,
- bool clear);
-void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr_list, u32 vmdq);
-s32 ixgbe_enable_mc(struct ixgbe_hw *hw);
-s32 ixgbe_disable_mc(struct ixgbe_hw *hw);
-s32 ixgbe_clear_vfta(struct ixgbe_hw *hw);
-s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan,
- u32 vind, bool vlan_on);
-s32 ixgbe_set_vlvf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
- bool vlan_on, bool *vfta_changed);
-s32 ixgbe_fc_enable(struct ixgbe_hw *hw);
-s32 ixgbe_set_fw_drv_ver(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build,
- u8 ver);
-s32 ixgbe_get_thermal_sensor_data(struct ixgbe_hw *hw);
-s32 ixgbe_init_thermal_sensor_thresh(struct ixgbe_hw *hw);
-void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr);
-s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw,
- u16 *firmware_version);
-s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val);
-s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val);
-s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw);
-s32 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data);
-u32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw);
-s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval);
-s32 ixgbe_disable_sec_rx_path(struct ixgbe_hw *hw);
-s32 ixgbe_enable_sec_rx_path(struct ixgbe_hw *hw);
-s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
-s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl);
-s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl);
-s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_hash_dword input,
- union ixgbe_atr_hash_dword common,
- u8 queue);
-s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_input *input_mask);
-s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_input *input,
- u16 soft_id, u8 queue);
-s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_input *input,
- u16 soft_id);
-s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
- union ixgbe_atr_input *input,
- union ixgbe_atr_input *mask,
- u16 soft_id,
- u8 queue);
-void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
- union ixgbe_atr_input *mask);
-u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
- union ixgbe_atr_hash_dword common);
-s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
- u8 *data);
-s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
- u8 data);
-s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data);
-s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr);
-s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr);
-s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps);
-s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u16 mask);
-void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u16 mask);
-s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix,
- u16 *wwpn_prefix);
-s32 ixgbe_get_fcoe_boot_status(struct ixgbe_hw *hw, u16 *bs);
-
-#endif /* _IXGBE_API_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_common.c b/kernel/linux/kni/ethtool/ixgbe/ixgbe_common.c
deleted file mode 100644
index e9b9529a2..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_common.c
+++ /dev/null
@@ -1,4067 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "ixgbe_common.h"
-#include "ixgbe_phy.h"
-#include "ixgbe_api.h"
-
-static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
-static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw);
-static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
-static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw);
-static void ixgbe_standby_eeprom(struct ixgbe_hw *hw);
-static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
- u16 count);
-static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
-static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
-static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
-static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
-
-static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
-static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
- u16 *san_mac_offset);
-static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data);
-static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data);
-static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
- u16 offset);
-
-/**
- * ixgbe_init_ops_generic - Inits function ptrs
- * @hw: pointer to the hardware structure
- *
- * Initialize the function pointers.
- **/
-s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
-{
- struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
- struct ixgbe_mac_info *mac = &hw->mac;
- u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC);
-
- /* EEPROM */
- eeprom->ops.init_params = &ixgbe_init_eeprom_params_generic;
- /* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */
- if (eec & IXGBE_EEC_PRES) {
- eeprom->ops.read = &ixgbe_read_eerd_generic;
- eeprom->ops.read_buffer = &ixgbe_read_eerd_buffer_generic;
- } else {
- eeprom->ops.read = &ixgbe_read_eeprom_bit_bang_generic;
- eeprom->ops.read_buffer =
- &ixgbe_read_eeprom_buffer_bit_bang_generic;
- }
- eeprom->ops.write = &ixgbe_write_eeprom_generic;
- eeprom->ops.write_buffer = &ixgbe_write_eeprom_buffer_bit_bang_generic;
- eeprom->ops.validate_checksum =
- &ixgbe_validate_eeprom_checksum_generic;
- eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_generic;
- eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_generic;
-
- /* MAC */
- mac->ops.init_hw = &ixgbe_init_hw_generic;
- mac->ops.reset_hw = NULL;
- mac->ops.start_hw = &ixgbe_start_hw_generic;
- mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic;
- mac->ops.get_media_type = NULL;
- mac->ops.get_supported_physical_layer = NULL;
- mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic;
- mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic;
- mac->ops.stop_adapter = &ixgbe_stop_adapter_generic;
- mac->ops.get_bus_info = &ixgbe_get_bus_info_generic;
- mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie;
- mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync;
- mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync;
-
- /* LEDs */
- mac->ops.led_on = &ixgbe_led_on_generic;
- mac->ops.led_off = &ixgbe_led_off_generic;
- mac->ops.blink_led_start = &ixgbe_blink_led_start_generic;
- mac->ops.blink_led_stop = &ixgbe_blink_led_stop_generic;
-
- /* RAR, Multicast, VLAN */
- mac->ops.set_rar = &ixgbe_set_rar_generic;
- mac->ops.clear_rar = &ixgbe_clear_rar_generic;
- mac->ops.insert_mac_addr = NULL;
- mac->ops.set_vmdq = NULL;
- mac->ops.clear_vmdq = NULL;
- mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic;
- mac->ops.update_uc_addr_list = &ixgbe_update_uc_addr_list_generic;
- mac->ops.update_mc_addr_list = &ixgbe_update_mc_addr_list_generic;
- mac->ops.enable_mc = &ixgbe_enable_mc_generic;
- mac->ops.disable_mc = &ixgbe_disable_mc_generic;
- mac->ops.clear_vfta = NULL;
- mac->ops.set_vfta = NULL;
- mac->ops.set_vlvf = NULL;
- mac->ops.init_uta_tables = NULL;
-
- /* Flow Control */
- mac->ops.fc_enable = &ixgbe_fc_enable_generic;
-
- /* Link */
- mac->ops.get_link_capabilities = NULL;
- mac->ops.setup_link = NULL;
- mac->ops.check_link = NULL;
-
- return 0;
-}
-
-/**
- * ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow
- * control
- * @hw: pointer to hardware structure
- *
- * There are several phys that do not support autoneg flow control. This
- * function check the device id to see if the associated phy supports
- * autoneg flow control.
- **/
-static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
-{
-
- switch (hw->device_id) {
- case IXGBE_DEV_ID_X540T:
- return 0;
- case IXGBE_DEV_ID_82599_T3_LOM:
- return 0;
- default:
- return IXGBE_ERR_FC_NOT_SUPPORTED;
- }
-}
-
-/**
- * ixgbe_setup_fc - Set up flow control
- * @hw: pointer to hardware structure
- *
- * Called at init time to set up flow control.
- **/
-static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
-{
- s32 ret_val = 0;
- u32 reg = 0, reg_bp = 0;
- u16 reg_cu = 0;
-
- /*
- * Validate the requested mode. Strict IEEE mode does not allow
- * ixgbe_fc_rx_pause because it will cause us to fail at UNH.
- */
- if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
- hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
-
- /*
- * 10gig parts do not have a word in the EEPROM to determine the
- * default flow control setting, so we explicitly set it to full.
- */
- if (hw->fc.requested_mode == ixgbe_fc_default)
- hw->fc.requested_mode = ixgbe_fc_full;
-
- /*
- * Set up the 1G and 10G flow control advertisement registers so the
- * HW will be able to do fc autoneg once the cable is plugged in. If
- * we link at 10G, the 1G advertisement is harmless and vice versa.
- */
- switch (hw->phy.media_type) {
- case ixgbe_media_type_fiber:
- case ixgbe_media_type_backplane:
- reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
- reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- break;
- case ixgbe_media_type_copper:
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®_cu);
- break;
- default:
- break;
- }
-
- /*
- * The possible values of fc.requested_mode are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames,
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but
- * we do not support receiving pause frames).
- * 3: Both Rx and Tx flow control (symmetric) are enabled.
- * other: Invalid.
- */
- switch (hw->fc.requested_mode) {
- case ixgbe_fc_none:
- /* Flow control completely disabled by software override. */
- reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
- if (hw->phy.media_type == ixgbe_media_type_backplane)
- reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE |
- IXGBE_AUTOC_ASM_PAUSE);
- else if (hw->phy.media_type == ixgbe_media_type_copper)
- reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
- break;
- case ixgbe_fc_tx_pause:
- /*
- * Tx Flow control is enabled, and Rx Flow control is
- * disabled by software override.
- */
- reg |= IXGBE_PCS1GANA_ASM_PAUSE;
- reg &= ~IXGBE_PCS1GANA_SYM_PAUSE;
- if (hw->phy.media_type == ixgbe_media_type_backplane) {
- reg_bp |= IXGBE_AUTOC_ASM_PAUSE;
- reg_bp &= ~IXGBE_AUTOC_SYM_PAUSE;
- } else if (hw->phy.media_type == ixgbe_media_type_copper) {
- reg_cu |= IXGBE_TAF_ASM_PAUSE;
- reg_cu &= ~IXGBE_TAF_SYM_PAUSE;
- }
- break;
- case ixgbe_fc_rx_pause:
- /*
- * Rx Flow control is enabled and Tx Flow control is
- * disabled by software override. Since there really
- * isn't a way to advertise that we are capable of RX
- * Pause ONLY, we will advertise that we support both
- * symmetric and asymmetric Rx PAUSE, as such we fall
- * through to the fc_full statement. Later, we will
- * disable the adapter's ability to send PAUSE frames.
- */
- case ixgbe_fc_full:
- /* Flow control (both Rx and Tx) is enabled by SW override. */
- reg |= IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE;
- if (hw->phy.media_type == ixgbe_media_type_backplane)
- reg_bp |= IXGBE_AUTOC_SYM_PAUSE |
- IXGBE_AUTOC_ASM_PAUSE;
- else if (hw->phy.media_type == ixgbe_media_type_copper)
- reg_cu |= IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE;
- break;
- default:
- hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = IXGBE_ERR_CONFIG;
- goto out;
- break;
- }
-
- if (hw->mac.type != ixgbe_mac_X540) {
- /*
- * Enable auto-negotiation between the MAC & PHY;
- * the MAC will advertise clause 37 flow control.
- */
- IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
- reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
-
- /* Disable AN timeout */
- if (hw->fc.strict_ieee)
- reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
-
- IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
- hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
- }
-
- /*
- * AUTOC restart handles negotiation of 1G and 10G on backplane
- * and copper. There is no need to set the PCS1GCTL register.
- *
- */
- if (hw->phy.media_type == ixgbe_media_type_backplane) {
- reg_bp |= IXGBE_AUTOC_AN_RESTART;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
- } else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
- (ixgbe_device_supports_autoneg_fc(hw) == 0)) {
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu);
- }
-
- hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
- * @hw: pointer to hardware structure
- *
- * Starts the hardware by filling the bus info structure and media type, clears
- * all on chip counters, initializes receive address registers, multicast
- * table, VLAN filter table, calls routine to set up link and flow control
- * settings, and leaves transmit and receive units disabled and uninitialized
- **/
-s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
-{
- s32 ret_val;
- u32 ctrl_ext;
-
- /* Set the media type */
- hw->phy.media_type = hw->mac.ops.get_media_type(hw);
-
- /* PHY ops initialization must be done in reset_hw() */
-
- /* Clear the VLAN filter table */
- hw->mac.ops.clear_vfta(hw);
-
- /* Clear statistics registers */
- hw->mac.ops.clear_hw_cntrs(hw);
-
- /* Set No Snoop Disable */
- ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
- ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS;
- IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
- IXGBE_WRITE_FLUSH(hw);
-
- /* Setup flow control */
- ret_val = ixgbe_setup_fc(hw);
- if (ret_val != 0)
- goto out;
-
- /* Clear adapter stopped flag */
- hw->adapter_stopped = false;
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_start_hw_gen2 - Init sequence for common device family
- * @hw: pointer to hw structure
- *
- * Performs the init sequence common to the second generation
- * of 10 GbE devices.
- * Devices in the second generation:
- * 82599
- * X540
- **/
-s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
-{
- u32 i;
- u32 regval;
-
- /* Clear the rate limiters */
- for (i = 0; i < hw->mac.max_tx_queues; i++) {
- IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
- IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
- }
- IXGBE_WRITE_FLUSH(hw);
-
- /* Disable relaxed ordering */
- for (i = 0; i < hw->mac.max_tx_queues; i++) {
- regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
- regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
- }
-
- for (i = 0; i < hw->mac.max_rx_queues; i++) {
- regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
- regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
- IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
- IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
- }
-
- return 0;
-}
-
-/**
- * ixgbe_init_hw_generic - Generic hardware initialization
- * @hw: pointer to hardware structure
- *
- * Initialize the hardware by resetting the hardware, filling the bus info
- * structure and media type, clears all on chip counters, initializes receive
- * address registers, multicast table, VLAN filter table, calls routine to set
- * up link and flow control settings, and leaves transmit and receive units
- * disabled and uninitialized
- **/
-s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
-{
- s32 status;
-
- /* Reset the hardware */
- status = hw->mac.ops.reset_hw(hw);
-
- if (status == 0) {
- /* Start the HW */
- status = hw->mac.ops.start_hw(hw);
- }
-
- return status;
-}
-
-/**
- * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters
- * @hw: pointer to hardware structure
- *
- * Clears all hardware statistics counters by reading them from the hardware
- * Statistics counters are clear on read.
- **/
-s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
-{
- u16 i = 0;
-
- IXGBE_READ_REG(hw, IXGBE_CRCERRS);
- IXGBE_READ_REG(hw, IXGBE_ILLERRC);
- IXGBE_READ_REG(hw, IXGBE_ERRBC);
- IXGBE_READ_REG(hw, IXGBE_MSPDC);
- for (i = 0; i < 8; i++)
- IXGBE_READ_REG(hw, IXGBE_MPC(i));
-
- IXGBE_READ_REG(hw, IXGBE_MLFC);
- IXGBE_READ_REG(hw, IXGBE_MRFC);
- IXGBE_READ_REG(hw, IXGBE_RLEC);
- IXGBE_READ_REG(hw, IXGBE_LXONTXC);
- IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
- if (hw->mac.type >= ixgbe_mac_82599EB) {
- IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
- IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
- } else {
- IXGBE_READ_REG(hw, IXGBE_LXONRXC);
- IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
- }
-
- for (i = 0; i < 8; i++) {
- IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
- IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
- if (hw->mac.type >= ixgbe_mac_82599EB) {
- IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
- IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
- } else {
- IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
- IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
- }
- }
- if (hw->mac.type >= ixgbe_mac_82599EB)
- for (i = 0; i < 8; i++)
- IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i));
- IXGBE_READ_REG(hw, IXGBE_PRC64);
- IXGBE_READ_REG(hw, IXGBE_PRC127);
- IXGBE_READ_REG(hw, IXGBE_PRC255);
- IXGBE_READ_REG(hw, IXGBE_PRC511);
- IXGBE_READ_REG(hw, IXGBE_PRC1023);
- IXGBE_READ_REG(hw, IXGBE_PRC1522);
- IXGBE_READ_REG(hw, IXGBE_GPRC);
- IXGBE_READ_REG(hw, IXGBE_BPRC);
- IXGBE_READ_REG(hw, IXGBE_MPRC);
- IXGBE_READ_REG(hw, IXGBE_GPTC);
- IXGBE_READ_REG(hw, IXGBE_GORCL);
- IXGBE_READ_REG(hw, IXGBE_GORCH);
- IXGBE_READ_REG(hw, IXGBE_GOTCL);
- IXGBE_READ_REG(hw, IXGBE_GOTCH);
- if (hw->mac.type == ixgbe_mac_82598EB)
- for (i = 0; i < 8; i++)
- IXGBE_READ_REG(hw, IXGBE_RNBC(i));
- IXGBE_READ_REG(hw, IXGBE_RUC);
- IXGBE_READ_REG(hw, IXGBE_RFC);
- IXGBE_READ_REG(hw, IXGBE_ROC);
- IXGBE_READ_REG(hw, IXGBE_RJC);
- IXGBE_READ_REG(hw, IXGBE_MNGPRC);
- IXGBE_READ_REG(hw, IXGBE_MNGPDC);
- IXGBE_READ_REG(hw, IXGBE_MNGPTC);
- IXGBE_READ_REG(hw, IXGBE_TORL);
- IXGBE_READ_REG(hw, IXGBE_TORH);
- IXGBE_READ_REG(hw, IXGBE_TPR);
- IXGBE_READ_REG(hw, IXGBE_TPT);
- IXGBE_READ_REG(hw, IXGBE_PTC64);
- IXGBE_READ_REG(hw, IXGBE_PTC127);
- IXGBE_READ_REG(hw, IXGBE_PTC255);
- IXGBE_READ_REG(hw, IXGBE_PTC511);
- IXGBE_READ_REG(hw, IXGBE_PTC1023);
- IXGBE_READ_REG(hw, IXGBE_PTC1522);
- IXGBE_READ_REG(hw, IXGBE_MPTC);
- IXGBE_READ_REG(hw, IXGBE_BPTC);
- for (i = 0; i < 16; i++) {
- IXGBE_READ_REG(hw, IXGBE_QPRC(i));
- IXGBE_READ_REG(hw, IXGBE_QPTC(i));
- if (hw->mac.type >= ixgbe_mac_82599EB) {
- IXGBE_READ_REG(hw, IXGBE_QBRC_L(i));
- IXGBE_READ_REG(hw, IXGBE_QBRC_H(i));
- IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
- IXGBE_READ_REG(hw, IXGBE_QBTC_H(i));
- IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
- } else {
- IXGBE_READ_REG(hw, IXGBE_QBRC(i));
- IXGBE_READ_REG(hw, IXGBE_QBTC(i));
- }
- }
-
- if (hw->mac.type == ixgbe_mac_X540) {
- if (hw->phy.id == 0)
- ixgbe_identify_phy(hw);
- hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECL,
- IXGBE_MDIO_PCS_DEV_TYPE, &i);
- hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECH,
- IXGBE_MDIO_PCS_DEV_TYPE, &i);
- hw->phy.ops.read_reg(hw, IXGBE_LDPCECL,
- IXGBE_MDIO_PCS_DEV_TYPE, &i);
- hw->phy.ops.read_reg(hw, IXGBE_LDPCECH,
- IXGBE_MDIO_PCS_DEV_TYPE, &i);
- }
-
- return 0;
-}
-
-/**
- * ixgbe_read_pba_string_generic - Reads part number string from EEPROM
- * @hw: pointer to hardware structure
- * @pba_num: stores the part number string from the EEPROM
- * @pba_num_size: part number string buffer length
- *
- * Reads the part number string from the EEPROM.
- **/
-s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
- u32 pba_num_size)
-{
- s32 ret_val;
- u16 data;
- u16 pba_ptr;
- u16 offset;
- u16 length;
-
- if (pba_num == NULL) {
- hw_dbg(hw, "PBA string buffer was null\n");
- return IXGBE_ERR_INVALID_ARGUMENT;
- }
-
- ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
-
- ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
-
- /*
- * if data is not ptr guard the PBA must be in legacy format which
- * means pba_ptr is actually our second data word for the PBA number
- * and we can decode it into an ascii string
- */
- if (data != IXGBE_PBANUM_PTR_GUARD) {
- hw_dbg(hw, "NVM PBA number is not stored as string\n");
-
- /* we will need 11 characters to store the PBA */
- if (pba_num_size < 11) {
- hw_dbg(hw, "PBA string buffer too small\n");
- return IXGBE_ERR_NO_SPACE;
- }
-
- /* extract hex string from data and pba_ptr */
- pba_num[0] = (data >> 12) & 0xF;
- pba_num[1] = (data >> 8) & 0xF;
- pba_num[2] = (data >> 4) & 0xF;
- pba_num[3] = data & 0xF;
- pba_num[4] = (pba_ptr >> 12) & 0xF;
- pba_num[5] = (pba_ptr >> 8) & 0xF;
- pba_num[6] = '-';
- pba_num[7] = 0;
- pba_num[8] = (pba_ptr >> 4) & 0xF;
- pba_num[9] = pba_ptr & 0xF;
-
- /* put a null character on the end of our string */
- pba_num[10] = '\0';
-
- /* switch all the data but the '-' to hex char */
- for (offset = 0; offset < 10; offset++) {
- if (pba_num[offset] < 0xA)
- pba_num[offset] += '0';
- else if (pba_num[offset] < 0x10)
- pba_num[offset] += 'A' - 0xA;
- }
-
- return 0;
- }
-
- ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
-
- if (length == 0xFFFF || length == 0) {
- hw_dbg(hw, "NVM PBA number section invalid length\n");
- return IXGBE_ERR_PBA_SECTION;
- }
-
- /* check if pba_num buffer is big enough */
- if (pba_num_size < (((u32)length * 2) - 1)) {
- hw_dbg(hw, "PBA string buffer too small\n");
- return IXGBE_ERR_NO_SPACE;
- }
-
- /* trim pba length from start of string */
- pba_ptr++;
- length--;
-
- for (offset = 0; offset < length; offset++) {
- ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- pba_num[offset * 2] = (u8)(data >> 8);
- pba_num[(offset * 2) + 1] = (u8)(data & 0xFF);
- }
- pba_num[offset * 2] = '\0';
-
- return 0;
-}
-
-/**
- * ixgbe_get_mac_addr_generic - Generic get MAC address
- * @hw: pointer to hardware structure
- * @mac_addr: Adapter MAC address
- *
- * Reads the adapter's MAC address from first Receive Address Register (RAR0)
- * A reset of the adapter must be performed prior to calling this function
- * in order for the MAC address to have been loaded from the EEPROM into RAR0
- **/
-s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
-{
- u32 rar_high;
- u32 rar_low;
- u16 i;
-
- rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0));
- rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0));
-
- for (i = 0; i < 4; i++)
- mac_addr[i] = (u8)(rar_low >> (i*8));
-
- for (i = 0; i < 2; i++)
- mac_addr[i+4] = (u8)(rar_high >> (i*8));
-
- return 0;
-}
-
-/**
- * ixgbe_get_bus_info_generic - Generic set PCI bus info
- * @hw: pointer to hardware structure
- *
- * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure
- **/
-s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
-{
- struct ixgbe_mac_info *mac = &hw->mac;
- u16 link_status;
-
- hw->bus.type = ixgbe_bus_type_pci_express;
-
- /* Get the negotiated link width and speed from PCI config space */
- link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS);
-
- switch (link_status & IXGBE_PCI_LINK_WIDTH) {
- case IXGBE_PCI_LINK_WIDTH_1:
- hw->bus.width = ixgbe_bus_width_pcie_x1;
- break;
- case IXGBE_PCI_LINK_WIDTH_2:
- hw->bus.width = ixgbe_bus_width_pcie_x2;
- break;
- case IXGBE_PCI_LINK_WIDTH_4:
- hw->bus.width = ixgbe_bus_width_pcie_x4;
- break;
- case IXGBE_PCI_LINK_WIDTH_8:
- hw->bus.width = ixgbe_bus_width_pcie_x8;
- break;
- default:
- hw->bus.width = ixgbe_bus_width_unknown;
- break;
- }
-
- switch (link_status & IXGBE_PCI_LINK_SPEED) {
- case IXGBE_PCI_LINK_SPEED_2500:
- hw->bus.speed = ixgbe_bus_speed_2500;
- break;
- case IXGBE_PCI_LINK_SPEED_5000:
- hw->bus.speed = ixgbe_bus_speed_5000;
- break;
- case IXGBE_PCI_LINK_SPEED_8000:
- hw->bus.speed = ixgbe_bus_speed_8000;
- break;
- default:
- hw->bus.speed = ixgbe_bus_speed_unknown;
- break;
- }
-
- mac->ops.set_lan_id(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
- * @hw: pointer to the HW structure
- *
- * Determines the LAN function id by reading memory-mapped registers
- * and swaps the port value if requested.
- **/
-void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
-{
- struct ixgbe_bus_info *bus = &hw->bus;
- u32 reg;
-
- reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
- bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
- bus->lan_id = bus->func;
-
- /* check for a port swap */
- reg = IXGBE_READ_REG(hw, IXGBE_FACTPS);
- if (reg & IXGBE_FACTPS_LFS)
- bus->func ^= 0x1;
-}
-
-/**
- * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
- * @hw: pointer to hardware structure
- *
- * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
- * disables transmit and receive units. The adapter_stopped flag is used by
- * the shared code and drivers to determine if the adapter is in a stopped
- * state and should not touch the hardware.
- **/
-s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
-{
- u32 reg_val;
- u16 i;
-
- /*
- * Set the adapter_stopped flag so other driver functions stop touching
- * the hardware
- */
- hw->adapter_stopped = true;
-
- /* Disable the receive unit */
- IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, 0);
-
- /* Clear interrupt mask to stop interrupts from being generated */
- IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
-
- /* Clear any pending interrupts, flush previous writes */
- IXGBE_READ_REG(hw, IXGBE_EICR);
-
- /* Disable the transmit unit. Each queue must be disabled. */
- for (i = 0; i < hw->mac.max_tx_queues; i++)
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), IXGBE_TXDCTL_SWFLSH);
-
- /* Disable the receive unit by stopping each queue */
- for (i = 0; i < hw->mac.max_rx_queues; i++) {
- reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
- reg_val &= ~IXGBE_RXDCTL_ENABLE;
- reg_val |= IXGBE_RXDCTL_SWFLSH;
- IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val);
- }
-
- /* flush all queues disables */
- IXGBE_WRITE_FLUSH(hw);
- msleep(2);
-
- /*
- * Prevent the PCI-E bus from from hanging by disabling PCI-E master
- * access and verify no pending requests
- */
- return ixgbe_disable_pcie_master(hw);
-}
-
-/**
- * ixgbe_led_on_generic - Turns on the software controllable LEDs.
- * @hw: pointer to hardware structure
- * @index: led number to turn on
- **/
-s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
-{
- u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
- /* To turn on the LED, set mode to ON. */
- led_reg &= ~IXGBE_LED_MODE_MASK(index);
- led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index);
- IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
- IXGBE_WRITE_FLUSH(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_led_off_generic - Turns off the software controllable LEDs.
- * @hw: pointer to hardware structure
- * @index: led number to turn off
- **/
-s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
-{
- u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
- /* To turn off the LED, set mode to OFF. */
- led_reg &= ~IXGBE_LED_MODE_MASK(index);
- led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index);
- IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
- IXGBE_WRITE_FLUSH(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_init_eeprom_params_generic - Initialize EEPROM params
- * @hw: pointer to hardware structure
- *
- * Initializes the EEPROM parameters ixgbe_eeprom_info within the
- * ixgbe_hw struct in order to set up EEPROM access.
- **/
-s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
-{
- struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
- u32 eec;
- u16 eeprom_size;
-
- if (eeprom->type == ixgbe_eeprom_uninitialized) {
- eeprom->type = ixgbe_eeprom_none;
- /* Set default semaphore delay to 10ms which is a well
- * tested value */
- eeprom->semaphore_delay = 10;
- /* Clear EEPROM page size, it will be initialized as needed */
- eeprom->word_page_size = 0;
-
- /*
- * Check for EEPROM present first.
- * If not present leave as none
- */
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
- if (eec & IXGBE_EEC_PRES) {
- eeprom->type = ixgbe_eeprom_spi;
-
- /*
- * SPI EEPROM is assumed here. This code would need to
- * change if a future EEPROM is not SPI.
- */
- eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
- IXGBE_EEC_SIZE_SHIFT);
- eeprom->word_size = 1 << (eeprom_size +
- IXGBE_EEPROM_WORD_SIZE_SHIFT);
- }
-
- if (eec & IXGBE_EEC_ADDR_SIZE)
- eeprom->address_bits = 16;
- else
- eeprom->address_bits = 8;
- hw_dbg(hw, "Eeprom params: type = %d, size = %d, address bits: "
- "%d\n", eeprom->type, eeprom->word_size,
- eeprom->address_bits);
- }
-
- return 0;
-}
-
-/**
- * ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to write
- * @words: number of word(s)
- * @data: 16 bit word(s) to write to EEPROM
- *
- * Reads 16 bit word(s) from EEPROM through bit-bang method
- **/
-s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- s32 status = 0;
- u16 i, count;
-
- hw->eeprom.ops.init_params(hw);
-
- if (words == 0) {
- status = IXGBE_ERR_INVALID_ARGUMENT;
- goto out;
- }
-
- if (offset + words > hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
-
- /*
- * The EEPROM page size cannot be queried from the chip. We do lazy
- * initialization. It is worth to do that when we write large buffer.
- */
- if ((hw->eeprom.word_page_size == 0) &&
- (words > IXGBE_EEPROM_PAGE_SIZE_MAX))
- ixgbe_detect_eeprom_page_size_generic(hw, offset);
-
- /*
- * We cannot hold synchronization semaphores for too long
- * to avoid other entity starvation. However it is more efficient
- * to read in bursts than synchronizing access for each word.
- */
- for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
- count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
- IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
- status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i,
- count, &data[i]);
-
- if (status != 0)
- break;
- }
-
-out:
- return status;
-}
-
-/**
- * ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be written to
- * @words: number of word(s)
- * @data: 16 bit word(s) to be written to the EEPROM
- *
- * If ixgbe_eeprom_update_checksum is not called after this function, the
- * EEPROM will most likely contain an invalid checksum.
- **/
-static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- s32 status;
- u16 word;
- u16 page_size;
- u16 i;
- u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
-
- /* Prepare the EEPROM for writing */
- status = ixgbe_acquire_eeprom(hw);
-
- if (status == 0) {
- if (ixgbe_ready_eeprom(hw) != 0) {
- ixgbe_release_eeprom(hw);
- status = IXGBE_ERR_EEPROM;
- }
- }
-
- if (status == 0) {
- for (i = 0; i < words; i++) {
- ixgbe_standby_eeprom(hw);
-
- /* Send the WRITE ENABLE command (8 bit opcode ) */
- ixgbe_shift_out_eeprom_bits(hw,
- IXGBE_EEPROM_WREN_OPCODE_SPI,
- IXGBE_EEPROM_OPCODE_BITS);
-
- ixgbe_standby_eeprom(hw);
-
- /*
- * Some SPI eeproms use the 8th address bit embedded
- * in the opcode
- */
- if ((hw->eeprom.address_bits == 8) &&
- ((offset + i) >= 128))
- write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
-
- /* Send the Write command (8-bit opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, write_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
- hw->eeprom.address_bits);
-
- page_size = hw->eeprom.word_page_size;
-
- /* Send the data in burst via SPI*/
- do {
- word = data[i];
- word = (word >> 8) | (word << 8);
- ixgbe_shift_out_eeprom_bits(hw, word, 16);
-
- if (page_size == 0)
- break;
-
- /* do not wrap around page */
- if (((offset + i) & (page_size - 1)) ==
- (page_size - 1))
- break;
- } while (++i < words);
-
- ixgbe_standby_eeprom(hw);
- msleep(10);
- }
- /* Done with writing - release the EEPROM */
- ixgbe_release_eeprom(hw);
- }
-
- return status;
-}
-
-/**
- * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be written to
- * @data: 16 bit word to be written to the EEPROM
- *
- * If ixgbe_eeprom_update_checksum is not called after this function, the
- * EEPROM will most likely contain an invalid checksum.
- **/
-s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
-{
- s32 status;
-
- hw->eeprom.ops.init_params(hw);
-
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
-
- status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
-
-out:
- return status;
-}
-
-/**
- * ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be read
- * @data: read 16 bit words(s) from EEPROM
- * @words: number of word(s)
- *
- * Reads 16 bit word(s) from EEPROM through bit-bang method
- **/
-s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- s32 status = 0;
- u16 i, count;
-
- hw->eeprom.ops.init_params(hw);
-
- if (words == 0) {
- status = IXGBE_ERR_INVALID_ARGUMENT;
- goto out;
- }
-
- if (offset + words > hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
-
- /*
- * We cannot hold synchronization semaphores for too long
- * to avoid other entity starvation. However it is more efficient
- * to read in bursts than synchronizing access for each word.
- */
- for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
- count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
- IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
-
- status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i,
- count, &data[i]);
-
- if (status != 0)
- break;
- }
-
-out:
- return status;
-}
-
-/**
- * ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be read
- * @words: number of word(s)
- * @data: read 16 bit word(s) from EEPROM
- *
- * Reads 16 bit word(s) from EEPROM through bit-bang method
- **/
-static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- s32 status;
- u16 word_in;
- u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
- u16 i;
-
- /* Prepare the EEPROM for reading */
- status = ixgbe_acquire_eeprom(hw);
-
- if (status == 0) {
- if (ixgbe_ready_eeprom(hw) != 0) {
- ixgbe_release_eeprom(hw);
- status = IXGBE_ERR_EEPROM;
- }
- }
-
- if (status == 0) {
- for (i = 0; i < words; i++) {
- ixgbe_standby_eeprom(hw);
- /*
- * Some SPI eeproms use the 8th address bit embedded
- * in the opcode
- */
- if ((hw->eeprom.address_bits == 8) &&
- ((offset + i) >= 128))
- read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
-
- /* Send the READ command (opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, read_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
- hw->eeprom.address_bits);
-
- /* Read the data. */
- word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
- data[i] = (word_in >> 8) | (word_in << 8);
- }
-
- /* End this read operation */
- ixgbe_release_eeprom(hw);
- }
-
- return status;
-}
-
-/**
- * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be read
- * @data: read 16 bit value from EEPROM
- *
- * Reads 16 bit value from EEPROM through bit-bang method
- **/
-s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
- u16 *data)
-{
- s32 status;
-
- hw->eeprom.ops.init_params(hw);
-
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
-
- status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
-
-out:
- return status;
-}
-
-/**
- * ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @words: number of word(s)
- * @data: 16 bit word(s) from the EEPROM
- *
- * Reads a 16 bit word(s) from the EEPROM using the EERD register.
- **/
-s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- u32 eerd;
- s32 status = 0;
- u32 i;
-
- hw->eeprom.ops.init_params(hw);
-
- if (words == 0) {
- status = IXGBE_ERR_INVALID_ARGUMENT;
- goto out;
- }
-
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
-
- for (i = 0; i < words; i++) {
- eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) +
- IXGBE_EEPROM_RW_REG_START;
-
- IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
-
- if (status == 0) {
- data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
- IXGBE_EEPROM_RW_REG_DATA);
- } else {
- hw_dbg(hw, "Eeprom read timed out\n");
- goto out;
- }
- }
-out:
- return status;
-}
-
-/**
- * ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size
- * @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be used as a scratch pad
- *
- * Discover EEPROM page size by writing marching data at given offset.
- * This function is called only when we are writing a new large buffer
- * at given offset so the data would be overwritten anyway.
- **/
-static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
- u16 offset)
-{
- u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX];
- s32 status = 0;
- u16 i;
-
- for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++)
- data[i] = i;
-
- hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX;
- status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset,
- IXGBE_EEPROM_PAGE_SIZE_MAX, data);
- hw->eeprom.word_page_size = 0;
- if (status != 0)
- goto out;
-
- status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
- if (status != 0)
- goto out;
-
- /*
- * When writing in burst more than the actual page size
- * EEPROM address wraps around current page.
- */
- hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
-
- hw_dbg(hw, "Detected EEPROM page size = %d words.",
- hw->eeprom.word_page_size);
-out:
- return status;
-}
-
-/**
- * ixgbe_read_eerd_generic - Read EEPROM word using EERD
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @data: word read from the EEPROM
- *
- * Reads a 16 bit word from the EEPROM using the EERD register.
- **/
-s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
-{
- return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data);
-}
-
-/**
- * ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to write
- * @words: number of word(s)
- * @data: word(s) write to the EEPROM
- *
- * Write a 16 bit word(s) to the EEPROM using the EEWR register.
- **/
-s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- u32 eewr;
- s32 status = 0;
- u16 i;
-
- hw->eeprom.ops.init_params(hw);
-
- if (words == 0) {
- status = IXGBE_ERR_INVALID_ARGUMENT;
- goto out;
- }
-
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
-
- for (i = 0; i < words; i++) {
- eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
- (data[i] << IXGBE_EEPROM_RW_REG_DATA) |
- IXGBE_EEPROM_RW_REG_START;
-
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
- hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
- }
-
- IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
-
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
- hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
- }
- }
-
-out:
- return status;
-}
-
-/**
- * ixgbe_write_eewr_generic - Write EEPROM word using EEWR
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to write
- * @data: word write to the EEPROM
- *
- * Write a 16 bit word to the EEPROM using the EEWR register.
- **/
-s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
-{
- return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data);
-}
-
-/**
- * ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
- * @hw: pointer to hardware structure
- * @ee_reg: EEPROM flag for polling
- *
- * Polls the status bit (bit 1) of the EERD or EEWR to determine when the
- * read or write is done respectively.
- **/
-s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
-{
- u32 i;
- u32 reg;
- s32 status = IXGBE_ERR_EEPROM;
-
- for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) {
- if (ee_reg == IXGBE_NVM_POLL_READ)
- reg = IXGBE_READ_REG(hw, IXGBE_EERD);
- else
- reg = IXGBE_READ_REG(hw, IXGBE_EEWR);
-
- if (reg & IXGBE_EEPROM_RW_REG_DONE) {
- status = 0;
- break;
- }
- udelay(5);
- }
- return status;
-}
-
-/**
- * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
- * @hw: pointer to hardware structure
- *
- * Prepares EEPROM for access using bit-bang method. This function should
- * be called before issuing a command to the EEPROM.
- **/
-static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- u32 eec;
- u32 i;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)
- != 0)
- status = IXGBE_ERR_SWFW_SYNC;
-
- if (status == 0) {
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
-
- /* Request EEPROM Access */
- eec |= IXGBE_EEC_REQ;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
-
- for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) {
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
- if (eec & IXGBE_EEC_GNT)
- break;
- udelay(5);
- }
-
- /* Release if grant not acquired */
- if (!(eec & IXGBE_EEC_GNT)) {
- eec &= ~IXGBE_EEC_REQ;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- hw_dbg(hw, "Could not acquire EEPROM grant\n");
-
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- status = IXGBE_ERR_EEPROM;
- }
-
- /* Setup EEPROM for Read/Write */
- if (status == 0) {
- /* Clear CS and SK */
- eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- IXGBE_WRITE_FLUSH(hw);
- udelay(1);
- }
- }
- return status;
-}
-
-/**
- * ixgbe_get_eeprom_semaphore - Get hardware semaphore
- * @hw: pointer to hardware structure
- *
- * Sets the hardware semaphores so EEPROM access can occur for bit-bang method
- **/
-static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
-{
- s32 status = IXGBE_ERR_EEPROM;
- u32 timeout = 2000;
- u32 i;
- u32 swsm;
-
- /* Get SMBI software semaphore between device drivers first */
- for (i = 0; i < timeout; i++) {
- /*
- * If the SMBI bit is 0 when we read it, then the bit will be
- * set and we have the semaphore
- */
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- if (!(swsm & IXGBE_SWSM_SMBI)) {
- status = 0;
- break;
- }
- udelay(50);
- }
-
- if (i == timeout) {
- hw_dbg(hw, "Driver can't access the Eeprom - SMBI Semaphore "
- "not granted.\n");
- /*
- * this release is particularly important because our attempts
- * above to get the semaphore may have succeeded, and if there
- * was a timeout, we should unconditionally clear the semaphore
- * bits to free the driver to make progress
- */
- ixgbe_release_eeprom_semaphore(hw);
-
- udelay(50);
- /*
- * one last try
- * If the SMBI bit is 0 when we read it, then the bit will be
- * set and we have the semaphore
- */
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- if (!(swsm & IXGBE_SWSM_SMBI))
- status = 0;
- }
-
- /* Now get the semaphore between SW/FW through the SWESMBI bit */
- if (status == 0) {
- for (i = 0; i < timeout; i++) {
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
-
- /* Set the SW EEPROM semaphore bit to request access */
- swsm |= IXGBE_SWSM_SWESMBI;
- IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
-
- /*
- * If we set the bit successfully then we got the
- * semaphore.
- */
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- if (swsm & IXGBE_SWSM_SWESMBI)
- break;
-
- udelay(50);
- }
-
- /*
- * Release semaphores and return error if SW EEPROM semaphore
- * was not granted because we don't have access to the EEPROM
- */
- if (i >= timeout) {
- hw_dbg(hw, "SWESMBI Software EEPROM semaphore "
- "not granted.\n");
- ixgbe_release_eeprom_semaphore(hw);
- status = IXGBE_ERR_EEPROM;
- }
- } else {
- hw_dbg(hw, "Software semaphore SMBI between device drivers "
- "not granted.\n");
- }
-
- return status;
-}
-
-/**
- * ixgbe_release_eeprom_semaphore - Release hardware semaphore
- * @hw: pointer to hardware structure
- *
- * This function clears hardware semaphore bits.
- **/
-static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
-{
- u32 swsm;
-
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
-
- /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */
- swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI);
- IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
- IXGBE_WRITE_FLUSH(hw);
-}
-
-/**
- * ixgbe_ready_eeprom - Polls for EEPROM ready
- * @hw: pointer to hardware structure
- **/
-static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- u16 i;
- u8 spi_stat_reg;
-
- /*
- * Read "Status Register" repeatedly until the LSB is cleared. The
- * EEPROM will signal that the command has been completed by clearing
- * bit 0 of the internal status register. If it's not cleared within
- * 5 milliseconds, then error out.
- */
- for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) {
- ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI,
- IXGBE_EEPROM_OPCODE_BITS);
- spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8);
- if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI))
- break;
-
- udelay(5);
- ixgbe_standby_eeprom(hw);
- };
-
- /*
- * On some parts, SPI write time could vary from 0-20mSec on 3.3V
- * devices (and only 0-5mSec on 5V devices)
- */
- if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) {
- hw_dbg(hw, "SPI EEPROM Status error\n");
- status = IXGBE_ERR_EEPROM;
- }
-
- return status;
-}
-
-/**
- * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
- * @hw: pointer to hardware structure
- **/
-static void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
-{
- u32 eec;
-
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
-
- /* Toggle CS to flush commands */
- eec |= IXGBE_EEC_CS;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- IXGBE_WRITE_FLUSH(hw);
- udelay(1);
- eec &= ~IXGBE_EEC_CS;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- IXGBE_WRITE_FLUSH(hw);
- udelay(1);
-}
-
-/**
- * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM.
- * @hw: pointer to hardware structure
- * @data: data to send to the EEPROM
- * @count: number of bits to shift out
- **/
-static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
- u16 count)
-{
- u32 eec;
- u32 mask;
- u32 i;
-
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
-
- /*
- * Mask is used to shift "count" bits of "data" out to the EEPROM
- * one bit at a time. Determine the starting bit based on count
- */
- mask = 0x01 << (count - 1);
-
- for (i = 0; i < count; i++) {
- /*
- * A "1" is shifted out to the EEPROM by setting bit "DI" to a
- * "1", and then raising and then lowering the clock (the SK
- * bit controls the clock input to the EEPROM). A "0" is
- * shifted out to the EEPROM by setting "DI" to "0" and then
- * raising and then lowering the clock.
- */
- if (data & mask)
- eec |= IXGBE_EEC_DI;
- else
- eec &= ~IXGBE_EEC_DI;
-
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- IXGBE_WRITE_FLUSH(hw);
-
- udelay(1);
-
- ixgbe_raise_eeprom_clk(hw, &eec);
- ixgbe_lower_eeprom_clk(hw, &eec);
-
- /*
- * Shift mask to signify next bit of data to shift in to the
- * EEPROM
- */
- mask = mask >> 1;
- };
-
- /* We leave the "DI" bit set to "0" when we leave this routine. */
- eec &= ~IXGBE_EEC_DI;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- IXGBE_WRITE_FLUSH(hw);
-}
-
-/**
- * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
- * @hw: pointer to hardware structure
- **/
-static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
-{
- u32 eec;
- u32 i;
- u16 data = 0;
-
- /*
- * In order to read a register from the EEPROM, we need to shift
- * 'count' bits in from the EEPROM. Bits are "shifted in" by raising
- * the clock input to the EEPROM (setting the SK bit), and then reading
- * the value of the "DO" bit. During this "shifting in" process the
- * "DI" bit should always be clear.
- */
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
-
- eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI);
-
- for (i = 0; i < count; i++) {
- data = data << 1;
- ixgbe_raise_eeprom_clk(hw, &eec);
-
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
-
- eec &= ~(IXGBE_EEC_DI);
- if (eec & IXGBE_EEC_DO)
- data |= 1;
-
- ixgbe_lower_eeprom_clk(hw, &eec);
- }
-
- return data;
-}
-
-/**
- * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input.
- * @hw: pointer to hardware structure
- * @eec: EEC register's current value
- **/
-static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
-{
- /*
- * Raise the clock input to the EEPROM
- * (setting the SK bit), then delay
- */
- *eec = *eec | IXGBE_EEC_SK;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
- IXGBE_WRITE_FLUSH(hw);
- udelay(1);
-}
-
-/**
- * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input.
- * @hw: pointer to hardware structure
- * @eecd: EECD's current value
- **/
-static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
-{
- /*
- * Lower the clock input to the EEPROM (clearing the SK bit), then
- * delay
- */
- *eec = *eec & ~IXGBE_EEC_SK;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
- IXGBE_WRITE_FLUSH(hw);
- udelay(1);
-}
-
-/**
- * ixgbe_release_eeprom - Release EEPROM, release semaphores
- * @hw: pointer to hardware structure
- **/
-static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
-{
- u32 eec;
-
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
-
- eec |= IXGBE_EEC_CS; /* Pull CS high */
- eec &= ~IXGBE_EEC_SK; /* Lower SCK */
-
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- IXGBE_WRITE_FLUSH(hw);
-
- udelay(1);
-
- /* Stop requesting EEPROM access */
- eec &= ~IXGBE_EEC_REQ;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
-
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
-
- /* Delay before attempt to obtain semaphore again to allow FW access */
- msleep(hw->eeprom.semaphore_delay);
-}
-
-/**
- * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
- * @hw: pointer to hardware structure
- **/
-u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
-{
- u16 i;
- u16 j;
- u16 checksum = 0;
- u16 length = 0;
- u16 pointer = 0;
- u16 word = 0;
-
- /* Include 0x0-0x3F in the checksum */
- for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
- if (hw->eeprom.ops.read(hw, i, &word) != 0) {
- hw_dbg(hw, "EEPROM read failed\n");
- break;
- }
- checksum += word;
- }
-
- /* Include all data from pointers except for the fw pointer */
- for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
- hw->eeprom.ops.read(hw, i, &pointer);
-
- /* Make sure the pointer seems valid */
- if (pointer != 0xFFFF && pointer != 0) {
- hw->eeprom.ops.read(hw, pointer, &length);
-
- if (length != 0xFFFF && length != 0) {
- for (j = pointer+1; j <= pointer+length; j++) {
- hw->eeprom.ops.read(hw, j, &word);
- checksum += word;
- }
- }
- }
- }
-
- checksum = (u16)IXGBE_EEPROM_SUM - checksum;
-
- return checksum;
-}
-
-/**
- * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum
- * @hw: pointer to hardware structure
- * @checksum_val: calculated checksum
- *
- * Performs checksum calculation and validates the EEPROM checksum. If the
- * caller does not need checksum_val, the value can be NULL.
- **/
-s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
- u16 *checksum_val)
-{
- s32 status;
- u16 checksum;
- u16 read_checksum = 0;
-
- /*
- * Read the first word from the EEPROM. If this times out or fails, do
- * not continue or we could be in for a very long wait while every
- * EEPROM read fails
- */
- status = hw->eeprom.ops.read(hw, 0, &checksum);
-
- if (status == 0) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
-
- hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
-
- /*
- * Verify read checksum from EEPROM is the same as
- * calculated checksum
- */
- if (read_checksum != checksum)
- status = IXGBE_ERR_EEPROM_CHECKSUM;
-
- /* If the user cares, return the calculated checksum */
- if (checksum_val)
- *checksum_val = checksum;
- } else {
- hw_dbg(hw, "EEPROM read failed\n");
- }
-
- return status;
-}
-
-/**
- * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum
- * @hw: pointer to hardware structure
- **/
-s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
-{
- s32 status;
- u16 checksum;
-
- /*
- * Read the first word from the EEPROM. If this times out or fails, do
- * not continue or we could be in for a very long wait while every
- * EEPROM read fails
- */
- status = hw->eeprom.ops.read(hw, 0, &checksum);
-
- if (status == 0) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
- status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
- checksum);
- } else {
- hw_dbg(hw, "EEPROM read failed\n");
- }
-
- return status;
-}
-
-/**
- * ixgbe_validate_mac_addr - Validate MAC address
- * @mac_addr: pointer to MAC address.
- *
- * Tests a MAC address to ensure it is a valid Individual Address
- **/
-s32 ixgbe_validate_mac_addr(u8 *mac_addr)
-{
- s32 status = 0;
-
- /* Make sure it is not a multicast address */
- if (IXGBE_IS_MULTICAST(mac_addr)) {
- hw_dbg(hw, "MAC address is multicast\n");
- status = IXGBE_ERR_INVALID_MAC_ADDR;
- /* Not a broadcast address */
- } else if (IXGBE_IS_BROADCAST(mac_addr)) {
- hw_dbg(hw, "MAC address is broadcast\n");
- status = IXGBE_ERR_INVALID_MAC_ADDR;
- /* Reject the zero address */
- } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
- mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
- hw_dbg(hw, "MAC address is all zeros\n");
- status = IXGBE_ERR_INVALID_MAC_ADDR;
- }
- return status;
-}
-
-/**
- * ixgbe_set_rar_generic - Set Rx address register
- * @hw: pointer to hardware structure
- * @index: Receive address register to write
- * @addr: Address to put into receive address register
- * @vmdq: VMDq "set" or "pool" index
- * @enable_addr: set flag that address is active
- *
- * Puts an ethernet address into a receive address register.
- **/
-s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
- u32 enable_addr)
-{
- u32 rar_low, rar_high;
- u32 rar_entries = hw->mac.num_rar_entries;
-
- /* Make sure we are using a valid rar index range */
- if (index >= rar_entries) {
- hw_dbg(hw, "RAR index %d is out of range.\n", index);
- return IXGBE_ERR_INVALID_ARGUMENT;
- }
-
- /* setup VMDq pool selection before this RAR gets enabled */
- hw->mac.ops.set_vmdq(hw, index, vmdq);
-
- /*
- * HW expects these in little endian so we reverse the byte
- * order from network order (big endian) to little endian
- */
- rar_low = ((u32)addr[0] |
- ((u32)addr[1] << 8) |
- ((u32)addr[2] << 16) |
- ((u32)addr[3] << 24));
- /*
- * Some parts put the VMDq setting in the extra RAH bits,
- * so save everything except the lower 16 bits that hold part
- * of the address and the address valid bit.
- */
- rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
- rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
- rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8));
-
- if (enable_addr != 0)
- rar_high |= IXGBE_RAH_AV;
-
- IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
- IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
-
- return 0;
-}
-
-/**
- * ixgbe_clear_rar_generic - Remove Rx address register
- * @hw: pointer to hardware structure
- * @index: Receive address register to write
- *
- * Clears an ethernet address from a receive address register.
- **/
-s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
-{
- u32 rar_high;
- u32 rar_entries = hw->mac.num_rar_entries;
-
- /* Make sure we are using a valid rar index range */
- if (index >= rar_entries) {
- hw_dbg(hw, "RAR index %d is out of range.\n", index);
- return IXGBE_ERR_INVALID_ARGUMENT;
- }
-
- /*
- * Some parts put the VMDq setting in the extra RAH bits,
- * so save everything except the lower 16 bits that hold part
- * of the address and the address valid bit.
- */
- rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
- rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
-
- IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
- IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
-
- /* clear VMDq pool/queue selection for this RAR */
- hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
-
- return 0;
-}
-
-/**
- * ixgbe_init_rx_addrs_generic - Initializes receive address filters.
- * @hw: pointer to hardware structure
- *
- * Places the MAC address in receive address register 0 and clears the rest
- * of the receive address registers. Clears the multicast table. Assumes
- * the receiver is in reset when the routine is called.
- **/
-s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
-{
- u32 i;
- u32 rar_entries = hw->mac.num_rar_entries;
-
- /*
- * If the current mac address is valid, assume it is a software override
- * to the permanent address.
- * Otherwise, use the permanent address from the eeprom.
- */
- if (ixgbe_validate_mac_addr(hw->mac.addr) ==
- IXGBE_ERR_INVALID_MAC_ADDR) {
- /* Get the MAC address from the RAR0 for later reference */
- hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
-
- hw_dbg(hw, " Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
- hw->mac.addr[0], hw->mac.addr[1],
- hw->mac.addr[2]);
- hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
- hw->mac.addr[4], hw->mac.addr[5]);
- } else {
- /* Setup the receive address. */
- hw_dbg(hw, "Overriding MAC Address in RAR[0]\n");
- hw_dbg(hw, " New MAC Addr =%.2X %.2X %.2X ",
- hw->mac.addr[0], hw->mac.addr[1],
- hw->mac.addr[2]);
- hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
- hw->mac.addr[4], hw->mac.addr[5]);
-
- hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
-
- /* clear VMDq pool/queue selection for RAR 0 */
- hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
- }
- hw->addr_ctrl.overflow_promisc = 0;
-
- hw->addr_ctrl.rar_used_count = 1;
-
- /* Zero out the other receive addresses. */
- hw_dbg(hw, "Clearing RAR[1-%d]\n", rar_entries - 1);
- for (i = 1; i < rar_entries; i++) {
- IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
- IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
- }
-
- /* Clear the MTA */
- hw->addr_ctrl.mta_in_use = 0;
- IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
-
- hw_dbg(hw, " Clearing MTA\n");
- for (i = 0; i < hw->mac.mcft_size; i++)
- IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
-
- ixgbe_init_uta_tables(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_add_uc_addr - Adds a secondary unicast address.
- * @hw: pointer to hardware structure
- * @addr: new address
- *
- * Adds it to unused receive address register or goes into promiscuous mode.
- **/
-void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
-{
- u32 rar_entries = hw->mac.num_rar_entries;
- u32 rar;
-
- hw_dbg(hw, " UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n",
- addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
-
- /*
- * Place this address in the RAR if there is room,
- * else put the controller into promiscuous mode
- */
- if (hw->addr_ctrl.rar_used_count < rar_entries) {
- rar = hw->addr_ctrl.rar_used_count;
- hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
- hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar);
- hw->addr_ctrl.rar_used_count++;
- } else {
- hw->addr_ctrl.overflow_promisc++;
- }
-
- hw_dbg(hw, "ixgbe_add_uc_addr Complete\n");
-}
-
-/**
- * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
- * @hw: pointer to hardware structure
- * @addr_list: the list of new addresses
- * @addr_count: number of addresses
- * @next: iterator function to walk the address list
- *
- * The given list replaces any existing list. Clears the secondary addrs from
- * receive address registers. Uses unused receive address registers for the
- * first secondary addresses, and falls back to promiscuous mode as needed.
- *
- * Drivers using secondary unicast addresses must set user_set_promisc when
- * manually putting the device into promiscuous mode.
- **/
-s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
- u32 addr_count, ixgbe_mc_addr_itr next)
-{
- u8 *addr;
- u32 i;
- u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
- u32 uc_addr_in_use;
- u32 fctrl;
- u32 vmdq;
-
- /*
- * Clear accounting of old secondary address list,
- * don't count RAR[0]
- */
- uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1;
- hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
- hw->addr_ctrl.overflow_promisc = 0;
-
- /* Zero out the other receive addresses */
- hw_dbg(hw, "Clearing RAR[1-%d]\n", uc_addr_in_use+1);
- for (i = 0; i < uc_addr_in_use; i++) {
- IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0);
- IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0);
- }
-
- /* Add the new addresses */
- for (i = 0; i < addr_count; i++) {
- hw_dbg(hw, " Adding the secondary addresses:\n");
- addr = next(hw, &addr_list, &vmdq);
- ixgbe_add_uc_addr(hw, addr, vmdq);
- }
-
- if (hw->addr_ctrl.overflow_promisc) {
- /* enable promisc if not already in overflow or set by user */
- if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
- hw_dbg(hw, " Entering address overflow promisc mode\n");
- fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- fctrl |= IXGBE_FCTRL_UPE;
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
- }
- } else {
- /* only disable if set by overflow, not by user */
- if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
- hw_dbg(hw, " Leaving address overflow promisc mode\n");
- fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- fctrl &= ~IXGBE_FCTRL_UPE;
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
- }
- }
-
- hw_dbg(hw, "ixgbe_update_uc_addr_list_generic Complete\n");
- return 0;
-}
-
-/**
- * ixgbe_mta_vector - Determines bit-vector in multicast table to set
- * @hw: pointer to hardware structure
- * @mc_addr: the multicast address
- *
- * Extracts the 12 bits, from a multicast address, to determine which
- * bit-vector to set in the multicast table. The hardware uses 12 bits, from
- * incoming rx multicast addresses, to determine the bit-vector to check in
- * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
- * by the MO field of the MCSTCTRL. The MO field is set during initialization
- * to mc_filter_type.
- **/
-static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
-{
- u32 vector = 0;
-
- switch (hw->mac.mc_filter_type) {
- case 0: /* use bits [47:36] of the address */
- vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
- break;
- case 1: /* use bits [46:35] of the address */
- vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
- break;
- case 2: /* use bits [45:34] of the address */
- vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
- break;
- case 3: /* use bits [43:32] of the address */
- vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
- break;
- default: /* Invalid mc_filter_type */
- hw_dbg(hw, "MC filter type param set incorrectly\n");
- break;
- }
-
- /* vector can only be 12-bits or boundary will be exceeded */
- vector &= 0xFFF;
- return vector;
-}
-
-/**
- * ixgbe_set_mta - Set bit-vector in multicast table
- * @hw: pointer to hardware structure
- * @hash_value: Multicast address hash value
- *
- * Sets the bit-vector in the multicast table.
- **/
-void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
-{
- u32 vector;
- u32 vector_bit;
- u32 vector_reg;
-
- hw->addr_ctrl.mta_in_use++;
-
- vector = ixgbe_mta_vector(hw, mc_addr);
- hw_dbg(hw, " bit-vector = 0x%03X\n", vector);
-
- /*
- * The MTA is a register array of 128 32-bit registers. It is treated
- * like an array of 4096 bits. We want to set bit
- * BitArray[vector_value]. So we figure out what register the bit is
- * in, read it, OR in the new bit, then write back the new value. The
- * register is determined by the upper 7 bits of the vector value and
- * the bit within that register are determined by the lower 5 bits of
- * the value.
- */
- vector_reg = (vector >> 5) & 0x7F;
- vector_bit = vector & 0x1F;
- hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit);
-}
-
-/**
- * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
- * @hw: pointer to hardware structure
- * @mc_addr_list: the list of new multicast addresses
- * @mc_addr_count: number of addresses
- * @next: iterator function to walk the multicast address list
- * @clear: flag, when set clears the table beforehand
- *
- * When the clear flag is set, the given list replaces any existing list.
- * Hashes the given addresses into the multicast table.
- **/
-s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, ixgbe_mc_addr_itr next,
- bool clear)
-{
- u32 i;
- u32 vmdq;
-
- /*
- * Set the new number of MC addresses that we are being requested to
- * use.
- */
- hw->addr_ctrl.num_mc_addrs = mc_addr_count;
- hw->addr_ctrl.mta_in_use = 0;
-
- /* Clear mta_shadow */
- if (clear) {
- hw_dbg(hw, " Clearing MTA\n");
- memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
- }
-
- /* Update mta_shadow */
- for (i = 0; i < mc_addr_count; i++) {
- hw_dbg(hw, " Adding the multicast addresses:\n");
- ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq));
- }
-
- /* Enable mta */
- for (i = 0; i < hw->mac.mcft_size; i++)
- IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i,
- hw->mac.mta_shadow[i]);
-
- if (hw->addr_ctrl.mta_in_use > 0)
- IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
- IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
-
- hw_dbg(hw, "ixgbe_update_mc_addr_list_generic Complete\n");
- return 0;
-}
-
-/**
- * ixgbe_enable_mc_generic - Enable multicast address in RAR
- * @hw: pointer to hardware structure
- *
- * Enables multicast address in RAR and the use of the multicast hash table.
- **/
-s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
-{
- struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
-
- if (a->mta_in_use > 0)
- IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
- hw->mac.mc_filter_type);
-
- return 0;
-}
-
-/**
- * ixgbe_disable_mc_generic - Disable multicast address in RAR
- * @hw: pointer to hardware structure
- *
- * Disables multicast address in RAR and the use of the multicast hash table.
- **/
-s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
-{
- struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
-
- if (a->mta_in_use > 0)
- IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
-
- return 0;
-}
-
-/**
- * ixgbe_fc_enable_generic - Enable flow control
- * @hw: pointer to hardware structure
- *
- * Enable flow control according to the current settings.
- **/
-s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
-{
- s32 ret_val = 0;
- u32 mflcn_reg, fccfg_reg;
- u32 reg;
- u32 fcrtl, fcrth;
- int i;
-
- /* Validate the water mark configuration */
- if (!hw->fc.pause_time) {
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
-
- /* Low water mark of zero causes XOFF floods */
- for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
- if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
- hw->fc.high_water[i]) {
- if (!hw->fc.low_water[i] ||
- hw->fc.low_water[i] >= hw->fc.high_water[i]) {
- hw_dbg(hw, "Invalid water mark configuration\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
- }
- }
-
- /* Negotiate the fc mode to use */
- ixgbe_fc_autoneg(hw);
-
- /* Disable any previous flow control settings */
- mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
- mflcn_reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
-
- fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
- fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
-
- /*
- * The possible values of fc.current_mode are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames,
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but
- * we do not support receiving pause frames).
- * 3: Both Rx and Tx flow control (symmetric) are enabled.
- * other: Invalid.
- */
- switch (hw->fc.current_mode) {
- case ixgbe_fc_none:
- /*
- * Flow control is disabled by software override or autoneg.
- * The code below will actually disable it in the HW.
- */
- break;
- case ixgbe_fc_rx_pause:
- /*
- * Rx Flow control is enabled and Tx Flow control is
- * disabled by software override. Since there really
- * isn't a way to advertise that we are capable of RX
- * Pause ONLY, we will advertise that we support both
- * symmetric and asymmetric Rx PAUSE. Later, we will
- * disable the adapter's ability to send PAUSE frames.
- */
- mflcn_reg |= IXGBE_MFLCN_RFCE;
- break;
- case ixgbe_fc_tx_pause:
- /*
- * Tx Flow control is enabled, and Rx Flow control is
- * disabled by software override.
- */
- fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
- break;
- case ixgbe_fc_full:
- /* Flow control (both Rx and Tx) is enabled by SW override. */
- mflcn_reg |= IXGBE_MFLCN_RFCE;
- fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
- break;
- default:
- hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = IXGBE_ERR_CONFIG;
- goto out;
- break;
- }
-
- /* Set 802.3x based flow control settings. */
- mflcn_reg |= IXGBE_MFLCN_DPF;
- IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
- IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
-
-
- /* Set up and enable Rx high/low water mark thresholds, enable XON. */
- for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
- if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
- hw->fc.high_water[i]) {
- fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
- fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
- } else {
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
- /*
- * In order to prevent Tx hangs when the internal Tx
- * switch is enabled we must set the high water mark
- * to the maximum FCRTH value. This allows the Tx
- * switch to function even under heavy Rx workloads.
- */
- fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
- }
-
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth);
- }
-
- /* Configure pause time (2 TCs per register) */
- reg = hw->fc.pause_time * 0x00010001;
- for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
-
- /* Configure flow control refresh threshold value */
- IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_negotiate_fc - Negotiate flow control
- * @hw: pointer to hardware structure
- * @adv_reg: flow control advertised settings
- * @lp_reg: link partner's flow control settings
- * @adv_sym: symmetric pause bit in advertisement
- * @adv_asm: asymmetric pause bit in advertisement
- * @lp_sym: symmetric pause bit in link partner advertisement
- * @lp_asm: asymmetric pause bit in link partner advertisement
- *
- * Find the intersection between advertised settings and link partner's
- * advertised settings
- **/
-static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
- u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
-{
- if (!adv_reg || !lp_reg)
- return IXGBE_ERR_FC_NOT_NEGOTIATED;
-
- if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) {
- /*
- * Now we need to check if the user selected Rx ONLY
- * of pause frames. In this case, we had to advertise
- * FULL flow control because we could not advertise RX
- * ONLY. Hence, we must now check to see if we need to
- * turn OFF the TRANSMISSION of PAUSE frames.
- */
- if (hw->fc.requested_mode == ixgbe_fc_full) {
- hw->fc.current_mode = ixgbe_fc_full;
- hw_dbg(hw, "Flow Control = FULL.\n");
- } else {
- hw->fc.current_mode = ixgbe_fc_rx_pause;
- hw_dbg(hw, "Flow Control=RX PAUSE frames only\n");
- }
- } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) &&
- (lp_reg & lp_sym) && (lp_reg & lp_asm)) {
- hw->fc.current_mode = ixgbe_fc_tx_pause;
- hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
- } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) &&
- !(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
- hw->fc.current_mode = ixgbe_fc_rx_pause;
- hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
- } else {
- hw->fc.current_mode = ixgbe_fc_none;
- hw_dbg(hw, "Flow Control = NONE.\n");
- }
- return 0;
-}
-
-/**
- * ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber
- * @hw: pointer to hardware structure
- *
- * Enable flow control according on 1 gig fiber.
- **/
-static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
-{
- u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
- s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
-
- /*
- * On multispeed fiber at 1g, bail out if
- * - link is up but AN did not complete, or if
- * - link is up and AN completed but timed out
- */
-
- linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
- if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
- (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1))
- goto out;
-
- pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
- pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
-
- ret_val = ixgbe_negotiate_fc(hw, pcs_anadv_reg,
- pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE,
- IXGBE_PCS1GANA_ASM_PAUSE,
- IXGBE_PCS1GANA_SYM_PAUSE,
- IXGBE_PCS1GANA_ASM_PAUSE);
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37
- * @hw: pointer to hardware structure
- *
- * Enable flow control according to IEEE clause 37.
- **/
-static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
-{
- u32 links2, anlp1_reg, autoc_reg, links;
- s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
-
- /*
- * On backplane, bail out if
- * - backplane autoneg was not completed, or if
- * - we are 82599 and link partner is not AN enabled
- */
- links = IXGBE_READ_REG(hw, IXGBE_LINKS);
- if ((links & IXGBE_LINKS_KX_AN_COMP) == 0)
- goto out;
-
- if (hw->mac.type == ixgbe_mac_82599EB) {
- links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
- if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0)
- goto out;
- }
- /*
- * Read the 10g AN autoc and LP ability registers and resolve
- * local flow control settings accordingly
- */
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
-
- ret_val = ixgbe_negotiate_fc(hw, autoc_reg,
- anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE,
- IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE);
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37
- * @hw: pointer to hardware structure
- *
- * Enable flow control according to IEEE clause 37.
- **/
-static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
-{
- u16 technology_ability_reg = 0;
- u16 lp_technology_ability_reg = 0;
-
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &technology_ability_reg);
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_LP,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &lp_technology_ability_reg);
-
- return ixgbe_negotiate_fc(hw, (u32)technology_ability_reg,
- (u32)lp_technology_ability_reg,
- IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE,
- IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE);
-}
-
-/**
- * ixgbe_fc_autoneg - Configure flow control
- * @hw: pointer to hardware structure
- *
- * Compares our advertised flow control capabilities to those advertised by
- * our link partner, and determines the proper flow control mode to use.
- **/
-void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
-{
- s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
- ixgbe_link_speed speed;
- bool link_up;
-
- /*
- * AN should have completed when the cable was plugged in.
- * Look for reasons to bail out. Bail out if:
- * - FC autoneg is disabled, or if
- * - link is not up.
- */
- if (hw->fc.disable_fc_autoneg)
- goto out;
-
- hw->mac.ops.check_link(hw, &speed, &link_up, false);
- if (!link_up)
- goto out;
-
- switch (hw->phy.media_type) {
- /* Autoneg flow control on fiber adapters */
- case ixgbe_media_type_fiber:
- if (speed == IXGBE_LINK_SPEED_1GB_FULL)
- ret_val = ixgbe_fc_autoneg_fiber(hw);
- break;
-
- /* Autoneg flow control on backplane adapters */
- case ixgbe_media_type_backplane:
- ret_val = ixgbe_fc_autoneg_backplane(hw);
- break;
-
- /* Autoneg flow control on copper adapters */
- case ixgbe_media_type_copper:
- if (ixgbe_device_supports_autoneg_fc(hw) == 0)
- ret_val = ixgbe_fc_autoneg_copper(hw);
- break;
-
- default:
- break;
- }
-
-out:
- if (ret_val == 0) {
- hw->fc.fc_was_autonegged = true;
- } else {
- hw->fc.fc_was_autonegged = false;
- hw->fc.current_mode = hw->fc.requested_mode;
- }
-}
-
-/**
- * ixgbe_disable_pcie_master - Disable PCI-express master access
- * @hw: pointer to hardware structure
- *
- * Disables PCI-Express master access and verifies there are no pending
- * requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable
- * bit hasn't caused the master requests to be disabled, else 0
- * is returned signifying master requests disabled.
- **/
-s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- u32 i;
-
- /* Always set this bit to ensure any future transactions are blocked */
- IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS);
-
- /* Exit if master requets are blocked */
- if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
- goto out;
-
- /* Poll for master request bit to clear */
- for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
- udelay(100);
- if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
- goto out;
- }
-
- /*
- * Two consecutive resets are required via CTRL.RST per datasheet
- * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine
- * of this need. The first reset prevents new master requests from
- * being issued by our device. We then must wait 1usec or more for any
- * remaining completions from the PCIe bus to trickle in, and then reset
- * again to clear out any effects they may have had on our device.
- */
- hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n");
- hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
-
- /*
- * Before proceeding, make sure that the PCIe block does not have
- * transactions pending.
- */
- for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
- udelay(100);
- if (!(IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS) &
- IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
- goto out;
- }
-
- hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n");
- status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
-
-out:
- return status;
-}
-
-/**
- * ixgbe_acquire_swfw_sync - Acquire SWFW semaphore
- * @hw: pointer to hardware structure
- * @mask: Mask to specify which semaphore to acquire
- *
- * Acquires the SWFW semaphore through the GSSR register for the specified
- * function (CSR, PHY0, PHY1, EEPROM, Flash)
- **/
-s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
-{
- u32 gssr;
- u32 swmask = mask;
- u32 fwmask = mask << 5;
- s32 timeout = 200;
-
- while (timeout) {
- /*
- * SW EEPROM semaphore bit is used for access to all
- * SW_FW_SYNC/GSSR bits (not just EEPROM)
- */
- if (ixgbe_get_eeprom_semaphore(hw))
- return IXGBE_ERR_SWFW_SYNC;
-
- gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
- if (!(gssr & (fwmask | swmask)))
- break;
-
- /*
- * Firmware currently using resource (fwmask) or other software
- * thread currently using resource (swmask)
- */
- ixgbe_release_eeprom_semaphore(hw);
- msleep(5);
- timeout--;
- }
-
- if (!timeout) {
- hw_dbg(hw, "Driver can't access resource, SW_FW_SYNC timeout.\n");
- return IXGBE_ERR_SWFW_SYNC;
- }
-
- gssr |= swmask;
- IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
-
- ixgbe_release_eeprom_semaphore(hw);
- return 0;
-}
-
-/**
- * ixgbe_release_swfw_sync - Release SWFW semaphore
- * @hw: pointer to hardware structure
- * @mask: Mask to specify which semaphore to release
- *
- * Releases the SWFW semaphore through the GSSR register for the specified
- * function (CSR, PHY0, PHY1, EEPROM, Flash)
- **/
-void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
-{
- u32 gssr;
- u32 swmask = mask;
-
- ixgbe_get_eeprom_semaphore(hw);
-
- gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
- gssr &= ~swmask;
- IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
-
- ixgbe_release_eeprom_semaphore(hw);
-}
-
-/**
- * ixgbe_disable_sec_rx_path_generic - Stops the receive data path
- * @hw: pointer to hardware structure
- *
- * Stops the receive data path and waits for the HW to internally empty
- * the Rx security block
- **/
-s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw)
-{
-#define IXGBE_MAX_SECRX_POLL 40
-
- int i;
- int secrxreg;
-
- secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
- secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
- IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
- for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
- secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
- if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY)
- break;
- else
- /* Use interrupt-safe sleep just in case */
- udelay(1000);
- }
-
- /* For informational purposes only */
- if (i >= IXGBE_MAX_SECRX_POLL)
- hw_dbg(hw, "Rx unit being enabled before security "
- "path fully disabled. Continuing with init.\n");
-
- return 0;
-}
-
-/**
- * ixgbe_enable_sec_rx_path_generic - Enables the receive data path
- * @hw: pointer to hardware structure
- *
- * Enables the receive data path.
- **/
-s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw)
-{
- int secrxreg;
-
- secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
- secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
- IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
- IXGBE_WRITE_FLUSH(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
- * @hw: pointer to hardware structure
- * @regval: register value to write to RXCTRL
- *
- * Enables the Rx DMA unit
- **/
-s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
-{
- IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
-
- return 0;
-}
-
-/**
- * ixgbe_blink_led_start_generic - Blink LED based on index.
- * @hw: pointer to hardware structure
- * @index: led number to blink
- **/
-s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
-{
- ixgbe_link_speed speed = 0;
- bool link_up = 0;
- u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
- /*
- * Link must be up to auto-blink the LEDs;
- * Force it if link is down.
- */
- hw->mac.ops.check_link(hw, &speed, &link_up, false);
-
- if (!link_up) {
- autoc_reg |= IXGBE_AUTOC_AN_RESTART;
- autoc_reg |= IXGBE_AUTOC_FLU;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
- IXGBE_WRITE_FLUSH(hw);
- msleep(10);
- }
-
- led_reg &= ~IXGBE_LED_MODE_MASK(index);
- led_reg |= IXGBE_LED_BLINK(index);
- IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
- IXGBE_WRITE_FLUSH(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
- * @hw: pointer to hardware structure
- * @index: led number to stop blinking
- **/
-s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
-{
- u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
- autoc_reg &= ~IXGBE_AUTOC_FLU;
- autoc_reg |= IXGBE_AUTOC_AN_RESTART;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-
- led_reg &= ~IXGBE_LED_MODE_MASK(index);
- led_reg &= ~IXGBE_LED_BLINK(index);
- led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
- IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
- IXGBE_WRITE_FLUSH(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM
- * @hw: pointer to hardware structure
- * @san_mac_offset: SAN MAC address offset
- *
- * This function will read the EEPROM location for the SAN MAC address
- * pointer, and returns the value at that location. This is used in both
- * get and set mac_addr routines.
- **/
-static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw,
- u16 *san_mac_offset)
-{
- /*
- * First read the EEPROM pointer to see if the MAC addresses are
- * available.
- */
- hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset);
-
- return 0;
-}
-
-/**
- * ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM
- * @hw: pointer to hardware structure
- * @san_mac_addr: SAN MAC address
- *
- * Reads the SAN MAC address from the EEPROM, if it's available. This is
- * per-port, so set_lan_id() must be called before reading the addresses.
- * set_lan_id() is called by identify_sfp(), but this cannot be relied
- * upon for non-SFP connections, so we must call it here.
- **/
-s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
-{
- u16 san_mac_data, san_mac_offset;
- u8 i;
-
- /*
- * First read the EEPROM pointer to see if the MAC addresses are
- * available. If they're not, no point in calling set_lan_id() here.
- */
- ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
-
- if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) {
- /*
- * No addresses available in this EEPROM. It's not an
- * error though, so just wipe the local address and return.
- */
- for (i = 0; i < 6; i++)
- san_mac_addr[i] = 0xFF;
-
- goto san_mac_addr_out;
- }
-
- /* make sure we know which port we need to program */
- hw->mac.ops.set_lan_id(hw);
- /* apply the port offset to the address offset */
- (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
- (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
- for (i = 0; i < 3; i++) {
- hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data);
- san_mac_addr[i * 2] = (u8)(san_mac_data);
- san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8);
- san_mac_offset++;
- }
-
-san_mac_addr_out:
- return 0;
-}
-
-/**
- * ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM
- * @hw: pointer to hardware structure
- * @san_mac_addr: SAN MAC address
- *
- * Write a SAN MAC address to the EEPROM.
- **/
-s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
-{
- s32 status = 0;
- u16 san_mac_data, san_mac_offset;
- u8 i;
-
- /* Look for SAN mac address pointer. If not defined, return */
- ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset);
-
- if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) {
- status = IXGBE_ERR_NO_SAN_ADDR_PTR;
- goto san_mac_addr_out;
- }
-
- /* Make sure we know which port we need to write */
- hw->mac.ops.set_lan_id(hw);
- /* Apply the port offset to the address offset */
- (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
- (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
-
- for (i = 0; i < 3; i++) {
- san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8);
- san_mac_data |= (u16)(san_mac_addr[i * 2]);
- hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data);
- san_mac_offset++;
- }
-
-san_mac_addr_out:
- return status;
-}
-
-/**
- * ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count
- * @hw: pointer to hardware structure
- *
- * Read PCIe configuration space, and get the MSI-X vector count from
- * the capabilities table.
- **/
-u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
-{
- u16 msix_count = 1;
- u16 max_msix_count;
- u16 pcie_offset;
-
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- pcie_offset = IXGBE_PCIE_MSIX_82598_CAPS;
- max_msix_count = IXGBE_MAX_MSIX_VECTORS_82598;
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS;
- max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599;
- break;
- default:
- return msix_count;
- }
-
- msix_count = IXGBE_READ_PCIE_WORD(hw, pcie_offset);
- msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
-
- /* MSI-X count is zero-based in HW */
- msix_count++;
-
- if (msix_count > max_msix_count)
- msix_count = max_msix_count;
-
- return msix_count;
-}
-
-/**
- * ixgbe_insert_mac_addr_generic - Find a RAR for this mac address
- * @hw: pointer to hardware structure
- * @addr: Address to put into receive address register
- * @vmdq: VMDq pool to assign
- *
- * Puts an ethernet address into a receive address register, or
- * finds the rar that it is already in; adds to the pool list
- **/
-s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
-{
- static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF;
- u32 first_empty_rar = NO_EMPTY_RAR_FOUND;
- u32 rar;
- u32 rar_low, rar_high;
- u32 addr_low, addr_high;
-
- /* swap bytes for HW little endian */
- addr_low = addr[0] | (addr[1] << 8)
- | (addr[2] << 16)
- | (addr[3] << 24);
- addr_high = addr[4] | (addr[5] << 8);
-
- /*
- * Either find the mac_id in rar or find the first empty space.
- * rar_highwater points to just after the highest currently used
- * rar in order to shorten the search. It grows when we add a new
- * rar to the top.
- */
- for (rar = 0; rar < hw->mac.rar_highwater; rar++) {
- rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
-
- if (((IXGBE_RAH_AV & rar_high) == 0)
- && first_empty_rar == NO_EMPTY_RAR_FOUND) {
- first_empty_rar = rar;
- } else if ((rar_high & 0xFFFF) == addr_high) {
- rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar));
- if (rar_low == addr_low)
- break; /* found it already in the rars */
- }
- }
-
- if (rar < hw->mac.rar_highwater) {
- /* already there so just add to the pool bits */
- ixgbe_set_vmdq(hw, rar, vmdq);
- } else if (first_empty_rar != NO_EMPTY_RAR_FOUND) {
- /* stick it into first empty RAR slot we found */
- rar = first_empty_rar;
- ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
- } else if (rar == hw->mac.rar_highwater) {
- /* add it to the top of the list and inc the highwater mark */
- ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
- hw->mac.rar_highwater++;
- } else if (rar >= hw->mac.num_rar_entries) {
- return IXGBE_ERR_INVALID_MAC_ADDR;
- }
-
- /*
- * If we found rar[0], make sure the default pool bit (we use pool 0)
- * remains cleared to be sure default pool packets will get delivered
- */
- if (rar == 0)
- ixgbe_clear_vmdq(hw, rar, 0);
-
- return rar;
-}
-
-/**
- * ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address
- * @hw: pointer to hardware struct
- * @rar: receive address register index to disassociate
- * @vmdq: VMDq pool index to remove from the rar
- **/
-s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
-{
- u32 mpsar_lo, mpsar_hi;
- u32 rar_entries = hw->mac.num_rar_entries;
-
- /* Make sure we are using a valid rar index range */
- if (rar >= rar_entries) {
- hw_dbg(hw, "RAR index %d is out of range.\n", rar);
- return IXGBE_ERR_INVALID_ARGUMENT;
- }
-
- mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
- mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
-
- if (!mpsar_lo && !mpsar_hi)
- goto done;
-
- if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
- if (mpsar_lo) {
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
- mpsar_lo = 0;
- }
- if (mpsar_hi) {
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
- mpsar_hi = 0;
- }
- } else if (vmdq < 32) {
- mpsar_lo &= ~(1 << vmdq);
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo);
- } else {
- mpsar_hi &= ~(1 << (vmdq - 32));
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi);
- }
-
- /* was that the last pool using this rar? */
- if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0)
- hw->mac.ops.clear_rar(hw, rar);
-done:
- return 0;
-}
-
-/**
- * ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address
- * @hw: pointer to hardware struct
- * @rar: receive address register index to associate with a VMDq index
- * @vmdq: VMDq pool index
- **/
-s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
-{
- u32 mpsar;
- u32 rar_entries = hw->mac.num_rar_entries;
-
- /* Make sure we are using a valid rar index range */
- if (rar >= rar_entries) {
- hw_dbg(hw, "RAR index %d is out of range.\n", rar);
- return IXGBE_ERR_INVALID_ARGUMENT;
- }
-
- if (vmdq < 32) {
- mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
- mpsar |= 1 << vmdq;
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
- } else {
- mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
- mpsar |= 1 << (vmdq - 32);
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
- }
- return 0;
-}
-
-/**
- * This function should only be involved in the IOV mode.
- * In IOV mode, Default pool is next pool after the number of
- * VFs advertized and not 0.
- * MPSAR table needs to be updated for SAN_MAC RAR [hw->mac.san_mac_rar_index]
- *
- * ixgbe_set_vmdq_san_mac - Associate default VMDq pool index with a rx address
- * @hw: pointer to hardware struct
- * @vmdq: VMDq pool index
- **/
-s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq)
-{
- u32 mpsar;
- u32 rar = hw->mac.san_mac_rar_index;
-
- if (vmdq < 32) {
- mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
- mpsar |= 1 << vmdq;
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
- } else {
- mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
- mpsar |= 1 << (vmdq - 32);
- IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
- }
-
- return 0;
-}
-
-/**
- * ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array
- * @hw: pointer to hardware structure
- **/
-s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw)
-{
- int i;
-
- hw_dbg(hw, " Clearing UTA\n");
-
- for (i = 0; i < 128; i++)
- IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0);
-
- return 0;
-}
-
-/**
- * ixgbe_find_vlvf_slot - find the vlanid or the first empty slot
- * @hw: pointer to hardware structure
- * @vlan: VLAN id to write to VLAN filter
- *
- * return the VLVF index where this VLAN id should be placed
- *
- **/
-s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan)
-{
- u32 bits = 0;
- u32 first_empty_slot = 0;
- s32 regindex;
-
- /* short cut the special case */
- if (vlan == 0)
- return 0;
-
- /*
- * Search for the vlan id in the VLVF entries. Save off the first empty
- * slot found along the way
- */
- for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
- bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
- if (!bits && !(first_empty_slot))
- first_empty_slot = regindex;
- else if ((bits & 0x0FFF) == vlan)
- break;
- }
-
- /*
- * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan
- * in the VLVF. Else use the first empty VLVF register for this
- * vlan id.
- */
- if (regindex >= IXGBE_VLVF_ENTRIES) {
- if (first_empty_slot)
- regindex = first_empty_slot;
- else {
- hw_dbg(hw, "No space in VLVF.\n");
- regindex = IXGBE_ERR_NO_SPACE;
- }
- }
-
- return regindex;
-}
-
-/**
- * ixgbe_set_vfta_generic - Set VLAN filter table
- * @hw: pointer to hardware structure
- * @vlan: VLAN id to write to VLAN filter
- * @vind: VMDq output index that maps queue to VLAN id in VFVFB
- * @vlan_on: boolean flag to turn on/off VLAN in VFVF
- *
- * Turn on/off specified VLAN in the VLAN filter table.
- **/
-s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
- bool vlan_on)
-{
- s32 regindex;
- u32 bitindex;
- u32 vfta;
- u32 targetbit;
- s32 ret_val = 0;
- bool vfta_changed = false;
-
- if (vlan > 4095)
- return IXGBE_ERR_PARAM;
-
- /*
- * this is a 2 part operation - first the VFTA, then the
- * VLVF and VLVFB if VT Mode is set
- * We don't write the VFTA until we know the VLVF part succeeded.
- */
-
- /* Part 1
- * The VFTA is a bitstring made up of 128 32-bit registers
- * that enable the particular VLAN id, much like the MTA:
- * bits[11-5]: which register
- * bits[4-0]: which bit in the register
- */
- regindex = (vlan >> 5) & 0x7F;
- bitindex = vlan & 0x1F;
- targetbit = (1 << bitindex);
- vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
-
- if (vlan_on) {
- if (!(vfta & targetbit)) {
- vfta |= targetbit;
- vfta_changed = true;
- }
- } else {
- if (vfta & targetbit) {
- vfta &= ~targetbit;
- vfta_changed = true;
- }
- }
-
- /* Part 2
- * Call ixgbe_set_vlvf_generic to set VLVFB and VLVF
- */
- ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on,
- &vfta_changed);
- if (ret_val != 0)
- return ret_val;
-
- if (vfta_changed)
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta);
-
- return 0;
-}
-
-/**
- * ixgbe_set_vlvf_generic - Set VLAN Pool Filter
- * @hw: pointer to hardware structure
- * @vlan: VLAN id to write to VLAN filter
- * @vind: VMDq output index that maps queue to VLAN id in VFVFB
- * @vlan_on: boolean flag to turn on/off VLAN in VFVF
- * @vfta_changed: pointer to boolean flag which indicates whether VFTA
- * should be changed
- *
- * Turn on/off specified bit in VLVF table.
- **/
-s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
- bool vlan_on, bool *vfta_changed)
-{
- u32 vt;
-
- if (vlan > 4095)
- return IXGBE_ERR_PARAM;
-
- /* If VT Mode is set
- * Either vlan_on
- * make sure the vlan is in VLVF
- * set the vind bit in the matching VLVFB
- * Or !vlan_on
- * clear the pool bit and possibly the vind
- */
- vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
- if (vt & IXGBE_VT_CTL_VT_ENABLE) {
- s32 vlvf_index;
- u32 bits;
-
- vlvf_index = ixgbe_find_vlvf_slot(hw, vlan);
- if (vlvf_index < 0)
- return vlvf_index;
-
- if (vlan_on) {
- /* set the pool bit */
- if (vind < 32) {
- bits = IXGBE_READ_REG(hw,
- IXGBE_VLVFB(vlvf_index * 2));
- bits |= (1 << vind);
- IXGBE_WRITE_REG(hw,
- IXGBE_VLVFB(vlvf_index * 2),
- bits);
- } else {
- bits = IXGBE_READ_REG(hw,
- IXGBE_VLVFB((vlvf_index * 2) + 1));
- bits |= (1 << (vind - 32));
- IXGBE_WRITE_REG(hw,
- IXGBE_VLVFB((vlvf_index * 2) + 1),
- bits);
- }
- } else {
- /* clear the pool bit */
- if (vind < 32) {
- bits = IXGBE_READ_REG(hw,
- IXGBE_VLVFB(vlvf_index * 2));
- bits &= ~(1 << vind);
- IXGBE_WRITE_REG(hw,
- IXGBE_VLVFB(vlvf_index * 2),
- bits);
- bits |= IXGBE_READ_REG(hw,
- IXGBE_VLVFB((vlvf_index * 2) + 1));
- } else {
- bits = IXGBE_READ_REG(hw,
- IXGBE_VLVFB((vlvf_index * 2) + 1));
- bits &= ~(1 << (vind - 32));
- IXGBE_WRITE_REG(hw,
- IXGBE_VLVFB((vlvf_index * 2) + 1),
- bits);
- bits |= IXGBE_READ_REG(hw,
- IXGBE_VLVFB(vlvf_index * 2));
- }
- }
-
- /*
- * If there are still bits set in the VLVFB registers
- * for the VLAN ID indicated we need to see if the
- * caller is requesting that we clear the VFTA entry bit.
- * If the caller has requested that we clear the VFTA
- * entry bit but there are still pools/VFs using this VLAN
- * ID entry then ignore the request. We're not worried
- * about the case where we're turning the VFTA VLAN ID
- * entry bit on, only when requested to turn it off as
- * there may be multiple pools and/or VFs using the
- * VLAN ID entry. In that case we cannot clear the
- * VFTA bit until all pools/VFs using that VLAN ID have also
- * been cleared. This will be indicated by "bits" being
- * zero.
- */
- if (bits) {
- IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index),
- (IXGBE_VLVF_VIEN | vlan));
- if (!vlan_on && (vfta_changed != NULL)) {
- /* someone wants to clear the vfta entry
- * but some pools/VFs are still using it.
- * Ignore it. */
- *vfta_changed = false;
- }
- } else
- IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0);
- }
-
- return 0;
-}
-
-/**
- * ixgbe_clear_vfta_generic - Clear VLAN filter table
- * @hw: pointer to hardware structure
- *
- * Clears the VLAN filer table, and the VMDq index associated with the filter
- **/
-s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
-{
- u32 offset;
-
- for (offset = 0; offset < hw->mac.vft_size; offset++)
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
-
- for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
- IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0);
- }
-
- return 0;
-}
-
-/**
- * ixgbe_check_mac_link_generic - Determine link and speed status
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @link_up: true when link is up
- * @link_up_wait_to_complete: bool used to wait for link up or not
- *
- * Reads the links register to determine if link is up and the current speed
- **/
-s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
- bool *link_up, bool link_up_wait_to_complete)
-{
- u32 links_reg, links_orig;
- u32 i;
-
- /* clear the old state */
- links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS);
-
- links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
-
- if (links_orig != links_reg) {
- hw_dbg(hw, "LINKS changed from %08X to %08X\n",
- links_orig, links_reg);
- }
-
- if (link_up_wait_to_complete) {
- for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
- if (links_reg & IXGBE_LINKS_UP) {
- *link_up = true;
- break;
- } else {
- *link_up = false;
- }
- msleep(100);
- links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
- }
- } else {
- if (links_reg & IXGBE_LINKS_UP)
- *link_up = true;
- else
- *link_up = false;
- }
-
- if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
- IXGBE_LINKS_SPEED_10G_82599)
- *speed = IXGBE_LINK_SPEED_10GB_FULL;
- else if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
- IXGBE_LINKS_SPEED_1G_82599)
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- else if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
- IXGBE_LINKS_SPEED_100_82599)
- *speed = IXGBE_LINK_SPEED_100_FULL;
- else
- *speed = IXGBE_LINK_SPEED_UNKNOWN;
-
- return 0;
-}
-
-/**
- * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from
- * the EEPROM
- * @hw: pointer to hardware structure
- * @wwnn_prefix: the alternative WWNN prefix
- * @wwpn_prefix: the alternative WWPN prefix
- *
- * This function will read the EEPROM from the alternative SAN MAC address
- * block to check the support for the alternative WWNN/WWPN prefix support.
- **/
-s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
- u16 *wwpn_prefix)
-{
- u16 offset, caps;
- u16 alt_san_mac_blk_offset;
-
- /* clear output first */
- *wwnn_prefix = 0xFFFF;
- *wwpn_prefix = 0xFFFF;
-
- /* check if alternative SAN MAC is supported */
- hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR,
- &alt_san_mac_blk_offset);
-
- if ((alt_san_mac_blk_offset == 0) ||
- (alt_san_mac_blk_offset == 0xFFFF))
- goto wwn_prefix_out;
-
- /* check capability in alternative san mac address block */
- offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
- hw->eeprom.ops.read(hw, offset, &caps);
- if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
- goto wwn_prefix_out;
-
- /* get the corresponding prefix for WWNN/WWPN */
- offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
- hw->eeprom.ops.read(hw, offset, wwnn_prefix);
-
- offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
- hw->eeprom.ops.read(hw, offset, wwpn_prefix);
-
-wwn_prefix_out:
- return 0;
-}
-
-/**
- * ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM
- * @hw: pointer to hardware structure
- * @bs: the fcoe boot status
- *
- * This function will read the FCOE boot status from the iSCSI FCOE block
- **/
-s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs)
-{
- u16 offset, caps, flags;
- s32 status;
-
- /* clear output first */
- *bs = ixgbe_fcoe_bootstatus_unavailable;
-
- /* check if FCOE IBA block is present */
- offset = IXGBE_FCOE_IBA_CAPS_BLK_PTR;
- status = hw->eeprom.ops.read(hw, offset, &caps);
- if (status != 0)
- goto out;
-
- if (!(caps & IXGBE_FCOE_IBA_CAPS_FCOE))
- goto out;
-
- /* check if iSCSI FCOE block is populated */
- status = hw->eeprom.ops.read(hw, IXGBE_ISCSI_FCOE_BLK_PTR, &offset);
- if (status != 0)
- goto out;
-
- if ((offset == 0) || (offset == 0xFFFF))
- goto out;
-
- /* read fcoe flags in iSCSI FCOE block */
- offset = offset + IXGBE_ISCSI_FCOE_FLAGS_OFFSET;
- status = hw->eeprom.ops.read(hw, offset, &flags);
- if (status != 0)
- goto out;
-
- if (flags & IXGBE_ISCSI_FCOE_FLAGS_ENABLE)
- *bs = ixgbe_fcoe_bootstatus_enabled;
- else
- *bs = ixgbe_fcoe_bootstatus_disabled;
-
-out:
- return status;
-}
-
-/**
- * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
- * @hw: pointer to hardware structure
- * @enable: enable or disable switch for anti-spoofing
- * @pf: Physical Function pool - do not enable anti-spoofing for the PF
- *
- **/
-void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf)
-{
- int j;
- int pf_target_reg = pf >> 3;
- int pf_target_shift = pf % 8;
- u32 pfvfspoof = 0;
-
- if (hw->mac.type == ixgbe_mac_82598EB)
- return;
-
- if (enable)
- pfvfspoof = IXGBE_SPOOF_MACAS_MASK;
-
- /*
- * PFVFSPOOF register array is size 8 with 8 bits assigned to
- * MAC anti-spoof enables in each register array element.
- */
- for (j = 0; j < IXGBE_PFVFSPOOF_REG_COUNT; j++)
- IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof);
-
- /* If not enabling anti-spoofing then done */
- if (!enable)
- return;
-
- /*
- * The PF should be allowed to spoof so that it can support
- * emulation mode NICs. Reset the bit assigned to the PF
- */
- pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg));
- pfvfspoof ^= (1 << pf_target_shift);
- IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg), pfvfspoof);
-}
-
-/**
- * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing
- * @hw: pointer to hardware structure
- * @enable: enable or disable switch for VLAN anti-spoofing
- * @pf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing
- *
- **/
-void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
-{
- int vf_target_reg = vf >> 3;
- int vf_target_shift = vf % 8 + IXGBE_SPOOF_VLANAS_SHIFT;
- u32 pfvfspoof;
-
- if (hw->mac.type == ixgbe_mac_82598EB)
- return;
-
- pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
- if (enable)
- pfvfspoof |= (1 << vf_target_shift);
- else
- pfvfspoof &= ~(1 << vf_target_shift);
- IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
-}
-
-/**
- * ixgbe_get_device_caps_generic - Get additional device capabilities
- * @hw: pointer to hardware structure
- * @device_caps: the EEPROM word with the extra device capabilities
- *
- * This function will read the EEPROM location for the device capabilities,
- * and return the word through device_caps.
- **/
-s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps)
-{
- hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
-
- return 0;
-}
-
-/**
- * ixgbe_calculate_checksum - Calculate checksum for buffer
- * @buffer: pointer to EEPROM
- * @length: size of EEPROM to calculate a checksum for
- * Calculates the checksum for some buffer on a specified length. The
- * checksum calculated is returned.
- **/
-static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
-{
- u32 i;
- u8 sum = 0;
-
- if (!buffer)
- return 0;
- for (i = 0; i < length; i++)
- sum += buffer[i];
-
- return (u8) (0 - sum);
-}
-
-/**
- * ixgbe_host_interface_command - Issue command to manageability block
- * @hw: pointer to the HW structure
- * @buffer: contains the command to write and where the return status will
- * be placed
- * @length: length of buffer, must be multiple of 4 bytes
- *
- * Communicates with the manageability block. On success return 0
- * else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
- **/
-static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
- u32 length)
-{
- u32 hicr, i, bi;
- u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
- u8 buf_len, dword_len;
-
- s32 ret_val = 0;
-
- if (length == 0 || length & 0x3 ||
- length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
- hw_dbg(hw, "Buffer length failure.\n");
- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
- goto out;
- }
-
- /* Check that the host interface is enabled. */
- hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
- if ((hicr & IXGBE_HICR_EN) == 0) {
- hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n");
- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
- goto out;
- }
-
- /* Calculate length in DWORDs */
- dword_len = length >> 2;
-
- /*
- * The device driver writes the relevant command block
- * into the ram area.
- */
- for (i = 0; i < dword_len; i++)
- IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG,
- i, IXGBE_CPU_TO_LE32(buffer[i]));
-
- /* Setting this bit tells the ARC that a new command is pending. */
- IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C);
-
- for (i = 0; i < IXGBE_HI_COMMAND_TIMEOUT; i++) {
- hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
- if (!(hicr & IXGBE_HICR_C))
- break;
- msleep(1);
- }
-
- /* Check command successful completion. */
- if (i == IXGBE_HI_COMMAND_TIMEOUT ||
- (!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) {
- hw_dbg(hw, "Command has failed with no status valid.\n");
- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
- goto out;
- }
-
- /* Calculate length in DWORDs */
- dword_len = hdr_size >> 2;
-
- /* first pull in the header so we know the buffer length */
- for (bi = 0; bi < dword_len; bi++) {
- buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
- IXGBE_LE32_TO_CPUS(&buffer[bi]);
- }
-
- /* If there is any thing in data position pull it in */
- buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len;
- if (buf_len == 0)
- goto out;
-
- if (length < (buf_len + hdr_size)) {
- hw_dbg(hw, "Buffer not large enough for reply message.\n");
- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
- goto out;
- }
-
- /* Calculate length in DWORDs, add 3 for odd lengths */
- dword_len = (buf_len + 3) >> 2;
-
- /* Pull in the rest of the buffer (bi is where we left off)*/
- for (; bi <= dword_len; bi++) {
- buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
- IXGBE_LE32_TO_CPUS(&buffer[bi]);
- }
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware
- * @hw: pointer to the HW structure
- * @maj: driver version major number
- * @min: driver version minor number
- * @build: driver version build number
- * @sub: driver version sub build number
- *
- * Sends driver version number to firmware through the manageability
- * block. On success return 0
- * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
- * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
- **/
-s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
- u8 build, u8 sub)
-{
- struct ixgbe_hic_drv_info fw_cmd;
- int i;
- s32 ret_val = 0;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM)
- != 0) {
- ret_val = IXGBE_ERR_SWFW_SYNC;
- goto out;
- }
-
- fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
- fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN;
- fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
- fw_cmd.port_num = (u8)hw->bus.func;
- fw_cmd.ver_maj = maj;
- fw_cmd.ver_min = min;
- fw_cmd.ver_build = build;
- fw_cmd.ver_sub = sub;
- fw_cmd.hdr.checksum = 0;
- fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
- (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
- fw_cmd.pad = 0;
- fw_cmd.pad2 = 0;
-
- for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
- ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
- sizeof(fw_cmd));
- if (ret_val != 0)
- continue;
-
- if (fw_cmd.hdr.cmd_or_resp.ret_status ==
- FW_CEM_RESP_STATUS_SUCCESS)
- ret_val = 0;
- else
- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
-
- break;
- }
-
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_set_rxpba_generic - Initialize Rx packet buffer
- * @hw: pointer to hardware structure
- * @num_pb: number of packet buffers to allocate
- * @headroom: reserve n KB of headroom
- * @strategy: packet buffer allocation strategy
- **/
-void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
- int strategy)
-{
- u32 pbsize = hw->mac.rx_pb_size;
- int i = 0;
- u32 rxpktsize, txpktsize, txpbthresh;
-
- /* Reserve headroom */
- pbsize -= headroom;
-
- if (!num_pb)
- num_pb = 1;
-
- /* Divide remaining packet buffer space amongst the number of packet
- * buffers requested using supplied strategy.
- */
- switch (strategy) {
- case PBA_STRATEGY_WEIGHTED:
- /* ixgbe_dcb_pba_80_48 strategy weight first half of packet
- * buffer with 5/8 of the packet buffer space.
- */
- rxpktsize = (pbsize * 5) / (num_pb * 4);
- pbsize -= rxpktsize * (num_pb / 2);
- rxpktsize <<= IXGBE_RXPBSIZE_SHIFT;
- for (; i < (num_pb / 2); i++)
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
- /* Fall through to configure remaining packet buffers */
- case PBA_STRATEGY_EQUAL:
- rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT;
- for (; i < num_pb; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
- break;
- default:
- break;
- }
-
- /* Only support an equally distributed Tx packet buffer strategy. */
- txpktsize = IXGBE_TXPBSIZE_MAX / num_pb;
- txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX;
- for (i = 0; i < num_pb; i++) {
- IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize);
- IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh);
- }
-
- /* Clear unused TCs, if any, to zero buffer size*/
- for (; i < IXGBE_MAX_PB; i++) {
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
- IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0);
- IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0);
- }
-}
-
-/**
- * ixgbe_clear_tx_pending - Clear pending TX work from the PCIe fifo
- * @hw: pointer to the hardware structure
- *
- * The 82599 and x540 MACs can experience issues if TX work is still pending
- * when a reset occurs. This function prevents this by flushing the PCIe
- * buffers on the system.
- **/
-void ixgbe_clear_tx_pending(struct ixgbe_hw *hw)
-{
- u32 gcr_ext, hlreg0;
-
- /*
- * If double reset is not requested then all transactions should
- * already be clear and as such there is no work to do
- */
- if (!(hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED))
- return;
-
- /*
- * Set loopback enable to prevent any transmits from being sent
- * should the link come up. This assumes that the RXCTRL.RXEN bit
- * has already been cleared.
- */
- hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
- IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0 | IXGBE_HLREG0_LPBK);
-
- /* initiate cleaning flow for buffers in the PCIe transaction layer */
- gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
- IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT,
- gcr_ext | IXGBE_GCR_EXT_BUFFERS_CLEAR);
-
- /* Flush all writes and allow 20usec for all transactions to clear */
- IXGBE_WRITE_FLUSH(hw);
- udelay(20);
-
- /* restore previous register values */
- IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
- IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
-}
-
-static const u8 ixgbe_emc_temp_data[4] = {
- IXGBE_EMC_INTERNAL_DATA,
- IXGBE_EMC_DIODE1_DATA,
- IXGBE_EMC_DIODE2_DATA,
- IXGBE_EMC_DIODE3_DATA
-};
-static const u8 ixgbe_emc_therm_limit[4] = {
- IXGBE_EMC_INTERNAL_THERM_LIMIT,
- IXGBE_EMC_DIODE1_THERM_LIMIT,
- IXGBE_EMC_DIODE2_THERM_LIMIT,
- IXGBE_EMC_DIODE3_THERM_LIMIT
-};
-
-/**
- * ixgbe_get_thermal_sensor_data - Gathers thermal sensor data
- * @hw: pointer to hardware structure
- * @data: pointer to the thermal sensor data structure
- *
- * Returns the thermal sensor data structure
- **/
-s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- u16 ets_offset;
- u16 ets_cfg;
- u16 ets_sensor;
- u8 num_sensors;
- u8 sensor_index;
- u8 sensor_location;
- u8 i;
- struct ixgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
-
- /* Only support thermal sensors attached to 82599 physical port 0 */
- if ((hw->mac.type != ixgbe_mac_82599EB) ||
- (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) {
- status = IXGBE_NOT_IMPLEMENTED;
- goto out;
- }
-
- status = hw->eeprom.ops.read(hw, IXGBE_ETS_CFG, &ets_offset);
- if (status)
- goto out;
-
- if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF)) {
- status = IXGBE_NOT_IMPLEMENTED;
- goto out;
- }
-
- status = hw->eeprom.ops.read(hw, ets_offset, &ets_cfg);
- if (status)
- goto out;
-
- if (((ets_cfg & IXGBE_ETS_TYPE_MASK) >> IXGBE_ETS_TYPE_SHIFT)
- != IXGBE_ETS_TYPE_EMC) {
- status = IXGBE_NOT_IMPLEMENTED;
- goto out;
- }
-
- num_sensors = (ets_cfg & IXGBE_ETS_NUM_SENSORS_MASK);
- if (num_sensors > IXGBE_MAX_SENSORS)
- num_sensors = IXGBE_MAX_SENSORS;
-
- for (i = 0; i < num_sensors; i++) {
- status = hw->eeprom.ops.read(hw, (ets_offset + 1 + i),
- &ets_sensor);
- if (status)
- goto out;
-
- sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >>
- IXGBE_ETS_DATA_INDEX_SHIFT);
- sensor_location = ((ets_sensor & IXGBE_ETS_DATA_LOC_MASK) >>
- IXGBE_ETS_DATA_LOC_SHIFT);
-
- if (sensor_location != 0) {
- status = hw->phy.ops.read_i2c_byte(hw,
- ixgbe_emc_temp_data[sensor_index],
- IXGBE_I2C_THERMAL_SENSOR_ADDR,
- &data->sensor[i].temp);
- if (status)
- goto out;
- }
- }
-out:
- return status;
-}
-
-/**
- * ixgbe_init_thermal_sensor_thresh_generic - Inits thermal sensor thresholds
- * @hw: pointer to hardware structure
- *
- * Inits the thermal sensor thresholds according to the NVM map
- * and save off the threshold and location values into mac.thermal_sensor_data
- **/
-s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- u16 ets_offset;
- u16 ets_cfg;
- u16 ets_sensor;
- u8 low_thresh_delta;
- u8 num_sensors;
- u8 sensor_index;
- u8 sensor_location;
- u8 therm_limit;
- u8 i;
- struct ixgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
-
- memset(data, 0, sizeof(struct ixgbe_thermal_sensor_data));
-
- /* Only support thermal sensors attached to 82599 physical port 0 */
- if ((hw->mac.type != ixgbe_mac_82599EB) ||
- (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1))
- return IXGBE_NOT_IMPLEMENTED;
-
- hw->eeprom.ops.read(hw, IXGBE_ETS_CFG, &ets_offset);
- if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF))
- return IXGBE_NOT_IMPLEMENTED;
-
- hw->eeprom.ops.read(hw, ets_offset, &ets_cfg);
- if (((ets_cfg & IXGBE_ETS_TYPE_MASK) >> IXGBE_ETS_TYPE_SHIFT)
- != IXGBE_ETS_TYPE_EMC)
- return IXGBE_NOT_IMPLEMENTED;
-
- low_thresh_delta = ((ets_cfg & IXGBE_ETS_LTHRES_DELTA_MASK) >>
- IXGBE_ETS_LTHRES_DELTA_SHIFT);
- num_sensors = (ets_cfg & IXGBE_ETS_NUM_SENSORS_MASK);
-
- for (i = 0; i < num_sensors; i++) {
- hw->eeprom.ops.read(hw, (ets_offset + 1 + i), &ets_sensor);
- sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >>
- IXGBE_ETS_DATA_INDEX_SHIFT);
- sensor_location = ((ets_sensor & IXGBE_ETS_DATA_LOC_MASK) >>
- IXGBE_ETS_DATA_LOC_SHIFT);
- therm_limit = ets_sensor & IXGBE_ETS_DATA_HTHRESH_MASK;
-
- hw->phy.ops.write_i2c_byte(hw,
- ixgbe_emc_therm_limit[sensor_index],
- IXGBE_I2C_THERMAL_SENSOR_ADDR, therm_limit);
-
- if ((i < IXGBE_MAX_SENSORS) && (sensor_location != 0)) {
- data->sensor[i].location = sensor_location;
- data->sensor[i].caution_thresh = therm_limit;
- data->sensor[i].max_op_thresh = therm_limit -
- low_thresh_delta;
- }
- }
- return status;
-}
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_common.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_common.h
deleted file mode 100644
index 2989a80b3..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_common.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_COMMON_H_
-#define _IXGBE_COMMON_H_
-
-#include "ixgbe_type.h"
-
-u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw);
-
-s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
-s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
-s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
-s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw);
-s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
-s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
- u32 pba_num_size);
-s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
-s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
-void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw);
-s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);
-
-s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
-
-s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
-s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
-s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data);
-s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
-s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data);
-s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
-s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data);
-s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
- u16 *data);
-s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
- u16 words, u16 *data);
-u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
-s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
- u16 *checksum_val);
-s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
-s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
-
-s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
- u32 enable_addr);
-s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw);
-s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count,
- ixgbe_mc_addr_itr func, bool clear);
-s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
- u32 addr_count, ixgbe_mc_addr_itr func);
-s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
-s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
-s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
-s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw);
-s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw);
-
-s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw);
-void ixgbe_fc_autoneg(struct ixgbe_hw *hw);
-
-s32 ixgbe_validate_mac_addr(u8 *mac_addr);
-s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
-void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask);
-s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
-
-s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
-
-s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr);
-s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr);
-
-s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
-s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq);
-s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
-s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
-s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw);
-s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan,
- u32 vind, bool vlan_on);
-s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind,
- bool vlan_on, bool *vfta_changed);
-s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw);
-s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan);
-
-s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *link_up, bool link_up_wait_to_complete);
-
-s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
- u16 *wwpn_prefix);
-
-s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs);
-void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf);
-void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf);
-s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps);
-void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
- int strategy);
-s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
- u8 build, u8 ver);
-void ixgbe_clear_tx_pending(struct ixgbe_hw *hw);
-
-#define IXGBE_I2C_THERMAL_SENSOR_ADDR 0xF8
-#define IXGBE_EMC_INTERNAL_DATA 0x00
-#define IXGBE_EMC_INTERNAL_THERM_LIMIT 0x20
-#define IXGBE_EMC_DIODE1_DATA 0x01
-#define IXGBE_EMC_DIODE1_THERM_LIMIT 0x19
-#define IXGBE_EMC_DIODE2_DATA 0x23
-#define IXGBE_EMC_DIODE2_THERM_LIMIT 0x1A
-#define IXGBE_EMC_DIODE3_DATA 0x2A
-#define IXGBE_EMC_DIODE3_THERM_LIMIT 0x30
-
-s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw);
-s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw);
-#endif /* IXGBE_COMMON */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_dcb.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_dcb.h
deleted file mode 100644
index e9a099d53..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_dcb.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_DCB_H_
-#define _IXGBE_DCB_H_
-
-
-#include "ixgbe_type.h"
-
-/* DCB defines */
-/* DCB credit calculation defines */
-#define IXGBE_DCB_CREDIT_QUANTUM 64
-#define IXGBE_DCB_MAX_CREDIT_REFILL 200 /* 200 * 64B = 12800B */
-#define IXGBE_DCB_MAX_TSO_SIZE (32 * 1024) /* Max TSO pkt size in DCB*/
-#define IXGBE_DCB_MAX_CREDIT (2 * IXGBE_DCB_MAX_CREDIT_REFILL)
-
-/* 513 for 32KB TSO packet */
-#define IXGBE_DCB_MIN_TSO_CREDIT \
- ((IXGBE_DCB_MAX_TSO_SIZE / IXGBE_DCB_CREDIT_QUANTUM) + 1)
-
-/* DCB configuration defines */
-#define IXGBE_DCB_MAX_USER_PRIORITY 8
-#define IXGBE_DCB_MAX_BW_GROUP 8
-#define IXGBE_DCB_BW_PERCENT 100
-
-#define IXGBE_DCB_TX_CONFIG 0
-#define IXGBE_DCB_RX_CONFIG 1
-
-/* DCB capability defines */
-#define IXGBE_DCB_PG_SUPPORT 0x00000001
-#define IXGBE_DCB_PFC_SUPPORT 0x00000002
-#define IXGBE_DCB_BCN_SUPPORT 0x00000004
-#define IXGBE_DCB_UP2TC_SUPPORT 0x00000008
-#define IXGBE_DCB_GSP_SUPPORT 0x00000010
-
-struct ixgbe_dcb_support {
- u32 capabilities; /* DCB capabilities */
-
- /* Each bit represents a number of TCs configurable in the hw.
- * If 8 traffic classes can be configured, the value is 0x80. */
- u8 traffic_classes;
- u8 pfc_traffic_classes;
-};
-
-enum ixgbe_dcb_tsa {
- ixgbe_dcb_tsa_ets = 0,
- ixgbe_dcb_tsa_group_strict_cee,
- ixgbe_dcb_tsa_strict
-};
-
-/* Traffic class bandwidth allocation per direction */
-struct ixgbe_dcb_tc_path {
- u8 bwg_id; /* Bandwidth Group (BWG) ID */
- u8 bwg_percent; /* % of BWG's bandwidth */
- u8 link_percent; /* % of link bandwidth */
- u8 up_to_tc_bitmap; /* User Priority to Traffic Class mapping */
- u16 data_credits_refill; /* Credit refill amount in 64B granularity */
- u16 data_credits_max; /* Max credits for a configured packet buffer
- * in 64B granularity.*/
- enum ixgbe_dcb_tsa tsa; /* Link or Group Strict Priority */
-};
-
-enum ixgbe_dcb_pfc {
- ixgbe_dcb_pfc_disabled = 0,
- ixgbe_dcb_pfc_enabled,
- ixgbe_dcb_pfc_enabled_txonly,
- ixgbe_dcb_pfc_enabled_rxonly
-};
-
-/* Traffic class configuration */
-struct ixgbe_dcb_tc_config {
- struct ixgbe_dcb_tc_path path[2]; /* One each for Tx/Rx */
- enum ixgbe_dcb_pfc pfc; /* Class based flow control setting */
-
- u16 desc_credits_max; /* For Tx Descriptor arbitration */
- u8 tc; /* Traffic class (TC) */
-};
-
-enum ixgbe_dcb_pba {
- /* PBA[0-7] each use 64KB FIFO */
- ixgbe_dcb_pba_equal = PBA_STRATEGY_EQUAL,
- /* PBA[0-3] each use 80KB, PBA[4-7] each use 48KB */
- ixgbe_dcb_pba_80_48 = PBA_STRATEGY_WEIGHTED
-};
-
-struct ixgbe_dcb_num_tcs {
- u8 pg_tcs;
- u8 pfc_tcs;
-};
-
-struct ixgbe_dcb_config {
- struct ixgbe_dcb_tc_config tc_config[IXGBE_DCB_MAX_TRAFFIC_CLASS];
- struct ixgbe_dcb_support support;
- struct ixgbe_dcb_num_tcs num_tcs;
- u8 bw_percentage[2][IXGBE_DCB_MAX_BW_GROUP]; /* One each for Tx/Rx */
- bool pfc_mode_enable;
- bool round_robin_enable;
-
- enum ixgbe_dcb_pba rx_pba_cfg;
-
- u32 dcb_cfg_version; /* Not used...OS-specific? */
- u32 link_speed; /* For bandwidth allocation validation purpose */
- bool vt_mode;
-};
-
-/* DCB driver APIs */
-
-/* DCB rule checking */
-s32 ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config *);
-
-/* DCB credits calculation */
-s32 ixgbe_dcb_calculate_tc_credits(u8 *, u16 *, u16 *, int);
-s32 ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw *,
- struct ixgbe_dcb_config *, u32, u8);
-
-/* DCB PFC */
-s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *, u8, u8 *);
-s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *, struct ixgbe_dcb_config *);
-
-/* DCB stats */
-s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *);
-s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8);
-s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8);
-
-/* DCB config arbiters */
-s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *,
- struct ixgbe_dcb_config *);
-s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *,
- struct ixgbe_dcb_config *);
-s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *,
- struct ixgbe_dcb_config *);
-
-/* DCB unpack routines */
-void ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config *, u8 *, u8 *);
-void ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config *, int, u16 *);
-void ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config *, u16 *);
-void ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config *, int, u8 *);
-void ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config *, int, u8 *);
-void ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config *, int, u8 *);
-
-/* DCB initialization */
-s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, u16 *, u16 *, u8 *, u8 *, u8 *);
-s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *, struct ixgbe_dcb_config *);
-#endif /* _IXGBE_DCB_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c b/kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c
deleted file mode 100644
index f2ded19e9..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c
+++ /dev/null
@@ -1,2894 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/* ethtool support for ixgbe */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/vmalloc.h>
-#include <linux/highmem.h>
-#ifdef SIOCETHTOOL
-#include <asm/uaccess.h>
-
-#include "ixgbe.h"
-
-#ifndef ETH_GSTRING_LEN
-#define ETH_GSTRING_LEN 32
-#endif
-
-#define IXGBE_ALL_RAR_ENTRIES 16
-
-#ifdef ETHTOOL_OPS_COMPAT
-#include "kcompat_ethtool.c"
-#endif
-#ifdef ETHTOOL_GSTATS
-struct ixgbe_stats {
- char stat_string[ETH_GSTRING_LEN];
- int sizeof_stat;
- int stat_offset;
-};
-
-#define IXGBE_NETDEV_STAT(_net_stat) { \
- .stat_string = #_net_stat, \
- .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
- .stat_offset = offsetof(struct net_device_stats, _net_stat) \
-}
-static const struct ixgbe_stats ixgbe_gstrings_net_stats[] = {
- IXGBE_NETDEV_STAT(rx_packets),
- IXGBE_NETDEV_STAT(tx_packets),
- IXGBE_NETDEV_STAT(rx_bytes),
- IXGBE_NETDEV_STAT(tx_bytes),
- IXGBE_NETDEV_STAT(rx_errors),
- IXGBE_NETDEV_STAT(tx_errors),
- IXGBE_NETDEV_STAT(rx_dropped),
- IXGBE_NETDEV_STAT(tx_dropped),
- IXGBE_NETDEV_STAT(multicast),
- IXGBE_NETDEV_STAT(collisions),
- IXGBE_NETDEV_STAT(rx_over_errors),
- IXGBE_NETDEV_STAT(rx_crc_errors),
- IXGBE_NETDEV_STAT(rx_frame_errors),
- IXGBE_NETDEV_STAT(rx_fifo_errors),
- IXGBE_NETDEV_STAT(rx_missed_errors),
- IXGBE_NETDEV_STAT(tx_aborted_errors),
- IXGBE_NETDEV_STAT(tx_carrier_errors),
- IXGBE_NETDEV_STAT(tx_fifo_errors),
- IXGBE_NETDEV_STAT(tx_heartbeat_errors),
-};
-
-#define IXGBE_STAT(_name, _stat) { \
- .stat_string = _name, \
- .sizeof_stat = FIELD_SIZEOF(struct ixgbe_adapter, _stat), \
- .stat_offset = offsetof(struct ixgbe_adapter, _stat) \
-}
-static struct ixgbe_stats ixgbe_gstrings_stats[] = {
- IXGBE_STAT("rx_pkts_nic", stats.gprc),
- IXGBE_STAT("tx_pkts_nic", stats.gptc),
- IXGBE_STAT("rx_bytes_nic", stats.gorc),
- IXGBE_STAT("tx_bytes_nic", stats.gotc),
- IXGBE_STAT("lsc_int", lsc_int),
- IXGBE_STAT("tx_busy", tx_busy),
- IXGBE_STAT("non_eop_descs", non_eop_descs),
-#ifndef CONFIG_IXGBE_NAPI
- IXGBE_STAT("rx_dropped_backlog", rx_dropped_backlog),
-#endif
- IXGBE_STAT("broadcast", stats.bprc),
- IXGBE_STAT("rx_no_buffer_count", stats.rnbc[0]) ,
- IXGBE_STAT("tx_timeout_count", tx_timeout_count),
- IXGBE_STAT("tx_restart_queue", restart_queue),
- IXGBE_STAT("rx_long_length_errors", stats.roc),
- IXGBE_STAT("rx_short_length_errors", stats.ruc),
- IXGBE_STAT("tx_flow_control_xon", stats.lxontxc),
- IXGBE_STAT("rx_flow_control_xon", stats.lxonrxc),
- IXGBE_STAT("tx_flow_control_xoff", stats.lxofftxc),
- IXGBE_STAT("rx_flow_control_xoff", stats.lxoffrxc),
- IXGBE_STAT("rx_csum_offload_errors", hw_csum_rx_error),
- IXGBE_STAT("alloc_rx_page_failed", alloc_rx_page_failed),
- IXGBE_STAT("alloc_rx_buff_failed", alloc_rx_buff_failed),
-#ifndef IXGBE_NO_LRO
- IXGBE_STAT("lro_aggregated", lro_stats.coal),
- IXGBE_STAT("lro_flushed", lro_stats.flushed),
-#endif /* IXGBE_NO_LRO */
- IXGBE_STAT("rx_no_dma_resources", hw_rx_no_dma_resources),
- IXGBE_STAT("hw_rsc_aggregated", rsc_total_count),
- IXGBE_STAT("hw_rsc_flushed", rsc_total_flush),
-#ifdef HAVE_TX_MQ
- IXGBE_STAT("fdir_match", stats.fdirmatch),
- IXGBE_STAT("fdir_miss", stats.fdirmiss),
- IXGBE_STAT("fdir_overflow", fdir_overflow),
-#endif /* HAVE_TX_MQ */
-#ifdef IXGBE_FCOE
- IXGBE_STAT("fcoe_bad_fccrc", stats.fccrc),
- IXGBE_STAT("fcoe_last_errors", stats.fclast),
- IXGBE_STAT("rx_fcoe_dropped", stats.fcoerpdc),
- IXGBE_STAT("rx_fcoe_packets", stats.fcoeprc),
- IXGBE_STAT("rx_fcoe_dwords", stats.fcoedwrc),
- IXGBE_STAT("fcoe_noddp", stats.fcoe_noddp),
- IXGBE_STAT("fcoe_noddp_ext_buff", stats.fcoe_noddp_ext_buff),
- IXGBE_STAT("tx_fcoe_packets", stats.fcoeptc),
- IXGBE_STAT("tx_fcoe_dwords", stats.fcoedwtc),
-#endif /* IXGBE_FCOE */
- IXGBE_STAT("os2bmc_rx_by_bmc", stats.o2bgptc),
- IXGBE_STAT("os2bmc_tx_by_bmc", stats.b2ospc),
- IXGBE_STAT("os2bmc_tx_by_host", stats.o2bspc),
- IXGBE_STAT("os2bmc_rx_by_host", stats.b2ogprc),
-};
-
-#define IXGBE_QUEUE_STATS_LEN \
- ((((struct ixgbe_adapter *)netdev_priv(netdev))->num_tx_queues + \
- ((struct ixgbe_adapter *)netdev_priv(netdev))->num_rx_queues) * \
- (sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
-#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
-#define IXGBE_NETDEV_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_net_stats)
-#define IXGBE_PB_STATS_LEN ( \
- (((struct ixgbe_adapter *)netdev_priv(netdev))->flags & \
- IXGBE_FLAG_DCB_ENABLED) ? \
- (sizeof(((struct ixgbe_adapter *)0)->stats.pxonrxc) + \
- sizeof(((struct ixgbe_adapter *)0)->stats.pxontxc) + \
- sizeof(((struct ixgbe_adapter *)0)->stats.pxoffrxc) + \
- sizeof(((struct ixgbe_adapter *)0)->stats.pxofftxc)) \
- / sizeof(u64) : 0)
-#define IXGBE_VF_STATS_LEN \
- ((((struct ixgbe_adapter *)netdev_priv(netdev))->num_vfs) * \
- (sizeof(struct vf_stats) / sizeof(u64)))
-#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + \
- IXGBE_NETDEV_STATS_LEN + \
- IXGBE_PB_STATS_LEN + \
- IXGBE_QUEUE_STATS_LEN + \
- IXGBE_VF_STATS_LEN)
-
-#endif /* ETHTOOL_GSTATS */
-#ifdef ETHTOOL_TEST
-static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
- "Register test (offline)", "Eeprom test (offline)",
- "Interrupt test (offline)", "Loopback test (offline)",
- "Link test (on/offline)"
-};
-#define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
-#endif /* ETHTOOL_TEST */
-
-#ifndef ETHTOOL_GLINKSETTINGS
-int ixgbe_get_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- u32 link_speed = 0;
- bool link_up;
-
- ecmd->supported = SUPPORTED_10000baseT_Full;
- ecmd->autoneg = AUTONEG_ENABLE;
- ecmd->transceiver = XCVR_EXTERNAL;
- if ((hw->phy.media_type == ixgbe_media_type_copper) ||
- (hw->phy.multispeed_fiber)) {
- ecmd->supported |= (SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg);
- switch (hw->mac.type) {
- case ixgbe_mac_X540:
- ecmd->supported |= SUPPORTED_100baseT_Full;
- break;
- default:
- break;
- }
-
- ecmd->advertising = ADVERTISED_Autoneg;
- if (hw->phy.autoneg_advertised) {
- if (hw->phy.autoneg_advertised &
- IXGBE_LINK_SPEED_100_FULL)
- ecmd->advertising |= ADVERTISED_100baseT_Full;
- if (hw->phy.autoneg_advertised &
- IXGBE_LINK_SPEED_10GB_FULL)
- ecmd->advertising |= ADVERTISED_10000baseT_Full;
- if (hw->phy.autoneg_advertised &
- IXGBE_LINK_SPEED_1GB_FULL)
- ecmd->advertising |= ADVERTISED_1000baseT_Full;
- } else {
- /*
- * Default advertised modes in case
- * phy.autoneg_advertised isn't set.
- */
- ecmd->advertising |= (ADVERTISED_10000baseT_Full |
- ADVERTISED_1000baseT_Full);
- if (hw->mac.type == ixgbe_mac_X540)
- ecmd->advertising |= ADVERTISED_100baseT_Full;
- }
-
- if (hw->phy.media_type == ixgbe_media_type_copper) {
- ecmd->supported |= SUPPORTED_TP;
- ecmd->advertising |= ADVERTISED_TP;
- ecmd->port = PORT_TP;
- } else {
- ecmd->supported |= SUPPORTED_FIBRE;
- ecmd->advertising |= ADVERTISED_FIBRE;
- ecmd->port = PORT_FIBRE;
- }
- } else if (hw->phy.media_type == ixgbe_media_type_backplane) {
- /* Set as FIBRE until SERDES defined in kernel */
- if (hw->device_id == IXGBE_DEV_ID_82598_BX) {
- ecmd->supported = (SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE);
- ecmd->advertising = (ADVERTISED_1000baseT_Full |
- ADVERTISED_FIBRE);
- ecmd->port = PORT_FIBRE;
- ecmd->autoneg = AUTONEG_DISABLE;
- } else if ((hw->device_id == IXGBE_DEV_ID_82599_COMBO_BACKPLANE)
- || (hw->device_id == IXGBE_DEV_ID_82599_KX4_MEZZ)) {
- ecmd->supported |= (SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_FIBRE);
- ecmd->advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_Autoneg |
- ADVERTISED_FIBRE);
- ecmd->port = PORT_FIBRE;
- } else {
- ecmd->supported |= (SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE);
- ecmd->advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_FIBRE);
- ecmd->port = PORT_FIBRE;
- }
- } else {
- ecmd->supported |= SUPPORTED_FIBRE;
- ecmd->advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
- ecmd->port = PORT_FIBRE;
- ecmd->autoneg = AUTONEG_DISABLE;
- }
-
-#ifdef HAVE_ETHTOOL_SFP_DISPLAY_PORT
- /* Get PHY type */
- switch (adapter->hw.phy.type) {
- case ixgbe_phy_tn:
- case ixgbe_phy_aq:
- case ixgbe_phy_cu_unknown:
- /* Copper 10G-BASET */
- ecmd->port = PORT_TP;
- break;
- case ixgbe_phy_qt:
- ecmd->port = PORT_FIBRE;
- break;
- case ixgbe_phy_nl:
- case ixgbe_phy_sfp_passive_tyco:
- case ixgbe_phy_sfp_passive_unknown:
- case ixgbe_phy_sfp_ftl:
- case ixgbe_phy_sfp_avago:
- case ixgbe_phy_sfp_intel:
- case ixgbe_phy_sfp_unknown:
- switch (adapter->hw.phy.sfp_type) {
- /* SFP+ devices, further checking needed */
- case ixgbe_sfp_type_da_cu:
- case ixgbe_sfp_type_da_cu_core0:
- case ixgbe_sfp_type_da_cu_core1:
- ecmd->port = PORT_DA;
- break;
- case ixgbe_sfp_type_sr:
- case ixgbe_sfp_type_lr:
- case ixgbe_sfp_type_srlr_core0:
- case ixgbe_sfp_type_srlr_core1:
- ecmd->port = PORT_FIBRE;
- break;
- case ixgbe_sfp_type_not_present:
- ecmd->port = PORT_NONE;
- break;
- case ixgbe_sfp_type_1g_cu_core0:
- case ixgbe_sfp_type_1g_cu_core1:
- ecmd->port = PORT_TP;
- ecmd->supported = SUPPORTED_TP;
- ecmd->advertising = (ADVERTISED_1000baseT_Full |
- ADVERTISED_TP);
- break;
- case ixgbe_sfp_type_1g_sx_core0:
- case ixgbe_sfp_type_1g_sx_core1:
- ecmd->port = PORT_FIBRE;
- ecmd->supported = SUPPORTED_FIBRE;
- ecmd->advertising = (ADVERTISED_1000baseT_Full |
- ADVERTISED_FIBRE);
- break;
- case ixgbe_sfp_type_unknown:
- default:
- ecmd->port = PORT_OTHER;
- break;
- }
- break;
- case ixgbe_phy_xaui:
- ecmd->port = PORT_NONE;
- break;
- case ixgbe_phy_unknown:
- case ixgbe_phy_generic:
- case ixgbe_phy_sfp_unsupported:
- default:
- ecmd->port = PORT_OTHER;
- break;
- }
-#endif
-
- if (!in_interrupt()) {
- hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
- } else {
- /*
- * this case is a special workaround for RHEL5 bonding
- * that calls this routine from interrupt context
- */
- link_speed = adapter->link_speed;
- link_up = adapter->link_up;
- }
-
- if (link_up) {
- switch (link_speed) {
- case IXGBE_LINK_SPEED_10GB_FULL:
- ecmd->speed = SPEED_10000;
- break;
- case IXGBE_LINK_SPEED_1GB_FULL:
- ecmd->speed = SPEED_1000;
- break;
- case IXGBE_LINK_SPEED_100_FULL:
- ecmd->speed = SPEED_100;
- break;
- default:
- break;
- }
- ecmd->duplex = DUPLEX_FULL;
- } else {
- ecmd->speed = -1;
- ecmd->duplex = -1;
- }
-
- return 0;
-}
-#endif
-
-#ifndef ETHTOOL_SLINKSETTINGS
-static int ixgbe_set_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- u32 advertised, old;
- s32 err = 0;
-
- if ((hw->phy.media_type == ixgbe_media_type_copper) ||
- (hw->phy.multispeed_fiber)) {
- /*
- * this function does not support duplex forcing, but can
- * limit the advertising of the adapter to the specified speed
- */
- if (ecmd->autoneg == AUTONEG_DISABLE)
- return -EINVAL;
-
- if (ecmd->advertising & ~ecmd->supported)
- return -EINVAL;
-
- old = hw->phy.autoneg_advertised;
- advertised = 0;
- if (ecmd->advertising & ADVERTISED_10000baseT_Full)
- advertised |= IXGBE_LINK_SPEED_10GB_FULL;
-
- if (ecmd->advertising & ADVERTISED_1000baseT_Full)
- advertised |= IXGBE_LINK_SPEED_1GB_FULL;
-
- if (ecmd->advertising & ADVERTISED_100baseT_Full)
- advertised |= IXGBE_LINK_SPEED_100_FULL;
-
- if (old == advertised)
- return err;
- /* this sets the link speed and restarts auto-neg */
- hw->mac.autotry_restart = true;
- err = hw->mac.ops.setup_link(hw, advertised, true, true);
- if (err) {
- e_info(probe, "setup link failed with code %d\n", err);
- hw->mac.ops.setup_link(hw, old, true, true);
- }
- }
- return err;
-}
-#endif
-
-static void ixgbe_get_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
-
- if (hw->fc.disable_fc_autoneg)
- pause->autoneg = 0;
- else
- pause->autoneg = 1;
-
- if (hw->fc.current_mode == ixgbe_fc_rx_pause) {
- pause->rx_pause = 1;
- } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) {
- pause->tx_pause = 1;
- } else if (hw->fc.current_mode == ixgbe_fc_full) {
- pause->rx_pause = 1;
- pause->tx_pause = 1;
- }
-}
-
-static int ixgbe_set_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- struct ixgbe_fc_info fc = hw->fc;
-
- /* 82598 does no support link flow control with DCB enabled */
- if ((hw->mac.type == ixgbe_mac_82598EB) &&
- (adapter->flags & IXGBE_FLAG_DCB_ENABLED))
- return -EINVAL;
-
- fc.disable_fc_autoneg = (pause->autoneg != AUTONEG_ENABLE);
-
- if ((pause->rx_pause && pause->tx_pause) || pause->autoneg)
- fc.requested_mode = ixgbe_fc_full;
- else if (pause->rx_pause)
- fc.requested_mode = ixgbe_fc_rx_pause;
- else if (pause->tx_pause)
- fc.requested_mode = ixgbe_fc_tx_pause;
- else
- fc.requested_mode = ixgbe_fc_none;
-
- /* if the thing changed then we'll update and use new autoneg */
- if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) {
- hw->fc = fc;
- if (netif_running(netdev))
- ixgbe_reinit_locked(adapter);
- else
- ixgbe_reset(adapter);
- }
-
- return 0;
-}
-
-static u32 ixgbe_get_msglevel(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- return adapter->msg_enable;
-}
-
-static void ixgbe_set_msglevel(struct net_device *netdev, u32 data)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- adapter->msg_enable = data;
-}
-
-static int ixgbe_get_regs_len(struct net_device *netdev)
-{
-#define IXGBE_REGS_LEN 1129
- return IXGBE_REGS_LEN * sizeof(u32);
-}
-
-#define IXGBE_GET_STAT(_A_, _R_) (_A_->stats._R_)
-
-
-static void ixgbe_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
- void *p)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- u32 *regs_buff = p;
- u8 i;
-
- printk(KERN_DEBUG "ixgbe_get_regs_1\n");
- memset(p, 0, IXGBE_REGS_LEN * sizeof(u32));
- printk(KERN_DEBUG "ixgbe_get_regs_2 0x%p\n", hw->hw_addr);
-
- regs->version = (1 << 24) | hw->revision_id << 16 | hw->device_id;
-
- /* General Registers */
- regs_buff[0] = IXGBE_READ_REG(hw, IXGBE_CTRL);
- printk(KERN_DEBUG "ixgbe_get_regs_3\n");
- regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_STATUS);
- regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
- regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_ESDP);
- regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_EODSDP);
- regs_buff[5] = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
- regs_buff[6] = IXGBE_READ_REG(hw, IXGBE_FRTIMER);
- regs_buff[7] = IXGBE_READ_REG(hw, IXGBE_TCPTIMER);
-
- printk(KERN_DEBUG "ixgbe_get_regs_4\n");
-
- /* NVM Register */
- regs_buff[8] = IXGBE_READ_REG(hw, IXGBE_EEC);
- regs_buff[9] = IXGBE_READ_REG(hw, IXGBE_EERD);
- regs_buff[10] = IXGBE_READ_REG(hw, IXGBE_FLA);
- regs_buff[11] = IXGBE_READ_REG(hw, IXGBE_EEMNGCTL);
- regs_buff[12] = IXGBE_READ_REG(hw, IXGBE_EEMNGDATA);
- regs_buff[13] = IXGBE_READ_REG(hw, IXGBE_FLMNGCTL);
- regs_buff[14] = IXGBE_READ_REG(hw, IXGBE_FLMNGDATA);
- regs_buff[15] = IXGBE_READ_REG(hw, IXGBE_FLMNGCNT);
- regs_buff[16] = IXGBE_READ_REG(hw, IXGBE_FLOP);
- regs_buff[17] = IXGBE_READ_REG(hw, IXGBE_GRC);
-
- /* Interrupt */
- /* don't read EICR because it can clear interrupt causes, instead
- * read EICS which is a shadow but doesn't clear EICR */
- regs_buff[18] = IXGBE_READ_REG(hw, IXGBE_EICS);
- regs_buff[19] = IXGBE_READ_REG(hw, IXGBE_EICS);
- regs_buff[20] = IXGBE_READ_REG(hw, IXGBE_EIMS);
- regs_buff[21] = IXGBE_READ_REG(hw, IXGBE_EIMC);
- regs_buff[22] = IXGBE_READ_REG(hw, IXGBE_EIAC);
- regs_buff[23] = IXGBE_READ_REG(hw, IXGBE_EIAM);
- regs_buff[24] = IXGBE_READ_REG(hw, IXGBE_EITR(0));
- regs_buff[25] = IXGBE_READ_REG(hw, IXGBE_IVAR(0));
- regs_buff[26] = IXGBE_READ_REG(hw, IXGBE_MSIXT);
- regs_buff[27] = IXGBE_READ_REG(hw, IXGBE_MSIXPBA);
- regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_PBACL(0));
- regs_buff[29] = IXGBE_READ_REG(hw, IXGBE_GPIE);
-
- /* Flow Control */
- regs_buff[30] = IXGBE_READ_REG(hw, IXGBE_PFCTOP);
- regs_buff[31] = IXGBE_READ_REG(hw, IXGBE_FCTTV(0));
- regs_buff[32] = IXGBE_READ_REG(hw, IXGBE_FCTTV(1));
- regs_buff[33] = IXGBE_READ_REG(hw, IXGBE_FCTTV(2));
- regs_buff[34] = IXGBE_READ_REG(hw, IXGBE_FCTTV(3));
- for (i = 0; i < 8; i++) {
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL(i));
- regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH(i));
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- regs_buff[35 + i] = IXGBE_READ_REG(hw,
- IXGBE_FCRTL_82599(i));
- regs_buff[43 + i] = IXGBE_READ_REG(hw,
- IXGBE_FCRTH_82599(i));
- break;
- default:
- break;
- }
- }
- regs_buff[51] = IXGBE_READ_REG(hw, IXGBE_FCRTV);
- regs_buff[52] = IXGBE_READ_REG(hw, IXGBE_TFCS);
-
- /* Receive DMA */
- for (i = 0; i < 64; i++)
- regs_buff[53 + i] = IXGBE_READ_REG(hw, IXGBE_RDBAL(i));
- for (i = 0; i < 64; i++)
- regs_buff[117 + i] = IXGBE_READ_REG(hw, IXGBE_RDBAH(i));
- for (i = 0; i < 64; i++)
- regs_buff[181 + i] = IXGBE_READ_REG(hw, IXGBE_RDLEN(i));
- for (i = 0; i < 64; i++)
- regs_buff[245 + i] = IXGBE_READ_REG(hw, IXGBE_RDH(i));
- for (i = 0; i < 64; i++)
- regs_buff[309 + i] = IXGBE_READ_REG(hw, IXGBE_RDT(i));
- for (i = 0; i < 64; i++)
- regs_buff[373 + i] = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
- for (i = 0; i < 16; i++)
- regs_buff[437 + i] = IXGBE_READ_REG(hw, IXGBE_SRRCTL(i));
- for (i = 0; i < 16; i++)
- regs_buff[453 + i] = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
- regs_buff[469] = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
- for (i = 0; i < 8; i++)
- regs_buff[470 + i] = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
- regs_buff[478] = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
- regs_buff[479] = IXGBE_READ_REG(hw, IXGBE_DROPEN);
-
- /* Receive */
- regs_buff[480] = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
- regs_buff[481] = IXGBE_READ_REG(hw, IXGBE_RFCTL);
- for (i = 0; i < 16; i++)
- regs_buff[482 + i] = IXGBE_READ_REG(hw, IXGBE_RAL(i));
- for (i = 0; i < 16; i++)
- regs_buff[498 + i] = IXGBE_READ_REG(hw, IXGBE_RAH(i));
- regs_buff[514] = IXGBE_READ_REG(hw, IXGBE_PSRTYPE(0));
- regs_buff[515] = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- regs_buff[516] = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
- regs_buff[517] = IXGBE_READ_REG(hw, IXGBE_MCSTCTRL);
- regs_buff[518] = IXGBE_READ_REG(hw, IXGBE_MRQC);
- regs_buff[519] = IXGBE_READ_REG(hw, IXGBE_VMD_CTL);
- for (i = 0; i < 8; i++)
- regs_buff[520 + i] = IXGBE_READ_REG(hw, IXGBE_IMIR(i));
- for (i = 0; i < 8; i++)
- regs_buff[528 + i] = IXGBE_READ_REG(hw, IXGBE_IMIREXT(i));
- regs_buff[536] = IXGBE_READ_REG(hw, IXGBE_IMIRVP);
-
- /* Transmit */
- for (i = 0; i < 32; i++)
- regs_buff[537 + i] = IXGBE_READ_REG(hw, IXGBE_TDBAL(i));
- for (i = 0; i < 32; i++)
- regs_buff[569 + i] = IXGBE_READ_REG(hw, IXGBE_TDBAH(i));
- for (i = 0; i < 32; i++)
- regs_buff[601 + i] = IXGBE_READ_REG(hw, IXGBE_TDLEN(i));
- for (i = 0; i < 32; i++)
- regs_buff[633 + i] = IXGBE_READ_REG(hw, IXGBE_TDH(i));
- for (i = 0; i < 32; i++)
- regs_buff[665 + i] = IXGBE_READ_REG(hw, IXGBE_TDT(i));
- for (i = 0; i < 32; i++)
- regs_buff[697 + i] = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
- for (i = 0; i < 32; i++)
- regs_buff[729 + i] = IXGBE_READ_REG(hw, IXGBE_TDWBAL(i));
- for (i = 0; i < 32; i++)
- regs_buff[761 + i] = IXGBE_READ_REG(hw, IXGBE_TDWBAH(i));
- regs_buff[793] = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
- for (i = 0; i < 16; i++)
- regs_buff[794 + i] = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
- regs_buff[810] = IXGBE_READ_REG(hw, IXGBE_TIPG);
- for (i = 0; i < 8; i++)
- regs_buff[811 + i] = IXGBE_READ_REG(hw, IXGBE_TXPBSIZE(i));
- regs_buff[819] = IXGBE_READ_REG(hw, IXGBE_MNGTXMAP);
-
- /* Wake Up */
- regs_buff[820] = IXGBE_READ_REG(hw, IXGBE_WUC);
- regs_buff[821] = IXGBE_READ_REG(hw, IXGBE_WUFC);
- regs_buff[822] = IXGBE_READ_REG(hw, IXGBE_WUS);
- regs_buff[823] = IXGBE_READ_REG(hw, IXGBE_IPAV);
- regs_buff[824] = IXGBE_READ_REG(hw, IXGBE_IP4AT);
- regs_buff[825] = IXGBE_READ_REG(hw, IXGBE_IP6AT);
- regs_buff[826] = IXGBE_READ_REG(hw, IXGBE_WUPL);
- regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM);
- regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT(0));
-
- /* DCB */
- regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS);
- regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS);
- regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
- regs_buff[832] = IXGBE_READ_REG(hw, IXGBE_RUPPBMR);
- for (i = 0; i < 8; i++)
- regs_buff[833 + i] = IXGBE_READ_REG(hw, IXGBE_RT2CR(i));
- for (i = 0; i < 8; i++)
- regs_buff[841 + i] = IXGBE_READ_REG(hw, IXGBE_RT2SR(i));
- for (i = 0; i < 8; i++)
- regs_buff[849 + i] = IXGBE_READ_REG(hw, IXGBE_TDTQ2TCCR(i));
- for (i = 0; i < 8; i++)
- regs_buff[857 + i] = IXGBE_READ_REG(hw, IXGBE_TDTQ2TCSR(i));
- for (i = 0; i < 8; i++)
- regs_buff[865 + i] = IXGBE_READ_REG(hw, IXGBE_TDPT2TCCR(i));
- for (i = 0; i < 8; i++)
- regs_buff[873 + i] = IXGBE_READ_REG(hw, IXGBE_TDPT2TCSR(i));
-
- /* Statistics */
- regs_buff[881] = IXGBE_GET_STAT(adapter, crcerrs);
- regs_buff[882] = IXGBE_GET_STAT(adapter, illerrc);
- regs_buff[883] = IXGBE_GET_STAT(adapter, errbc);
- regs_buff[884] = IXGBE_GET_STAT(adapter, mspdc);
- for (i = 0; i < 8; i++)
- regs_buff[885 + i] = IXGBE_GET_STAT(adapter, mpc[i]);
- regs_buff[893] = IXGBE_GET_STAT(adapter, mlfc);
- regs_buff[894] = IXGBE_GET_STAT(adapter, mrfc);
- regs_buff[895] = IXGBE_GET_STAT(adapter, rlec);
- regs_buff[896] = IXGBE_GET_STAT(adapter, lxontxc);
- regs_buff[897] = IXGBE_GET_STAT(adapter, lxonrxc);
- regs_buff[898] = IXGBE_GET_STAT(adapter, lxofftxc);
- regs_buff[899] = IXGBE_GET_STAT(adapter, lxoffrxc);
- for (i = 0; i < 8; i++)
- regs_buff[900 + i] = IXGBE_GET_STAT(adapter, pxontxc[i]);
- for (i = 0; i < 8; i++)
- regs_buff[908 + i] = IXGBE_GET_STAT(adapter, pxonrxc[i]);
- for (i = 0; i < 8; i++)
- regs_buff[916 + i] = IXGBE_GET_STAT(adapter, pxofftxc[i]);
- for (i = 0; i < 8; i++)
- regs_buff[924 + i] = IXGBE_GET_STAT(adapter, pxoffrxc[i]);
- regs_buff[932] = IXGBE_GET_STAT(adapter, prc64);
- regs_buff[933] = IXGBE_GET_STAT(adapter, prc127);
- regs_buff[934] = IXGBE_GET_STAT(adapter, prc255);
- regs_buff[935] = IXGBE_GET_STAT(adapter, prc511);
- regs_buff[936] = IXGBE_GET_STAT(adapter, prc1023);
- regs_buff[937] = IXGBE_GET_STAT(adapter, prc1522);
- regs_buff[938] = IXGBE_GET_STAT(adapter, gprc);
- regs_buff[939] = IXGBE_GET_STAT(adapter, bprc);
- regs_buff[940] = IXGBE_GET_STAT(adapter, mprc);
- regs_buff[941] = IXGBE_GET_STAT(adapter, gptc);
- regs_buff[942] = IXGBE_GET_STAT(adapter, gorc);
- regs_buff[944] = IXGBE_GET_STAT(adapter, gotc);
- for (i = 0; i < 8; i++)
- regs_buff[946 + i] = IXGBE_GET_STAT(adapter, rnbc[i]);
- regs_buff[954] = IXGBE_GET_STAT(adapter, ruc);
- regs_buff[955] = IXGBE_GET_STAT(adapter, rfc);
- regs_buff[956] = IXGBE_GET_STAT(adapter, roc);
- regs_buff[957] = IXGBE_GET_STAT(adapter, rjc);
- regs_buff[958] = IXGBE_GET_STAT(adapter, mngprc);
- regs_buff[959] = IXGBE_GET_STAT(adapter, mngpdc);
- regs_buff[960] = IXGBE_GET_STAT(adapter, mngptc);
- regs_buff[961] = IXGBE_GET_STAT(adapter, tor);
- regs_buff[963] = IXGBE_GET_STAT(adapter, tpr);
- regs_buff[964] = IXGBE_GET_STAT(adapter, tpt);
- regs_buff[965] = IXGBE_GET_STAT(adapter, ptc64);
- regs_buff[966] = IXGBE_GET_STAT(adapter, ptc127);
- regs_buff[967] = IXGBE_GET_STAT(adapter, ptc255);
- regs_buff[968] = IXGBE_GET_STAT(adapter, ptc511);
- regs_buff[969] = IXGBE_GET_STAT(adapter, ptc1023);
- regs_buff[970] = IXGBE_GET_STAT(adapter, ptc1522);
- regs_buff[971] = IXGBE_GET_STAT(adapter, mptc);
- regs_buff[972] = IXGBE_GET_STAT(adapter, bptc);
- regs_buff[973] = IXGBE_GET_STAT(adapter, xec);
- for (i = 0; i < 16; i++)
- regs_buff[974 + i] = IXGBE_GET_STAT(adapter, qprc[i]);
- for (i = 0; i < 16; i++)
- regs_buff[990 + i] = IXGBE_GET_STAT(adapter, qptc[i]);
- for (i = 0; i < 16; i++)
- regs_buff[1006 + i] = IXGBE_GET_STAT(adapter, qbrc[i]);
- for (i = 0; i < 16; i++)
- regs_buff[1022 + i] = IXGBE_GET_STAT(adapter, qbtc[i]);
-
- /* MAC */
- regs_buff[1038] = IXGBE_READ_REG(hw, IXGBE_PCS1GCFIG);
- regs_buff[1039] = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
- regs_buff[1040] = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
- regs_buff[1041] = IXGBE_READ_REG(hw, IXGBE_PCS1GDBG0);
- regs_buff[1042] = IXGBE_READ_REG(hw, IXGBE_PCS1GDBG1);
- regs_buff[1043] = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
- regs_buff[1044] = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
- regs_buff[1045] = IXGBE_READ_REG(hw, IXGBE_PCS1GANNP);
- regs_buff[1046] = IXGBE_READ_REG(hw, IXGBE_PCS1GANLPNP);
- regs_buff[1047] = IXGBE_READ_REG(hw, IXGBE_HLREG0);
- regs_buff[1048] = IXGBE_READ_REG(hw, IXGBE_HLREG1);
- regs_buff[1049] = IXGBE_READ_REG(hw, IXGBE_PAP);
- regs_buff[1050] = IXGBE_READ_REG(hw, IXGBE_MACA);
- regs_buff[1051] = IXGBE_READ_REG(hw, IXGBE_APAE);
- regs_buff[1052] = IXGBE_READ_REG(hw, IXGBE_ARD);
- regs_buff[1053] = IXGBE_READ_REG(hw, IXGBE_AIS);
- regs_buff[1054] = IXGBE_READ_REG(hw, IXGBE_MSCA);
- regs_buff[1055] = IXGBE_READ_REG(hw, IXGBE_MSRWD);
- regs_buff[1056] = IXGBE_READ_REG(hw, IXGBE_MLADD);
- regs_buff[1057] = IXGBE_READ_REG(hw, IXGBE_MHADD);
- regs_buff[1058] = IXGBE_READ_REG(hw, IXGBE_TREG);
- regs_buff[1059] = IXGBE_READ_REG(hw, IXGBE_PCSS1);
- regs_buff[1060] = IXGBE_READ_REG(hw, IXGBE_PCSS2);
- regs_buff[1061] = IXGBE_READ_REG(hw, IXGBE_XPCSS);
- regs_buff[1062] = IXGBE_READ_REG(hw, IXGBE_SERDESC);
- regs_buff[1063] = IXGBE_READ_REG(hw, IXGBE_MACS);
- regs_buff[1064] = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- regs_buff[1065] = IXGBE_READ_REG(hw, IXGBE_LINKS);
- regs_buff[1066] = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
- regs_buff[1067] = IXGBE_READ_REG(hw, IXGBE_AUTOC3);
- regs_buff[1068] = IXGBE_READ_REG(hw, IXGBE_ANLP1);
- regs_buff[1069] = IXGBE_READ_REG(hw, IXGBE_ANLP2);
- regs_buff[1070] = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
-
- /* Diagnostic */
- regs_buff[1071] = IXGBE_READ_REG(hw, IXGBE_RDSTATCTL);
- for (i = 0; i < 8; i++)
- regs_buff[1072 + i] = IXGBE_READ_REG(hw, IXGBE_RDSTAT(i));
- regs_buff[1080] = IXGBE_READ_REG(hw, IXGBE_RDHMPN);
- for (i = 0; i < 4; i++)
- regs_buff[1081 + i] = IXGBE_READ_REG(hw, IXGBE_RIC_DW(i));
- regs_buff[1085] = IXGBE_READ_REG(hw, IXGBE_RDPROBE);
- regs_buff[1086] = IXGBE_READ_REG(hw, IXGBE_TDSTATCTL);
- for (i = 0; i < 8; i++)
- regs_buff[1087 + i] = IXGBE_READ_REG(hw, IXGBE_TDSTAT(i));
- regs_buff[1095] = IXGBE_READ_REG(hw, IXGBE_TDHMPN);
- for (i = 0; i < 4; i++)
- regs_buff[1096 + i] = IXGBE_READ_REG(hw, IXGBE_TIC_DW(i));
- regs_buff[1100] = IXGBE_READ_REG(hw, IXGBE_TDPROBE);
- regs_buff[1101] = IXGBE_READ_REG(hw, IXGBE_TXBUFCTRL);
- regs_buff[1102] = IXGBE_READ_REG(hw, IXGBE_TXBUFDATA0);
- regs_buff[1103] = IXGBE_READ_REG(hw, IXGBE_TXBUFDATA1);
- regs_buff[1104] = IXGBE_READ_REG(hw, IXGBE_TXBUFDATA2);
- regs_buff[1105] = IXGBE_READ_REG(hw, IXGBE_TXBUFDATA3);
- regs_buff[1106] = IXGBE_READ_REG(hw, IXGBE_RXBUFCTRL);
- regs_buff[1107] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA0);
- regs_buff[1108] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA1);
- regs_buff[1109] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA2);
- regs_buff[1110] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA3);
- for (i = 0; i < 8; i++)
- regs_buff[1111 + i] = IXGBE_READ_REG(hw, IXGBE_PCIE_DIAG(i));
- regs_buff[1119] = IXGBE_READ_REG(hw, IXGBE_RFVAL);
- regs_buff[1120] = IXGBE_READ_REG(hw, IXGBE_MDFTC1);
- regs_buff[1121] = IXGBE_READ_REG(hw, IXGBE_MDFTC2);
- regs_buff[1122] = IXGBE_READ_REG(hw, IXGBE_MDFTFIFO1);
- regs_buff[1123] = IXGBE_READ_REG(hw, IXGBE_MDFTFIFO2);
- regs_buff[1124] = IXGBE_READ_REG(hw, IXGBE_MDFTS);
- regs_buff[1125] = IXGBE_READ_REG(hw, IXGBE_PCIEECCCTL);
- regs_buff[1126] = IXGBE_READ_REG(hw, IXGBE_PBTXECC);
- regs_buff[1127] = IXGBE_READ_REG(hw, IXGBE_PBRXECC);
-
- /* 82599 X540 specific registers */
- regs_buff[1128] = IXGBE_READ_REG(hw, IXGBE_MFLCN);
-}
-
-static int ixgbe_get_eeprom_len(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- return adapter->hw.eeprom.word_size * 2;
-}
-
-static int ixgbe_get_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *eeprom, u8 *bytes)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- u16 *eeprom_buff;
- int first_word, last_word, eeprom_len;
- int ret_val = 0;
- u16 i;
-
- if (eeprom->len == 0)
- return -EINVAL;
-
- eeprom->magic = hw->vendor_id | (hw->device_id << 16);
-
- first_word = eeprom->offset >> 1;
- last_word = (eeprom->offset + eeprom->len - 1) >> 1;
- eeprom_len = last_word - first_word + 1;
-
- eeprom_buff = kmalloc(sizeof(u16) * eeprom_len, GFP_KERNEL);
- if (!eeprom_buff)
- return -ENOMEM;
-
- ret_val = ixgbe_read_eeprom_buffer(hw, first_word, eeprom_len,
- eeprom_buff);
-
- /* Device's eeprom is always little-endian, word addressable */
- for (i = 0; i < eeprom_len; i++)
- le16_to_cpus(&eeprom_buff[i]);
-
- memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
- kfree(eeprom_buff);
-
- return ret_val;
-}
-
-static int ixgbe_set_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *eeprom, u8 *bytes)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- u16 *eeprom_buff;
- void *ptr;
- int max_len, first_word, last_word, ret_val = 0;
- u16 i;
-
- if (eeprom->len == 0)
- return -EINVAL;
-
- if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
- return -EINVAL;
-
- max_len = hw->eeprom.word_size * 2;
-
- first_word = eeprom->offset >> 1;
- last_word = (eeprom->offset + eeprom->len - 1) >> 1;
- eeprom_buff = kmalloc(max_len, GFP_KERNEL);
- if (!eeprom_buff)
- return -ENOMEM;
-
- ptr = eeprom_buff;
-
- if (eeprom->offset & 1) {
- /*
- * need read/modify/write of first changed EEPROM word
- * only the second byte of the word is being modified
- */
- ret_val = ixgbe_read_eeprom(hw, first_word, &eeprom_buff[0]);
- if (ret_val)
- goto err;
-
- ptr++;
- }
- if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
- /*
- * need read/modify/write of last changed EEPROM word
- * only the first byte of the word is being modified
- */
- ret_val = ixgbe_read_eeprom(hw, last_word,
- &eeprom_buff[last_word - first_word]);
- if (ret_val)
- goto err;
- }
-
- /* Device's eeprom is always little-endian, word addressable */
- for (i = 0; i < last_word - first_word + 1; i++)
- le16_to_cpus(&eeprom_buff[i]);
-
- memcpy(ptr, bytes, eeprom->len);
-
- for (i = 0; i < last_word - first_word + 1; i++)
- cpu_to_le16s(&eeprom_buff[i]);
-
- ret_val = ixgbe_write_eeprom_buffer(hw, first_word,
- last_word - first_word + 1,
- eeprom_buff);
-
- /* Update the checksum */
- if (ret_val == 0)
- ixgbe_update_eeprom_checksum(hw);
-
-err:
- kfree(eeprom_buff);
- return ret_val;
-}
-
-static void ixgbe_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- strlcpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver));
-
- strlcpy(drvinfo->version, ixgbe_driver_version,
- sizeof(drvinfo->version));
-
- strlcpy(drvinfo->fw_version, adapter->eeprom_id,
- sizeof(drvinfo->fw_version));
-
- strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
- sizeof(drvinfo->bus_info));
-
- drvinfo->n_stats = IXGBE_STATS_LEN;
- drvinfo->testinfo_len = IXGBE_TEST_LEN;
- drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
-}
-
-static void ixgbe_get_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- ring->rx_max_pending = IXGBE_MAX_RXD;
- ring->tx_max_pending = IXGBE_MAX_TXD;
- ring->rx_mini_max_pending = 0;
- ring->rx_jumbo_max_pending = 0;
- ring->rx_pending = adapter->rx_ring_count;
- ring->tx_pending = adapter->tx_ring_count;
- ring->rx_mini_pending = 0;
- ring->rx_jumbo_pending = 0;
-}
-
-static int ixgbe_set_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_ring *tx_ring = NULL, *rx_ring = NULL;
- u32 new_rx_count, new_tx_count;
- int i, err = 0;
-
- if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
- return -EINVAL;
-
- new_tx_count = clamp_t(u32, ring->tx_pending,
- IXGBE_MIN_TXD, IXGBE_MAX_TXD);
- new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE);
-
- new_rx_count = clamp_t(u32, ring->rx_pending,
- IXGBE_MIN_RXD, IXGBE_MAX_RXD);
- new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE);
-
- /* if nothing to do return success */
- if ((new_tx_count == adapter->tx_ring_count) &&
- (new_rx_count == adapter->rx_ring_count))
- return 0;
-
- while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- usleep_range(1000, 2000);
-
- if (!netif_running(adapter->netdev)) {
- for (i = 0; i < adapter->num_tx_queues; i++)
- adapter->tx_ring[i]->count = new_tx_count;
- for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i]->count = new_rx_count;
- adapter->tx_ring_count = new_tx_count;
- adapter->rx_ring_count = new_rx_count;
- goto clear_reset;
- }
-
- /* alloc updated Tx resources */
- if (new_tx_count != adapter->tx_ring_count) {
- tx_ring = vmalloc(adapter->num_tx_queues * sizeof(*tx_ring));
- if (!tx_ring) {
- err = -ENOMEM;
- goto clear_reset;
- }
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- /* clone ring and setup updated count */
- tx_ring[i] = *adapter->tx_ring[i];
- tx_ring[i].count = new_tx_count;
- err = ixgbe_setup_tx_resources(&tx_ring[i]);
- if (err) {
- while (i) {
- i--;
- ixgbe_free_tx_resources(&tx_ring[i]);
- }
-
- vfree(tx_ring);
- tx_ring = NULL;
-
- goto clear_reset;
- }
- }
- }
-
- /* alloc updated Rx resources */
- if (new_rx_count != adapter->rx_ring_count) {
- rx_ring = vmalloc(adapter->num_rx_queues * sizeof(*rx_ring));
- if (!rx_ring) {
- err = -ENOMEM;
- goto clear_reset;
- }
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- /* clone ring and setup updated count */
- rx_ring[i] = *adapter->rx_ring[i];
- rx_ring[i].count = new_rx_count;
- err = ixgbe_setup_rx_resources(&rx_ring[i]);
- if (err) {
- while (i) {
- i--;
- ixgbe_free_rx_resources(&rx_ring[i]);
- }
-
- vfree(rx_ring);
- rx_ring = NULL;
-
- goto clear_reset;
- }
- }
- }
-
- /* bring interface down to prepare for update */
- ixgbe_down(adapter);
-
- /* Tx */
- if (tx_ring) {
- for (i = 0; i < adapter->num_tx_queues; i++) {
- ixgbe_free_tx_resources(adapter->tx_ring[i]);
- *adapter->tx_ring[i] = tx_ring[i];
- }
- adapter->tx_ring_count = new_tx_count;
-
- vfree(tx_ring);
- tx_ring = NULL;
- }
-
- /* Rx */
- if (rx_ring) {
- for (i = 0; i < adapter->num_rx_queues; i++) {
- ixgbe_free_rx_resources(adapter->rx_ring[i]);
- *adapter->rx_ring[i] = rx_ring[i];
- }
- adapter->rx_ring_count = new_rx_count;
-
- vfree(rx_ring);
- rx_ring = NULL;
- }
-
- /* restore interface using new values */
- ixgbe_up(adapter);
-
-clear_reset:
- /* free Tx resources if Rx error is encountered */
- if (tx_ring) {
- for (i = 0; i < adapter->num_tx_queues; i++)
- ixgbe_free_tx_resources(&tx_ring[i]);
- vfree(tx_ring);
- }
-
- clear_bit(__IXGBE_RESETTING, &adapter->state);
- return err;
-}
-
-#ifndef HAVE_ETHTOOL_GET_SSET_COUNT
-static int ixgbe_get_stats_count(struct net_device *netdev)
-{
- return IXGBE_STATS_LEN;
-}
-
-#else /* HAVE_ETHTOOL_GET_SSET_COUNT */
-static int ixgbe_get_sset_count(struct net_device *netdev, int sset)
-{
- switch (sset) {
- case ETH_SS_TEST:
- return IXGBE_TEST_LEN;
- case ETH_SS_STATS:
- return IXGBE_STATS_LEN;
- default:
- return -EOPNOTSUPP;
- }
-}
-
-#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */
-static void ixgbe_get_ethtool_stats(struct net_device *netdev,
- struct ethtool_stats *stats, u64 *data)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-#ifdef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats *net_stats = &netdev->stats;
-#else
- struct net_device_stats *net_stats = &adapter->net_stats;
-#endif
- u64 *queue_stat;
- int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
- int i, j, k;
- char *p;
-
- printk(KERN_DEBUG "ixgbe_stats 0\n");
- ixgbe_update_stats(adapter);
- printk(KERN_DEBUG "ixgbe_stats 1\n");
-
- for (i = 0; i < IXGBE_NETDEV_STATS_LEN; i++) {
- p = (char *)net_stats + ixgbe_gstrings_net_stats[i].stat_offset;
- data[i] = (ixgbe_gstrings_net_stats[i].sizeof_stat ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
- }
- for (j = 0; j < IXGBE_GLOBAL_STATS_LEN; j++, i++) {
- p = (char *)adapter + ixgbe_gstrings_stats[j].stat_offset;
- data[i] = (ixgbe_gstrings_stats[j].sizeof_stat ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
- }
- printk(KERN_DEBUG "ixgbe_stats 2\n");
-#ifdef NO_VNIC
- for (j = 0; j < adapter->num_tx_queues; j++) {
- queue_stat = (u64 *)&adapter->tx_ring[j]->stats;
- for (k = 0; k < stat_count; k++)
- data[i + k] = queue_stat[k];
- i += k;
- }
- for (j = 0; j < adapter->num_rx_queues; j++) {
- queue_stat = (u64 *)&adapter->rx_ring[j]->stats;
- for (k = 0; k < stat_count; k++)
- data[i + k] = queue_stat[k];
- i += k;
- }
- printk(KERN_DEBUG "ixgbe_stats 3\n");
-#endif
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- for (j = 0; j < MAX_TX_PACKET_BUFFERS; j++) {
- data[i++] = adapter->stats.pxontxc[j];
- data[i++] = adapter->stats.pxofftxc[j];
- }
- for (j = 0; j < MAX_RX_PACKET_BUFFERS; j++) {
- data[i++] = adapter->stats.pxonrxc[j];
- data[i++] = adapter->stats.pxoffrxc[j];
- }
- }
- printk(KERN_DEBUG "ixgbe_stats 4\n");
- stat_count = sizeof(struct vf_stats) / sizeof(u64);
- for (j = 0; j < adapter->num_vfs; j++) {
- queue_stat = (u64 *)&adapter->vfinfo[j].vfstats;
- for (k = 0; k < stat_count; k++)
- data[i + k] = queue_stat[k];
- queue_stat = (u64 *)&adapter->vfinfo[j].saved_rst_vfstats;
- for (k = 0; k < stat_count; k++)
- data[i + k] += queue_stat[k];
- i += k;
- }
-}
-
-static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
- u8 *data)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- char *p = (char *)data;
- int i;
-
- switch (stringset) {
- case ETH_SS_TEST:
- memcpy(data, *ixgbe_gstrings_test,
- IXGBE_TEST_LEN * ETH_GSTRING_LEN);
- break;
- case ETH_SS_STATS:
- for (i = 0; i < IXGBE_NETDEV_STATS_LEN; i++) {
- memcpy(p, ixgbe_gstrings_net_stats[i].stat_string,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
- memcpy(p, ixgbe_gstrings_stats[i].stat_string,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < adapter->num_tx_queues; i++) {
- sprintf(p, "tx_queue_%u_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "tx_queue_%u_bytes", i);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < adapter->num_rx_queues; i++) {
- sprintf(p, "rx_queue_%u_packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_queue_%u_bytes", i);
- p += ETH_GSTRING_LEN;
- }
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) {
- sprintf(p, "tx_pb_%u_pxon", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "tx_pb_%u_pxoff", i);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < MAX_RX_PACKET_BUFFERS; i++) {
- sprintf(p, "rx_pb_%u_pxon", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_pb_%u_pxoff", i);
- p += ETH_GSTRING_LEN;
- }
- }
- for (i = 0; i < adapter->num_vfs; i++) {
- sprintf(p, "VF %d Rx Packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "VF %d Rx Bytes", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "VF %d Tx Packets", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "VF %d Tx Bytes", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "VF %d MC Packets", i);
- p += ETH_GSTRING_LEN;
- }
- /* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
- break;
- }
-}
-
-static int ixgbe_link_test(struct ixgbe_adapter *adapter, u64 *data)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- bool link_up;
- u32 link_speed = 0;
- *data = 0;
-
- hw->mac.ops.check_link(hw, &link_speed, &link_up, true);
- if (link_up)
- return *data;
- else
- *data = 1;
- return *data;
-}
-
-/* ethtool register test data */
-struct ixgbe_reg_test {
- u16 reg;
- u8 array_len;
- u8 test_type;
- u32 mask;
- u32 write;
-};
-
-/* In the hardware, registers are laid out either singly, in arrays
- * spaced 0x40 bytes apart, or in contiguous tables. We assume
- * most tests take place on arrays or single registers (handled
- * as a single-element array) and special-case the tables.
- * Table tests are always pattern tests.
- *
- * We also make provision for some required setup steps by specifying
- * registers to be written without any read-back testing.
- */
-
-#define PATTERN_TEST 1
-#define SET_READ_TEST 2
-#define WRITE_NO_TEST 3
-#define TABLE32_TEST 4
-#define TABLE64_TEST_LO 5
-#define TABLE64_TEST_HI 6
-
-/* default 82599 register test */
-static struct ixgbe_reg_test reg_test_82599[] = {
- { IXGBE_FCRTL_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
- { IXGBE_FCRTH_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
- { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 },
- { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
- { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE },
- { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 },
- { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
- { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFF80 },
- { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000001, 0x00000001 },
- { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x8001FFFF, 0x800CFFFF },
- { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { 0, 0, 0, 0 }
-};
-
-/* default 82598 register test */
-static struct ixgbe_reg_test reg_test_82598[] = {
- { IXGBE_FCRTL(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
- { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
- { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 },
- { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- /* Enable all four RX queues before testing. */
- { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE },
- /* RDH is read-only for 82598, only test RDT. */
- { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 },
- { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
- { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_TIPG, 1, PATTERN_TEST, 0x000000FF, 0x000000FF },
- { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000003, 0x00000003 },
- { IXGBE_DTXCTL, 1, SET_READ_TEST, 0x00000005, 0x00000005 },
- { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
- { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x800CFFFF, 0x800CFFFF },
- { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { 0, 0, 0, 0 }
-};
-
-#define REG_PATTERN_TEST(R, M, W) \
-{ \
- u32 pat, val, before; \
- const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
- for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { \
- before = readl(adapter->hw.hw_addr + R); \
- writel((_test[pat] & W), (adapter->hw.hw_addr + R)); \
- val = readl(adapter->hw.hw_addr + R); \
- if (val != (_test[pat] & W & M)) { \
- e_err(drv, "pattern test reg %04X failed: got " \
- "0x%08X expected 0x%08X\n", \
- R, val, (_test[pat] & W & M)); \
- *data = R; \
- writel(before, adapter->hw.hw_addr + R); \
- return 1; \
- } \
- writel(before, adapter->hw.hw_addr + R); \
- } \
-}
-
-#define REG_SET_AND_CHECK(R, M, W) \
-{ \
- u32 val, before; \
- before = readl(adapter->hw.hw_addr + R); \
- writel((W & M), (adapter->hw.hw_addr + R)); \
- val = readl(adapter->hw.hw_addr + R); \
- if ((W & M) != (val & M)) { \
- e_err(drv, "set/check reg %04X test failed: got 0x%08X " \
- "expected 0x%08X\n", R, (val & M), (W & M)); \
- *data = R; \
- writel(before, (adapter->hw.hw_addr + R)); \
- return 1; \
- } \
- writel(before, (adapter->hw.hw_addr + R)); \
-}
-
-static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
-{
- struct ixgbe_reg_test *test;
- u32 value, status_before, status_after;
- u32 i, toggle;
-
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- toggle = 0x7FFFF3FF;
- test = reg_test_82598;
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- toggle = 0x7FFFF30F;
- test = reg_test_82599;
- break;
- default:
- *data = 1;
- return 1;
- break;
- }
-
- /*
- * Because the status register is such a special case,
- * we handle it separately from the rest of the register
- * tests. Some bits are read-only, some toggle, and some
- * are writeable on newer MACs.
- */
- status_before = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS);
- value = (IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, toggle);
- status_after = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle;
- if (value != status_after) {
- e_err(drv, "failed STATUS register test got: "
- "0x%08X expected: 0x%08X\n", status_after, value);
- *data = 1;
- return 1;
- }
- /* restore previous status */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, status_before);
-
- /*
- * Perform the remainder of the register test, looping through
- * the test table until we either fail or reach the null entry.
- */
- while (test->reg) {
- for (i = 0; i < test->array_len; i++) {
- switch (test->test_type) {
- case PATTERN_TEST:
- REG_PATTERN_TEST(test->reg + (i * 0x40),
- test->mask,
- test->write);
- break;
- case SET_READ_TEST:
- REG_SET_AND_CHECK(test->reg + (i * 0x40),
- test->mask,
- test->write);
- break;
- case WRITE_NO_TEST:
- writel(test->write,
- (adapter->hw.hw_addr + test->reg)
- + (i * 0x40));
- break;
- case TABLE32_TEST:
- REG_PATTERN_TEST(test->reg + (i * 4),
- test->mask,
- test->write);
- break;
- case TABLE64_TEST_LO:
- REG_PATTERN_TEST(test->reg + (i * 8),
- test->mask,
- test->write);
- break;
- case TABLE64_TEST_HI:
- REG_PATTERN_TEST((test->reg + 4) + (i * 8),
- test->mask,
- test->write);
- break;
- }
- }
- test++;
- }
-
- *data = 0;
- return 0;
-}
-
-static int ixgbe_eeprom_test(struct ixgbe_adapter *adapter, u64 *data)
-{
- if (ixgbe_validate_eeprom_checksum(&adapter->hw, NULL))
- *data = 1;
- else
- *data = 0;
- return *data;
-}
-
-static irqreturn_t ixgbe_test_intr(int irq, void *data)
-{
- struct net_device *netdev = data;
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- adapter->test_icr |= IXGBE_READ_REG(&adapter->hw, IXGBE_EICR);
-
- return IRQ_HANDLED;
-}
-
-static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
-{
- struct net_device *netdev = adapter->netdev;
- u32 mask, i = 0, shared_int = true;
- u32 irq = adapter->pdev->irq;
-
- *data = 0;
-
- /* Hook up test interrupt handler just for this test */
- if (adapter->msix_entries) {
- /* NOTE: we don't test MSI-X interrupts here, yet */
- return 0;
- } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
- shared_int = false;
- if (request_irq(irq, &ixgbe_test_intr, 0, netdev->name,
- netdev)) {
- *data = 1;
- return -1;
- }
- } else if (!request_irq(irq, &ixgbe_test_intr, IRQF_PROBE_SHARED,
- netdev->name, netdev)) {
- shared_int = false;
- } else if (request_irq(irq, &ixgbe_test_intr, IRQF_SHARED,
- netdev->name, netdev)) {
- *data = 1;
- return -1;
- }
- e_info(hw, "testing %s interrupt\n",
- (shared_int ? "shared" : "unshared"));
-
- /* Disable all the interrupts */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
- IXGBE_WRITE_FLUSH(&adapter->hw);
- usleep_range(10000, 20000);
-
- /* Test each interrupt */
- for (; i < 10; i++) {
- /* Interrupt to test */
- mask = 1 << i;
-
- if (!shared_int) {
- /*
- * Disable the interrupts to be reported in
- * the cause register and then force the same
- * interrupt and see if one gets posted. If
- * an interrupt was posted to the bus, the
- * test failed.
- */
- adapter->test_icr = 0;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC,
- ~mask & 0x00007FFF);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
- ~mask & 0x00007FFF);
- IXGBE_WRITE_FLUSH(&adapter->hw);
- usleep_range(10000, 20000);
-
- if (adapter->test_icr & mask) {
- *data = 3;
- break;
- }
- }
-
- /*
- * Enable the interrupt to be reported in the cause
- * register and then force the same interrupt and see
- * if one gets posted. If an interrupt was not posted
- * to the bus, the test failed.
- */
- adapter->test_icr = 0;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
- IXGBE_WRITE_FLUSH(&adapter->hw);
- usleep_range(10000, 20000);
-
- if (!(adapter->test_icr & mask)) {
- *data = 4;
- break;
- }
-
- if (!shared_int) {
- /*
- * Disable the other interrupts to be reported in
- * the cause register and then force the other
- * interrupts and see if any get posted. If
- * an interrupt was posted to the bus, the
- * test failed.
- */
- adapter->test_icr = 0;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC,
- ~mask & 0x00007FFF);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
- ~mask & 0x00007FFF);
- IXGBE_WRITE_FLUSH(&adapter->hw);
- usleep_range(10000, 20000);
-
- if (adapter->test_icr) {
- *data = 5;
- break;
- }
- }
- }
-
- /* Disable all the interrupts */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
- IXGBE_WRITE_FLUSH(&adapter->hw);
- usleep_range(10000, 20000);
-
- /* Unhook test interrupt handler */
- free_irq(irq, netdev);
-
- return *data;
-}
-
-
-
-static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- u32 reg_data;
-
- /* X540 needs to set the MACC.FLU bit to force link up */
- if (adapter->hw.mac.type == ixgbe_mac_X540) {
- reg_data = IXGBE_READ_REG(hw, IXGBE_MACC);
- reg_data |= IXGBE_MACC_FLU;
- IXGBE_WRITE_REG(hw, IXGBE_MACC, reg_data);
- }
-
- /* right now we only support MAC loopback in the driver */
- reg_data = IXGBE_READ_REG(hw, IXGBE_HLREG0);
- /* Setup MAC loopback */
- reg_data |= IXGBE_HLREG0_LPBK;
- IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg_data);
-
- reg_data = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE;
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg_data);
-
- reg_data = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- reg_data &= ~IXGBE_AUTOC_LMS_MASK;
- reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_data);
- IXGBE_WRITE_FLUSH(hw);
- usleep_range(10000, 20000);
-
- /* Disable Atlas Tx lanes; re-enabled in reset path */
- if (hw->mac.type == ixgbe_mac_82598EB) {
- u8 atlas;
-
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &atlas);
- atlas |= IXGBE_ATLAS_PDN_TX_REG_EN;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, atlas);
-
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &atlas);
- atlas |= IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, atlas);
-
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &atlas);
- atlas |= IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, atlas);
-
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &atlas);
- atlas |= IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, atlas);
- }
-
- return 0;
-}
-
-static void ixgbe_loopback_cleanup(struct ixgbe_adapter *adapter)
-{
- u32 reg_data;
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
- reg_data &= ~IXGBE_HLREG0_LPBK;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
-}
-
-
-
-
-
-
-static int ixgbe_loopback_test(struct ixgbe_adapter *adapter, u64 *data)
-{
-
- //*data = ixgbe_setup_desc_rings(adapter);
- //if (*data)
- // goto out;
- *data = ixgbe_setup_loopback_test(adapter);
- if (*data)
- goto err_loopback;
- //*data = ixgbe_run_loopback_test(adapter);
- ixgbe_loopback_cleanup(adapter);
-
-err_loopback:
- //ixgbe_free_desc_rings(adapter);
-//out:
- return *data;
-
-}
-
-#ifndef HAVE_ETHTOOL_GET_SSET_COUNT
-static int ixgbe_diag_test_count(struct net_device *netdev)
-{
- return IXGBE_TEST_LEN;
-}
-
-#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */
-static void ixgbe_diag_test(struct net_device *netdev,
- struct ethtool_test *eth_test, u64 *data)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- bool if_running = netif_running(netdev);
-
- set_bit(__IXGBE_TESTING, &adapter->state);
- if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
- /* Offline tests */
-
- e_info(hw, "offline testing starting\n");
-
- /* Link test performed before hardware reset so autoneg doesn't
- * interfere with test result */
- if (ixgbe_link_test(adapter, &data[4]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
- int i;
- for (i = 0; i < adapter->num_vfs; i++) {
- if (adapter->vfinfo[i].clear_to_send) {
- e_warn(drv, "Please take active VFS "
- "offline and restart the "
- "adapter before running NIC "
- "diagnostics\n");
- data[0] = 1;
- data[1] = 1;
- data[2] = 1;
- data[3] = 1;
- eth_test->flags |= ETH_TEST_FL_FAILED;
- clear_bit(__IXGBE_TESTING,
- &adapter->state);
- goto skip_ol_tests;
- }
- }
- }
-
- if (if_running)
- /* indicate we're in test mode */
- dev_close(netdev);
- else
- ixgbe_reset(adapter);
-
- e_info(hw, "register testing starting\n");
- if (ixgbe_reg_test(adapter, &data[0]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- ixgbe_reset(adapter);
- e_info(hw, "eeprom testing starting\n");
- if (ixgbe_eeprom_test(adapter, &data[1]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- ixgbe_reset(adapter);
- e_info(hw, "interrupt testing starting\n");
- if (ixgbe_intr_test(adapter, &data[2]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- /* If SRIOV or VMDq is enabled then skip MAC
- * loopback diagnostic. */
- if (adapter->flags & (IXGBE_FLAG_SRIOV_ENABLED |
- IXGBE_FLAG_VMDQ_ENABLED)) {
- e_info(hw, "skip MAC loopback diagnostic in VT mode\n");
- data[3] = 0;
- goto skip_loopback;
- }
-
- ixgbe_reset(adapter);
- e_info(hw, "loopback testing starting\n");
- if (ixgbe_loopback_test(adapter, &data[3]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
-skip_loopback:
- ixgbe_reset(adapter);
-
- clear_bit(__IXGBE_TESTING, &adapter->state);
- if (if_running)
- dev_open(netdev);
- } else {
- e_info(hw, "online testing starting\n");
- /* Online tests */
- if (ixgbe_link_test(adapter, &data[4]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- /* Online tests aren't run; pass by default */
- data[0] = 0;
- data[1] = 0;
- data[2] = 0;
- data[3] = 0;
-
- clear_bit(__IXGBE_TESTING, &adapter->state);
- }
-skip_ol_tests:
- msleep_interruptible(4 * 1000);
-}
-
-static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter,
- struct ethtool_wolinfo *wol)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- int retval = 1;
- u16 wol_cap = adapter->eeprom_cap & IXGBE_DEVICE_CAPS_WOL_MASK;
-
- /* WOL not supported except for the following */
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82599_SFP:
- /* Only these subdevice could supports WOL */
- switch (hw->subsystem_device_id) {
- case IXGBE_SUBDEV_ID_82599_560FLR:
- /* only support first port */
- if (hw->bus.func != 0) {
- wol->supported = 0;
- break;
- }
- case IXGBE_SUBDEV_ID_82599_SFP:
- retval = 0;
- break;
- default:
- wol->supported = 0;
- break;
- }
- break;
- case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
- /* All except this subdevice support WOL */
- if (hw->subsystem_device_id ==
- IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) {
- wol->supported = 0;
- break;
- }
- retval = 0;
- break;
- case IXGBE_DEV_ID_82599_KX4:
- retval = 0;
- break;
- case IXGBE_DEV_ID_X540T:
- /* check eeprom to see if enabled wol */
- if ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0_1) ||
- ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0) &&
- (hw->bus.func == 0))) {
- retval = 0;
- break;
- }
-
- /* All others not supported */
- wol->supported = 0;
- break;
- default:
- wol->supported = 0;
- }
- return retval;
-}
-
-static void ixgbe_get_wol(struct net_device *netdev,
- struct ethtool_wolinfo *wol)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- wol->supported = WAKE_UCAST | WAKE_MCAST |
- WAKE_BCAST | WAKE_MAGIC;
- wol->wolopts = 0;
-
- if (ixgbe_wol_exclusion(adapter, wol) ||
- !device_can_wakeup(&adapter->pdev->dev))
- return;
-
- if (adapter->wol & IXGBE_WUFC_EX)
- wol->wolopts |= WAKE_UCAST;
- if (adapter->wol & IXGBE_WUFC_MC)
- wol->wolopts |= WAKE_MCAST;
- if (adapter->wol & IXGBE_WUFC_BC)
- wol->wolopts |= WAKE_BCAST;
- if (adapter->wol & IXGBE_WUFC_MAG)
- wol->wolopts |= WAKE_MAGIC;
-}
-
-static int ixgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
- return -EOPNOTSUPP;
-
- if (ixgbe_wol_exclusion(adapter, wol))
- return wol->wolopts ? -EOPNOTSUPP : 0;
-
- adapter->wol = 0;
-
- if (wol->wolopts & WAKE_UCAST)
- adapter->wol |= IXGBE_WUFC_EX;
- if (wol->wolopts & WAKE_MCAST)
- adapter->wol |= IXGBE_WUFC_MC;
- if (wol->wolopts & WAKE_BCAST)
- adapter->wol |= IXGBE_WUFC_BC;
- if (wol->wolopts & WAKE_MAGIC)
- adapter->wol |= IXGBE_WUFC_MAG;
-
- device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
-
- return 0;
-}
-
-static int ixgbe_nway_reset(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- if (netif_running(netdev))
- ixgbe_reinit_locked(adapter);
-
- return 0;
-}
-
-#ifdef HAVE_ETHTOOL_SET_PHYS_ID
-static int ixgbe_set_phys_id(struct net_device *netdev,
- enum ethtool_phys_id_state state)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
-
- switch (state) {
- case ETHTOOL_ID_ACTIVE:
- adapter->led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
- return 2;
-
- case ETHTOOL_ID_ON:
- hw->mac.ops.led_on(hw, IXGBE_LED_ON);
- break;
-
- case ETHTOOL_ID_OFF:
- hw->mac.ops.led_off(hw, IXGBE_LED_ON);
- break;
-
- case ETHTOOL_ID_INACTIVE:
- /* Restore LED settings */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_LEDCTL, adapter->led_reg);
- break;
- }
-
- return 0;
-}
-#else
-static int ixgbe_phys_id(struct net_device *netdev, u32 data)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
- u32 i;
-
- if (!data || data > 300)
- data = 300;
-
- for (i = 0; i < (data * 1000); i += 400) {
- ixgbe_led_on(hw, IXGBE_LED_ON);
- msleep_interruptible(200);
- ixgbe_led_off(hw, IXGBE_LED_ON);
- msleep_interruptible(200);
- }
-
- /* Restore LED settings */
- IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
-
- return 0;
-}
-#endif /* HAVE_ETHTOOL_SET_PHYS_ID */
-
-static int ixgbe_get_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *ec)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- ec->tx_max_coalesced_frames_irq = adapter->tx_work_limit;
-#ifndef CONFIG_IXGBE_NAPI
- ec->rx_max_coalesced_frames_irq = adapter->rx_work_limit;
-#endif /* CONFIG_IXGBE_NAPI */
- /* only valid if in constant ITR mode */
- if (adapter->rx_itr_setting <= 1)
- ec->rx_coalesce_usecs = adapter->rx_itr_setting;
- else
- ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2;
-
- /* if in mixed tx/rx queues per vector mode, report only rx settings */
- if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count)
- return 0;
-
- /* only valid if in constant ITR mode */
- if (adapter->tx_itr_setting <= 1)
- ec->tx_coalesce_usecs = adapter->tx_itr_setting;
- else
- ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2;
-
- return 0;
-}
-
-/*
- * this function must be called before setting the new value of
- * rx_itr_setting
- */
-#ifdef NO_VNIC
-static bool ixgbe_update_rsc(struct ixgbe_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
-
- /* nothing to do if LRO or RSC are not enabled */
- if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) ||
- !(netdev->features & NETIF_F_LRO))
- return false;
-
- /* check the feature flag value and enable RSC if necessary */
- if (adapter->rx_itr_setting == 1 ||
- adapter->rx_itr_setting > IXGBE_MIN_RSC_ITR) {
- if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) {
- adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
- e_info(probe, "rx-usecs value high enough "
- "to re-enable RSC\n");
- return true;
- }
- /* if interrupt rate is too high then disable RSC */
- } else if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
- adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
-#ifdef IXGBE_NO_LRO
- e_info(probe, "rx-usecs set too low, disabling RSC\n");
-#else
- e_info(probe, "rx-usecs set too low, "
- "falling back to software LRO\n");
-#endif
- return true;
- }
- return false;
-}
-#endif
-
-static int ixgbe_set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *ec)
-{
-#ifdef NO_VNIC
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_q_vector *q_vector;
- int i;
- int num_vectors;
- u16 tx_itr_param, rx_itr_param;
- bool need_reset = false;
-
- /* don't accept tx specific changes if we've got mixed RxTx vectors */
- if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count
- && ec->tx_coalesce_usecs)
- return -EINVAL;
-
- if (ec->tx_max_coalesced_frames_irq)
- adapter->tx_work_limit = ec->tx_max_coalesced_frames_irq;
-
-#ifndef CONFIG_IXGBE_NAPI
- if (ec->rx_max_coalesced_frames_irq)
- adapter->rx_work_limit = ec->rx_max_coalesced_frames_irq;
-
-#endif
- if ((ec->rx_coalesce_usecs > (IXGBE_MAX_EITR >> 2)) ||
- (ec->tx_coalesce_usecs > (IXGBE_MAX_EITR >> 2)))
- return -EINVAL;
-
- if (ec->rx_coalesce_usecs > 1)
- adapter->rx_itr_setting = ec->rx_coalesce_usecs << 2;
- else
- adapter->rx_itr_setting = ec->rx_coalesce_usecs;
-
- if (adapter->rx_itr_setting == 1)
- rx_itr_param = IXGBE_20K_ITR;
- else
- rx_itr_param = adapter->rx_itr_setting;
-
- if (ec->tx_coalesce_usecs > 1)
- adapter->tx_itr_setting = ec->tx_coalesce_usecs << 2;
- else
- adapter->tx_itr_setting = ec->tx_coalesce_usecs;
-
- if (adapter->tx_itr_setting == 1)
- tx_itr_param = IXGBE_10K_ITR;
- else
- tx_itr_param = adapter->tx_itr_setting;
-
- /* check the old value and enable RSC if necessary */
- need_reset = ixgbe_update_rsc(adapter);
-
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
- num_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
- else
- num_vectors = 1;
-
- for (i = 0; i < num_vectors; i++) {
- q_vector = adapter->q_vector[i];
- q_vector->tx.work_limit = adapter->tx_work_limit;
- q_vector->rx.work_limit = adapter->rx_work_limit;
- if (q_vector->tx.count && !q_vector->rx.count)
- /* tx only */
- q_vector->itr = tx_itr_param;
- else
- /* rx only or mixed */
- q_vector->itr = rx_itr_param;
- ixgbe_write_eitr(q_vector);
- }
-
- /*
- * do reset here at the end to make sure EITR==0 case is handled
- * correctly w.r.t stopping tx, and changing TXDCTL.WTHRESH settings
- * also locks in RSC enable/disable which requires reset
- */
- if (need_reset)
- ixgbe_do_reset(netdev);
-#endif
- return 0;
-}
-
-#ifndef HAVE_NDO_SET_FEATURES
-static u32 ixgbe_get_rx_csum(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_ring *ring = adapter->rx_ring[0];
- return test_bit(__IXGBE_RX_CSUM_ENABLED, &ring->state);
-}
-
-static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- int i;
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- struct ixgbe_ring *ring = adapter->rx_ring[i];
- if (data)
- set_bit(__IXGBE_RX_CSUM_ENABLED, &ring->state);
- else
- clear_bit(__IXGBE_RX_CSUM_ENABLED, &ring->state);
- }
-
- /* LRO and RSC both depend on RX checksum to function */
- if (!data && (netdev->features & NETIF_F_LRO)) {
- netdev->features &= ~NETIF_F_LRO;
-
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
- adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
- ixgbe_do_reset(netdev);
- }
- }
-
- return 0;
-}
-
-static u32 ixgbe_get_tx_csum(struct net_device *netdev)
-{
- return (netdev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u32 feature_list;
-
-#ifdef NETIF_F_IPV6_CSUM
- feature_list = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-#else
- feature_list = NETIF_F_IP_CSUM;
-#endif
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- feature_list |= NETIF_F_SCTP_CSUM;
- break;
- default:
- break;
- }
- if (data)
- netdev->features |= feature_list;
- else
- netdev->features &= ~feature_list;
-
- return 0;
-}
-
-#ifdef NETIF_F_TSO
-static int ixgbe_set_tso(struct net_device *netdev, u32 data)
-{
- if (data) {
- netdev->features |= NETIF_F_TSO;
-#ifdef NETIF_F_TSO6
- netdev->features |= NETIF_F_TSO6;
-#endif
- } else {
-#ifndef HAVE_NETDEV_VLAN_FEATURES
-#ifdef NETIF_F_HW_VLAN_TX
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- /* disable TSO on all VLANs if they're present */
- if (adapter->vlgrp) {
- int i;
- struct net_device *v_netdev;
- for (i = 0; i < VLAN_N_VID; i++) {
- v_netdev =
- vlan_group_get_device(adapter->vlgrp, i);
- if (v_netdev) {
- v_netdev->features &= ~NETIF_F_TSO;
-#ifdef NETIF_F_TSO6
- v_netdev->features &= ~NETIF_F_TSO6;
-#endif
- vlan_group_set_device(adapter->vlgrp, i,
- v_netdev);
- }
- }
- }
-#endif
-#endif /* HAVE_NETDEV_VLAN_FEATURES */
- netdev->features &= ~NETIF_F_TSO;
-#ifdef NETIF_F_TSO6
- netdev->features &= ~NETIF_F_TSO6;
-#endif
- }
- return 0;
-}
-
-#endif /* NETIF_F_TSO */
-#ifdef ETHTOOL_GFLAGS
-static int ixgbe_set_flags(struct net_device *netdev, u32 data)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u32 supported_flags = ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN;
- u32 changed = netdev->features ^ data;
- bool need_reset = false;
- int rc;
-
-#ifndef HAVE_VLAN_RX_REGISTER
- if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
- !(data & ETH_FLAG_RXVLAN))
- return -EINVAL;
-
-#endif
-#ifdef NETIF_F_RXHASH
- if (adapter->flags & IXGBE_FLAG_RSS_ENABLED)
- supported_flags |= ETH_FLAG_RXHASH;
-#endif
-#ifdef IXGBE_NO_LRO
- if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)
-#endif
- supported_flags |= ETH_FLAG_LRO;
-
-#ifdef ETHTOOL_GRXRINGS
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_X540:
- case ixgbe_mac_82599EB:
- supported_flags |= ETH_FLAG_NTUPLE;
- default:
- break;
- }
-
-#endif
- rc = ethtool_op_set_flags(netdev, data, supported_flags);
- if (rc)
- return rc;
-
-#ifndef HAVE_VLAN_RX_REGISTER
- if (changed & ETH_FLAG_RXVLAN)
- ixgbe_vlan_mode(netdev, netdev->features);
-
-#endif
- /* if state changes we need to update adapter->flags and reset */
- if (!(netdev->features & NETIF_F_LRO)) {
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
- need_reset = true;
- adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
- } else if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) &&
- !(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) {
- if (adapter->rx_itr_setting == 1 ||
- adapter->rx_itr_setting > IXGBE_MIN_RSC_ITR) {
- adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
- need_reset = true;
- } else if (changed & ETH_FLAG_LRO) {
-#ifdef IXGBE_NO_LRO
- e_info(probe, "rx-usecs set too low, "
- "disabling RSC\n");
-#else
- e_info(probe, "rx-usecs set too low, "
- "falling back to software LRO\n");
-#endif
- }
- }
-
-#ifdef ETHTOOL_GRXRINGS
- /*
- * Check if Flow Director n-tuple support was enabled or disabled. If
- * the state changed, we need to reset.
- */
- if (!(netdev->features & NETIF_F_NTUPLE)) {
- if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) {
- /* turn off Flow Director, set ATR and reset */
- if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) &&
- !(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
- adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
- need_reset = true;
- }
- adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
- } else if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) {
- /* turn off ATR, enable perfect filters and reset */
- adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
- adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
- need_reset = true;
- }
-
-#endif /* ETHTOOL_GRXRINGS */
- if (need_reset)
- ixgbe_do_reset(netdev);
-
- return 0;
-}
-
-#endif /* ETHTOOL_GFLAGS */
-#endif /* HAVE_NDO_SET_FEATURES */
-#ifdef ETHTOOL_GRXRINGS
-static int ixgbe_get_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
- struct ethtool_rxnfc *cmd)
-{
- union ixgbe_atr_input *mask = &adapter->fdir_mask;
- struct ethtool_rx_flow_spec *fsp =
- (struct ethtool_rx_flow_spec *)&cmd->fs;
- struct hlist_node *node, *node2;
- struct ixgbe_fdir_filter *rule = NULL;
-
- /* report total rule count */
- cmd->data = (1024 << adapter->fdir_pballoc) - 2;
-
- hlist_for_each_entry_safe(rule, node, node2,
- &adapter->fdir_filter_list, fdir_node) {
- if (fsp->location <= rule->sw_idx)
- break;
- }
-
- if (!rule || fsp->location != rule->sw_idx)
- return -EINVAL;
-
- /* fill out the flow spec entry */
-
- /* set flow type field */
- switch (rule->filter.formatted.flow_type) {
- case IXGBE_ATR_FLOW_TYPE_TCPV4:
- fsp->flow_type = TCP_V4_FLOW;
- break;
- case IXGBE_ATR_FLOW_TYPE_UDPV4:
- fsp->flow_type = UDP_V4_FLOW;
- break;
- case IXGBE_ATR_FLOW_TYPE_SCTPV4:
- fsp->flow_type = SCTP_V4_FLOW;
- break;
- case IXGBE_ATR_FLOW_TYPE_IPV4:
- fsp->flow_type = IP_USER_FLOW;
- fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
- fsp->h_u.usr_ip4_spec.proto = 0;
- fsp->m_u.usr_ip4_spec.proto = 0;
- break;
- default:
- return -EINVAL;
- }
-
- fsp->h_u.tcp_ip4_spec.psrc = rule->filter.formatted.src_port;
- fsp->m_u.tcp_ip4_spec.psrc = mask->formatted.src_port;
- fsp->h_u.tcp_ip4_spec.pdst = rule->filter.formatted.dst_port;
- fsp->m_u.tcp_ip4_spec.pdst = mask->formatted.dst_port;
- fsp->h_u.tcp_ip4_spec.ip4src = rule->filter.formatted.src_ip[0];
- fsp->m_u.tcp_ip4_spec.ip4src = mask->formatted.src_ip[0];
- fsp->h_u.tcp_ip4_spec.ip4dst = rule->filter.formatted.dst_ip[0];
- fsp->m_u.tcp_ip4_spec.ip4dst = mask->formatted.dst_ip[0];
- fsp->h_ext.vlan_tci = rule->filter.formatted.vlan_id;
- fsp->m_ext.vlan_tci = mask->formatted.vlan_id;
- fsp->h_ext.vlan_etype = rule->filter.formatted.flex_bytes;
- fsp->m_ext.vlan_etype = mask->formatted.flex_bytes;
- fsp->h_ext.data[1] = htonl(rule->filter.formatted.vm_pool);
- fsp->m_ext.data[1] = htonl(mask->formatted.vm_pool);
- fsp->flow_type |= FLOW_EXT;
-
- /* record action */
- if (rule->action == IXGBE_FDIR_DROP_QUEUE)
- fsp->ring_cookie = RX_CLS_FLOW_DISC;
- else
- fsp->ring_cookie = rule->action;
-
- return 0;
-}
-
-static int ixgbe_get_ethtool_fdir_all(struct ixgbe_adapter *adapter,
- struct ethtool_rxnfc *cmd,
- u32 *rule_locs)
-{
- struct hlist_node *node, *node2;
- struct ixgbe_fdir_filter *rule;
- int cnt = 0;
-
- /* report total rule count */
- cmd->data = (1024 << adapter->fdir_pballoc) - 2;
-
- hlist_for_each_entry_safe(rule, node, node2,
- &adapter->fdir_filter_list, fdir_node) {
- if (cnt == cmd->rule_cnt)
- return -EMSGSIZE;
- rule_locs[cnt] = rule->sw_idx;
- cnt++;
- }
-
- cmd->rule_cnt = cnt;
-
- return 0;
-}
-
-static int ixgbe_get_rss_hash_opts(struct ixgbe_adapter *adapter,
- struct ethtool_rxnfc *cmd)
-{
- cmd->data = 0;
-
- /* if RSS is disabled then report no hashing */
- if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
- return 0;
-
- /* Report default options for RSS on ixgbe */
- switch (cmd->flow_type) {
- case TCP_V4_FLOW:
- cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- case UDP_V4_FLOW:
- if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV4_UDP)
- cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- case SCTP_V4_FLOW:
- case AH_ESP_V4_FLOW:
- case AH_V4_FLOW:
- case ESP_V4_FLOW:
- case IPV4_FLOW:
- cmd->data |= RXH_IP_SRC | RXH_IP_DST;
- break;
- case TCP_V6_FLOW:
- cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- case UDP_V6_FLOW:
- if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP)
- cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
- case SCTP_V6_FLOW:
- case AH_ESP_V6_FLOW:
- case AH_V6_FLOW:
- case ESP_V6_FLOW:
- case IPV6_FLOW:
- cmd->data |= RXH_IP_SRC | RXH_IP_DST;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
-#ifdef HAVE_ETHTOOL_GET_RXNFC_VOID_RULE_LOCS
- void *rule_locs)
-#else
- u32 *rule_locs)
-#endif
-{
- struct ixgbe_adapter *adapter = netdev_priv(dev);
- int ret = -EOPNOTSUPP;
-
- switch (cmd->cmd) {
- case ETHTOOL_GRXRINGS:
- cmd->data = adapter->num_rx_queues;
- ret = 0;
- break;
- case ETHTOOL_GRXCLSRLCNT:
- cmd->rule_cnt = adapter->fdir_filter_count;
- ret = 0;
- break;
- case ETHTOOL_GRXCLSRULE:
- ret = ixgbe_get_ethtool_fdir_entry(adapter, cmd);
- break;
- case ETHTOOL_GRXCLSRLALL:
- ret = ixgbe_get_ethtool_fdir_all(adapter, cmd,
- rule_locs);
- break;
- case ETHTOOL_GRXFH:
- ret = ixgbe_get_rss_hash_opts(adapter, cmd);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-static int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
- struct ixgbe_fdir_filter *input,
- u16 sw_idx)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- struct hlist_node *node, *node2, *parent;
- struct ixgbe_fdir_filter *rule;
- int err = -EINVAL;
-
- parent = NULL;
- rule = NULL;
-
- hlist_for_each_entry_safe(rule, node, node2,
- &adapter->fdir_filter_list, fdir_node) {
- /* hash found, or no matching entry */
- if (rule->sw_idx >= sw_idx)
- break;
- parent = node;
- }
-
- /* if there is an old rule occupying our place remove it */
- if (rule && (rule->sw_idx == sw_idx)) {
- if (!input || (rule->filter.formatted.bkt_hash !=
- input->filter.formatted.bkt_hash)) {
- err = ixgbe_fdir_erase_perfect_filter_82599(hw,
- &rule->filter,
- sw_idx);
- }
-
- hlist_del(&rule->fdir_node);
- kfree(rule);
- adapter->fdir_filter_count--;
- }
-
- /*
- * If no input this was a delete, err should be 0 if a rule was
- * successfully found and removed from the list else -EINVAL
- */
- if (!input)
- return err;
-
- /* initialize node and set software index */
- INIT_HLIST_NODE(&input->fdir_node);
-
- /* add filter to the list */
- if (parent)
- hlist_add_after(parent, &input->fdir_node);
- else
- hlist_add_head(&input->fdir_node,
- &adapter->fdir_filter_list);
-
- /* update counts */
- adapter->fdir_filter_count++;
-
- return 0;
-}
-
-static int ixgbe_flowspec_to_flow_type(struct ethtool_rx_flow_spec *fsp,
- u8 *flow_type)
-{
- switch (fsp->flow_type & ~FLOW_EXT) {
- case TCP_V4_FLOW:
- *flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4;
- break;
- case UDP_V4_FLOW:
- *flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4;
- break;
- case SCTP_V4_FLOW:
- *flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4;
- break;
- case IP_USER_FLOW:
- switch (fsp->h_u.usr_ip4_spec.proto) {
- case IPPROTO_TCP:
- *flow_type = IXGBE_ATR_FLOW_TYPE_TCPV4;
- break;
- case IPPROTO_UDP:
- *flow_type = IXGBE_ATR_FLOW_TYPE_UDPV4;
- break;
- case IPPROTO_SCTP:
- *flow_type = IXGBE_ATR_FLOW_TYPE_SCTPV4;
- break;
- case 0:
- if (!fsp->m_u.usr_ip4_spec.proto) {
- *flow_type = IXGBE_ATR_FLOW_TYPE_IPV4;
- break;
- }
- default:
- return 0;
- }
- break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static int ixgbe_add_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
- struct ethtool_rxnfc *cmd)
-{
- struct ethtool_rx_flow_spec *fsp =
- (struct ethtool_rx_flow_spec *)&cmd->fs;
- struct ixgbe_hw *hw = &adapter->hw;
- struct ixgbe_fdir_filter *input;
- union ixgbe_atr_input mask;
- int err;
-
- if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
- return -EOPNOTSUPP;
-
- /*
- * Don't allow programming if the action is a queue greater than
- * the number of online Rx queues.
- */
- if ((fsp->ring_cookie != RX_CLS_FLOW_DISC) &&
- (fsp->ring_cookie >= adapter->num_rx_queues))
- return -EINVAL;
-
- /* Don't allow indexes to exist outside of available space */
- if (fsp->location >= ((1024 << adapter->fdir_pballoc) - 2)) {
- e_err(drv, "Location out of range\n");
- return -EINVAL;
- }
-
- input = kzalloc(sizeof(*input), GFP_ATOMIC);
- if (!input)
- return -ENOMEM;
-
- memset(&mask, 0, sizeof(union ixgbe_atr_input));
-
- /* set SW index */
- input->sw_idx = fsp->location;
-
- /* record flow type */
- if (!ixgbe_flowspec_to_flow_type(fsp,
- &input->filter.formatted.flow_type)) {
- e_err(drv, "Unrecognized flow type\n");
- goto err_out;
- }
-
- mask.formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK |
- IXGBE_ATR_L4TYPE_MASK;
-
- if (input->filter.formatted.flow_type == IXGBE_ATR_FLOW_TYPE_IPV4)
- mask.formatted.flow_type &= IXGBE_ATR_L4TYPE_IPV6_MASK;
-
- /* Copy input into formatted structures */
- input->filter.formatted.src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src;
- mask.formatted.src_ip[0] = fsp->m_u.tcp_ip4_spec.ip4src;
- input->filter.formatted.dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst;
- mask.formatted.dst_ip[0] = fsp->m_u.tcp_ip4_spec.ip4dst;
- input->filter.formatted.src_port = fsp->h_u.tcp_ip4_spec.psrc;
- mask.formatted.src_port = fsp->m_u.tcp_ip4_spec.psrc;
- input->filter.formatted.dst_port = fsp->h_u.tcp_ip4_spec.pdst;
- mask.formatted.dst_port = fsp->m_u.tcp_ip4_spec.pdst;
-
- if (fsp->flow_type & FLOW_EXT) {
- input->filter.formatted.vm_pool =
- (unsigned char)ntohl(fsp->h_ext.data[1]);
- mask.formatted.vm_pool =
- (unsigned char)ntohl(fsp->m_ext.data[1]);
- input->filter.formatted.vlan_id = fsp->h_ext.vlan_tci;
- mask.formatted.vlan_id = fsp->m_ext.vlan_tci;
- input->filter.formatted.flex_bytes =
- fsp->h_ext.vlan_etype;
- mask.formatted.flex_bytes = fsp->m_ext.vlan_etype;
- }
-
- /* determine if we need to drop or route the packet */
- if (fsp->ring_cookie == RX_CLS_FLOW_DISC)
- input->action = IXGBE_FDIR_DROP_QUEUE;
- else
- input->action = fsp->ring_cookie;
-
- spin_lock(&adapter->fdir_perfect_lock);
-
- if (hlist_empty(&adapter->fdir_filter_list)) {
- /* save mask and program input mask into HW */
- memcpy(&adapter->fdir_mask, &mask, sizeof(mask));
- err = ixgbe_fdir_set_input_mask_82599(hw, &mask);
- if (err) {
- e_err(drv, "Error writing mask\n");
- goto err_out_w_lock;
- }
- } else if (memcmp(&adapter->fdir_mask, &mask, sizeof(mask))) {
- e_err(drv, "Only one mask supported per port\n");
- goto err_out_w_lock;
- }
-
- /* apply mask and compute/store hash */
- ixgbe_atr_compute_perfect_hash_82599(&input->filter, &mask);
-
- /* program filters to filter memory */
- err = ixgbe_fdir_write_perfect_filter_82599(hw,
- &input->filter, input->sw_idx,
- (input->action == IXGBE_FDIR_DROP_QUEUE) ?
- IXGBE_FDIR_DROP_QUEUE :
- adapter->rx_ring[input->action]->reg_idx);
- if (err)
- goto err_out_w_lock;
-
- ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx);
-
- spin_unlock(&adapter->fdir_perfect_lock);
-
- kfree(input);
- return err;
-err_out_w_lock:
- spin_unlock(&adapter->fdir_perfect_lock);
-err_out:
- kfree(input);
- return -EINVAL;
-}
-
-static int ixgbe_del_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
- struct ethtool_rxnfc *cmd)
-{
- struct ethtool_rx_flow_spec *fsp =
- (struct ethtool_rx_flow_spec *)&cmd->fs;
- int err;
-
- spin_lock(&adapter->fdir_perfect_lock);
- err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, (u16)(fsp->location));
- spin_unlock(&adapter->fdir_perfect_lock);
-
- return err;
-}
-
-#ifdef ETHTOOL_SRXNTUPLE
-/*
- * We need to keep this around for kernels 2.6.33 - 2.6.39 in order to avoid
- * a null pointer dereference as it was assumend if the NETIF_F_NTUPLE flag
- * was defined that this function was present.
- */
-static int ixgbe_set_rx_ntuple(struct net_device *dev,
- struct ethtool_rx_ntuple *cmd)
-{
- return -EOPNOTSUPP;
-}
-
-#endif
-#define UDP_RSS_FLAGS (IXGBE_FLAG2_RSS_FIELD_IPV4_UDP | \
- IXGBE_FLAG2_RSS_FIELD_IPV6_UDP)
-static int ixgbe_set_rss_hash_opt(struct ixgbe_adapter *adapter,
- struct ethtool_rxnfc *nfc)
-{
- u32 flags2 = adapter->flags2;
-
- /*
- * RSS does not support anything other than hashing
- * to queues on src and dst IPs and ports
- */
- if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
- RXH_L4_B_0_1 | RXH_L4_B_2_3))
- return -EINVAL;
-
- switch (nfc->flow_type) {
- case TCP_V4_FLOW:
- case TCP_V6_FLOW:
- if (!(nfc->data & RXH_IP_SRC) ||
- !(nfc->data & RXH_IP_DST) ||
- !(nfc->data & RXH_L4_B_0_1) ||
- !(nfc->data & RXH_L4_B_2_3))
- return -EINVAL;
- break;
- case UDP_V4_FLOW:
- if (!(nfc->data & RXH_IP_SRC) ||
- !(nfc->data & RXH_IP_DST))
- return -EINVAL;
- switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
- case 0:
- flags2 &= ~IXGBE_FLAG2_RSS_FIELD_IPV4_UDP;
- break;
- case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
- flags2 |= IXGBE_FLAG2_RSS_FIELD_IPV4_UDP;
- break;
- default:
- return -EINVAL;
- }
- break;
- case UDP_V6_FLOW:
- if (!(nfc->data & RXH_IP_SRC) ||
- !(nfc->data & RXH_IP_DST))
- return -EINVAL;
- switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
- case 0:
- flags2 &= ~IXGBE_FLAG2_RSS_FIELD_IPV6_UDP;
- break;
- case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
- flags2 |= IXGBE_FLAG2_RSS_FIELD_IPV6_UDP;
- break;
- default:
- return -EINVAL;
- }
- break;
- case AH_ESP_V4_FLOW:
- case AH_V4_FLOW:
- case ESP_V4_FLOW:
- case SCTP_V4_FLOW:
- case AH_ESP_V6_FLOW:
- case AH_V6_FLOW:
- case ESP_V6_FLOW:
- case SCTP_V6_FLOW:
- if (!(nfc->data & RXH_IP_SRC) ||
- !(nfc->data & RXH_IP_DST) ||
- (nfc->data & RXH_L4_B_0_1) ||
- (nfc->data & RXH_L4_B_2_3))
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- /* if we changed something we need to update flags */
- if (flags2 != adapter->flags2) {
- struct ixgbe_hw *hw = &adapter->hw;
- u32 mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC);
-
- if ((flags2 & UDP_RSS_FLAGS) &&
- !(adapter->flags2 & UDP_RSS_FLAGS))
- e_warn(drv, "enabling UDP RSS: fragmented packets"
- " may arrive out of order to the stack above\n");
-
- adapter->flags2 = flags2;
-
- /* Perform hash on these packet types */
- mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4
- | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV6
- | IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
-
- mrqc &= ~(IXGBE_MRQC_RSS_FIELD_IPV4_UDP |
- IXGBE_MRQC_RSS_FIELD_IPV6_UDP);
-
- if (flags2 & IXGBE_FLAG2_RSS_FIELD_IPV4_UDP)
- mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP;
-
- if (flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP)
- mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
-
- IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
- }
-
- return 0;
-}
-
-static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
-{
- struct ixgbe_adapter *adapter = netdev_priv(dev);
- int ret = -EOPNOTSUPP;
-
- switch (cmd->cmd) {
- case ETHTOOL_SRXCLSRLINS:
- ret = ixgbe_add_ethtool_fdir_entry(adapter, cmd);
- break;
- case ETHTOOL_SRXCLSRLDEL:
- ret = ixgbe_del_ethtool_fdir_entry(adapter, cmd);
- break;
- case ETHTOOL_SRXFH:
- ret = ixgbe_set_rss_hash_opt(adapter, cmd);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-#endif /* ETHTOOL_GRXRINGS */
-//static
-struct ethtool_ops ixgbe_ethtool_ops = {
-#ifndef ETHTOOL_GLINKSETTINGS
- .get_settings = ixgbe_get_settings,
-#endif
-#ifndef ETHTOOL_SLINKSETTINGS
- .set_settings = ixgbe_set_settings,
-#endif
- .get_drvinfo = ixgbe_get_drvinfo,
- .get_regs_len = ixgbe_get_regs_len,
- .get_regs = ixgbe_get_regs,
- .get_wol = ixgbe_get_wol,
- .set_wol = ixgbe_set_wol,
- .nway_reset = ixgbe_nway_reset,
- .get_link = ethtool_op_get_link,
- .get_eeprom_len = ixgbe_get_eeprom_len,
- .get_eeprom = ixgbe_get_eeprom,
- .set_eeprom = ixgbe_set_eeprom,
- .get_ringparam = ixgbe_get_ringparam,
- .set_ringparam = ixgbe_set_ringparam,
- .get_pauseparam = ixgbe_get_pauseparam,
- .set_pauseparam = ixgbe_set_pauseparam,
- .get_msglevel = ixgbe_get_msglevel,
- .set_msglevel = ixgbe_set_msglevel,
-#ifndef HAVE_ETHTOOL_GET_SSET_COUNT
- .self_test_count = ixgbe_diag_test_count,
-#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */
- .self_test = ixgbe_diag_test,
- .get_strings = ixgbe_get_strings,
-#ifdef HAVE_ETHTOOL_SET_PHYS_ID
- .set_phys_id = ixgbe_set_phys_id,
-#else
- .phys_id = ixgbe_phys_id,
-#endif /* HAVE_ETHTOOL_SET_PHYS_ID */
-#ifndef HAVE_ETHTOOL_GET_SSET_COUNT
- .get_stats_count = ixgbe_get_stats_count,
-#else /* HAVE_ETHTOOL_GET_SSET_COUNT */
- .get_sset_count = ixgbe_get_sset_count,
-#endif /* HAVE_ETHTOOL_GET_SSET_COUNT */
- .get_ethtool_stats = ixgbe_get_ethtool_stats,
-#ifdef HAVE_ETHTOOL_GET_PERM_ADDR
- .get_perm_addr = ethtool_op_get_perm_addr,
-#endif
- .get_coalesce = ixgbe_get_coalesce,
- .set_coalesce = ixgbe_set_coalesce,
-#ifndef HAVE_NDO_SET_FEATURES
- .get_rx_csum = ixgbe_get_rx_csum,
- .set_rx_csum = ixgbe_set_rx_csum,
- .get_tx_csum = ixgbe_get_tx_csum,
- .set_tx_csum = ixgbe_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
-#ifdef NETIF_F_TSO
- .get_tso = ethtool_op_get_tso,
- .set_tso = ixgbe_set_tso,
-#endif
-#ifdef ETHTOOL_GFLAGS
- .get_flags = ethtool_op_get_flags,
- .set_flags = ixgbe_set_flags,
-#endif
-#endif /* HAVE_NDO_SET_FEATURES */
-#ifdef ETHTOOL_GRXRINGS
- .get_rxnfc = ixgbe_get_rxnfc,
- .set_rxnfc = ixgbe_set_rxnfc,
-#ifdef ETHTOOL_SRXNTUPLE
- .set_rx_ntuple = ixgbe_set_rx_ntuple,
-#endif
-#endif
-};
-
-void ixgbe_set_ethtool_ops(struct net_device *netdev)
-{
- SET_ETHTOOL_OPS(netdev, &ixgbe_ethtool_ops);
-}
-#endif /* SIOCETHTOOL */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_fcoe.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_fcoe.h
deleted file mode 100644
index eec86cbb3..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_fcoe.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_FCOE_H
-#define _IXGBE_FCOE_H
-
-#ifdef IXGBE_FCOE
-
-#include <scsi/fc/fc_fs.h>
-#include <scsi/fc/fc_fcoe.h>
-
-/* shift bits within STAT fo FCSTAT */
-#define IXGBE_RXDADV_FCSTAT_SHIFT 4
-
-/* ddp user buffer */
-#define IXGBE_BUFFCNT_MAX 256 /* 8 bits bufcnt */
-#define IXGBE_FCPTR_ALIGN 16
-#define IXGBE_FCPTR_MAX (IXGBE_BUFFCNT_MAX * sizeof(dma_addr_t))
-#define IXGBE_FCBUFF_4KB 0x0
-#define IXGBE_FCBUFF_8KB 0x1
-#define IXGBE_FCBUFF_16KB 0x2
-#define IXGBE_FCBUFF_64KB 0x3
-#define IXGBE_FCBUFF_MAX 65536 /* 64KB max */
-#define IXGBE_FCBUFF_MIN 4096 /* 4KB min */
-#define IXGBE_FCOE_DDP_MAX 512 /* 9 bits xid */
-
-/* Default traffic class to use for FCoE */
-#define IXGBE_FCOE_DEFTC 3
-
-/* fcerr */
-#define IXGBE_FCERR_BADCRC 0x00100000
-#define IXGBE_FCERR_EOFSOF 0x00200000
-#define IXGBE_FCERR_NOFIRST 0x00300000
-#define IXGBE_FCERR_OOOSEQ 0x00400000
-#define IXGBE_FCERR_NODMA 0x00500000
-#define IXGBE_FCERR_PKTLOST 0x00600000
-
-/* FCoE DDP for target mode */
-#define __IXGBE_FCOE_TARGET 1
-
-struct ixgbe_fcoe_ddp {
- int len;
- u32 err;
- unsigned int sgc;
- struct scatterlist *sgl;
- dma_addr_t udp;
- u64 *udl;
- struct pci_pool *pool;
-};
-
-struct ixgbe_fcoe {
- struct pci_pool **pool;
- atomic_t refcnt;
- spinlock_t lock;
- struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];
- unsigned char *extra_ddp_buffer;
- dma_addr_t extra_ddp_buffer_dma;
- u64 __percpu *pcpu_noddp;
- u64 __percpu *pcpu_noddp_ext_buff;
- unsigned long mode;
- u8 tc;
- u8 up;
- u8 up_set;
-};
-#endif /* IXGBE_FCOE */
-
-#endif /* _IXGBE_FCOE_H */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_main.c b/kernel/linux/kni/ethtool/ixgbe/ixgbe_main.c
deleted file mode 100644
index a5acf19c5..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_main.c
+++ /dev/null
@@ -1,2951 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/******************************************************************************
- Copyright (c)2006 - 2007 Myricom, Inc. for some LRO specific code
-******************************************************************************/
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/vmalloc.h>
-#include <linux/highmem.h>
-#include <linux/string.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#ifdef HAVE_SCTP
-#include <linux/sctp.h>
-#endif
-#include <linux/pkt_sched.h>
-#include <linux/ipv6.h>
-#ifdef NETIF_F_TSO
-#include <net/checksum.h>
-#ifdef NETIF_F_TSO6
-#include <net/ip6_checksum.h>
-#endif
-#endif
-#ifdef SIOCETHTOOL
-#include <linux/ethtool.h>
-#endif
-
-#include "ixgbe.h"
-
-#undef CONFIG_DCA
-#undef CONFIG_DCA_MODULE
-
-char ixgbe_driver_name[] = "ixgbe";
-#define DRV_HW_PERF
-
-#ifndef CONFIG_IXGBE_NAPI
-#define DRIVERNAPI
-#else
-#define DRIVERNAPI "-NAPI"
-#endif
-
-#define FPGA
-
-#define VMDQ_TAG
-
-#define MAJ 3
-#define MIN 9
-#define BUILD 17
-#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
- __stringify(BUILD) DRIVERNAPI DRV_HW_PERF FPGA VMDQ_TAG
-const char ixgbe_driver_version[] = DRV_VERSION;
-
-/* ixgbe_pci_tbl - PCI Device ID Table
- *
- * Wildcard entries (PCI_ANY_ID) should come last
- * Last entry must be all 0s
- *
- * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
- * Class, Class Mask, private data (not used) }
- */
-const struct pci_device_id ixgbe_pci_tbl[] = {
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT2)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_DA_DUAL_PORT)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_XF_LR)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_SFP_LOM)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_BX)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_XAUI_LOM)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KR)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_EM)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4_MEZZ)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_BACKPLANE_FCOE)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_FCOE)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_T3_LOM)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599EN_SFP)},
- {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_QSFP_SF_QP)},
- /* required last entry */
- {0, }
-};
-
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
-static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
- void *p);
-static struct notifier_block dca_notifier = {
- .notifier_call = ixgbe_notify_dca,
- .next = NULL,
- .priority = 0
-};
-
-#endif
-MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
-MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
-
-#define DEFAULT_DEBUG_LEVEL_SHIFT 3
-
-
-static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
-{
- u32 ctrl_ext;
-
- /* Let firmware take over control of h/w */
- ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
-}
-
-#ifdef NO_VNIC
-static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
-{
- u32 ctrl_ext;
-
- /* Let firmware know the driver has taken over */
- ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
-}
-#endif
-
-
-static void ixgbe_update_xoff_rx_lfc(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- struct ixgbe_hw_stats *hwstats = &adapter->stats;
- int i;
- u32 data;
-
- if ((hw->fc.current_mode != ixgbe_fc_full) &&
- (hw->fc.current_mode != ixgbe_fc_rx_pause))
- return;
-
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
- break;
- default:
- data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
- }
- hwstats->lxoffrxc += data;
-
- /* refill credits (no tx hang) if we received xoff */
- if (!data)
- return;
-
- for (i = 0; i < adapter->num_tx_queues; i++)
- clear_bit(__IXGBE_HANG_CHECK_ARMED,
- &adapter->tx_ring[i]->state);
-}
-
-static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- struct ixgbe_hw_stats *hwstats = &adapter->stats;
- u32 xoff[8] = {0};
- int i;
- bool pfc_en = adapter->dcb_cfg.pfc_mode_enable;
-
-#ifdef HAVE_DCBNL_IEEE
- if (adapter->ixgbe_ieee_pfc)
- pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en);
-
-#endif
- if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || !pfc_en) {
- ixgbe_update_xoff_rx_lfc(adapter);
- return;
- }
-
- /* update stats for each tc, only valid with PFC enabled */
- for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) {
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- xoff[i] = IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
- break;
- default:
- xoff[i] = IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
- }
- hwstats->pxoffrxc[i] += xoff[i];
- }
-
- /* disarm tx queues that have received xoff frames */
- for (i = 0; i < adapter->num_tx_queues; i++) {
- struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
- u8 tc = tx_ring->dcb_tc;
-
- if ((tc <= 7) && (xoff[tc]))
- clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state);
- }
-}
-
-
-
-
-#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
-
-
-
-
-#ifdef HAVE_8021P_SUPPORT
-/**
- * ixgbe_vlan_stripping_disable - helper to disable vlan tag stripping
- * @adapter: driver data
- */
-void ixgbe_vlan_stripping_disable(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- u32 vlnctrl;
- int i;
-
- /* leave vlan tag stripping enabled for DCB */
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
- return;
-
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
- vlnctrl &= ~IXGBE_VLNCTRL_VME;
- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- for (i = 0; i < adapter->num_rx_queues; i++) {
- u8 reg_idx = adapter->rx_ring[i]->reg_idx;
- vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
- vlnctrl &= ~IXGBE_RXDCTL_VME;
- IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), vlnctrl);
- }
- break;
- default:
- break;
- }
-}
-
-#endif
-/**
- * ixgbe_vlan_stripping_enable - helper to enable vlan tag stripping
- * @adapter: driver data
- */
-void ixgbe_vlan_stripping_enable(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- u32 vlnctrl;
- int i;
-
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
- vlnctrl |= IXGBE_VLNCTRL_VME;
- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- for (i = 0; i < adapter->num_rx_queues; i++) {
- u8 reg_idx = adapter->rx_ring[i]->reg_idx;
- vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
- vlnctrl |= IXGBE_RXDCTL_VME;
- IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), vlnctrl);
- }
- break;
- default:
- break;
- }
-}
-
-#ifdef HAVE_VLAN_RX_REGISTER
-void ixgbe_vlan_mode(struct net_device *netdev, struct vlan_group *grp)
-#else
-void ixgbe_vlan_mode(struct net_device *netdev, u32 features)
-#endif
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-#ifdef HAVE_8021P_SUPPORT
- bool enable;
-#endif
-#ifdef HAVE_VLAN_RX_REGISTER
-
- //if (!test_bit(__IXGBE_DOWN, &adapter->state))
- // ixgbe_irq_disable(adapter);
-
- adapter->vlgrp = grp;
-
- //if (!test_bit(__IXGBE_DOWN, &adapter->state))
- // ixgbe_irq_enable(adapter, true, true);
-#endif
-#ifdef HAVE_8021P_SUPPORT
-#ifdef HAVE_VLAN_RX_REGISTER
- enable = (grp || (adapter->flags & IXGBE_FLAG_DCB_ENABLED));
-#else
- enable = !!(features & NETIF_F_HW_VLAN_RX);
-#endif
- if (enable)
- /* enable VLAN tag insert/strip */
- ixgbe_vlan_stripping_enable(adapter);
- else
- /* disable VLAN tag insert/strip */
- ixgbe_vlan_stripping_disable(adapter);
-
-#endif
-}
-
-static u8 *ixgbe_addr_list_itr(struct ixgbe_hw *hw, u8 **mc_addr_ptr, u32 *vmdq)
-{
-#ifdef NETDEV_HW_ADDR_T_MULTICAST
- struct netdev_hw_addr *mc_ptr;
-#else
- struct dev_mc_list *mc_ptr;
-#endif
- struct ixgbe_adapter *adapter = hw->back;
- u8 *addr = *mc_addr_ptr;
-
- *vmdq = adapter->num_vfs;
-
-#ifdef NETDEV_HW_ADDR_T_MULTICAST
- mc_ptr = container_of(addr, struct netdev_hw_addr, addr[0]);
- if (mc_ptr->list.next) {
- struct netdev_hw_addr *ha;
-
- ha = list_entry(mc_ptr->list.next, struct netdev_hw_addr, list);
- *mc_addr_ptr = ha->addr;
- }
-#else
- mc_ptr = container_of(addr, struct dev_mc_list, dmi_addr[0]);
- if (mc_ptr->next)
- *mc_addr_ptr = mc_ptr->next->dmi_addr;
-#endif
- else
- *mc_addr_ptr = NULL;
-
- return addr;
-}
-
-/**
- * ixgbe_write_mc_addr_list - write multicast addresses to MTA
- * @netdev: network interface device structure
- *
- * Writes multicast address list to the MTA hash table.
- * Returns: -ENOMEM on failure
- * 0 on no addresses written
- * X on writing X addresses to MTA
- **/
-int ixgbe_write_mc_addr_list(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
-#ifdef NETDEV_HW_ADDR_T_MULTICAST
- struct netdev_hw_addr *ha;
-#endif
- u8 *addr_list = NULL;
- int addr_count = 0;
-
- if (!hw->mac.ops.update_mc_addr_list)
- return -ENOMEM;
-
- if (!netif_running(netdev))
- return 0;
-
-
- hw->mac.ops.update_mc_addr_list(hw, NULL, 0,
- ixgbe_addr_list_itr, true);
-
- if (!netdev_mc_empty(netdev)) {
-#ifdef NETDEV_HW_ADDR_T_MULTICAST
- ha = list_first_entry(&netdev->mc.list,
- struct netdev_hw_addr, list);
- addr_list = ha->addr;
-#else
- addr_list = netdev->mc_list->dmi_addr;
-#endif
- addr_count = netdev_mc_count(netdev);
-
- hw->mac.ops.update_mc_addr_list(hw, addr_list, addr_count,
- ixgbe_addr_list_itr, false);
- }
-
-#ifdef CONFIG_PCI_IOV
- //ixgbe_restore_vf_multicasts(adapter);
-#endif
- return addr_count;
-}
-
-
-void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- int i;
- for (i = 0; i < hw->mac.num_rar_entries; i++) {
- if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE) {
- hw->mac.ops.set_rar(hw, i, adapter->mac_table[i].addr,
- adapter->mac_table[i].queue,
- IXGBE_RAH_AV);
- } else {
- hw->mac.ops.clear_rar(hw, i);
- }
- }
-}
-
-void ixgbe_sync_mac_table(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- int i;
- for (i = 0; i < hw->mac.num_rar_entries; i++) {
- if (adapter->mac_table[i].state & IXGBE_MAC_STATE_MODIFIED) {
- if (adapter->mac_table[i].state &
- IXGBE_MAC_STATE_IN_USE) {
- hw->mac.ops.set_rar(hw, i,
- adapter->mac_table[i].addr,
- adapter->mac_table[i].queue,
- IXGBE_RAH_AV);
- } else {
- hw->mac.ops.clear_rar(hw, i);
- }
- adapter->mac_table[i].state &=
- ~(IXGBE_MAC_STATE_MODIFIED);
- }
- }
-}
-
-int ixgbe_available_rars(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- int i, count = 0;
-
- for (i = 0; i < hw->mac.num_rar_entries; i++) {
- if (adapter->mac_table[i].state == 0)
- count++;
- }
- return count;
-}
-
-int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- int i;
-
- if (is_zero_ether_addr(addr))
- return 0;
-
- for (i = 0; i < hw->mac.num_rar_entries; i++) {
- if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE)
- continue;
- adapter->mac_table[i].state |= (IXGBE_MAC_STATE_MODIFIED |
- IXGBE_MAC_STATE_IN_USE);
- memcpy(adapter->mac_table[i].addr, addr, ETH_ALEN);
- adapter->mac_table[i].queue = queue;
- ixgbe_sync_mac_table(adapter);
- return i;
- }
- return -ENOMEM;
-}
-
-void ixgbe_flush_sw_mac_table(struct ixgbe_adapter *adapter)
-{
- int i;
- struct ixgbe_hw *hw = &adapter->hw;
-
- for (i = 0; i < hw->mac.num_rar_entries; i++) {
- adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
- adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
- memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
- adapter->mac_table[i].queue = 0;
- }
- ixgbe_sync_mac_table(adapter);
-}
-
-void ixgbe_del_mac_filter_by_index(struct ixgbe_adapter *adapter, int index)
-{
- adapter->mac_table[index].state |= IXGBE_MAC_STATE_MODIFIED;
- adapter->mac_table[index].state &= ~IXGBE_MAC_STATE_IN_USE;
- memset(adapter->mac_table[index].addr, 0, ETH_ALEN);
- adapter->mac_table[index].queue = 0;
- ixgbe_sync_mac_table(adapter);
-}
-
-int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, u8* addr, u16 queue)
-{
- /* search table for addr, if found, set to 0 and sync */
- int i;
- struct ixgbe_hw *hw = &adapter->hw;
-
- if (is_zero_ether_addr(addr))
- return 0;
- for (i = 0; i < hw->mac.num_rar_entries; i++) {
- if (ether_addr_equal(addr, adapter->mac_table[i].addr) &&
- adapter->mac_table[i].queue == queue) {
- adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
- adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
- memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
- adapter->mac_table[i].queue = 0;
- ixgbe_sync_mac_table(adapter);
- return 0;
- }
- }
- return -ENOMEM;
-}
-#ifdef HAVE_SET_RX_MODE
-/**
- * ixgbe_write_uc_addr_list - write unicast addresses to RAR table
- * @netdev: network interface device structure
- *
- * Writes unicast address list to the RAR table.
- * Returns: -ENOMEM on failure/insufficient address space
- * 0 on no addresses written
- * X on writing X addresses to the RAR table
- **/
-int ixgbe_write_uc_addr_list(struct ixgbe_adapter *adapter,
- struct net_device *netdev, unsigned int vfn)
-{
- int count = 0;
-
- /* return ENOMEM indicating insufficient memory for addresses */
- if (netdev_uc_count(netdev) > ixgbe_available_rars(adapter))
- return -ENOMEM;
-
- if (!netdev_uc_empty(netdev)) {
-#ifdef NETDEV_HW_ADDR_T_UNICAST
- struct netdev_hw_addr *ha;
-#else
- struct dev_mc_list *ha;
-#endif
- netdev_for_each_uc_addr(ha, netdev) {
-#ifdef NETDEV_HW_ADDR_T_UNICAST
- ixgbe_del_mac_filter(adapter, ha->addr, (u16)vfn);
- ixgbe_add_mac_filter(adapter, ha->addr, (u16)vfn);
-#else
- ixgbe_del_mac_filter(adapter, ha->da_addr, (u16)vfn);
- ixgbe_add_mac_filter(adapter, ha->da_addr, (u16)vfn);
-#endif
- count++;
- }
- }
- return count;
-}
-
-#endif
-/**
- * ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set
- * @netdev: network interface device structure
- *
- * The set_rx_method entry point is called whenever the unicast/multicast
- * address list or the network interface flags are updated. This routine is
- * responsible for configuring the hardware for proper unicast, multicast and
- * promiscuous mode.
- **/
-void ixgbe_set_rx_mode(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
- u32 vlnctrl;
- int count;
-
- /* Check for Promiscuous and All Multicast modes */
- fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
-
- /* set all bits that we expect to always be set */
- fctrl |= IXGBE_FCTRL_BAM;
- fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
- fctrl |= IXGBE_FCTRL_PMCF;
-
- /* clear the bits we are changing the status of */
- fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
-
- if (netdev->flags & IFF_PROMISC) {
- hw->addr_ctrl.user_set_promisc = true;
- fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- vmolr |= IXGBE_VMOLR_MPE;
- } else {
- if (netdev->flags & IFF_ALLMULTI) {
- fctrl |= IXGBE_FCTRL_MPE;
- vmolr |= IXGBE_VMOLR_MPE;
- } else {
- /*
- * Write addresses to the MTA, if the attempt fails
- * then we should just turn on promiscuous mode so
- * that we can at least receive multicast traffic
- */
- count = ixgbe_write_mc_addr_list(netdev);
- if (count < 0) {
- fctrl |= IXGBE_FCTRL_MPE;
- vmolr |= IXGBE_VMOLR_MPE;
- } else if (count) {
- vmolr |= IXGBE_VMOLR_ROMPE;
- }
- }
-#ifdef NETIF_F_HW_VLAN_TX
- /* enable hardware vlan filtering */
- vlnctrl |= IXGBE_VLNCTRL_VFE;
-#endif
- hw->addr_ctrl.user_set_promisc = false;
-#ifdef HAVE_SET_RX_MODE
- /*
- * Write addresses to available RAR registers, if there is not
- * sufficient space to store all the addresses then enable
- * unicast promiscuous mode
- */
- count = ixgbe_write_uc_addr_list(adapter, netdev,
- adapter->num_vfs);
- if (count < 0) {
- fctrl |= IXGBE_FCTRL_UPE;
- vmolr |= IXGBE_VMOLR_ROPE;
- }
-#endif
- }
-
- if (hw->mac.type != ixgbe_mac_82598EB) {
- vmolr |= IXGBE_READ_REG(hw, IXGBE_VMOLR(adapter->num_vfs)) &
- ~(IXGBE_VMOLR_MPE | IXGBE_VMOLR_ROMPE |
- IXGBE_VMOLR_ROPE);
- IXGBE_WRITE_REG(hw, IXGBE_VMOLR(adapter->num_vfs), vmolr);
- }
-
- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
-}
-
-
-
-
-
-
-
-
-/* Additional bittime to account for IXGBE framing */
-#define IXGBE_ETH_FRAMING 20
-
-/*
- * ixgbe_hpbthresh - calculate high water mark for flow control
- *
- * @adapter: board private structure to calculate for
- * @pb - packet buffer to calculate
- */
-static int ixgbe_hpbthresh(struct ixgbe_adapter *adapter, int pb)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- struct net_device *dev = adapter->netdev;
- int link, tc, kb, marker;
- u32 dv_id, rx_pba;
-
- /* Calculate max LAN frame size */
- tc = link = dev->mtu + ETH_HLEN + ETH_FCS_LEN + IXGBE_ETH_FRAMING;
-
-#ifdef IXGBE_FCOE
- /* FCoE traffic class uses FCOE jumbo frames */
- if (dev->features & NETIF_F_FCOE_MTU) {
- int fcoe_pb = 0;
-
- fcoe_pb = netdev_get_prio_tc_map(dev, adapter->fcoe.up);
-
- if (fcoe_pb == pb && tc < IXGBE_FCOE_JUMBO_FRAME_SIZE)
- tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
- }
-#endif
-
- /* Calculate delay value for device */
- switch (hw->mac.type) {
- case ixgbe_mac_X540:
- dv_id = IXGBE_DV_X540(link, tc);
- break;
- default:
- dv_id = IXGBE_DV(link, tc);
- break;
- }
-
- /* Loopback switch introduces additional latency */
- if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
- dv_id += IXGBE_B2BT(tc);
-
- /* Delay value is calculated in bit times convert to KB */
- kb = IXGBE_BT2KB(dv_id);
- rx_pba = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(pb)) >> 10;
-
- marker = rx_pba - kb;
-
- /* It is possible that the packet buffer is not large enough
- * to provide required headroom. In this case throw an error
- * to user and a do the best we can.
- */
- if (marker < 0) {
- e_warn(drv, "Packet Buffer(%i) can not provide enough"
- "headroom to suppport flow control."
- "Decrease MTU or number of traffic classes\n", pb);
- marker = tc + 1;
- }
-
- return marker;
-}
-
-/*
- * ixgbe_lpbthresh - calculate low water mark for for flow control
- *
- * @adapter: board private structure to calculate for
- * @pb - packet buffer to calculate
- */
-static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter, int pb)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- struct net_device *dev = adapter->netdev;
- int tc;
- u32 dv_id;
-
- /* Calculate max LAN frame size */
- tc = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
-
-#ifdef IXGBE_FCOE
- /* FCoE traffic class uses FCOE jumbo frames */
- if (dev->features & NETIF_F_FCOE_MTU) {
- int fcoe_pb = 0;
-
- fcoe_pb = netdev_get_prio_tc_map(dev, adapter->fcoe.up);
-
- if (fcoe_pb == pb && tc < IXGBE_FCOE_JUMBO_FRAME_SIZE)
- tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
- }
-#endif
-
- /* Calculate delay value for device */
- switch (hw->mac.type) {
- case ixgbe_mac_X540:
- dv_id = IXGBE_LOW_DV_X540(tc);
- break;
- default:
- dv_id = IXGBE_LOW_DV(tc);
- break;
- }
-
- /* Delay value is calculated in bit times convert to KB */
- return IXGBE_BT2KB(dv_id);
-}
-
-/*
- * ixgbe_pbthresh_setup - calculate and setup high low water marks
- */
-static void ixgbe_pbthresh_setup(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- int num_tc = netdev_get_num_tc(adapter->netdev);
- int i;
-
- if (!num_tc)
- num_tc = 1;
- if (num_tc > IXGBE_DCB_MAX_TRAFFIC_CLASS)
- num_tc = IXGBE_DCB_MAX_TRAFFIC_CLASS;
-
- for (i = 0; i < num_tc; i++) {
- hw->fc.high_water[i] = ixgbe_hpbthresh(adapter, i);
- hw->fc.low_water[i] = ixgbe_lpbthresh(adapter, i);
-
- /* Low water marks must not be larger than high water marks */
- if (hw->fc.low_water[i] > hw->fc.high_water[i])
- hw->fc.low_water[i] = 0;
- }
-
- for (; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++)
- hw->fc.high_water[i] = 0;
-}
-
-
-
-#ifdef NO_VNIC
-static void ixgbe_configure(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
-
- ixgbe_configure_pb(adapter);
- ixgbe_configure_dcb(adapter);
-
- ixgbe_set_rx_mode(adapter->netdev);
-#ifdef NETIF_F_HW_VLAN_TX
- ixgbe_restore_vlan(adapter);
-#endif
-
-#ifdef IXGBE_FCOE
- if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
- ixgbe_configure_fcoe(adapter);
-
-#endif /* IXGBE_FCOE */
-
- if (adapter->hw.mac.type != ixgbe_mac_82598EB)
- hw->mac.ops.disable_sec_rx_path(hw);
-
- if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
- ixgbe_init_fdir_signature_82599(&adapter->hw,
- adapter->fdir_pballoc);
- } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) {
- ixgbe_init_fdir_perfect_82599(&adapter->hw,
- adapter->fdir_pballoc);
- ixgbe_fdir_filter_restore(adapter);
- }
-
- if (adapter->hw.mac.type != ixgbe_mac_82598EB)
- hw->mac.ops.enable_sec_rx_path(hw);
-
- ixgbe_configure_virtualization(adapter);
-
- ixgbe_configure_tx(adapter);
- ixgbe_configure_rx(adapter);
-}
-#endif
-
-static bool ixgbe_is_sfp(struct ixgbe_hw *hw)
-{
- switch (hw->phy.type) {
- case ixgbe_phy_sfp_avago:
- case ixgbe_phy_sfp_ftl:
- case ixgbe_phy_sfp_intel:
- case ixgbe_phy_sfp_unknown:
- case ixgbe_phy_sfp_passive_tyco:
- case ixgbe_phy_sfp_passive_unknown:
- case ixgbe_phy_sfp_active_unknown:
- case ixgbe_phy_sfp_ftl_active:
- return true;
- case ixgbe_phy_nl:
- if (hw->mac.type == ixgbe_mac_82598EB)
- return true;
- default:
- return false;
- }
-}
-
-
-/**
- * ixgbe_clear_vf_stats_counters - Clear out VF stats after reset
- * @adapter: board private structure
- *
- * On a reset we need to clear out the VF stats or accounting gets
- * messed up because they're not clear on read.
- **/
-void ixgbe_clear_vf_stats_counters(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- int i;
-
- for (i = 0; i < adapter->num_vfs; i++) {
- adapter->vfinfo[i].last_vfstats.gprc =
- IXGBE_READ_REG(hw, IXGBE_PVFGPRC(i));
- adapter->vfinfo[i].saved_rst_vfstats.gprc +=
- adapter->vfinfo[i].vfstats.gprc;
- adapter->vfinfo[i].vfstats.gprc = 0;
- adapter->vfinfo[i].last_vfstats.gptc =
- IXGBE_READ_REG(hw, IXGBE_PVFGPTC(i));
- adapter->vfinfo[i].saved_rst_vfstats.gptc +=
- adapter->vfinfo[i].vfstats.gptc;
- adapter->vfinfo[i].vfstats.gptc = 0;
- adapter->vfinfo[i].last_vfstats.gorc =
- IXGBE_READ_REG(hw, IXGBE_PVFGORC_LSB(i));
- adapter->vfinfo[i].saved_rst_vfstats.gorc +=
- adapter->vfinfo[i].vfstats.gorc;
- adapter->vfinfo[i].vfstats.gorc = 0;
- adapter->vfinfo[i].last_vfstats.gotc =
- IXGBE_READ_REG(hw, IXGBE_PVFGOTC_LSB(i));
- adapter->vfinfo[i].saved_rst_vfstats.gotc +=
- adapter->vfinfo[i].vfstats.gotc;
- adapter->vfinfo[i].vfstats.gotc = 0;
- adapter->vfinfo[i].last_vfstats.mprc =
- IXGBE_READ_REG(hw, IXGBE_PVFMPRC(i));
- adapter->vfinfo[i].saved_rst_vfstats.mprc +=
- adapter->vfinfo[i].vfstats.mprc;
- adapter->vfinfo[i].vfstats.mprc = 0;
- }
-}
-
-
-
-void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
-{
-#ifdef NO_VNIC
- WARN_ON(in_interrupt());
- /* put off any impending NetWatchDogTimeout */
- adapter->netdev->trans_start = jiffies;
-
- while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
- usleep_range(1000, 2000);
- ixgbe_down(adapter);
- /*
- * If SR-IOV enabled then wait a bit before bringing the adapter
- * back up to give the VFs time to respond to the reset. The
- * two second wait is based upon the watchdog timer cycle in
- * the VF driver.
- */
- if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
- msleep(2000);
- ixgbe_up(adapter);
- clear_bit(__IXGBE_RESETTING, &adapter->state);
-#endif
-}
-
-void ixgbe_up(struct ixgbe_adapter *adapter)
-{
- /* hardware has been reset, we need to reload some things */
- //ixgbe_configure(adapter);
-
- //ixgbe_up_complete(adapter);
-}
-
-void ixgbe_reset(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- int err;
-
- /* lock SFP init bit to prevent race conditions with the watchdog */
- while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
- usleep_range(1000, 2000);
-
- /* clear all SFP and link config related flags while holding SFP_INIT */
- adapter->flags2 &= ~(IXGBE_FLAG2_SEARCH_FOR_SFP |
- IXGBE_FLAG2_SFP_NEEDS_RESET);
- adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
-
- err = hw->mac.ops.init_hw(hw);
- switch (err) {
- case 0:
- case IXGBE_ERR_SFP_NOT_PRESENT:
- case IXGBE_ERR_SFP_NOT_SUPPORTED:
- break;
- case IXGBE_ERR_MASTER_REQUESTS_PENDING:
- e_dev_err("master disable timed out\n");
- break;
- case IXGBE_ERR_EEPROM_VERSION:
- /* We are running on a pre-production device, log a warning */
- e_dev_warn("This device is a pre-production adapter/LOM. "
- "Please be aware there may be issues associated "
- "with your hardware. If you are experiencing "
- "problems please contact your Intel or hardware "
- "representative who provided you with this "
- "hardware.\n");
- break;
- default:
- e_dev_err("Hardware Error: %d\n", err);
- }
-
- clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
-
- ixgbe_flush_sw_mac_table(adapter);
- memcpy(&adapter->mac_table[0].addr, hw->mac.perm_addr,
- netdev->addr_len);
- adapter->mac_table[0].queue = adapter->num_vfs;
- adapter->mac_table[0].state = (IXGBE_MAC_STATE_DEFAULT |
- IXGBE_MAC_STATE_IN_USE);
- hw->mac.ops.set_rar(hw, 0, adapter->mac_table[0].addr,
- adapter->mac_table[0].queue,
- IXGBE_RAH_AV);
-}
-
-
-
-
-
-
-void ixgbe_down(struct ixgbe_adapter *adapter)
-{
-#ifdef NO_VNIC
- struct net_device *netdev = adapter->netdev;
- struct ixgbe_hw *hw = &adapter->hw;
- u32 rxctrl;
- int i;
-
- /* signal that we are down to the interrupt handler */
- set_bit(__IXGBE_DOWN, &adapter->state);
-
- /* disable receives */
- rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
- IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
-
- /* disable all enabled rx queues */
- for (i = 0; i < adapter->num_rx_queues; i++)
- /* this call also flushes the previous write */
- ixgbe_disable_rx_queue(adapter, adapter->rx_ring[i]);
-
- usleep_range(10000, 20000);
-
- netif_tx_stop_all_queues(netdev);
-
- /* call carrier off first to avoid false dev_watchdog timeouts */
- netif_carrier_off(netdev);
- netif_tx_disable(netdev);
-
- ixgbe_irq_disable(adapter);
-
- ixgbe_napi_disable_all(adapter);
-
- adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
- IXGBE_FLAG2_RESET_REQUESTED);
- adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
-
- del_timer_sync(&adapter->service_timer);
-
- if (adapter->num_vfs) {
- /* Clear EITR Select mapping */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITRSEL, 0);
-
- /* Mark all the VFs as inactive */
- for (i = 0 ; i < adapter->num_vfs; i++)
- adapter->vfinfo[i].clear_to_send = 0;
-
- /* ping all the active vfs to let them know we are going down */
- ixgbe_ping_all_vfs(adapter);
-
- /* Disable all VFTE/VFRE TX/RX */
- ixgbe_disable_tx_rx(adapter);
- }
-
- /* disable transmits in the hardware now that interrupts are off */
- for (i = 0; i < adapter->num_tx_queues; i++) {
- u8 reg_idx = adapter->tx_ring[i]->reg_idx;
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
- }
-
- /* Disable the Tx DMA engine on 82599 and X540 */
- switch (hw->mac.type) {
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
- (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
- ~IXGBE_DMATXCTL_TE));
- break;
- default:
- break;
- }
-
-#ifdef HAVE_PCI_ERS
- if (!pci_channel_offline(adapter->pdev))
-#endif
- ixgbe_reset(adapter);
- /* power down the optics */
- if ((hw->phy.multispeed_fiber) ||
- ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
- (hw->mac.type == ixgbe_mac_82599EB)))
- ixgbe_disable_tx_laser(hw);
-
- ixgbe_clean_all_tx_rings(adapter);
- ixgbe_clean_all_rx_rings(adapter);
-
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
- /* since we reset the hardware DCA settings were cleared */
- ixgbe_setup_dca(adapter);
-#endif
-
-#endif /* NO_VNIC */
-}
-
-#ifndef NO_VNIC
-
-#undef IXGBE_FCOE
-
-/* Artificial max queue cap per traffic class in DCB mode */
-#define DCB_QUEUE_CAP 8
-
-/**
- * ixgbe_set_dcb_queues: Allocate queues for a DCB-enabled device
- * @adapter: board private structure to initialize
- *
- * When DCB (Data Center Bridging) is enabled, allocate queues for
- * each traffic class. If multiqueue isn't available,then abort DCB
- * initialization.
- *
- * This function handles all combinations of DCB, RSS, and FCoE.
- *
- **/
-static bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
-{
- int tcs;
-#ifdef HAVE_MQPRIO
- int rss_i, i, offset = 0;
- struct net_device *dev = adapter->netdev;
-
- /* Map queue offset and counts onto allocated tx queues */
- tcs = netdev_get_num_tc(dev);
-
- if (!tcs)
- return false;
-
- rss_i = min_t(int, dev->num_tx_queues / tcs, num_online_cpus());
-
- if (rss_i > DCB_QUEUE_CAP)
- rss_i = DCB_QUEUE_CAP;
-
- for (i = 0; i < tcs; i++) {
- netdev_set_tc_queue(dev, i, rss_i, offset);
- offset += rss_i;
- }
-
- adapter->num_tx_queues = rss_i * tcs;
- adapter->num_rx_queues = rss_i * tcs;
-
-#ifdef IXGBE_FCOE
- /* FCoE enabled queues require special configuration indexed
- * by feature specific indices and mask. Here we map FCoE
- * indices onto the DCB queue pairs allowing FCoE to own
- * configuration later.
- */
-
- if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
- struct ixgbe_ring_feature *f;
- int tc;
- u8 prio_tc[IXGBE_DCB_MAX_USER_PRIORITY] = {0};
-
- ixgbe_dcb_unpack_map_cee(&adapter->dcb_cfg,
- IXGBE_DCB_TX_CONFIG,
- prio_tc);
- tc = prio_tc[adapter->fcoe.up];
-
- f = &adapter->ring_feature[RING_F_FCOE];
- f->indices = min_t(int, rss_i, f->indices);
- f->mask = rss_i * tc;
- }
-#endif /* IXGBE_FCOE */
-#else
- if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
- return false;
-
- /* Enable one Queue per traffic class */
- tcs = adapter->tc;
- if (!tcs)
- return false;
-
-#ifdef IXGBE_FCOE
- if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
- struct ixgbe_ring_feature *f;
- int tc = netdev_get_prio_tc_map(adapter->netdev,
- adapter->fcoe.up);
-
- f = &adapter->ring_feature[RING_F_FCOE];
-
- /*
- * We have max 8 queues for FCoE, where 8 the is
- * FCoE redirection table size. We must also share
- * ring resources with network traffic so if FCoE TC is
- * 4 or greater and we are in 8 TC mode we can only use
- * 7 queues.
- */
- if ((tcs > 4) && (tc >= 4) && (f->indices > 7))
- f->indices = 7;
-
- f->indices = min_t(int, num_online_cpus(), f->indices);
- f->mask = tcs;
-
- adapter->num_rx_queues = f->indices + tcs;
- adapter->num_tx_queues = f->indices + tcs;
-
- return true;
- }
-
-#endif /* IXGBE_FCOE */
- adapter->num_rx_queues = tcs;
- adapter->num_tx_queues = tcs;
-#endif /* HAVE_MQ */
-
- return true;
-}
-
-/**
- * ixgbe_set_vmdq_queues: Allocate queues for VMDq devices
- * @adapter: board private structure to initialize
- *
- * When VMDq (Virtual Machine Devices queue) is enabled, allocate queues
- * and VM pools where appropriate. If RSS is available, then also try and
- * enable RSS and map accordingly.
- *
- **/
-static bool ixgbe_set_vmdq_queues(struct ixgbe_adapter *adapter)
-{
- int vmdq_i = adapter->ring_feature[RING_F_VMDQ].indices;
- int vmdq_m = 0;
- int rss_i = adapter->ring_feature[RING_F_RSS].indices;
- unsigned long i;
- int rss_shift;
- bool ret = false;
-
-
- switch (adapter->flags & (IXGBE_FLAG_RSS_ENABLED
- | IXGBE_FLAG_DCB_ENABLED
- | IXGBE_FLAG_VMDQ_ENABLED)) {
-
- case (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_VMDQ_ENABLED):
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- vmdq_i = min((int)IXGBE_MAX_VMDQ_INDICES, vmdq_i);
- if (vmdq_i > 32)
- rss_i = 2;
- else
- rss_i = 4;
- i = rss_i;
- rss_shift = find_first_bit(&i, sizeof(i) * 8);
- vmdq_m = ((IXGBE_MAX_VMDQ_INDICES - 1) <<
- rss_shift) & (MAX_RX_QUEUES - 1);
- break;
- default:
- break;
- }
- adapter->num_rx_queues = vmdq_i * rss_i;
- adapter->num_tx_queues = min((int)MAX_TX_QUEUES, vmdq_i * rss_i);
- ret = true;
- break;
-
- case (IXGBE_FLAG_VMDQ_ENABLED):
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- vmdq_m = (IXGBE_MAX_VMDQ_INDICES - 1);
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- vmdq_m = (IXGBE_MAX_VMDQ_INDICES - 1) << 1;
- break;
- default:
- break;
- }
- adapter->num_rx_queues = vmdq_i;
- adapter->num_tx_queues = vmdq_i;
- ret = true;
- break;
-
- default:
- ret = false;
- goto vmdq_queues_out;
- }
-
- if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) {
- adapter->num_rx_pools = vmdq_i;
- adapter->num_rx_queues_per_pool = adapter->num_rx_queues /
- vmdq_i;
- } else {
- adapter->num_rx_pools = adapter->num_rx_queues;
- adapter->num_rx_queues_per_pool = 1;
- }
- /* save the mask for later use */
- adapter->ring_feature[RING_F_VMDQ].mask = vmdq_m;
-vmdq_queues_out:
- return ret;
-}
-
-/**
- * ixgbe_set_rss_queues: Allocate queues for RSS
- * @adapter: board private structure to initialize
- *
- * This is our "base" multiqueue mode. RSS (Receive Side Scaling) will try
- * to allocate one Rx queue per CPU, and if available, one Tx queue per CPU.
- *
- **/
-static bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_ring_feature *f;
-
- if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) {
- adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
- return false;
- }
-
- /* set mask for 16 queue limit of RSS */
- f = &adapter->ring_feature[RING_F_RSS];
- f->mask = 0xF;
-
- /*
- * Use Flow Director in addition to RSS to ensure the best
- * distribution of flows across cores, even when an FDIR flow
- * isn't matched.
- */
- if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
- f = &adapter->ring_feature[RING_F_FDIR];
-
- f->indices = min_t(int, num_online_cpus(), f->indices);
- f->mask = 0;
- }
-
- adapter->num_rx_queues = f->indices;
-#ifdef HAVE_TX_MQ
- adapter->num_tx_queues = f->indices;
-#endif
-
- return true;
-}
-
-#ifdef IXGBE_FCOE
-/**
- * ixgbe_set_fcoe_queues: Allocate queues for Fiber Channel over Ethernet (FCoE)
- * @adapter: board private structure to initialize
- *
- * FCoE RX FCRETA can use up to 8 rx queues for up to 8 different exchanges.
- * The ring feature mask is not used as a mask for FCoE, as it can take any 8
- * rx queues out of the max number of rx queues, instead, it is used as the
- * index of the first rx queue used by FCoE.
- *
- **/
-static bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_ring_feature *f;
-
- if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
- return false;
-
- ixgbe_set_rss_queues(adapter);
-
- f = &adapter->ring_feature[RING_F_FCOE];
- f->indices = min_t(int, num_online_cpus(), f->indices);
-
- /* adding FCoE queues */
- f->mask = adapter->num_rx_queues;
- adapter->num_rx_queues += f->indices;
- adapter->num_tx_queues += f->indices;
-
- return true;
-}
-
-#endif /* IXGBE_FCOE */
-/*
- * ixgbe_set_num_queues: Allocate queues for device, feature dependent
- * @adapter: board private structure to initialize
- *
- * This is the top level queue allocation routine. The order here is very
- * important, starting with the "most" number of features turned on at once,
- * and ending with the smallest set of features. This way large combinations
- * can be allocated if they're turned on, and smaller combinations are the
- * fallthrough conditions.
- *
- **/
-static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
-{
- /* Start with base case */
- adapter->num_rx_queues = 1;
- adapter->num_tx_queues = 1;
- adapter->num_rx_pools = adapter->num_rx_queues;
- adapter->num_rx_queues_per_pool = 1;
-
- if (ixgbe_set_vmdq_queues(adapter))
- return;
-
- if (ixgbe_set_dcb_queues(adapter))
- return;
-
-#ifdef IXGBE_FCOE
- if (ixgbe_set_fcoe_queues(adapter))
- return;
-
-#endif /* IXGBE_FCOE */
- ixgbe_set_rss_queues(adapter);
-}
-
-#endif
-
-
-/**
- * ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter)
- * @adapter: board private structure to initialize
- *
- * ixgbe_sw_init initializes the Adapter private data structure.
- * Fields are initialized based on PCI device information and
- * OS network device settings (MTU size).
- **/
-static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- struct pci_dev *pdev = adapter->pdev;
- int err;
-
- /* PCI config space info */
-
- hw->vendor_id = pdev->vendor;
- hw->device_id = pdev->device;
- pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
- hw->subsystem_vendor_id = pdev->subsystem_vendor;
- hw->subsystem_device_id = pdev->subsystem_device;
-
- err = ixgbe_init_shared_code(hw);
- if (err) {
- e_err(probe, "init_shared_code failed: %d\n", err);
- goto out;
- }
- adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) *
- hw->mac.num_rar_entries,
- GFP_ATOMIC);
- /* Set capability flags */
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- adapter->flags |= IXGBE_FLAG_MSI_CAPABLE |
- IXGBE_FLAG_MSIX_CAPABLE |
- IXGBE_FLAG_MQ_CAPABLE |
- IXGBE_FLAG_RSS_CAPABLE;
- adapter->flags |= IXGBE_FLAG_DCB_CAPABLE;
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
- adapter->flags |= IXGBE_FLAG_DCA_CAPABLE;
-#endif
- adapter->flags &= ~IXGBE_FLAG_SRIOV_CAPABLE;
- adapter->flags2 &= ~IXGBE_FLAG2_RSC_CAPABLE;
-
- if (hw->device_id == IXGBE_DEV_ID_82598AT)
- adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
-
- adapter->max_msix_q_vectors = IXGBE_MAX_MSIX_Q_VECTORS_82598;
- break;
- case ixgbe_mac_X540:
- adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
- case ixgbe_mac_82599EB:
- adapter->flags |= IXGBE_FLAG_MSI_CAPABLE |
- IXGBE_FLAG_MSIX_CAPABLE |
- IXGBE_FLAG_MQ_CAPABLE |
- IXGBE_FLAG_RSS_CAPABLE;
- adapter->flags |= IXGBE_FLAG_DCB_CAPABLE;
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
- adapter->flags |= IXGBE_FLAG_DCA_CAPABLE;
-#endif
- adapter->flags |= IXGBE_FLAG_SRIOV_CAPABLE;
- adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE;
-#ifdef IXGBE_FCOE
- adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE;
- adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
- adapter->ring_feature[RING_F_FCOE].indices = 0;
-#ifdef CONFIG_DCB
- /* Default traffic class to use for FCoE */
- adapter->fcoe.tc = IXGBE_FCOE_DEFTC;
- adapter->fcoe.up = IXGBE_FCOE_DEFTC;
- adapter->fcoe.up_set = IXGBE_FCOE_DEFTC;
-#endif
-#endif
- if (hw->device_id == IXGBE_DEV_ID_82599_T3_LOM)
- adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
-#ifndef IXGBE_NO_SMART_SPEED
- hw->phy.smart_speed = ixgbe_smart_speed_on;
-#else
- hw->phy.smart_speed = ixgbe_smart_speed_off;
-#endif
- adapter->max_msix_q_vectors = IXGBE_MAX_MSIX_Q_VECTORS_82599;
- default:
- break;
- }
-
- /* n-tuple support exists, always init our spinlock */
- //spin_lock_init(&adapter->fdir_perfect_lock);
-
- if (adapter->flags & IXGBE_FLAG_DCB_CAPABLE) {
- int j;
- struct ixgbe_dcb_tc_config *tc;
- int dcb_i = IXGBE_DCB_MAX_TRAFFIC_CLASS;
-
-
- adapter->dcb_cfg.num_tcs.pg_tcs = dcb_i;
- adapter->dcb_cfg.num_tcs.pfc_tcs = dcb_i;
- for (j = 0; j < dcb_i; j++) {
- tc = &adapter->dcb_cfg.tc_config[j];
- tc->path[IXGBE_DCB_TX_CONFIG].bwg_id = 0;
- tc->path[IXGBE_DCB_TX_CONFIG].bwg_percent = 100 / dcb_i;
- tc->path[IXGBE_DCB_RX_CONFIG].bwg_id = 0;
- tc->path[IXGBE_DCB_RX_CONFIG].bwg_percent = 100 / dcb_i;
- tc->pfc = ixgbe_dcb_pfc_disabled;
- if (j == 0) {
- /* total of all TCs bandwidth needs to be 100 */
- tc->path[IXGBE_DCB_TX_CONFIG].bwg_percent +=
- 100 % dcb_i;
- tc->path[IXGBE_DCB_RX_CONFIG].bwg_percent +=
- 100 % dcb_i;
- }
- }
-
- /* Initialize default user to priority mapping, UPx->TC0 */
- tc = &adapter->dcb_cfg.tc_config[0];
- tc->path[IXGBE_DCB_TX_CONFIG].up_to_tc_bitmap = 0xFF;
- tc->path[IXGBE_DCB_RX_CONFIG].up_to_tc_bitmap = 0xFF;
-
- adapter->dcb_cfg.bw_percentage[IXGBE_DCB_TX_CONFIG][0] = 100;
- adapter->dcb_cfg.bw_percentage[IXGBE_DCB_RX_CONFIG][0] = 100;
- adapter->dcb_cfg.rx_pba_cfg = ixgbe_dcb_pba_equal;
- adapter->dcb_cfg.pfc_mode_enable = false;
- adapter->dcb_cfg.round_robin_enable = false;
- adapter->dcb_set_bitmap = 0x00;
-#ifdef CONFIG_DCB
- adapter->dcbx_cap = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_CEE;
-#endif /* CONFIG_DCB */
-
- if (hw->mac.type == ixgbe_mac_X540) {
- adapter->dcb_cfg.num_tcs.pg_tcs = 4;
- adapter->dcb_cfg.num_tcs.pfc_tcs = 4;
- }
- }
-#ifdef CONFIG_DCB
- /* XXX does this need to be initialized even w/o DCB? */
- //memcpy(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
- // sizeof(adapter->temp_dcb_cfg));
-
-#endif
- //if (hw->mac.type == ixgbe_mac_82599EB ||
- // hw->mac.type == ixgbe_mac_X540)
- // hw->mbx.ops.init_params(hw);
-
- /* default flow control settings */
- hw->fc.requested_mode = ixgbe_fc_full;
- hw->fc.current_mode = ixgbe_fc_full; /* init for ethtool output */
-
- adapter->last_lfc_mode = hw->fc.current_mode;
- ixgbe_pbthresh_setup(adapter);
- hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
- hw->fc.send_xon = true;
- hw->fc.disable_fc_autoneg = false;
-
- /* set default ring sizes */
- adapter->tx_ring_count = IXGBE_DEFAULT_TXD;
- adapter->rx_ring_count = IXGBE_DEFAULT_RXD;
-
- /* set default work limits */
- adapter->tx_work_limit = IXGBE_DEFAULT_TX_WORK;
- adapter->rx_work_limit = IXGBE_DEFAULT_RX_WORK;
-
- set_bit(__IXGBE_DOWN, &adapter->state);
-out:
- return err;
-}
-
-/**
- * ixgbe_setup_tx_resources - allocate Tx resources (Descriptors)
- * @tx_ring: tx descriptor ring (for a specific queue) to setup
- *
- * Return 0 on success, negative on failure
- **/
-int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring)
-{
- struct device *dev = tx_ring->dev;
- //int orig_node = dev_to_node(dev);
- int numa_node = -1;
- int size;
-
- size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count;
-
- if (tx_ring->q_vector)
- numa_node = tx_ring->q_vector->numa_node;
-
- tx_ring->tx_buffer_info = vzalloc_node(size, numa_node);
- if (!tx_ring->tx_buffer_info)
- tx_ring->tx_buffer_info = vzalloc(size);
- if (!tx_ring->tx_buffer_info)
- goto err;
-
- /* round up to nearest 4K */
- tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
- tx_ring->size = ALIGN(tx_ring->size, 4096);
-
- //set_dev_node(dev, numa_node);
- //tx_ring->desc = dma_alloc_coherent(dev,
- // tx_ring->size,
- // &tx_ring->dma,
- // GFP_KERNEL);
- //set_dev_node(dev, orig_node);
- //if (!tx_ring->desc)
- // tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size,
- // &tx_ring->dma, GFP_KERNEL);
- //if (!tx_ring->desc)
- // goto err;
-
- return 0;
-
-err:
- vfree(tx_ring->tx_buffer_info);
- tx_ring->tx_buffer_info = NULL;
- dev_err(dev, "Unable to allocate memory for the Tx descriptor ring\n");
- return -ENOMEM;
-}
-
-/**
- * ixgbe_setup_all_tx_resources - allocate all queues Tx resources
- * @adapter: board private structure
- *
- * If this function returns with an error, then it's possible one or
- * more of the rings is populated (while the rest are not). It is the
- * callers duty to clean those orphaned rings.
- *
- * Return 0 on success, negative on failure
- **/
-static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
-{
- int i, err = 0;
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- err = ixgbe_setup_tx_resources(adapter->tx_ring[i]);
- if (!err)
- continue;
- e_err(probe, "Allocation for Tx Queue %u failed\n", i);
- break;
- }
-
- return err;
-}
-
-/**
- * ixgbe_setup_rx_resources - allocate Rx resources (Descriptors)
- * @rx_ring: rx descriptor ring (for a specific queue) to setup
- *
- * Returns 0 on success, negative on failure
- **/
-int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring)
-{
- struct device *dev = rx_ring->dev;
- //int orig_node = dev_to_node(dev);
- int numa_node = -1;
- int size;
-
- size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
-
- if (rx_ring->q_vector)
- numa_node = rx_ring->q_vector->numa_node;
-
- rx_ring->rx_buffer_info = vzalloc_node(size, numa_node);
- if (!rx_ring->rx_buffer_info)
- rx_ring->rx_buffer_info = vzalloc(size);
- if (!rx_ring->rx_buffer_info)
- goto err;
-
- /* Round up to nearest 4K */
- rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
- rx_ring->size = ALIGN(rx_ring->size, 4096);
-
-#ifdef NO_VNIC
- set_dev_node(dev, numa_node);
- rx_ring->desc = dma_alloc_coherent(dev,
- rx_ring->size,
- &rx_ring->dma,
- GFP_KERNEL);
- set_dev_node(dev, orig_node);
- if (!rx_ring->desc)
- rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size,
- &rx_ring->dma, GFP_KERNEL);
- if (!rx_ring->desc)
- goto err;
-
-#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT
- ixgbe_init_rx_page_offset(rx_ring);
-
-#endif
-
-#endif /* NO_VNIC */
- return 0;
-err:
- vfree(rx_ring->rx_buffer_info);
- rx_ring->rx_buffer_info = NULL;
- dev_err(dev, "Unable to allocate memory for the Rx descriptor ring\n");
- return -ENOMEM;
-}
-
-/**
- * ixgbe_setup_all_rx_resources - allocate all queues Rx resources
- * @adapter: board private structure
- *
- * If this function returns with an error, then it's possible one or
- * more of the rings is populated (while the rest are not). It is the
- * callers duty to clean those orphaned rings.
- *
- * Return 0 on success, negative on failure
- **/
-static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
-{
- int i, err = 0;
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- err = ixgbe_setup_rx_resources(adapter->rx_ring[i]);
- if (!err)
- continue;
- e_err(probe, "Allocation for Rx Queue %u failed\n", i);
- break;
- }
-
- return err;
-}
-
-/**
- * ixgbe_free_tx_resources - Free Tx Resources per Queue
- * @tx_ring: Tx descriptor ring for a specific queue
- *
- * Free all transmit software resources
- **/
-void ixgbe_free_tx_resources(struct ixgbe_ring *tx_ring)
-{
- //ixgbe_clean_tx_ring(tx_ring);
-
- vfree(tx_ring->tx_buffer_info);
- tx_ring->tx_buffer_info = NULL;
-
- /* if not set, then don't free */
- if (!tx_ring->desc)
- return;
-
- //dma_free_coherent(tx_ring->dev, tx_ring->size,
- // tx_ring->desc, tx_ring->dma);
-
- tx_ring->desc = NULL;
-}
-
-/**
- * ixgbe_free_all_tx_resources - Free Tx Resources for All Queues
- * @adapter: board private structure
- *
- * Free all transmit software resources
- **/
-static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter)
-{
- int i;
-
- for (i = 0; i < adapter->num_tx_queues; i++)
- if (adapter->tx_ring[i]->desc)
- ixgbe_free_tx_resources(adapter->tx_ring[i]);
-}
-
-/**
- * ixgbe_free_rx_resources - Free Rx Resources
- * @rx_ring: ring to clean the resources from
- *
- * Free all receive software resources
- **/
-void ixgbe_free_rx_resources(struct ixgbe_ring *rx_ring)
-{
- //ixgbe_clean_rx_ring(rx_ring);
-
- vfree(rx_ring->rx_buffer_info);
- rx_ring->rx_buffer_info = NULL;
-
- /* if not set, then don't free */
- if (!rx_ring->desc)
- return;
-
- //dma_free_coherent(rx_ring->dev, rx_ring->size,
- // rx_ring->desc, rx_ring->dma);
-
- rx_ring->desc = NULL;
-}
-
-/**
- * ixgbe_free_all_rx_resources - Free Rx Resources for All Queues
- * @adapter: board private structure
- *
- * Free all receive software resources
- **/
-static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
-{
- int i;
-
- for (i = 0; i < adapter->num_rx_queues; i++)
- if (adapter->rx_ring[i]->desc)
- ixgbe_free_rx_resources(adapter->rx_ring[i]);
-}
-
-
-/**
- * ixgbe_open - Called when a network interface is made active
- * @netdev: network interface device structure
- *
- * Returns 0 on success, negative value on failure
- *
- * The open entry point is called when a network interface is made
- * active by the system (IFF_UP). At this point all resources needed
- * for transmit and receive operations are allocated, the interrupt
- * handler is registered with the OS, the watchdog timer is started,
- * and the stack is notified that the interface is ready.
- **/
-//static
-int ixgbe_open(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- int err;
-
- /* disallow open during test */
- if (test_bit(__IXGBE_TESTING, &adapter->state))
- return -EBUSY;
-
- netif_carrier_off(netdev);
-
- /* allocate transmit descriptors */
- err = ixgbe_setup_all_tx_resources(adapter);
- if (err)
- goto err_setup_tx;
-
- /* allocate receive descriptors */
- err = ixgbe_setup_all_rx_resources(adapter);
- if (err)
- goto err_setup_rx;
-
-#ifdef NO_VNIC
- ixgbe_configure(adapter);
-
- err = ixgbe_request_irq(adapter);
- if (err)
- goto err_req_irq;
-
- ixgbe_up_complete(adapter);
-
-err_req_irq:
-#else
- return 0;
-#endif
-err_setup_rx:
- ixgbe_free_all_rx_resources(adapter);
-err_setup_tx:
- ixgbe_free_all_tx_resources(adapter);
- ixgbe_reset(adapter);
-
- return err;
-}
-
-/**
- * ixgbe_close - Disables a network interface
- * @netdev: network interface device structure
- *
- * Returns 0, this is not allowed to fail
- *
- * The close entry point is called when an interface is de-activated
- * by the OS. The hardware is still under the drivers control, but
- * needs to be disabled. A global MAC reset is issued to stop the
- * hardware, and all transmit and receive resources are freed.
- **/
-//static
-int ixgbe_close(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- //ixgbe_down(adapter);
- //ixgbe_free_irq(adapter);
-
- //ixgbe_fdir_filter_exit(adapter);
-
- //ixgbe_free_all_tx_resources(adapter);
- //ixgbe_free_all_rx_resources(adapter);
-
- ixgbe_release_hw_control(adapter);
-
- return 0;
-}
-
-
-
-
-
-/**
- * ixgbe_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- **/
-//static
-struct net_device_stats *ixgbe_get_stats(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- /* update the stats data */
- ixgbe_update_stats(adapter);
-
-#ifdef HAVE_NETDEV_STATS_IN_NETDEV
- /* only return the current stats */
- return &netdev->stats;
-#else
- /* only return the current stats */
- return &adapter->net_stats;
-#endif /* HAVE_NETDEV_STATS_IN_NETDEV */
-}
-
-/**
- * ixgbe_update_stats - Update the board statistics counters.
- * @adapter: board private structure
- **/
-void ixgbe_update_stats(struct ixgbe_adapter *adapter)
-{
-#ifdef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats *net_stats = &adapter->netdev->stats;
-#else
- struct net_device_stats *net_stats = &adapter->net_stats;
-#endif /* HAVE_NETDEV_STATS_IN_NETDEV */
- struct ixgbe_hw *hw = &adapter->hw;
- struct ixgbe_hw_stats *hwstats = &adapter->stats;
- u64 total_mpc = 0;
- u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
- u64 non_eop_descs = 0, restart_queue = 0, tx_busy = 0;
- u64 alloc_rx_page_failed = 0, alloc_rx_buff_failed = 0;
- u64 bytes = 0, packets = 0, hw_csum_rx_error = 0;
-#ifndef IXGBE_NO_LRO
- u32 flushed = 0, coal = 0;
- int num_q_vectors = 1;
-#endif
-#ifdef IXGBE_FCOE
- struct ixgbe_fcoe *fcoe = &adapter->fcoe;
- unsigned int cpu;
- u64 fcoe_noddp_counts_sum = 0, fcoe_noddp_ext_buff_counts_sum = 0;
-#endif /* IXGBE_FCOE */
-
- printk(KERN_DEBUG "ixgbe_update_stats, tx_queues=%d, rx_queues=%d\n",
- adapter->num_tx_queues, adapter->num_rx_queues);
-
- if (test_bit(__IXGBE_DOWN, &adapter->state) ||
- test_bit(__IXGBE_RESETTING, &adapter->state))
- return;
-
-#ifndef IXGBE_NO_LRO
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
- num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
-
-#endif
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
- u64 rsc_count = 0;
- u64 rsc_flush = 0;
- for (i = 0; i < adapter->num_rx_queues; i++) {
- rsc_count += adapter->rx_ring[i]->rx_stats.rsc_count;
- rsc_flush += adapter->rx_ring[i]->rx_stats.rsc_flush;
- }
- adapter->rsc_total_count = rsc_count;
- adapter->rsc_total_flush = rsc_flush;
- }
-
-#ifndef IXGBE_NO_LRO
- for (i = 0; i < num_q_vectors; i++) {
- struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
- if (!q_vector)
- continue;
- flushed += q_vector->lrolist.stats.flushed;
- coal += q_vector->lrolist.stats.coal;
- }
- adapter->lro_stats.flushed = flushed;
- adapter->lro_stats.coal = coal;
-
-#endif
- for (i = 0; i < adapter->num_rx_queues; i++) {
- struct ixgbe_ring *rx_ring = adapter->rx_ring[i];
- non_eop_descs += rx_ring->rx_stats.non_eop_descs;
- alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed;
- alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed;
- hw_csum_rx_error += rx_ring->rx_stats.csum_err;
- bytes += rx_ring->stats.bytes;
- packets += rx_ring->stats.packets;
-
- }
- adapter->non_eop_descs = non_eop_descs;
- adapter->alloc_rx_page_failed = alloc_rx_page_failed;
- adapter->alloc_rx_buff_failed = alloc_rx_buff_failed;
- adapter->hw_csum_rx_error = hw_csum_rx_error;
- net_stats->rx_bytes = bytes;
- net_stats->rx_packets = packets;
-
- bytes = 0;
- packets = 0;
- /* gather some stats to the adapter struct that are per queue */
- for (i = 0; i < adapter->num_tx_queues; i++) {
- struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
- restart_queue += tx_ring->tx_stats.restart_queue;
- tx_busy += tx_ring->tx_stats.tx_busy;
- bytes += tx_ring->stats.bytes;
- packets += tx_ring->stats.packets;
- }
- adapter->restart_queue = restart_queue;
- adapter->tx_busy = tx_busy;
- net_stats->tx_bytes = bytes;
- net_stats->tx_packets = packets;
-
- hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
-
- /* 8 register reads */
- for (i = 0; i < 8; i++) {
- /* for packet buffers not used, the register should read 0 */
- mpc = IXGBE_READ_REG(hw, IXGBE_MPC(i));
- missed_rx += mpc;
- hwstats->mpc[i] += mpc;
- total_mpc += hwstats->mpc[i];
- hwstats->pxontxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
- hwstats->pxofftxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- hwstats->rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
- hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
- hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
- hwstats->pxonrxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- hwstats->pxonrxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
- break;
- default:
- break;
- }
- }
-
- /*16 register reads */
- for (i = 0; i < 16; i++) {
- hwstats->qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
- hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
- if ((hw->mac.type == ixgbe_mac_82599EB) ||
- (hw->mac.type == ixgbe_mac_X540)) {
- hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
- IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); /* to clear */
- hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC_L(i));
- IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); /* to clear */
- }
- }
-
- hwstats->gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
- /* work around hardware counting issue */
- hwstats->gprc -= missed_rx;
-
- ixgbe_update_xoff_received(adapter);
-
- /* 82598 hardware only has a 32 bit counter in the high register */
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
- hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
- hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
- hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH);
- break;
- case ixgbe_mac_X540:
- /* OS2BMC stats are X540 only*/
- hwstats->o2bgptc += IXGBE_READ_REG(hw, IXGBE_O2BGPTC);
- hwstats->o2bspc += IXGBE_READ_REG(hw, IXGBE_O2BSPC);
- hwstats->b2ospc += IXGBE_READ_REG(hw, IXGBE_B2OSPC);
- hwstats->b2ogprc += IXGBE_READ_REG(hw, IXGBE_B2OGPRC);
- case ixgbe_mac_82599EB:
- for (i = 0; i < 16; i++)
- adapter->hw_rx_no_dma_resources +=
- IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
- hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
- IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
- hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
- IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */
- hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL);
- IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
- hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
-#ifdef HAVE_TX_MQ
- hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
- hwstats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
-#endif /* HAVE_TX_MQ */
-#ifdef IXGBE_FCOE
- hwstats->fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
- hwstats->fclast += IXGBE_READ_REG(hw, IXGBE_FCLAST);
- hwstats->fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
- hwstats->fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
- hwstats->fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
- hwstats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
- hwstats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
- /* Add up per cpu counters for total ddp aloc fail */
- if (fcoe && fcoe->pcpu_noddp && fcoe->pcpu_noddp_ext_buff) {
- for_each_possible_cpu(cpu) {
- fcoe_noddp_counts_sum +=
- *per_cpu_ptr(fcoe->pcpu_noddp, cpu);
- fcoe_noddp_ext_buff_counts_sum +=
- *per_cpu_ptr(fcoe->
- pcpu_noddp_ext_buff, cpu);
- }
- }
- hwstats->fcoe_noddp = fcoe_noddp_counts_sum;
- hwstats->fcoe_noddp_ext_buff = fcoe_noddp_ext_buff_counts_sum;
-
-#endif /* IXGBE_FCOE */
- break;
- default:
- break;
- }
- bprc = IXGBE_READ_REG(hw, IXGBE_BPRC);
- hwstats->bprc += bprc;
- hwstats->mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
- if (hw->mac.type == ixgbe_mac_82598EB)
- hwstats->mprc -= bprc;
- hwstats->roc += IXGBE_READ_REG(hw, IXGBE_ROC);
- hwstats->prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64);
- hwstats->prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127);
- hwstats->prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255);
- hwstats->prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511);
- hwstats->prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
- hwstats->prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
- hwstats->rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
- lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC);
- hwstats->lxontxc += lxon;
- lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
- hwstats->lxofftxc += lxoff;
- hwstats->gptc += IXGBE_READ_REG(hw, IXGBE_GPTC);
- hwstats->mptc += IXGBE_READ_REG(hw, IXGBE_MPTC);
- /*
- * 82598 errata - tx of flow control packets is included in tx counters
- */
- xon_off_tot = lxon + lxoff;
- hwstats->gptc -= xon_off_tot;
- hwstats->mptc -= xon_off_tot;
- hwstats->gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN));
- hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
- hwstats->rfc += IXGBE_READ_REG(hw, IXGBE_RFC);
- hwstats->rjc += IXGBE_READ_REG(hw, IXGBE_RJC);
- hwstats->tpr += IXGBE_READ_REG(hw, IXGBE_TPR);
- hwstats->ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64);
- hwstats->ptc64 -= xon_off_tot;
- hwstats->ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127);
- hwstats->ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255);
- hwstats->ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511);
- hwstats->ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023);
- hwstats->ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522);
- hwstats->bptc += IXGBE_READ_REG(hw, IXGBE_BPTC);
- /* Fill out the OS statistics structure */
- net_stats->multicast = hwstats->mprc;
-
- /* Rx Errors */
- net_stats->rx_errors = hwstats->crcerrs +
- hwstats->rlec;
- net_stats->rx_dropped = 0;
- net_stats->rx_length_errors = hwstats->rlec;
- net_stats->rx_crc_errors = hwstats->crcerrs;
- net_stats->rx_missed_errors = total_mpc;
-
- /*
- * VF Stats Collection - skip while resetting because these
- * are not clear on read and otherwise you'll sometimes get
- * crazy values.
- */
- if (!test_bit(__IXGBE_RESETTING, &adapter->state)) {
- for (i = 0; i < adapter->num_vfs; i++) {
- UPDATE_VF_COUNTER_32bit(IXGBE_PVFGPRC(i), \
- adapter->vfinfo[i].last_vfstats.gprc, \
- adapter->vfinfo[i].vfstats.gprc);
- UPDATE_VF_COUNTER_32bit(IXGBE_PVFGPTC(i), \
- adapter->vfinfo[i].last_vfstats.gptc, \
- adapter->vfinfo[i].vfstats.gptc);
- UPDATE_VF_COUNTER_36bit(IXGBE_PVFGORC_LSB(i), \
- IXGBE_PVFGORC_MSB(i), \
- adapter->vfinfo[i].last_vfstats.gorc, \
- adapter->vfinfo[i].vfstats.gorc);
- UPDATE_VF_COUNTER_36bit(IXGBE_PVFGOTC_LSB(i), \
- IXGBE_PVFGOTC_MSB(i), \
- adapter->vfinfo[i].last_vfstats.gotc, \
- adapter->vfinfo[i].vfstats.gotc);
- UPDATE_VF_COUNTER_32bit(IXGBE_PVFMPRC(i), \
- adapter->vfinfo[i].last_vfstats.mprc, \
- adapter->vfinfo[i].vfstats.mprc);
- }
- }
-}
-
-
-#ifdef NO_VNIC
-
-/**
- * ixgbe_watchdog_update_link - update the link status
- * @adapter - pointer to the device adapter structure
- * @link_speed - pointer to a u32 to store the link_speed
- **/
-static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- u32 link_speed = adapter->link_speed;
- bool link_up = adapter->link_up;
- bool pfc_en = adapter->dcb_cfg.pfc_mode_enable;
-
- if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE))
- return;
-
- if (hw->mac.ops.check_link) {
- hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
- } else {
- /* always assume link is up, if no check link function */
- link_speed = IXGBE_LINK_SPEED_10GB_FULL;
- link_up = true;
- }
-
-#ifdef HAVE_DCBNL_IEEE
- if (adapter->ixgbe_ieee_pfc)
- pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en);
-
-#endif
- if (link_up && !((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && pfc_en)) {
- hw->mac.ops.fc_enable(hw);
- //ixgbe_set_rx_drop_en(adapter);
- }
-
- if (link_up ||
- time_after(jiffies, (adapter->link_check_timeout +
- IXGBE_TRY_LINK_TIMEOUT))) {
- adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
- IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
- IXGBE_WRITE_FLUSH(hw);
- }
-
- adapter->link_up = link_up;
- adapter->link_speed = link_speed;
-}
-#endif
-
-
-
-#ifdef NO_VNIC
-
-/**
- * ixgbe_service_task - manages and runs subtasks
- * @work: pointer to work_struct containing our data
- **/
-static void ixgbe_service_task(struct work_struct *work)
-{
- //struct ixgbe_adapter *adapter = container_of(work,
- // struct ixgbe_adapter,
- // service_task);
-
- //ixgbe_reset_subtask(adapter);
- //ixgbe_sfp_detection_subtask(adapter);
- //ixgbe_sfp_link_config_subtask(adapter);
- //ixgbe_check_overtemp_subtask(adapter);
- //ixgbe_watchdog_subtask(adapter);
-#ifdef HAVE_TX_MQ
- //ixgbe_fdir_reinit_subtask(adapter);
-#endif
- //ixgbe_check_hang_subtask(adapter);
-
- //ixgbe_service_event_complete(adapter);
-}
-
-
-
-
-#define IXGBE_TXD_CMD (IXGBE_TXD_CMD_EOP | \
- IXGBE_TXD_CMD_RS)
-
-
-/**
- * ixgbe_set_mac - Change the Ethernet Address of the NIC
- * @netdev: network interface device structure
- * @p: pointer to an address structure
- *
- * Returns 0 on success, negative on failure
- **/
-static int ixgbe_set_mac(struct net_device *netdev, void *p)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- struct sockaddr *addr = p;
- int ret;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- ixgbe_del_mac_filter(adapter, hw->mac.addr,
- adapter->num_vfs);
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
-
-
- /* set the correct pool for the new PF MAC address in entry 0 */
- ret = ixgbe_add_mac_filter(adapter, hw->mac.addr,
- adapter->num_vfs);
- return ret > 0 ? 0 : ret;
-}
-
-
-/**
- * ixgbe_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- **/
-static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
- switch (cmd) {
-#ifdef ETHTOOL_OPS_COMPAT
- case SIOCETHTOOL:
- return ethtool_ioctl(ifr);
-#endif
- default:
- return -EOPNOTSUPP;
- }
-}
-#endif /* NO_VNIC */
-
-
-void ixgbe_do_reset(struct net_device *netdev)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- if (netif_running(netdev))
- ixgbe_reinit_locked(adapter);
- else
- ixgbe_reset(adapter);
-}
-
-
-
-
-
-
-/**
- * ixgbe_probe - Device Initialization Routine
- * @pdev: PCI device information struct
- * @ent: entry in ixgbe_pci_tbl
- *
- * Returns 0 on success, negative on failure
- *
- * ixgbe_probe initializes an adapter identified by a pci_dev structure.
- * The OS initialization, configuring of the adapter private structure,
- * and a hardware reset occur.
- **/
-//static
-int ixgbe_kni_probe(struct pci_dev *pdev,
- struct net_device **lad_dev)
-{
- size_t count;
- struct net_device *netdev;
- struct ixgbe_adapter *adapter = NULL;
- struct ixgbe_hw *hw = NULL;
- static int cards_found;
- int i, err;
- u16 offset;
- u16 eeprom_verh, eeprom_verl, eeprom_cfg_blkh, eeprom_cfg_blkl;
- u32 etrack_id;
- u16 build, major, patch;
- char *info_string, *i_s_var;
- u8 part_str[IXGBE_PBANUM_LENGTH];
- enum ixgbe_mac_type mac_type = ixgbe_mac_unknown;
-#ifdef HAVE_TX_MQ
- unsigned int indices = num_possible_cpus();
-#endif /* HAVE_TX_MQ */
-#ifdef IXGBE_FCOE
- u16 device_caps;
-#endif
- u16 wol_cap;
-
- err = pci_enable_device_mem(pdev);
- if (err)
- return err;
-
-
-#ifdef NO_VNIC
- err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
- IORESOURCE_MEM), ixgbe_driver_name);
- if (err) {
- dev_err(pci_dev_to_dev(pdev),
- "pci_request_selected_regions failed 0x%x\n", err);
- goto err_pci_reg;
- }
-#endif
-
- /*
- * The mac_type is needed before we have the adapter is set up
- * so rather than maintain two devID -> MAC tables we dummy up
- * an ixgbe_hw stuct and use ixgbe_set_mac_type.
- */
- hw = vmalloc(sizeof(struct ixgbe_hw));
- if (!hw) {
- pr_info("Unable to allocate memory for early mac "
- "check\n");
- } else {
- hw->vendor_id = pdev->vendor;
- hw->device_id = pdev->device;
- ixgbe_set_mac_type(hw);
- mac_type = hw->mac.type;
- vfree(hw);
- }
-
-#ifdef NO_VNIC
- /*
- * Workaround of Silicon errata on 82598. Disable LOs in the PCI switch
- * port to which the 82598 is connected to prevent duplicate
- * completions caused by LOs. We need the mac type so that we only
- * do this on 82598 devices, ixgbe_set_mac_type does this for us if
- * we set it's device ID.
- */
- if (mac_type == ixgbe_mac_82598EB)
- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
-
- pci_enable_pcie_error_reporting(pdev);
-
- pci_set_master(pdev);
-#endif
-
-#ifdef HAVE_TX_MQ
-#ifdef CONFIG_DCB
-#ifdef HAVE_MQPRIO
- indices *= IXGBE_DCB_MAX_TRAFFIC_CLASS;
-#else
- indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES);
-#endif /* HAVE_MQPRIO */
-#endif /* CONFIG_DCB */
-
- if (mac_type == ixgbe_mac_82598EB)
- indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES);
- else
- indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES);
-
-#ifdef IXGBE_FCOE
- indices += min_t(unsigned int, num_possible_cpus(),
- IXGBE_MAX_FCOE_INDICES);
-#endif
- netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);
-#else /* HAVE_TX_MQ */
- netdev = alloc_etherdev(sizeof(struct ixgbe_adapter));
-#endif /* HAVE_TX_MQ */
- if (!netdev) {
- err = -ENOMEM;
- goto err_alloc_etherdev;
- }
-
- SET_NETDEV_DEV(netdev, &pdev->dev);
-
- adapter = netdev_priv(netdev);
- //pci_set_drvdata(pdev, adapter);
-
- adapter->netdev = netdev;
- adapter->pdev = pdev;
- hw = &adapter->hw;
- hw->back = adapter;
- adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
-
-#ifdef HAVE_PCI_ERS
- /*
- * call save state here in standalone driver because it relies on
- * adapter struct to exist, and needs to call netdev_priv
- */
- pci_save_state(pdev);
-
-#endif
- hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- if (!hw->hw_addr) {
- err = -EIO;
- goto err_ioremap;
- }
- //ixgbe_assign_netdev_ops(netdev);
- ixgbe_set_ethtool_ops(netdev);
-
- strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
-
- adapter->bd_number = cards_found;
-
- /* setup the private structure */
- err = ixgbe_sw_init(adapter);
- if (err)
- goto err_sw_init;
-
- /* Make it possible the adapter to be woken up via WOL */
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
- break;
- default:
- break;
- }
-
- /*
- * check_options must be called before setup_link to set up
- * hw->fc completely
- */
- //ixgbe_check_options(adapter);
-
-#ifndef NO_VNIC
- /* reset_hw fills in the perm_addr as well */
- hw->phy.reset_if_overtemp = true;
- err = hw->mac.ops.reset_hw(hw);
- hw->phy.reset_if_overtemp = false;
- if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
- hw->mac.type == ixgbe_mac_82598EB) {
- err = 0;
- } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- e_dev_err("failed to load because an unsupported SFP+ "
- "module type was detected.\n");
- e_dev_err("Reload the driver after installing a supported "
- "module.\n");
- goto err_sw_init;
- } else if (err) {
- e_dev_err("HW Init failed: %d\n", err);
- goto err_sw_init;
- }
-#endif
-
- //if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
- // ixgbe_probe_vf(adapter);
-
-
-#ifdef MAX_SKB_FRAGS
- netdev->features |= NETIF_F_SG |
- NETIF_F_IP_CSUM;
-
-#ifdef NETIF_F_IPV6_CSUM
- netdev->features |= NETIF_F_IPV6_CSUM;
-#endif
-
-#ifdef NETIF_F_HW_VLAN_TX
- netdev->features |= NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX;
-#endif
-#ifdef NETIF_F_TSO
- netdev->features |= NETIF_F_TSO;
-#endif /* NETIF_F_TSO */
-#ifdef NETIF_F_TSO6
- netdev->features |= NETIF_F_TSO6;
-#endif /* NETIF_F_TSO6 */
-#ifdef NETIF_F_RXHASH
- netdev->features |= NETIF_F_RXHASH;
-#endif /* NETIF_F_RXHASH */
-
-#ifdef HAVE_NDO_SET_FEATURES
- netdev->features |= NETIF_F_RXCSUM;
-
- /* copy netdev features into list of user selectable features */
- netdev->hw_features |= netdev->features;
-
- /* give us the option of enabling RSC/LRO later */
-#ifdef IXGBE_NO_LRO
- if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)
-#endif
- netdev->hw_features |= NETIF_F_LRO;
-
-#else
-#ifdef NETIF_F_GRO
-
- /* this is only needed on kernels prior to 2.6.39 */
- netdev->features |= NETIF_F_GRO;
-#endif /* NETIF_F_GRO */
-#endif
-
-#ifdef NETIF_F_HW_VLAN_TX
- /* set this bit last since it cannot be part of hw_features */
- netdev->features |= NETIF_F_HW_VLAN_FILTER;
-#endif
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- netdev->features |= NETIF_F_SCTP_CSUM;
-#ifdef HAVE_NDO_SET_FEATURES
- netdev->hw_features |= NETIF_F_SCTP_CSUM |
- NETIF_F_NTUPLE;
-#endif
- break;
- default:
- break;
- }
-
-#ifdef HAVE_NETDEV_VLAN_FEATURES
- netdev->vlan_features |= NETIF_F_SG |
- NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM |
- NETIF_F_TSO |
- NETIF_F_TSO6;
-
-#endif /* HAVE_NETDEV_VLAN_FEATURES */
- /*
- * If perfect filters were enabled in check_options(), enable them
- * on the netdevice too.
- */
- if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
- netdev->features |= NETIF_F_NTUPLE;
- if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED)
- adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
- adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) {
- adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
- /* clear n-tuple support in the netdev unconditionally */
- netdev->features &= ~NETIF_F_NTUPLE;
- }
-
-#ifdef NETIF_F_RXHASH
- if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
- netdev->features &= ~NETIF_F_RXHASH;
-
-#endif /* NETIF_F_RXHASH */
- if (netdev->features & NETIF_F_LRO) {
- if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) &&
- ((adapter->rx_itr_setting == 1) ||
- (adapter->rx_itr_setting > IXGBE_MIN_RSC_ITR))) {
- adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
- } else if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) {
-#ifdef IXGBE_NO_LRO
- e_info(probe, "InterruptThrottleRate set too high, "
- "disabling RSC\n");
-#else
- e_info(probe, "InterruptThrottleRate set too high, "
- "falling back to software LRO\n");
-#endif
- }
- }
-#ifdef CONFIG_DCB
- //netdev->dcbnl_ops = &dcbnl_ops;
-#endif
-
-#ifdef IXGBE_FCOE
-#ifdef NETIF_F_FSO
- if (adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) {
- ixgbe_get_device_caps(hw, &device_caps);
- if (device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS) {
- adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
- adapter->flags &= ~IXGBE_FLAG_FCOE_CAPABLE;
- e_info(probe, "FCoE offload feature is not available. "
- "Disabling FCoE offload feature\n");
- }
-#ifndef HAVE_NETDEV_OPS_FCOE_ENABLE
- else {
- adapter->flags |= IXGBE_FLAG_FCOE_ENABLED;
- adapter->ring_feature[RING_F_FCOE].indices =
- IXGBE_FCRETA_SIZE;
- netdev->features |= NETIF_F_FSO |
- NETIF_F_FCOE_CRC |
- NETIF_F_FCOE_MTU;
- netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
- }
-#endif /* HAVE_NETDEV_OPS_FCOE_ENABLE */
-#ifdef HAVE_NETDEV_VLAN_FEATURES
- netdev->vlan_features |= NETIF_F_FSO |
- NETIF_F_FCOE_CRC |
- NETIF_F_FCOE_MTU;
-#endif /* HAVE_NETDEV_VLAN_FEATURES */
- }
-#endif /* NETIF_F_FSO */
-#endif /* IXGBE_FCOE */
-
-#endif /* MAX_SKB_FRAGS */
- /* make sure the EEPROM is good */
- if (hw->eeprom.ops.validate_checksum &&
- (hw->eeprom.ops.validate_checksum(hw, NULL) < 0)) {
- e_dev_err("The EEPROM Checksum Is Not Valid\n");
- err = -EIO;
- goto err_sw_init;
- }
-
- memcpy(netdev->dev_addr, hw->mac.perm_addr, netdev->addr_len);
-#ifdef ETHTOOL_GPERMADDR
- memcpy(netdev->perm_addr, hw->mac.perm_addr, netdev->addr_len);
-
- if (ixgbe_validate_mac_addr(netdev->perm_addr)) {
- e_dev_err("invalid MAC address\n");
- err = -EIO;
- goto err_sw_init;
- }
-#else
- if (ixgbe_validate_mac_addr(netdev->dev_addr)) {
- e_dev_err("invalid MAC address\n");
- err = -EIO;
- goto err_sw_init;
- }
-#endif
- memcpy(&adapter->mac_table[0].addr, hw->mac.perm_addr,
- netdev->addr_len);
- adapter->mac_table[0].queue = adapter->num_vfs;
- adapter->mac_table[0].state = (IXGBE_MAC_STATE_DEFAULT |
- IXGBE_MAC_STATE_IN_USE);
- hw->mac.ops.set_rar(hw, 0, adapter->mac_table[0].addr,
- adapter->mac_table[0].queue,
- IXGBE_RAH_AV);
-
- //setup_timer(&adapter->service_timer, &ixgbe_service_timer,
- // (unsigned long) adapter);
-
- //INIT_WORK(&adapter->service_task, ixgbe_service_task);
- //clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
-
- //err = ixgbe_init_interrupt_scheme(adapter);
- //if (err)
- // goto err_sw_init;
-
- //adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- ixgbe_set_num_queues(adapter);
-
- adapter->wol = 0;
- /* WOL not supported for all but the following */
- switch (pdev->device) {
- case IXGBE_DEV_ID_82599_SFP:
- /* Only these subdevice supports WOL */
- switch (pdev->subsystem_device) {
- case IXGBE_SUBDEV_ID_82599_560FLR:
- /* only support first port */
- if (hw->bus.func != 0)
- break;
- case IXGBE_SUBDEV_ID_82599_SFP:
- adapter->wol = IXGBE_WUFC_MAG;
- break;
- }
- break;
- case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
- /* All except this subdevice support WOL */
- if (pdev->subsystem_device != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ)
- adapter->wol = IXGBE_WUFC_MAG;
- break;
- case IXGBE_DEV_ID_82599_KX4:
- adapter->wol = IXGBE_WUFC_MAG;
- break;
- case IXGBE_DEV_ID_X540T:
- /* Check eeprom to see if it is enabled */
- ixgbe_read_eeprom(hw, 0x2c, &adapter->eeprom_cap);
- wol_cap = adapter->eeprom_cap & IXGBE_DEVICE_CAPS_WOL_MASK;
-
- if ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0_1) ||
- ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0) &&
- (hw->bus.func == 0)))
- adapter->wol = IXGBE_WUFC_MAG;
- break;
- }
- //device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
-
-
- /*
- * Save off EEPROM version number and Option Rom version which
- * together make a unique identify for the eeprom
- */
- ixgbe_read_eeprom(hw, 0x2e, &eeprom_verh);
- ixgbe_read_eeprom(hw, 0x2d, &eeprom_verl);
-
- etrack_id = (eeprom_verh << 16) | eeprom_verl;
-
- ixgbe_read_eeprom(hw, 0x17, &offset);
-
- /* Make sure offset to SCSI block is valid */
- if (!(offset == 0x0) && !(offset == 0xffff)) {
- ixgbe_read_eeprom(hw, offset + 0x84, &eeprom_cfg_blkh);
- ixgbe_read_eeprom(hw, offset + 0x83, &eeprom_cfg_blkl);
-
- /* Only display Option Rom if exist */
- if (eeprom_cfg_blkl && eeprom_cfg_blkh) {
- major = eeprom_cfg_blkl >> 8;
- build = (eeprom_cfg_blkl << 8) | (eeprom_cfg_blkh >> 8);
- patch = eeprom_cfg_blkh & 0x00ff;
-
- snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id),
- "0x%08x, %d.%d.%d", etrack_id, major, build,
- patch);
- } else {
- snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id),
- "0x%08x", etrack_id);
- }
- } else {
- snprintf(adapter->eeprom_id, sizeof(adapter->eeprom_id),
- "0x%08x", etrack_id);
- }
-
- /* reset the hardware with the new settings */
- err = hw->mac.ops.start_hw(hw);
- if (err == IXGBE_ERR_EEPROM_VERSION) {
- /* We are running on a pre-production device, log a warning */
- e_dev_warn("This device is a pre-production adapter/LOM. "
- "Please be aware there may be issues associated "
- "with your hardware. If you are experiencing "
- "problems please contact your Intel or hardware "
- "representative who provided you with this "
- "hardware.\n");
- }
- /* pick up the PCI bus settings for reporting later */
- if (hw->mac.ops.get_bus_info)
- hw->mac.ops.get_bus_info(hw);
-
- strlcpy(netdev->name, "eth%d", sizeof(netdev->name));
- *lad_dev = netdev;
-
- adapter->netdev_registered = true;
-#ifdef NO_VNIC
- /* power down the optics */
- if ((hw->phy.multispeed_fiber) ||
- ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
- (hw->mac.type == ixgbe_mac_82599EB)))
- ixgbe_disable_tx_laser(hw);
-
- /* carrier off reporting is important to ethtool even BEFORE open */
- netif_carrier_off(netdev);
- /* keep stopping all the transmit queues for older kernels */
- netif_tx_stop_all_queues(netdev);
-#endif
-
- /* print all messages at the end so that we use our eth%d name */
- /* print bus type/speed/width info */
- e_dev_info("(PCI Express:%s:%s) ",
- (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" :
- hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5GT/s" :
- "Unknown"),
- (hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" :
- hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" :
- hw->bus.width == ixgbe_bus_width_pcie_x1 ? "Width x1" :
- "Unknown"));
-
- /* print the MAC address */
- for (i = 0; i < 6; i++)
- pr_cont("%2.2x%c", netdev->dev_addr[i], i == 5 ? '\n' : ':');
-
- /* First try to read PBA as a string */
- err = ixgbe_read_pba_string(hw, part_str, IXGBE_PBANUM_LENGTH);
- if (err)
- strlcpy(part_str, "Unknown", sizeof(part_str));
- if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present)
- e_info(probe, "MAC: %d, PHY: %d, SFP+: %d, PBA No: %s\n",
- hw->mac.type, hw->phy.type, hw->phy.sfp_type, part_str);
- else
- e_info(probe, "MAC: %d, PHY: %d, PBA No: %s\n",
- hw->mac.type, hw->phy.type, part_str);
-
- if (((hw->bus.speed == ixgbe_bus_speed_2500) &&
- (hw->bus.width <= ixgbe_bus_width_pcie_x4)) ||
- (hw->bus.width <= ixgbe_bus_width_pcie_x2)) {
- e_dev_warn("PCI-Express bandwidth available for this "
- "card is not sufficient for optimal "
- "performance.\n");
- e_dev_warn("For optimal performance a x8 PCI-Express "
- "slot is required.\n");
- }
-
-#define INFO_STRING_LEN 255
- info_string = kzalloc(INFO_STRING_LEN, GFP_KERNEL);
- if (!info_string) {
- e_err(probe, "allocation for info string failed\n");
- goto no_info_string;
- }
- count = 0;
- i_s_var = info_string;
- count += snprintf(i_s_var, INFO_STRING_LEN, "Enabled Features: ");
-
- i_s_var = info_string + count;
- count += snprintf(i_s_var, (INFO_STRING_LEN - count),
- "RxQ: %d TxQ: %d ", adapter->num_rx_queues,
- adapter->num_tx_queues);
- i_s_var = info_string + count;
-#ifdef IXGBE_FCOE
- if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
- count += snprintf(i_s_var, INFO_STRING_LEN - count, "FCoE ");
- i_s_var = info_string + count;
- }
-#endif
- if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
- count += snprintf(i_s_var, INFO_STRING_LEN - count,
- "FdirHash ");
- i_s_var = info_string + count;
- }
- if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) {
- count += snprintf(i_s_var, INFO_STRING_LEN - count,
- "FdirPerfect ");
- i_s_var = info_string + count;
- }
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- count += snprintf(i_s_var, INFO_STRING_LEN - count, "DCB ");
- i_s_var = info_string + count;
- }
- if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
- count += snprintf(i_s_var, INFO_STRING_LEN - count, "RSS ");
- i_s_var = info_string + count;
- }
- if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
- count += snprintf(i_s_var, INFO_STRING_LEN - count, "DCA ");
- i_s_var = info_string + count;
- }
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
- count += snprintf(i_s_var, INFO_STRING_LEN - count, "RSC ");
- i_s_var = info_string + count;
- }
-#ifndef IXGBE_NO_LRO
- else if (netdev->features & NETIF_F_LRO) {
- count += snprintf(i_s_var, INFO_STRING_LEN - count, "LRO ");
- i_s_var = info_string + count;
- }
-#endif
-
- BUG_ON(i_s_var > (info_string + INFO_STRING_LEN));
- /* end features printing */
- e_info(probe, "%s\n", info_string);
- kfree(info_string);
-no_info_string:
-
- /* firmware requires blank driver version */
- ixgbe_set_fw_drv_ver(hw, 0xFF, 0xFF, 0xFF, 0xFF);
-
-#if defined(HAVE_NETDEV_STORAGE_ADDRESS) && defined(NETDEV_HW_ADDR_T_SAN)
- /* add san mac addr to netdev */
- //ixgbe_add_sanmac_netdev(netdev);
-
-#endif /* (HAVE_NETDEV_STORAGE_ADDRESS) && (NETDEV_HW_ADDR_T_SAN) */
- e_info(probe, "Intel(R) 10 Gigabit Network Connection\n");
- cards_found++;
-
-#ifdef IXGBE_SYSFS
- //if (ixgbe_sysfs_init(adapter))
- // e_err(probe, "failed to allocate sysfs resources\n");
-#else
-#ifdef IXGBE_PROCFS
- //if (ixgbe_procfs_init(adapter))
- // e_err(probe, "failed to allocate procfs resources\n");
-#endif /* IXGBE_PROCFS */
-#endif /* IXGBE_SYSFS */
-
- return 0;
-
-//err_register:
- //ixgbe_clear_interrupt_scheme(adapter);
- //ixgbe_release_hw_control(adapter);
-err_sw_init:
- adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
- if (adapter->mac_table)
- kfree(adapter->mac_table);
- iounmap(hw->hw_addr);
-err_ioremap:
- free_netdev(netdev);
-err_alloc_etherdev:
- //pci_release_selected_regions(pdev,
- // pci_select_bars(pdev, IORESOURCE_MEM));
-//err_pci_reg:
-//err_dma:
- pci_disable_device(pdev);
- return err;
-}
-
-/**
- * ixgbe_remove - Device Removal Routine
- * @pdev: PCI device information struct
- *
- * ixgbe_remove is called by the PCI subsystem to alert the driver
- * that it should release a PCI device. The could be caused by a
- * Hot-Plug event, or because the driver is going to be removed from
- * memory.
- **/
-void ixgbe_kni_remove(struct pci_dev *pdev)
-{
- pci_disable_device(pdev);
-}
-
-
-u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg)
-{
- u16 value;
- struct ixgbe_adapter *adapter = hw->back;
-
- pci_read_config_word(adapter->pdev, reg, &value);
- return value;
-}
-
-void ixgbe_write_pci_cfg_word(struct ixgbe_hw *hw, u32 reg, u16 value)
-{
- struct ixgbe_adapter *adapter = hw->back;
-
- pci_write_config_word(adapter->pdev, reg, value);
-}
-
-void ewarn(struct ixgbe_hw *hw, const char *st, u32 status)
-{
- struct ixgbe_adapter *adapter = hw->back;
-
- netif_warn(adapter, drv, adapter->netdev, "%s", st);
-}
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_mbx.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_mbx.h
deleted file mode 100644
index 53ace941e..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_mbx.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_MBX_H_
-#define _IXGBE_MBX_H_
-
-#include "ixgbe_type.h"
-
-#define IXGBE_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
-#define IXGBE_ERR_MBX -100
-
-#define IXGBE_VFMAILBOX 0x002FC
-#define IXGBE_VFMBMEM 0x00200
-
-/* Define mailbox register bits */
-#define IXGBE_VFMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */
-#define IXGBE_VFMAILBOX_ACK 0x00000002 /* Ack PF message received */
-#define IXGBE_VFMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
-#define IXGBE_VFMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
-#define IXGBE_VFMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */
-#define IXGBE_VFMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */
-#define IXGBE_VFMAILBOX_RSTI 0x00000040 /* PF has reset indication */
-#define IXGBE_VFMAILBOX_RSTD 0x00000080 /* PF has indicated reset done */
-#define IXGBE_VFMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */
-
-#define IXGBE_PFMAILBOX_STS 0x00000001 /* Initiate message send to VF */
-#define IXGBE_PFMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
-#define IXGBE_PFMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
-#define IXGBE_PFMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
-#define IXGBE_PFMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */
-
-#define IXGBE_MBVFICR_VFREQ_MASK 0x0000FFFF /* bits for VF messages */
-#define IXGBE_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */
-#define IXGBE_MBVFICR_VFACK_MASK 0xFFFF0000 /* bits for VF acks */
-#define IXGBE_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */
-
-
-/* If it's a IXGBE_VF_* msg then it originates in the VF and is sent to the
- * PF. The reverse is true if it is IXGBE_PF_*.
- * Message ACK's are the value or'd with 0xF0000000
- */
-#define IXGBE_VT_MSGTYPE_ACK 0x80000000 /* Messages below or'd with
- * this are the ACK */
-#define IXGBE_VT_MSGTYPE_NACK 0x40000000 /* Messages below or'd with
- * this are the NACK */
-#define IXGBE_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still
- * clear to send requests */
-#define IXGBE_VT_MSGINFO_SHIFT 16
-/* bits 23:16 are used for extra info for certain messages */
-#define IXGBE_VT_MSGINFO_MASK (0xFF << IXGBE_VT_MSGINFO_SHIFT)
-
-#define IXGBE_VF_RESET 0x01 /* VF requests reset */
-#define IXGBE_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */
-#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
-#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
-#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
-#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
-
-/* length of permanent address message returned from PF */
-#define IXGBE_VF_PERMADDR_MSG_LEN 4
-/* word in permanent address message with the current multicast type */
-#define IXGBE_VF_MC_TYPE_WORD 3
-
-#define IXGBE_PF_CONTROL_MSG 0x0100 /* PF control message */
-
-
-#define IXGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
-#define IXGBE_VF_MBX_INIT_DELAY 500 /* microseconds between retries */
-
-s32 ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16);
-s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16);
-s32 ixgbe_read_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);
-s32 ixgbe_write_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);
-s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16);
-s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16);
-s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16);
-void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw);
-void ixgbe_init_mbx_params_vf(struct ixgbe_hw *);
-void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
-
-#endif /* _IXGBE_MBX_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_osdep.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_osdep.h
deleted file mode 100644
index 7b3f8c51d..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_osdep.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-
-/* glue for the OS independent part of ixgbe
- * includes register access macros
- */
-
-#ifndef _IXGBE_OSDEP_H_
-#define _IXGBE_OSDEP_H_
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/sched.h>
-#include "kcompat.h"
-
-
-#ifndef msleep
-#define msleep(x) do { if (in_interrupt()) { \
- /* Don't mdelay in interrupt context! */ \
- BUG(); \
- } else { \
- msleep(x); \
- } } while (0)
-
-#endif
-
-#undef ASSERT
-
-#ifdef DBG
-#define hw_dbg(hw, S, A...) printk(KERN_DEBUG S, ## A)
-#else
-#define hw_dbg(hw, S, A...) do {} while (0)
-#endif
-
-#define e_dev_info(format, arg...) \
- dev_info(pci_dev_to_dev(adapter->pdev), format, ## arg)
-#define e_dev_warn(format, arg...) \
- dev_warn(pci_dev_to_dev(adapter->pdev), format, ## arg)
-#define e_dev_err(format, arg...) \
- dev_err(pci_dev_to_dev(adapter->pdev), format, ## arg)
-#define e_dev_notice(format, arg...) \
- dev_notice(pci_dev_to_dev(adapter->pdev), format, ## arg)
-#define e_info(msglvl, format, arg...) \
- netif_info(adapter, msglvl, adapter->netdev, format, ## arg)
-#define e_err(msglvl, format, arg...) \
- netif_err(adapter, msglvl, adapter->netdev, format, ## arg)
-#define e_warn(msglvl, format, arg...) \
- netif_warn(adapter, msglvl, adapter->netdev, format, ## arg)
-#define e_crit(msglvl, format, arg...) \
- netif_crit(adapter, msglvl, adapter->netdev, format, ## arg)
-
-
-#ifdef DBG
-#define IXGBE_WRITE_REG(a, reg, value) do {\
- switch (reg) { \
- case IXGBE_EIMS: \
- case IXGBE_EIMC: \
- case IXGBE_EIAM: \
- case IXGBE_EIAC: \
- case IXGBE_EICR: \
- case IXGBE_EICS: \
- printk("%s: Reg - 0x%05X, value - 0x%08X\n", __func__, \
- reg, (u32)(value)); \
- default: \
- break; \
- } \
- writel((value), ((a)->hw_addr + (reg))); \
-} while (0)
-#else
-#define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
-#endif
-
-#define IXGBE_READ_REG(a, reg) readl((a)->hw_addr + (reg))
-
-#define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) ( \
- writel((value), ((a)->hw_addr + (reg) + ((offset) << 2))))
-
-#define IXGBE_READ_REG_ARRAY(a, reg, offset) ( \
- readl((a)->hw_addr + (reg) + ((offset) << 2)))
-
-#ifndef writeq
-#define writeq(val, addr) do { writel((u32) (val), addr); \
- writel((u32) (val >> 32), (addr + 4)); \
- } while (0);
-#endif
-
-#define IXGBE_WRITE_REG64(a, reg, value) writeq((value), ((a)->hw_addr + (reg)))
-
-#define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS)
-struct ixgbe_hw;
-extern u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg);
-extern void ixgbe_write_pci_cfg_word(struct ixgbe_hw *hw, u32 reg, u16 value);
-extern void ewarn(struct ixgbe_hw *hw, const char *str, u32 status);
-
-#define IXGBE_READ_PCIE_WORD ixgbe_read_pci_cfg_word
-#define IXGBE_WRITE_PCIE_WORD ixgbe_write_pci_cfg_word
-#define IXGBE_EEPROM_GRANT_ATTEMPS 100
-#define IXGBE_HTONL(_i) htonl(_i)
-#define IXGBE_NTOHL(_i) ntohl(_i)
-#define IXGBE_NTOHS(_i) ntohs(_i)
-#define IXGBE_CPU_TO_LE32(_i) cpu_to_le32(_i)
-#define IXGBE_LE32_TO_CPUS(_i) le32_to_cpus(_i)
-#define EWARN(H, W, S) ewarn(H, W, S)
-
-#endif /* _IXGBE_OSDEP_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.c b/kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.c
deleted file mode 100644
index a47a2ff8e..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.c
+++ /dev/null
@@ -1,1832 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "ixgbe_api.h"
-#include "ixgbe_common.h"
-#include "ixgbe_phy.h"
-
-static void ixgbe_i2c_start(struct ixgbe_hw *hw);
-static void ixgbe_i2c_stop(struct ixgbe_hw *hw);
-static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
-static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
-static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
-static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
-static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
-static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
-static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
-static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
-static bool ixgbe_get_i2c_data(u32 *i2cctl);
-
-/**
- * ixgbe_init_phy_ops_generic - Inits PHY function ptrs
- * @hw: pointer to the hardware structure
- *
- * Initialize the function pointers.
- **/
-s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
-{
- struct ixgbe_phy_info *phy = &hw->phy;
-
- /* PHY */
- phy->ops.identify = &ixgbe_identify_phy_generic;
- phy->ops.reset = &ixgbe_reset_phy_generic;
- phy->ops.read_reg = &ixgbe_read_phy_reg_generic;
- phy->ops.write_reg = &ixgbe_write_phy_reg_generic;
- phy->ops.setup_link = &ixgbe_setup_phy_link_generic;
- phy->ops.setup_link_speed = &ixgbe_setup_phy_link_speed_generic;
- phy->ops.check_link = NULL;
- phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_generic;
- phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_generic;
- phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_generic;
- phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic;
- phy->ops.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic;
- phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear;
- phy->ops.identify_sfp = &ixgbe_identify_module_generic;
- phy->sfp_type = ixgbe_sfp_type_unknown;
- phy->ops.check_overtemp = &ixgbe_tn_check_overtemp;
- return 0;
-}
-
-/**
- * ixgbe_identify_phy_generic - Get physical layer module
- * @hw: pointer to hardware structure
- *
- * Determines the physical layer module found on the current adapter.
- **/
-s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
-{
- s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
- u32 phy_addr;
- u16 ext_ability = 0;
-
- if (hw->phy.type == ixgbe_phy_unknown) {
- for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
- if (ixgbe_validate_phy_addr(hw, phy_addr)) {
- hw->phy.addr = phy_addr;
- ixgbe_get_phy_id(hw);
- hw->phy.type =
- ixgbe_get_phy_type_from_id(hw->phy.id);
-
- if (hw->phy.type == ixgbe_phy_unknown) {
- hw->phy.ops.read_reg(hw,
- IXGBE_MDIO_PHY_EXT_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &ext_ability);
- if (ext_ability &
- (IXGBE_MDIO_PHY_10GBASET_ABILITY |
- IXGBE_MDIO_PHY_1000BASET_ABILITY))
- hw->phy.type =
- ixgbe_phy_cu_unknown;
- else
- hw->phy.type =
- ixgbe_phy_generic;
- }
-
- status = 0;
- break;
- }
- }
- /* clear value if nothing found */
- if (status != 0)
- hw->phy.addr = 0;
- } else {
- status = 0;
- }
-
- return status;
-}
-
-/**
- * ixgbe_validate_phy_addr - Determines phy address is valid
- * @hw: pointer to hardware structure
- *
- **/
-bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
-{
- u16 phy_id = 0;
- bool valid = false;
-
- hw->phy.addr = phy_addr;
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
-
- if (phy_id != 0xFFFF && phy_id != 0x0)
- valid = true;
-
- return valid;
-}
-
-/**
- * ixgbe_get_phy_id - Get the phy type
- * @hw: pointer to hardware structure
- *
- **/
-s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
-{
- u32 status;
- u16 phy_id_high = 0;
- u16 phy_id_low = 0;
-
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &phy_id_high);
-
- if (status == 0) {
- hw->phy.id = (u32)(phy_id_high << 16);
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &phy_id_low);
- hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
- hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
- }
- return status;
-}
-
-/**
- * ixgbe_get_phy_type_from_id - Get the phy type
- * @hw: pointer to hardware structure
- *
- **/
-enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
-{
- enum ixgbe_phy_type phy_type;
-
- switch (phy_id) {
- case TN1010_PHY_ID:
- phy_type = ixgbe_phy_tn;
- break;
- case X540_PHY_ID:
- phy_type = ixgbe_phy_aq;
- break;
- case QT2022_PHY_ID:
- phy_type = ixgbe_phy_qt;
- break;
- case ATH_PHY_ID:
- phy_type = ixgbe_phy_nl;
- break;
- default:
- phy_type = ixgbe_phy_unknown;
- break;
- }
-
- hw_dbg(hw, "phy type found is %d\n", phy_type);
- return phy_type;
-}
-
-/**
- * ixgbe_reset_phy_generic - Performs a PHY reset
- * @hw: pointer to hardware structure
- **/
-s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
-{
- u32 i;
- u16 ctrl = 0;
- s32 status = 0;
-
- if (hw->phy.type == ixgbe_phy_unknown)
- status = ixgbe_identify_phy_generic(hw);
-
- if (status != 0 || hw->phy.type == ixgbe_phy_none)
- goto out;
-
- /* Don't reset PHY if it's shut down due to overtemp. */
- if (!hw->phy.reset_if_overtemp &&
- (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
- goto out;
-
- /*
- * Perform soft PHY reset to the PHY_XS.
- * This will cause a soft reset to the PHY
- */
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE,
- IXGBE_MDIO_PHY_XS_RESET);
-
- /*
- * Poll for reset bit to self-clear indicating reset is complete.
- * Some PHYs could take up to 3 seconds to complete and need about
- * 1.7 usec delay after the reset is complete.
- */
- for (i = 0; i < 30; i++) {
- msleep(100);
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl);
- if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) {
- udelay(2);
- break;
- }
- }
-
- if (ctrl & IXGBE_MDIO_PHY_XS_RESET) {
- status = IXGBE_ERR_RESET_FAILED;
- hw_dbg(hw, "PHY reset polling failed to complete.\n");
- }
-
-out:
- return status;
-}
-
-/**
- * ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
- * @hw: pointer to hardware structure
- * @reg_addr: 32 bit address of PHY register to read
- * @phy_data: Pointer to read data from PHY register
- **/
-s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 *phy_data)
-{
- u32 command;
- u32 i;
- u32 data;
- s32 status = 0;
- u16 gssr;
-
- if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
- gssr = IXGBE_GSSR_PHY1_SM;
- else
- gssr = IXGBE_GSSR_PHY0_SM;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0)
- status = IXGBE_ERR_SWFW_SYNC;
-
- if (status == 0) {
- /* Setup and write the address cycle command */
- command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
-
- IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
-
- /*
- * Check every 10 usec to see if the address cycle completed.
- * The MDI Command bit will clear when the operation is
- * complete
- */
- for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
- udelay(10);
-
- command = IXGBE_READ_REG(hw, IXGBE_MSCA);
-
- if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
- break;
- }
-
- if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
- hw_dbg(hw, "PHY address command did not complete.\n");
- status = IXGBE_ERR_PHY;
- }
-
- if (status == 0) {
- /*
- * Address cycle complete, setup and write the read
- * command
- */
- command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
-
- IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
-
- /*
- * Check every 10 usec to see if the address cycle
- * completed. The MDI Command bit will clear when the
- * operation is complete
- */
- for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
- udelay(10);
-
- command = IXGBE_READ_REG(hw, IXGBE_MSCA);
-
- if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
- break;
- }
-
- if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
- hw_dbg(hw, "PHY read command didn't complete\n");
- status = IXGBE_ERR_PHY;
- } else {
- /*
- * Read operation is complete. Get the data
- * from MSRWD
- */
- data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
- data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
- *phy_data = (u16)(data);
- }
- }
-
- hw->mac.ops.release_swfw_sync(hw, gssr);
- }
-
- return status;
-}
-
-/**
- * ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
- * @hw: pointer to hardware structure
- * @reg_addr: 32 bit PHY register to write
- * @device_type: 5 bit device type
- * @phy_data: Data to write to the PHY register
- **/
-s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 phy_data)
-{
- u32 command;
- u32 i;
- s32 status = 0;
- u16 gssr;
-
- if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
- gssr = IXGBE_GSSR_PHY1_SM;
- else
- gssr = IXGBE_GSSR_PHY0_SM;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0)
- status = IXGBE_ERR_SWFW_SYNC;
-
- if (status == 0) {
- /* Put the data in the MDI single read and write data register*/
- IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
-
- /* Setup and write the address cycle command */
- command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
-
- IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
-
- /*
- * Check every 10 usec to see if the address cycle completed.
- * The MDI Command bit will clear when the operation is
- * complete
- */
- for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
- udelay(10);
-
- command = IXGBE_READ_REG(hw, IXGBE_MSCA);
-
- if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
- break;
- }
-
- if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
- hw_dbg(hw, "PHY address cmd didn't complete\n");
- status = IXGBE_ERR_PHY;
- }
-
- if (status == 0) {
- /*
- * Address cycle complete, setup and write the write
- * command
- */
- command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
-
- IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
-
- /*
- * Check every 10 usec to see if the address cycle
- * completed. The MDI Command bit will clear when the
- * operation is complete
- */
- for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
- udelay(10);
-
- command = IXGBE_READ_REG(hw, IXGBE_MSCA);
-
- if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
- break;
- }
-
- if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
- hw_dbg(hw, "PHY address cmd didn't complete\n");
- status = IXGBE_ERR_PHY;
- }
- }
-
- hw->mac.ops.release_swfw_sync(hw, gssr);
- }
-
- return status;
-}
-
-/**
- * ixgbe_setup_phy_link_generic - Set and restart autoneg
- * @hw: pointer to hardware structure
- *
- * Restart autonegotiation and PHY and waits for completion.
- **/
-s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- u32 time_out;
- u32 max_time_out = 10;
- u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
- bool autoneg = false;
- ixgbe_link_speed speed;
-
- ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
-
- if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
- /* Set or unset auto-negotiation 10G advertisement */
- hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
-
- autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE;
- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
- autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE;
-
- hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
- }
-
- if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
- /* Set or unset auto-negotiation 1G advertisement */
- hw->phy.ops.read_reg(hw,
- IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
-
- autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE;
- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
- autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE;
-
- hw->phy.ops.write_reg(hw,
- IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
- }
-
- if (speed & IXGBE_LINK_SPEED_100_FULL) {
- /* Set or unset auto-negotiation 100M advertisement */
- hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
-
- autoneg_reg &= ~(IXGBE_MII_100BASE_T_ADVERTISE |
- IXGBE_MII_100BASE_T_ADVERTISE_HALF);
- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
- autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE;
-
- hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
- }
-
- /* Restart PHY autonegotiation and wait for completion */
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
-
- autoneg_reg |= IXGBE_MII_RESTART;
-
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
-
- /* Wait for autonegotiation to finish */
- for (time_out = 0; time_out < max_time_out; time_out++) {
- udelay(10);
- /* Restart PHY autonegotiation and wait for completion */
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
-
- autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
- if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE)
- break;
- }
-
- if (time_out == max_time_out) {
- status = IXGBE_ERR_LINK_SETUP;
- hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out");
- }
-
- return status;
-}
-
-/**
- * ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- **/
-s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete)
-{
-
- /*
- * Clear autoneg_advertised and set new values based on input link
- * speed.
- */
- hw->phy.autoneg_advertised = 0;
-
- if (speed & IXGBE_LINK_SPEED_10GB_FULL)
- hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
-
- if (speed & IXGBE_LINK_SPEED_1GB_FULL)
- hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
-
- if (speed & IXGBE_LINK_SPEED_100_FULL)
- hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
-
- /* Setup link based on the new speed settings */
- hw->phy.ops.setup_link(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @autoneg: boolean auto-negotiation value
- *
- * Determines the link capabilities by reading the AUTOC register.
- **/
-s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *autoneg)
-{
- s32 status = IXGBE_ERR_LINK_SETUP;
- u16 speed_ability;
-
- *speed = 0;
- *autoneg = true;
-
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &speed_ability);
-
- if (status == 0) {
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
- *speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
- *speed |= IXGBE_LINK_SPEED_1GB_FULL;
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M)
- *speed |= IXGBE_LINK_SPEED_100_FULL;
- }
-
- return status;
-}
-
-/**
- * ixgbe_check_phy_link_tnx - Determine link and speed status
- * @hw: pointer to hardware structure
- *
- * Reads the VS1 register to determine if link is up and the current speed for
- * the PHY.
- **/
-s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
- bool *link_up)
-{
- s32 status = 0;
- u32 time_out;
- u32 max_time_out = 10;
- u16 phy_link = 0;
- u16 phy_speed = 0;
- u16 phy_data = 0;
-
- /* Initialize speed and link to default case */
- *link_up = false;
- *speed = IXGBE_LINK_SPEED_10GB_FULL;
-
- /*
- * Check current speed and link status of the PHY register.
- * This is a vendor specific register and may have to
- * be changed for other copper PHYs.
- */
- for (time_out = 0; time_out < max_time_out; time_out++) {
- udelay(10);
- status = hw->phy.ops.read_reg(hw,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
- &phy_data);
- phy_link = phy_data & IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
- phy_speed = phy_data &
- IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
- if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
- *link_up = true;
- if (phy_speed ==
- IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- break;
- }
- }
-
- return status;
-}
-
-/**
- * ixgbe_setup_phy_link_tnx - Set and restart autoneg
- * @hw: pointer to hardware structure
- *
- * Restart autonegotiation and PHY and waits for completion.
- **/
-s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- u32 time_out;
- u32 max_time_out = 10;
- u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
- bool autoneg = false;
- ixgbe_link_speed speed;
-
- ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
-
- if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
- /* Set or unset auto-negotiation 10G advertisement */
- hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
-
- autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE;
- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
- autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE;
-
- hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
- }
-
- if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
- /* Set or unset auto-negotiation 1G advertisement */
- hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
-
- autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
- autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
-
- hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
- }
-
- if (speed & IXGBE_LINK_SPEED_100_FULL) {
- /* Set or unset auto-negotiation 100M advertisement */
- hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
-
- autoneg_reg &= ~IXGBE_MII_100BASE_T_ADVERTISE;
- if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
- autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE;
-
- hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
- }
-
- /* Restart PHY autonegotiation and wait for completion */
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
-
- autoneg_reg |= IXGBE_MII_RESTART;
-
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
-
- /* Wait for autonegotiation to finish */
- for (time_out = 0; time_out < max_time_out; time_out++) {
- udelay(10);
- /* Restart PHY autonegotiation and wait for completion */
- status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
-
- autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
- if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE)
- break;
- }
-
- if (time_out == max_time_out) {
- status = IXGBE_ERR_LINK_SETUP;
- hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out");
- }
-
- return status;
-}
-
-/**
- * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
- * @hw: pointer to hardware structure
- * @firmware_version: pointer to the PHY Firmware Version
- **/
-s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
- u16 *firmware_version)
-{
- s32 status = 0;
-
- status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
- firmware_version);
-
- return status;
-}
-
-/**
- * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version
- * @hw: pointer to hardware structure
- * @firmware_version: pointer to the PHY Firmware Version
- **/
-s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
- u16 *firmware_version)
-{
- s32 status = 0;
-
- status = hw->phy.ops.read_reg(hw, AQ_FW_REV,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
- firmware_version);
-
- return status;
-}
-
-/**
- * ixgbe_reset_phy_nl - Performs a PHY reset
- * @hw: pointer to hardware structure
- **/
-s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
-{
- u16 phy_offset, control, eword, edata, block_crc;
- bool end_data = false;
- u16 list_offset, data_offset;
- u16 phy_data = 0;
- s32 ret_val = 0;
- u32 i;
-
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
-
- /* reset the PHY and poll for completion */
- hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE,
- (phy_data | IXGBE_MDIO_PHY_XS_RESET));
-
- for (i = 0; i < 100; i++) {
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
- if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0)
- break;
- msleep(10);
- }
-
- if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) {
- hw_dbg(hw, "PHY reset did not complete.\n");
- ret_val = IXGBE_ERR_PHY;
- goto out;
- }
-
- /* Get init offsets */
- ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
- &data_offset);
- if (ret_val != 0)
- goto out;
-
- ret_val = hw->eeprom.ops.read(hw, data_offset, &block_crc);
- data_offset++;
- while (!end_data) {
- /*
- * Read control word from PHY init contents offset
- */
- ret_val = hw->eeprom.ops.read(hw, data_offset, &eword);
- control = (eword & IXGBE_CONTROL_MASK_NL) >>
- IXGBE_CONTROL_SHIFT_NL;
- edata = eword & IXGBE_DATA_MASK_NL;
- switch (control) {
- case IXGBE_DELAY_NL:
- data_offset++;
- hw_dbg(hw, "DELAY: %d MS\n", edata);
- msleep(edata);
- break;
- case IXGBE_DATA_NL:
- hw_dbg(hw, "DATA:\n");
- data_offset++;
- hw->eeprom.ops.read(hw, data_offset++,
- &phy_offset);
- for (i = 0; i < edata; i++) {
- hw->eeprom.ops.read(hw, data_offset, &eword);
- hw->phy.ops.write_reg(hw, phy_offset,
- IXGBE_TWINAX_DEV, eword);
- hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword,
- phy_offset);
- data_offset++;
- phy_offset++;
- }
- break;
- case IXGBE_CONTROL_NL:
- data_offset++;
- hw_dbg(hw, "CONTROL:\n");
- if (edata == IXGBE_CONTROL_EOL_NL) {
- hw_dbg(hw, "EOL\n");
- end_data = true;
- } else if (edata == IXGBE_CONTROL_SOL_NL) {
- hw_dbg(hw, "SOL\n");
- } else {
- hw_dbg(hw, "Bad control value\n");
- ret_val = IXGBE_ERR_PHY;
- goto out;
- }
- break;
- default:
- hw_dbg(hw, "Bad control type\n");
- ret_val = IXGBE_ERR_PHY;
- goto out;
- }
- }
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_identify_module_generic - Identifies module type
- * @hw: pointer to hardware structure
- *
- * Determines HW type and calls appropriate function.
- **/
-s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw)
-{
- s32 status = IXGBE_ERR_SFP_NOT_PRESENT;
-
- switch (hw->mac.ops.get_media_type(hw)) {
- case ixgbe_media_type_fiber:
- status = ixgbe_identify_sfp_module_generic(hw);
- break;
-
- case ixgbe_media_type_fiber_qsfp:
- status = ixgbe_identify_qsfp_module_generic(hw);
- break;
-
- default:
- hw->phy.sfp_type = ixgbe_sfp_type_not_present;
- status = IXGBE_ERR_SFP_NOT_PRESENT;
- break;
- }
-
- return status;
-}
-
-/**
- * ixgbe_identify_sfp_module_generic - Identifies SFP modules
- * @hw: pointer to hardware structure
- *
- * Searches for and identifies the SFP module and assigns appropriate PHY type.
- **/
-s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
-{
- s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
- u32 vendor_oui = 0;
- enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
- u8 identifier = 0;
- u8 comp_codes_1g = 0;
- u8 comp_codes_10g = 0;
- u8 oui_bytes[3] = {0, 0, 0};
- u8 cable_tech = 0;
- u8 cable_spec = 0;
- u16 enforce_sfp = 0;
-
- if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) {
- hw->phy.sfp_type = ixgbe_sfp_type_not_present;
- status = IXGBE_ERR_SFP_NOT_PRESENT;
- goto out;
- }
-
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_IDENTIFIER,
- &identifier);
-
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
- goto err_read_i2c_eeprom;
-
- /* LAN ID is needed for sfp_type determination */
- hw->mac.ops.set_lan_id(hw);
-
- if (identifier != IXGBE_SFF_IDENTIFIER_SFP) {
- hw->phy.type = ixgbe_phy_sfp_unsupported;
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
- } else {
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_1GBE_COMP_CODES,
- &comp_codes_1g);
-
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
- goto err_read_i2c_eeprom;
-
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_10GBE_COMP_CODES,
- &comp_codes_10g);
-
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
- goto err_read_i2c_eeprom;
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_CABLE_TECHNOLOGY,
- &cable_tech);
-
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
- goto err_read_i2c_eeprom;
-
- /* ID Module
- * =========
- * 0 SFP_DA_CU
- * 1 SFP_SR
- * 2 SFP_LR
- * 3 SFP_DA_CORE0 - 82599-specific
- * 4 SFP_DA_CORE1 - 82599-specific
- * 5 SFP_SR/LR_CORE0 - 82599-specific
- * 6 SFP_SR/LR_CORE1 - 82599-specific
- * 7 SFP_act_lmt_DA_CORE0 - 82599-specific
- * 8 SFP_act_lmt_DA_CORE1 - 82599-specific
- * 9 SFP_1g_cu_CORE0 - 82599-specific
- * 10 SFP_1g_cu_CORE1 - 82599-specific
- * 11 SFP_1g_sx_CORE0 - 82599-specific
- * 12 SFP_1g_sx_CORE1 - 82599-specific
- */
- if (hw->mac.type == ixgbe_mac_82598EB) {
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
- else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_sr;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_lr;
- else
- hw->phy.sfp_type = ixgbe_sfp_type_unknown;
- } else if (hw->mac.type == ixgbe_mac_82599EB) {
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_da_cu_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_da_cu_core1;
- } else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) {
- hw->phy.ops.read_i2c_eeprom(
- hw, IXGBE_SFF_CABLE_SPEC_COMP,
- &cable_spec);
- if (cable_spec &
- IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_da_act_lmt_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_da_act_lmt_core1;
- } else {
- hw->phy.sfp_type =
- ixgbe_sfp_type_unknown;
- }
- } else if (comp_codes_10g &
- (IXGBE_SFF_10GBASESR_CAPABLE |
- IXGBE_SFF_10GBASELR_CAPABLE)) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_srlr_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_srlr_core1;
- } else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_1g_cu_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_1g_cu_core1;
- } else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_1g_sx_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_1g_sx_core1;
- } else {
- hw->phy.sfp_type = ixgbe_sfp_type_unknown;
- }
- }
-
- if (hw->phy.sfp_type != stored_sfp_type)
- hw->phy.sfp_setup_needed = true;
-
- /* Determine if the SFP+ PHY is dual speed or not. */
- hw->phy.multispeed_fiber = false;
- if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
- (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
- ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
- (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
- hw->phy.multispeed_fiber = true;
-
- /* Determine PHY vendor */
- if (hw->phy.type != ixgbe_phy_nl) {
- hw->phy.id = identifier;
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_VENDOR_OUI_BYTE0,
- &oui_bytes[0]);
-
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
- goto err_read_i2c_eeprom;
-
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_VENDOR_OUI_BYTE1,
- &oui_bytes[1]);
-
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
- goto err_read_i2c_eeprom;
-
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_VENDOR_OUI_BYTE2,
- &oui_bytes[2]);
-
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
- goto err_read_i2c_eeprom;
-
- vendor_oui =
- ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
- (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
- (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
-
- switch (vendor_oui) {
- case IXGBE_SFF_VENDOR_OUI_TYCO:
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
- hw->phy.type =
- ixgbe_phy_sfp_passive_tyco;
- break;
- case IXGBE_SFF_VENDOR_OUI_FTL:
- if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
- hw->phy.type = ixgbe_phy_sfp_ftl_active;
- else
- hw->phy.type = ixgbe_phy_sfp_ftl;
- break;
- case IXGBE_SFF_VENDOR_OUI_AVAGO:
- hw->phy.type = ixgbe_phy_sfp_avago;
- break;
- case IXGBE_SFF_VENDOR_OUI_INTEL:
- hw->phy.type = ixgbe_phy_sfp_intel;
- break;
- default:
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
- hw->phy.type =
- ixgbe_phy_sfp_passive_unknown;
- else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
- hw->phy.type =
- ixgbe_phy_sfp_active_unknown;
- else
- hw->phy.type = ixgbe_phy_sfp_unknown;
- break;
- }
- }
-
- /* Allow any DA cable vendor */
- if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE |
- IXGBE_SFF_DA_ACTIVE_CABLE)) {
- status = 0;
- goto out;
- }
-
- /* Verify supported 1G SFP modules */
- if (comp_codes_10g == 0 &&
- !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
- hw->phy.type = ixgbe_phy_sfp_unsupported;
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
- }
-
- /* Anything else 82598-based is supported */
- if (hw->mac.type == ixgbe_mac_82598EB) {
- status = 0;
- goto out;
- }
-
- ixgbe_get_device_caps(hw, &enforce_sfp);
- if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
- !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) ||
- (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) ||
- (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0) ||
- (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1))) {
- /* Make sure we're a supported PHY type */
- if (hw->phy.type == ixgbe_phy_sfp_intel) {
- status = 0;
- } else {
- if (hw->allow_unsupported_sfp == true) {
- EWARN(hw, "WARNING: Intel (R) Network "
- "Connections are quality tested "
- "using Intel (R) Ethernet Optics."
- " Using untested modules is not "
- "supported and may cause unstable"
- " operation or damage to the "
- "module or the adapter. Intel "
- "Corporation is not responsible "
- "for any harm caused by using "
- "untested modules.\n", status);
- status = 0;
- } else {
- hw_dbg(hw, "SFP+ module not supported\n");
- hw->phy.type =
- ixgbe_phy_sfp_unsupported;
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
- }
- }
- } else {
- status = 0;
- }
- }
-
-out:
- return status;
-
-err_read_i2c_eeprom:
- hw->phy.sfp_type = ixgbe_sfp_type_not_present;
- if (hw->phy.type != ixgbe_phy_nl) {
- hw->phy.id = 0;
- hw->phy.type = ixgbe_phy_unknown;
- }
- return IXGBE_ERR_SFP_NOT_PRESENT;
-}
-
-/**
- * ixgbe_identify_qsfp_module_generic - Identifies QSFP modules
- * @hw: pointer to hardware structure
- *
- * Searches for and identifies the QSFP module and assigns appropriate PHY type
- **/
-s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
-{
- s32 status = 0;
-
- if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) {
- hw->phy.sfp_type = ixgbe_sfp_type_not_present;
- status = IXGBE_ERR_SFP_NOT_PRESENT;
- }
-
- return status;
-}
-
-
-/**
- * ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence
- * @hw: pointer to hardware structure
- * @list_offset: offset to the SFP ID list
- * @data_offset: offset to the SFP data block
- *
- * Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if
- * so it returns the offsets to the phy init sequence block.
- **/
-s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
- u16 *list_offset,
- u16 *data_offset)
-{
- u16 sfp_id;
- u16 sfp_type = hw->phy.sfp_type;
-
- if (hw->phy.sfp_type == ixgbe_sfp_type_unknown)
- return IXGBE_ERR_SFP_NOT_SUPPORTED;
-
- if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
- return IXGBE_ERR_SFP_NOT_PRESENT;
-
- if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) &&
- (hw->phy.sfp_type == ixgbe_sfp_type_da_cu))
- return IXGBE_ERR_SFP_NOT_SUPPORTED;
-
- /*
- * Limiting active cables and 1G Phys must be initialized as
- * SR modules
- */
- if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 ||
- sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
- sfp_type == ixgbe_sfp_type_1g_sx_core0)
- sfp_type = ixgbe_sfp_type_srlr_core0;
- else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 ||
- sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
- sfp_type == ixgbe_sfp_type_1g_sx_core1)
- sfp_type = ixgbe_sfp_type_srlr_core1;
-
- /* Read offset to PHY init contents */
- hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
-
- if ((!*list_offset) || (*list_offset == 0xFFFF))
- return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
-
- /* Shift offset to first ID word */
- (*list_offset)++;
-
- /*
- * Find the matching SFP ID in the EEPROM
- * and program the init sequence
- */
- hw->eeprom.ops.read(hw, *list_offset, &sfp_id);
-
- while (sfp_id != IXGBE_PHY_INIT_END_NL) {
- if (sfp_id == sfp_type) {
- (*list_offset)++;
- hw->eeprom.ops.read(hw, *list_offset, data_offset);
- if ((!*data_offset) || (*data_offset == 0xFFFF)) {
- hw_dbg(hw, "SFP+ module not supported\n");
- return IXGBE_ERR_SFP_NOT_SUPPORTED;
- } else {
- break;
- }
- } else {
- (*list_offset) += 2;
- if (hw->eeprom.ops.read(hw, *list_offset, &sfp_id))
- return IXGBE_ERR_PHY;
- }
- }
-
- if (sfp_id == IXGBE_PHY_INIT_END_NL) {
- hw_dbg(hw, "No matching SFP+ module found\n");
- return IXGBE_ERR_SFP_NOT_SUPPORTED;
- }
-
- return 0;
-}
-
-/**
- * ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
- * @hw: pointer to hardware structure
- * @byte_offset: EEPROM byte offset to read
- * @eeprom_data: value read
- *
- * Performs byte read operation to SFP module's EEPROM over I2C interface.
- **/
-s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 *eeprom_data)
-{
- return hw->phy.ops.read_i2c_byte(hw, byte_offset,
- IXGBE_I2C_EEPROM_DEV_ADDR,
- eeprom_data);
-}
-
-/**
- * ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
- * @hw: pointer to hardware structure
- * @byte_offset: EEPROM byte offset to write
- * @eeprom_data: value to write
- *
- * Performs byte write operation to SFP module's EEPROM over I2C interface.
- **/
-s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 eeprom_data)
-{
- return hw->phy.ops.write_i2c_byte(hw, byte_offset,
- IXGBE_I2C_EEPROM_DEV_ADDR,
- eeprom_data);
-}
-
-/**
- * ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to read
- * @data: value read
- *
- * Performs byte read operation to SFP module's EEPROM over I2C interface at
- * a specified device address.
- **/
-s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data)
-{
- s32 status = 0;
- u32 max_retry = 10;
- u32 retry = 0;
- u16 swfw_mask = 0;
- bool nack = 1;
- *data = 0;
-
- if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
- swfw_mask = IXGBE_GSSR_PHY1_SM;
- else
- swfw_mask = IXGBE_GSSR_PHY0_SM;
-
- do {
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)
- != 0) {
- status = IXGBE_ERR_SWFW_SYNC;
- goto read_byte_out;
- }
-
- ixgbe_i2c_start(hw);
-
- /* Device Address and write indication */
- status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
- if (status != 0)
- goto fail;
-
- status = ixgbe_get_i2c_ack(hw);
- if (status != 0)
- goto fail;
-
- status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
- if (status != 0)
- goto fail;
-
- status = ixgbe_get_i2c_ack(hw);
- if (status != 0)
- goto fail;
-
- ixgbe_i2c_start(hw);
-
- /* Device Address and read indication */
- status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
- if (status != 0)
- goto fail;
-
- status = ixgbe_get_i2c_ack(hw);
- if (status != 0)
- goto fail;
-
- status = ixgbe_clock_in_i2c_byte(hw, data);
- if (status != 0)
- goto fail;
-
- status = ixgbe_clock_out_i2c_bit(hw, nack);
- if (status != 0)
- goto fail;
-
- ixgbe_i2c_stop(hw);
- break;
-
-fail:
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
- msleep(100);
- ixgbe_i2c_bus_clear(hw);
- retry++;
- if (retry < max_retry)
- hw_dbg(hw, "I2C byte read error - Retrying.\n");
- else
- hw_dbg(hw, "I2C byte read error.\n");
-
- } while (retry < max_retry);
-
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-
-read_byte_out:
- return status;
-}
-
-/**
- * ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
- * @hw: pointer to hardware structure
- * @byte_offset: byte offset to write
- * @data: value to write
- *
- * Performs byte write operation to SFP module's EEPROM over I2C interface at
- * a specified device address.
- **/
-s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data)
-{
- s32 status = 0;
- u32 max_retry = 1;
- u32 retry = 0;
- u16 swfw_mask = 0;
-
- if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
- swfw_mask = IXGBE_GSSR_PHY1_SM;
- else
- swfw_mask = IXGBE_GSSR_PHY0_SM;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
- status = IXGBE_ERR_SWFW_SYNC;
- goto write_byte_out;
- }
-
- do {
- ixgbe_i2c_start(hw);
-
- status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
- if (status != 0)
- goto fail;
-
- status = ixgbe_get_i2c_ack(hw);
- if (status != 0)
- goto fail;
-
- status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
- if (status != 0)
- goto fail;
-
- status = ixgbe_get_i2c_ack(hw);
- if (status != 0)
- goto fail;
-
- status = ixgbe_clock_out_i2c_byte(hw, data);
- if (status != 0)
- goto fail;
-
- status = ixgbe_get_i2c_ack(hw);
- if (status != 0)
- goto fail;
-
- ixgbe_i2c_stop(hw);
- break;
-
-fail:
- ixgbe_i2c_bus_clear(hw);
- retry++;
- if (retry < max_retry)
- hw_dbg(hw, "I2C byte write error - Retrying.\n");
- else
- hw_dbg(hw, "I2C byte write error.\n");
- } while (retry < max_retry);
-
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-
-write_byte_out:
- return status;
-}
-
-/**
- * ixgbe_i2c_start - Sets I2C start condition
- * @hw: pointer to hardware structure
- *
- * Sets I2C start condition (High -> Low on SDA while SCL is High)
- **/
-static void ixgbe_i2c_start(struct ixgbe_hw *hw)
-{
- u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
-
- /* Start condition must begin with data and clock high */
- ixgbe_set_i2c_data(hw, &i2cctl, 1);
- ixgbe_raise_i2c_clk(hw, &i2cctl);
-
- /* Setup time for start condition (4.7us) */
- udelay(IXGBE_I2C_T_SU_STA);
-
- ixgbe_set_i2c_data(hw, &i2cctl, 0);
-
- /* Hold time for start condition (4us) */
- udelay(IXGBE_I2C_T_HD_STA);
-
- ixgbe_lower_i2c_clk(hw, &i2cctl);
-
- /* Minimum low period of clock is 4.7 us */
- udelay(IXGBE_I2C_T_LOW);
-
-}
-
-/**
- * ixgbe_i2c_stop - Sets I2C stop condition
- * @hw: pointer to hardware structure
- *
- * Sets I2C stop condition (Low -> High on SDA while SCL is High)
- **/
-static void ixgbe_i2c_stop(struct ixgbe_hw *hw)
-{
- u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
-
- /* Stop condition must begin with data low and clock high */
- ixgbe_set_i2c_data(hw, &i2cctl, 0);
- ixgbe_raise_i2c_clk(hw, &i2cctl);
-
- /* Setup time for stop condition (4us) */
- udelay(IXGBE_I2C_T_SU_STO);
-
- ixgbe_set_i2c_data(hw, &i2cctl, 1);
-
- /* bus free time between stop and start (4.7us)*/
- udelay(IXGBE_I2C_T_BUF);
-}
-
-/**
- * ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
- * @hw: pointer to hardware structure
- * @data: data byte to clock in
- *
- * Clocks in one byte data via I2C data/clock
- **/
-static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
-{
- s32 i;
- bool bit = 0;
-
- for (i = 7; i >= 0; i--) {
- ixgbe_clock_in_i2c_bit(hw, &bit);
- *data |= bit << i;
- }
-
- return 0;
-}
-
-/**
- * ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
- * @hw: pointer to hardware structure
- * @data: data byte clocked out
- *
- * Clocks out one byte data via I2C data/clock
- **/
-static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
-{
- s32 status = 0;
- s32 i;
- u32 i2cctl;
- bool bit = 0;
-
- for (i = 7; i >= 0; i--) {
- bit = (data >> i) & 0x1;
- status = ixgbe_clock_out_i2c_bit(hw, bit);
-
- if (status != 0)
- break;
- }
-
- /* Release SDA line (set high) */
- i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
- i2cctl |= IXGBE_I2C_DATA_OUT;
- IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl);
- IXGBE_WRITE_FLUSH(hw);
-
- return status;
-}
-
-/**
- * ixgbe_get_i2c_ack - Polls for I2C ACK
- * @hw: pointer to hardware structure
- *
- * Clocks in/out one bit via I2C data/clock
- **/
-static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- u32 i = 0;
- u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
- u32 timeout = 10;
- bool ack = 1;
-
- ixgbe_raise_i2c_clk(hw, &i2cctl);
-
-
- /* Minimum high period of clock is 4us */
- udelay(IXGBE_I2C_T_HIGH);
-
- /* Poll for ACK. Note that ACK in I2C spec is
- * transition from 1 to 0 */
- for (i = 0; i < timeout; i++) {
- i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
- ack = ixgbe_get_i2c_data(&i2cctl);
-
- udelay(1);
- if (ack == 0)
- break;
- }
-
- if (ack == 1) {
- hw_dbg(hw, "I2C ack was not received.\n");
- status = IXGBE_ERR_I2C;
- }
-
- ixgbe_lower_i2c_clk(hw, &i2cctl);
-
- /* Minimum low period of clock is 4.7 us */
- udelay(IXGBE_I2C_T_LOW);
-
- return status;
-}
-
-/**
- * ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
- * @hw: pointer to hardware structure
- * @data: read data value
- *
- * Clocks in one bit via I2C data/clock
- **/
-static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
-{
- u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
-
- ixgbe_raise_i2c_clk(hw, &i2cctl);
-
- /* Minimum high period of clock is 4us */
- udelay(IXGBE_I2C_T_HIGH);
-
- i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
- *data = ixgbe_get_i2c_data(&i2cctl);
-
- ixgbe_lower_i2c_clk(hw, &i2cctl);
-
- /* Minimum low period of clock is 4.7 us */
- udelay(IXGBE_I2C_T_LOW);
-
- return 0;
-}
-
-/**
- * ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
- * @hw: pointer to hardware structure
- * @data: data value to write
- *
- * Clocks out one bit via I2C data/clock
- **/
-static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
-{
- s32 status;
- u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
-
- status = ixgbe_set_i2c_data(hw, &i2cctl, data);
- if (status == 0) {
- ixgbe_raise_i2c_clk(hw, &i2cctl);
-
- /* Minimum high period of clock is 4us */
- udelay(IXGBE_I2C_T_HIGH);
-
- ixgbe_lower_i2c_clk(hw, &i2cctl);
-
- /* Minimum low period of clock is 4.7 us.
- * This also takes care of the data hold time.
- */
- udelay(IXGBE_I2C_T_LOW);
- } else {
- status = IXGBE_ERR_I2C;
- hw_dbg(hw, "I2C data was not set to %X\n", data);
- }
-
- return status;
-}
-/**
- * ixgbe_raise_i2c_clk - Raises the I2C SCL clock
- * @hw: pointer to hardware structure
- * @i2cctl: Current value of I2CCTL register
- *
- * Raises the I2C clock line '0'->'1'
- **/
-static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
-{
- u32 i = 0;
- u32 timeout = IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT;
- u32 i2cctl_r = 0;
-
- for (i = 0; i < timeout; i++) {
- *i2cctl |= IXGBE_I2C_CLK_OUT;
-
- IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
- IXGBE_WRITE_FLUSH(hw);
- /* SCL rise time (1000ns) */
- udelay(IXGBE_I2C_T_RISE);
-
- i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
- if (i2cctl_r & IXGBE_I2C_CLK_IN)
- break;
- }
-}
-
-/**
- * ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
- * @hw: pointer to hardware structure
- * @i2cctl: Current value of I2CCTL register
- *
- * Lowers the I2C clock line '1'->'0'
- **/
-static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
-{
-
- *i2cctl &= ~IXGBE_I2C_CLK_OUT;
-
- IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
- IXGBE_WRITE_FLUSH(hw);
-
- /* SCL fall time (300ns) */
- udelay(IXGBE_I2C_T_FALL);
-}
-
-/**
- * ixgbe_set_i2c_data - Sets the I2C data bit
- * @hw: pointer to hardware structure
- * @i2cctl: Current value of I2CCTL register
- * @data: I2C data value (0 or 1) to set
- *
- * Sets the I2C data bit
- **/
-static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
-{
- s32 status = 0;
-
- if (data)
- *i2cctl |= IXGBE_I2C_DATA_OUT;
- else
- *i2cctl &= ~IXGBE_I2C_DATA_OUT;
-
- IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
- IXGBE_WRITE_FLUSH(hw);
-
- /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
- udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
-
- /* Verify data was set correctly */
- *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
- if (data != ixgbe_get_i2c_data(i2cctl)) {
- status = IXGBE_ERR_I2C;
- hw_dbg(hw, "Error - I2C data was not set to %X.\n", data);
- }
-
- return status;
-}
-
-/**
- * ixgbe_get_i2c_data - Reads the I2C SDA data bit
- * @hw: pointer to hardware structure
- * @i2cctl: Current value of I2CCTL register
- *
- * Returns the I2C data bit value
- **/
-static bool ixgbe_get_i2c_data(u32 *i2cctl)
-{
- bool data;
-
- if (*i2cctl & IXGBE_I2C_DATA_IN)
- data = 1;
- else
- data = 0;
-
- return data;
-}
-
-/**
- * ixgbe_i2c_bus_clear - Clears the I2C bus
- * @hw: pointer to hardware structure
- *
- * Clears the I2C bus by sending nine clock pulses.
- * Used when data line is stuck low.
- **/
-void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
-{
- u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
- u32 i;
-
- ixgbe_i2c_start(hw);
-
- ixgbe_set_i2c_data(hw, &i2cctl, 1);
-
- for (i = 0; i < 9; i++) {
- ixgbe_raise_i2c_clk(hw, &i2cctl);
-
- /* Min high period of clock is 4us */
- udelay(IXGBE_I2C_T_HIGH);
-
- ixgbe_lower_i2c_clk(hw, &i2cctl);
-
- /* Min low period of clock is 4.7us*/
- udelay(IXGBE_I2C_T_LOW);
- }
-
- ixgbe_i2c_start(hw);
-
- /* Put the i2c bus back to default state */
- ixgbe_i2c_stop(hw);
-}
-
-/**
- * ixgbe_tn_check_overtemp - Checks if an overtemp occurred.
- * @hw: pointer to hardware structure
- *
- * Checks if the LASI temp alarm status was triggered due to overtemp
- **/
-s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
-{
- s32 status = 0;
- u16 phy_data = 0;
-
- if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
- goto out;
-
- /* Check that the LASI temp alarm status was triggered */
- hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_data);
-
- if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
- goto out;
-
- status = IXGBE_ERR_OVERTEMP;
-out:
- return status;
-}
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.h
deleted file mode 100644
index 6baa9acbf..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_PHY_H_
-#define _IXGBE_PHY_H_
-
-#include "ixgbe_type.h"
-#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0
-
-/* EEPROM byte offsets */
-#define IXGBE_SFF_IDENTIFIER 0x0
-#define IXGBE_SFF_IDENTIFIER_SFP 0x3
-#define IXGBE_SFF_VENDOR_OUI_BYTE0 0x25
-#define IXGBE_SFF_VENDOR_OUI_BYTE1 0x26
-#define IXGBE_SFF_VENDOR_OUI_BYTE2 0x27
-#define IXGBE_SFF_1GBE_COMP_CODES 0x6
-#define IXGBE_SFF_10GBE_COMP_CODES 0x3
-#define IXGBE_SFF_CABLE_TECHNOLOGY 0x8
-#define IXGBE_SFF_CABLE_SPEC_COMP 0x3C
-
-/* Bitmasks */
-#define IXGBE_SFF_DA_PASSIVE_CABLE 0x4
-#define IXGBE_SFF_DA_ACTIVE_CABLE 0x8
-#define IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING 0x4
-#define IXGBE_SFF_1GBASESX_CAPABLE 0x1
-#define IXGBE_SFF_1GBASELX_CAPABLE 0x2
-#define IXGBE_SFF_1GBASET_CAPABLE 0x8
-#define IXGBE_SFF_10GBASESR_CAPABLE 0x10
-#define IXGBE_SFF_10GBASELR_CAPABLE 0x20
-#define IXGBE_I2C_EEPROM_READ_MASK 0x100
-#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3
-#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0
-#define IXGBE_I2C_EEPROM_STATUS_PASS 0x1
-#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2
-#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
-
-/* Flow control defines */
-#define IXGBE_TAF_SYM_PAUSE 0x400
-#define IXGBE_TAF_ASM_PAUSE 0x800
-
-/* Bit-shift macros */
-#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24
-#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16
-#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 8
-
-/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
-#define IXGBE_SFF_VENDOR_OUI_TYCO 0x00407600
-#define IXGBE_SFF_VENDOR_OUI_FTL 0x00906500
-#define IXGBE_SFF_VENDOR_OUI_AVAGO 0x00176A00
-#define IXGBE_SFF_VENDOR_OUI_INTEL 0x001B2100
-
-/* I2C SDA and SCL timing parameters for standard mode */
-#define IXGBE_I2C_T_HD_STA 4
-#define IXGBE_I2C_T_LOW 5
-#define IXGBE_I2C_T_HIGH 4
-#define IXGBE_I2C_T_SU_STA 5
-#define IXGBE_I2C_T_HD_DATA 5
-#define IXGBE_I2C_T_SU_DATA 1
-#define IXGBE_I2C_T_RISE 1
-#define IXGBE_I2C_T_FALL 1
-#define IXGBE_I2C_T_SU_STO 4
-#define IXGBE_I2C_T_BUF 5
-
-#define IXGBE_TN_LASI_STATUS_REG 0x9005
-#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008
-
-s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
-bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
-enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
-s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
-s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw);
-s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw);
-s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 *phy_data);
-s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 phy_data);
-s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw);
-s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
-s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *autoneg);
-
-/* PHY specific */
-s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *link_up);
-s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw);
-s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
- u16 *firmware_version);
-s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
- u16 *firmware_version);
-
-s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw);
-s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw);
-s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
-s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw);
-s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
- u16 *list_offset,
- u16 *data_offset);
-s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw);
-s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data);
-s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data);
-s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 *eeprom_data);
-s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 eeprom_data);
-void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
-#endif /* _IXGBE_PHY_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_type.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_type.h
deleted file mode 100644
index 0689590e2..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_type.h
+++ /dev/null
@@ -1,3239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_TYPE_H_
-#define _IXGBE_TYPE_H_
-
-#include "ixgbe_osdep.h"
-
-
-/* Vendor ID */
-#define IXGBE_INTEL_VENDOR_ID 0x8086
-
-/* Device IDs */
-#define IXGBE_DEV_ID_82598 0x10B6
-#define IXGBE_DEV_ID_82598_BX 0x1508
-#define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6
-#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
-#define IXGBE_DEV_ID_82598AT 0x10C8
-#define IXGBE_DEV_ID_82598AT2 0x150B
-#define IXGBE_DEV_ID_82598EB_SFP_LOM 0x10DB
-#define IXGBE_DEV_ID_82598EB_CX4 0x10DD
-#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
-#define IXGBE_DEV_ID_82598_DA_DUAL_PORT 0x10F1
-#define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1
-#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4
-#define IXGBE_DEV_ID_82599_KX4 0x10F7
-#define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514
-#define IXGBE_DEV_ID_82599_KR 0x1517
-#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
-#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C
-#define IXGBE_DEV_ID_82599_CX4 0x10F9
-#define IXGBE_DEV_ID_82599_SFP 0x10FB
-#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9
-#define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0
-#define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152A
-#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529
-#define IXGBE_DEV_ID_82599_SFP_EM 0x1507
-#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D
-#define IXGBE_DEV_ID_82599_QSFP_SF_QP 0x1558
-#define IXGBE_DEV_ID_82599EN_SFP 0x1557
-#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
-#define IXGBE_DEV_ID_82599_T3_LOM 0x151C
-#define IXGBE_DEV_ID_82599_LS 0x154F
-#define IXGBE_DEV_ID_X540T 0x1528
-
-/* General Registers */
-#define IXGBE_CTRL 0x00000
-#define IXGBE_STATUS 0x00008
-#define IXGBE_CTRL_EXT 0x00018
-#define IXGBE_ESDP 0x00020
-#define IXGBE_EODSDP 0x00028
-#define IXGBE_I2CCTL 0x00028
-#define IXGBE_PHY_GPIO 0x00028
-#define IXGBE_MAC_GPIO 0x00030
-#define IXGBE_PHYINT_STATUS0 0x00100
-#define IXGBE_PHYINT_STATUS1 0x00104
-#define IXGBE_PHYINT_STATUS2 0x00108
-#define IXGBE_LEDCTL 0x00200
-#define IXGBE_FRTIMER 0x00048
-#define IXGBE_TCPTIMER 0x0004C
-#define IXGBE_CORESPARE 0x00600
-#define IXGBE_EXVET 0x05078
-
-/* NVM Registers */
-#define IXGBE_EEC 0x10010
-#define IXGBE_EERD 0x10014
-#define IXGBE_EEWR 0x10018
-#define IXGBE_FLA 0x1001C
-#define IXGBE_EEMNGCTL 0x10110
-#define IXGBE_EEMNGDATA 0x10114
-#define IXGBE_FLMNGCTL 0x10118
-#define IXGBE_FLMNGDATA 0x1011C
-#define IXGBE_FLMNGCNT 0x10120
-#define IXGBE_FLOP 0x1013C
-#define IXGBE_GRC 0x10200
-#define IXGBE_SRAMREL 0x10210
-#define IXGBE_PHYDBG 0x10218
-
-/* General Receive Control */
-#define IXGBE_GRC_MNG 0x00000001 /* Manageability Enable */
-#define IXGBE_GRC_APME 0x00000002 /* APM enabled in EEPROM */
-
-#define IXGBE_VPDDIAG0 0x10204
-#define IXGBE_VPDDIAG1 0x10208
-
-/* I2CCTL Bit Masks */
-#define IXGBE_I2C_CLK_IN 0x00000001
-#define IXGBE_I2C_CLK_OUT 0x00000002
-#define IXGBE_I2C_DATA_IN 0x00000004
-#define IXGBE_I2C_DATA_OUT 0x00000008
-#define IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT 500
-
-#define IXGBE_I2C_THERMAL_SENSOR_ADDR 0xF8
-#define IXGBE_EMC_INTERNAL_DATA 0x00
-#define IXGBE_EMC_INTERNAL_THERM_LIMIT 0x20
-#define IXGBE_EMC_DIODE1_DATA 0x01
-#define IXGBE_EMC_DIODE1_THERM_LIMIT 0x19
-#define IXGBE_EMC_DIODE2_DATA 0x23
-#define IXGBE_EMC_DIODE2_THERM_LIMIT 0x1A
-
-#define IXGBE_MAX_SENSORS 3
-
-struct ixgbe_thermal_diode_data {
- u8 location;
- u8 temp;
- u8 caution_thresh;
- u8 max_op_thresh;
-};
-
-struct ixgbe_thermal_sensor_data {
- struct ixgbe_thermal_diode_data sensor[IXGBE_MAX_SENSORS];
-};
-
-/* Interrupt Registers */
-#define IXGBE_EICR 0x00800
-#define IXGBE_EICS 0x00808
-#define IXGBE_EIMS 0x00880
-#define IXGBE_EIMC 0x00888
-#define IXGBE_EIAC 0x00810
-#define IXGBE_EIAM 0x00890
-#define IXGBE_EICS_EX(_i) (0x00A90 + (_i) * 4)
-#define IXGBE_EIMS_EX(_i) (0x00AA0 + (_i) * 4)
-#define IXGBE_EIMC_EX(_i) (0x00AB0 + (_i) * 4)
-#define IXGBE_EIAM_EX(_i) (0x00AD0 + (_i) * 4)
-/* 82599 EITR is only 12 bits, with the lower 3 always zero */
-/*
- * 82598 EITR is 16 bits but set the limits based on the max
- * supported by all ixgbe hardware
- */
-#define IXGBE_MAX_INT_RATE 488281
-#define IXGBE_MIN_INT_RATE 956
-#define IXGBE_MAX_EITR 0x00000FF8
-#define IXGBE_MIN_EITR 8
-#define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : \
- (0x012300 + (((_i) - 24) * 4)))
-#define IXGBE_EITR_ITR_INT_MASK 0x00000FF8
-#define IXGBE_EITR_LLI_MOD 0x00008000
-#define IXGBE_EITR_CNT_WDIS 0x80000000
-#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
-#define IXGBE_IVAR_MISC 0x00A00 /* misc MSI-X interrupt causes */
-#define IXGBE_EITRSEL 0x00894
-#define IXGBE_MSIXT 0x00000 /* MSI-X Table. 0x0000 - 0x01C */
-#define IXGBE_MSIXPBA 0x02000 /* MSI-X Pending bit array */
-#define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4)))
-#define IXGBE_GPIE 0x00898
-
-/* Flow Control Registers */
-#define IXGBE_FCADBUL 0x03210
-#define IXGBE_FCADBUH 0x03214
-#define IXGBE_FCAMACL 0x04328
-#define IXGBE_FCAMACH 0x0432C
-#define IXGBE_FCRTH_82599(_i) (0x03260 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_FCRTL_82599(_i) (0x03220 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_PFCTOP 0x03008
-#define IXGBE_FCTTV(_i) (0x03200 + ((_i) * 4)) /* 4 of these (0-3) */
-#define IXGBE_FCRTL(_i) (0x03220 + ((_i) * 8)) /* 8 of these (0-7) */
-#define IXGBE_FCRTH(_i) (0x03260 + ((_i) * 8)) /* 8 of these (0-7) */
-#define IXGBE_FCRTV 0x032A0
-#define IXGBE_FCCFG 0x03D00
-#define IXGBE_TFCS 0x0CE00
-
-/* Receive DMA Registers */
-#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : \
- (0x0D000 + (((_i) - 64) * 0x40)))
-#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : \
- (0x0D004 + (((_i) - 64) * 0x40)))
-#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : \
- (0x0D008 + (((_i) - 64) * 0x40)))
-#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : \
- (0x0D010 + (((_i) - 64) * 0x40)))
-#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : \
- (0x0D018 + (((_i) - 64) * 0x40)))
-#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \
- (0x0D028 + (((_i) - 64) * 0x40)))
-#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \
- (0x0D02C + (((_i) - 64) * 0x40)))
-#define IXGBE_RSCDBU 0x03028
-#define IXGBE_RDDCC 0x02F20
-#define IXGBE_RXMEMWRAP 0x03190
-#define IXGBE_STARCTRL 0x03024
-/*
- * Split and Replication Receive Control Registers
- * 00-15 : 0x02100 + n*4
- * 16-64 : 0x01014 + n*0x40
- * 64-127: 0x0D014 + (n-64)*0x40
- */
-#define IXGBE_SRRCTL(_i) (((_i) <= 15) ? (0x02100 + ((_i) * 4)) : \
- (((_i) < 64) ? (0x01014 + ((_i) * 0x40)) : \
- (0x0D014 + (((_i) - 64) * 0x40))))
-/*
- * Rx DCA Control Register:
- * 00-15 : 0x02200 + n*4
- * 16-64 : 0x0100C + n*0x40
- * 64-127: 0x0D00C + (n-64)*0x40
- */
-#define IXGBE_DCA_RXCTRL(_i) (((_i) <= 15) ? (0x02200 + ((_i) * 4)) : \
- (((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \
- (0x0D00C + (((_i) - 64) * 0x40))))
-#define IXGBE_RDRXCTL 0x02F00
-#define IXGBE_RDRXCTL_RSC_PUSH 0x80
-/* 8 of these 0x03C00 - 0x03C1C */
-#define IXGBE_RXPBSIZE(_i) (0x03C00 + ((_i) * 4))
-#define IXGBE_RXCTRL 0x03000
-#define IXGBE_DROPEN 0x03D04
-#define IXGBE_RXPBSIZE_SHIFT 10
-
-/* Receive Registers */
-#define IXGBE_RXCSUM 0x05000
-#define IXGBE_RFCTL 0x05008
-#define IXGBE_DRECCCTL 0x02F08
-#define IXGBE_DRECCCTL_DISABLE 0
-#define IXGBE_DRECCCTL2 0x02F8C
-
-/* Multicast Table Array - 128 entries */
-#define IXGBE_MTA(_i) (0x05200 + ((_i) * 4))
-#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
- (0x0A200 + ((_i) * 8)))
-#define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
- (0x0A204 + ((_i) * 8)))
-#define IXGBE_MPSAR_LO(_i) (0x0A600 + ((_i) * 8))
-#define IXGBE_MPSAR_HI(_i) (0x0A604 + ((_i) * 8))
-/* Packet split receive type */
-#define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : \
- (0x0EA00 + ((_i) * 4)))
-/* array of 4096 1-bit vlan filters */
-#define IXGBE_VFTA(_i) (0x0A000 + ((_i) * 4))
-/*array of 4096 4-bit vlan vmdq indices */
-#define IXGBE_VFTAVIND(_j, _i) (0x0A200 + ((_j) * 0x200) + ((_i) * 4))
-#define IXGBE_FCTRL 0x05080
-#define IXGBE_VLNCTRL 0x05088
-#define IXGBE_MCSTCTRL 0x05090
-#define IXGBE_MRQC 0x05818
-#define IXGBE_SAQF(_i) (0x0E000 + ((_i) * 4)) /* Source Address Queue Filter */
-#define IXGBE_DAQF(_i) (0x0E200 + ((_i) * 4)) /* Dest. Address Queue Filter */
-#define IXGBE_SDPQF(_i) (0x0E400 + ((_i) * 4)) /* Src Dest. Addr Queue Filter */
-#define IXGBE_FTQF(_i) (0x0E600 + ((_i) * 4)) /* Five Tuple Queue Filter */
-#define IXGBE_ETQF(_i) (0x05128 + ((_i) * 4)) /* EType Queue Filter */
-#define IXGBE_ETQS(_i) (0x0EC00 + ((_i) * 4)) /* EType Queue Select */
-#define IXGBE_SYNQF 0x0EC30 /* SYN Packet Queue Filter */
-#define IXGBE_RQTC 0x0EC70
-#define IXGBE_MTQC 0x08120
-#define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */
-#define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */
-#define IXGBE_VMVIR(_i) (0x08000 + ((_i) * 4)) /* 64 of these (0-63) */
-#define IXGBE_VT_CTL 0x051B0
-#define IXGBE_PFMAILBOX(_i) (0x04B00 + (4 * (_i))) /* 64 total */
-/* 64 Mailboxes, 16 DW each */
-#define IXGBE_PFMBMEM(_i) (0x13000 + (64 * (_i)))
-#define IXGBE_PFMBICR(_i) (0x00710 + (4 * (_i))) /* 4 total */
-#define IXGBE_PFMBIMR(_i) (0x00720 + (4 * (_i))) /* 4 total */
-#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4))
-#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4))
-#define IXGBE_VMECM(_i) (0x08790 + ((_i) * 4))
-#define IXGBE_QDE 0x2F04
-#define IXGBE_VMTXSW(_i) (0x05180 + ((_i) * 4)) /* 2 total */
-#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */
-#define IXGBE_UTA(_i) (0x0F400 + ((_i) * 4))
-#define IXGBE_MRCTL(_i) (0x0F600 + ((_i) * 4))
-#define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4))
-#define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4))
-#define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
-#define IXGBE_RXFECCERR0 0x051B8
-#define IXGBE_LLITHRESH 0x0EC90
-#define IXGBE_IMIR(_i) (0x05A80 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_IMIRVP 0x05AC0
-#define IXGBE_VMD_CTL 0x0581C
-#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */
-#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
-
-/* Flow Director registers */
-#define IXGBE_FDIRCTRL 0x0EE00
-#define IXGBE_FDIRHKEY 0x0EE68
-#define IXGBE_FDIRSKEY 0x0EE6C
-#define IXGBE_FDIRDIP4M 0x0EE3C
-#define IXGBE_FDIRSIP4M 0x0EE40
-#define IXGBE_FDIRTCPM 0x0EE44
-#define IXGBE_FDIRUDPM 0x0EE48
-#define IXGBE_FDIRIP6M 0x0EE74
-#define IXGBE_FDIRM 0x0EE70
-
-/* Flow Director Stats registers */
-#define IXGBE_FDIRFREE 0x0EE38
-#define IXGBE_FDIRLEN 0x0EE4C
-#define IXGBE_FDIRUSTAT 0x0EE50
-#define IXGBE_FDIRFSTAT 0x0EE54
-#define IXGBE_FDIRMATCH 0x0EE58
-#define IXGBE_FDIRMISS 0x0EE5C
-
-/* Flow Director Programming registers */
-#define IXGBE_FDIRSIPv6(_i) (0x0EE0C + ((_i) * 4)) /* 3 of these (0-2) */
-#define IXGBE_FDIRIPSA 0x0EE18
-#define IXGBE_FDIRIPDA 0x0EE1C
-#define IXGBE_FDIRPORT 0x0EE20
-#define IXGBE_FDIRVLAN 0x0EE24
-#define IXGBE_FDIRHASH 0x0EE28
-#define IXGBE_FDIRCMD 0x0EE2C
-
-/* Transmit DMA registers */
-#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of them (0-31)*/
-#define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
-#define IXGBE_TDLEN(_i) (0x06008 + ((_i) * 0x40))
-#define IXGBE_TDH(_i) (0x06010 + ((_i) * 0x40))
-#define IXGBE_TDT(_i) (0x06018 + ((_i) * 0x40))
-#define IXGBE_TXDCTL(_i) (0x06028 + ((_i) * 0x40))
-#define IXGBE_TDWBAL(_i) (0x06038 + ((_i) * 0x40))
-#define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40))
-#define IXGBE_DTXCTL 0x07E00
-
-#define IXGBE_DMATXCTL 0x04A80
-#define IXGBE_PFVFSPOOF(_i) (0x08200 + ((_i) * 4)) /* 8 of these 0 - 7 */
-#define IXGBE_PFDTXGSWC 0x08220
-#define IXGBE_DTXMXSZRQ 0x08100
-#define IXGBE_DTXTCPFLGL 0x04A88
-#define IXGBE_DTXTCPFLGH 0x04A8C
-#define IXGBE_LBDRPEN 0x0CA00
-#define IXGBE_TXPBTHRESH(_i) (0x04950 + ((_i) * 4)) /* 8 of these 0 - 7 */
-
-#define IXGBE_DMATXCTL_TE 0x1 /* Transmit Enable */
-#define IXGBE_DMATXCTL_NS 0x2 /* No Snoop LSO hdr buffer */
-#define IXGBE_DMATXCTL_GDV 0x8 /* Global Double VLAN */
-#define IXGBE_DMATXCTL_VT_SHIFT 16 /* VLAN EtherType */
-
-#define IXGBE_PFDTXGSWC_VT_LBEN 0x1 /* Local L2 VT switch enable */
-
-/* Anti-spoofing defines */
-#define IXGBE_SPOOF_MACAS_MASK 0xFF
-#define IXGBE_SPOOF_VLANAS_MASK 0xFF00
-#define IXGBE_SPOOF_VLANAS_SHIFT 8
-#define IXGBE_PFVFSPOOF_REG_COUNT 8
-/* 16 of these (0-15) */
-#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4))
-/* Tx DCA Control register : 128 of these (0-127) */
-#define IXGBE_DCA_TXCTRL_82599(_i) (0x0600C + ((_i) * 0x40))
-#define IXGBE_TIPG 0x0CB00
-#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) * 4)) /* 8 of these */
-#define IXGBE_MNGTXMAP 0x0CD10
-#define IXGBE_TIPG_FIBER_DEFAULT 3
-#define IXGBE_TXPBSIZE_SHIFT 10
-
-/* Wake up registers */
-#define IXGBE_WUC 0x05800
-#define IXGBE_WUFC 0x05808
-#define IXGBE_WUS 0x05810
-#define IXGBE_IPAV 0x05838
-#define IXGBE_IP4AT 0x05840 /* IPv4 table 0x5840-0x5858 */
-#define IXGBE_IP6AT 0x05880 /* IPv6 table 0x5880-0x588F */
-
-#define IXGBE_WUPL 0x05900
-#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
-#define IXGBE_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flex host filter table */
-/* Ext Flexible Host Filter Table */
-#define IXGBE_FHFT_EXT(_n) (0x09800 + (_n * 0x100))
-
-#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4
-#define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2
-
-/* Each Flexible Filter is at most 128 (0x80) bytes in length */
-#define IXGBE_FLEXIBLE_FILTER_SIZE_MAX 128
-#define IXGBE_FHFT_LENGTH_OFFSET 0xFC /* Length byte in FHFT */
-#define IXGBE_FHFT_LENGTH_MASK 0x0FF /* Length in lower byte */
-
-/* Definitions for power management and wakeup registers */
-/* Wake Up Control */
-#define IXGBE_WUC_PME_EN 0x00000002 /* PME Enable */
-#define IXGBE_WUC_PME_STATUS 0x00000004 /* PME Status */
-#define IXGBE_WUC_WKEN 0x00000010 /* Enable PE_WAKE_N pin assertion */
-
-/* Wake Up Filter Control */
-#define IXGBE_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
-#define IXGBE_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
-#define IXGBE_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
-#define IXGBE_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
-#define IXGBE_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
-#define IXGBE_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
-#define IXGBE_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
-#define IXGBE_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
-#define IXGBE_WUFC_MNG 0x00000100 /* Directed Mgmt Packet Wakeup Enable */
-
-#define IXGBE_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
-#define IXGBE_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
-#define IXGBE_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
-#define IXGBE_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
-#define IXGBE_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
-#define IXGBE_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */
-#define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */
-#define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */
-/* Mask for Ext. flex filters */
-#define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000
-#define IXGBE_WUFC_ALL_FILTERS 0x003F00FF /* Mask for all wakeup filters */
-#define IXGBE_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
-
-/* Wake Up Status */
-#define IXGBE_WUS_LNKC IXGBE_WUFC_LNKC
-#define IXGBE_WUS_MAG IXGBE_WUFC_MAG
-#define IXGBE_WUS_EX IXGBE_WUFC_EX
-#define IXGBE_WUS_MC IXGBE_WUFC_MC
-#define IXGBE_WUS_BC IXGBE_WUFC_BC
-#define IXGBE_WUS_ARP IXGBE_WUFC_ARP
-#define IXGBE_WUS_IPV4 IXGBE_WUFC_IPV4
-#define IXGBE_WUS_IPV6 IXGBE_WUFC_IPV6
-#define IXGBE_WUS_MNG IXGBE_WUFC_MNG
-#define IXGBE_WUS_FLX0 IXGBE_WUFC_FLX0
-#define IXGBE_WUS_FLX1 IXGBE_WUFC_FLX1
-#define IXGBE_WUS_FLX2 IXGBE_WUFC_FLX2
-#define IXGBE_WUS_FLX3 IXGBE_WUFC_FLX3
-#define IXGBE_WUS_FLX4 IXGBE_WUFC_FLX4
-#define IXGBE_WUS_FLX5 IXGBE_WUFC_FLX5
-#define IXGBE_WUS_FLX_FILTERS IXGBE_WUFC_FLX_FILTERS
-
-/* Wake Up Packet Length */
-#define IXGBE_WUPL_LENGTH_MASK 0xFFFF
-
-/* DCB registers */
-#define IXGBE_DCB_MAX_TRAFFIC_CLASS 8
-#define IXGBE_RMCS 0x03D00
-#define IXGBE_DPMCS 0x07F40
-#define IXGBE_PDPMCS 0x0CD00
-#define IXGBE_RUPPBMR 0x050A0
-#define IXGBE_RT2CR(_i) (0x03C20 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_RT2SR(_i) (0x03C40 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_TDTQ2TCCR(_i) (0x0602C + ((_i) * 0x40)) /* 8 of these (0-7) */
-#define IXGBE_TDTQ2TCSR(_i) (0x0622C + ((_i) * 0x40)) /* 8 of these (0-7) */
-#define IXGBE_TDPT2TCCR(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_TDPT2TCSR(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
-
-
-/* Security Control Registers */
-#define IXGBE_SECTXCTRL 0x08800
-#define IXGBE_SECTXSTAT 0x08804
-#define IXGBE_SECTXBUFFAF 0x08808
-#define IXGBE_SECTXMINIFG 0x08810
-#define IXGBE_SECRXCTRL 0x08D00
-#define IXGBE_SECRXSTAT 0x08D04
-
-/* Security Bit Fields and Masks */
-#define IXGBE_SECTXCTRL_SECTX_DIS 0x00000001
-#define IXGBE_SECTXCTRL_TX_DIS 0x00000002
-#define IXGBE_SECTXCTRL_STORE_FORWARD 0x00000004
-
-#define IXGBE_SECTXSTAT_SECTX_RDY 0x00000001
-#define IXGBE_SECTXSTAT_ECC_TXERR 0x00000002
-
-#define IXGBE_SECRXCTRL_SECRX_DIS 0x00000001
-#define IXGBE_SECRXCTRL_RX_DIS 0x00000002
-
-#define IXGBE_SECRXSTAT_SECRX_RDY 0x00000001
-#define IXGBE_SECRXSTAT_ECC_RXERR 0x00000002
-
-/* LinkSec (MacSec) Registers */
-#define IXGBE_LSECTXCAP 0x08A00
-#define IXGBE_LSECRXCAP 0x08F00
-#define IXGBE_LSECTXCTRL 0x08A04
-#define IXGBE_LSECTXSCL 0x08A08 /* SCI Low */
-#define IXGBE_LSECTXSCH 0x08A0C /* SCI High */
-#define IXGBE_LSECTXSA 0x08A10
-#define IXGBE_LSECTXPN0 0x08A14
-#define IXGBE_LSECTXPN1 0x08A18
-#define IXGBE_LSECTXKEY0(_n) (0x08A1C + (4 * (_n))) /* 4 of these (0-3) */
-#define IXGBE_LSECTXKEY1(_n) (0x08A2C + (4 * (_n))) /* 4 of these (0-3) */
-#define IXGBE_LSECRXCTRL 0x08F04
-#define IXGBE_LSECRXSCL 0x08F08
-#define IXGBE_LSECRXSCH 0x08F0C
-#define IXGBE_LSECRXSA(_i) (0x08F10 + (4 * (_i))) /* 2 of these (0-1) */
-#define IXGBE_LSECRXPN(_i) (0x08F18 + (4 * (_i))) /* 2 of these (0-1) */
-#define IXGBE_LSECRXKEY(_n, _m) (0x08F20 + ((0x10 * (_n)) + (4 * (_m))))
-#define IXGBE_LSECTXUT 0x08A3C /* OutPktsUntagged */
-#define IXGBE_LSECTXPKTE 0x08A40 /* OutPktsEncrypted */
-#define IXGBE_LSECTXPKTP 0x08A44 /* OutPktsProtected */
-#define IXGBE_LSECTXOCTE 0x08A48 /* OutOctetsEncrypted */
-#define IXGBE_LSECTXOCTP 0x08A4C /* OutOctetsProtected */
-#define IXGBE_LSECRXUT 0x08F40 /* InPktsUntagged/InPktsNoTag */
-#define IXGBE_LSECRXOCTD 0x08F44 /* InOctetsDecrypted */
-#define IXGBE_LSECRXOCTV 0x08F48 /* InOctetsValidated */
-#define IXGBE_LSECRXBAD 0x08F4C /* InPktsBadTag */
-#define IXGBE_LSECRXNOSCI 0x08F50 /* InPktsNoSci */
-#define IXGBE_LSECRXUNSCI 0x08F54 /* InPktsUnknownSci */
-#define IXGBE_LSECRXUNCH 0x08F58 /* InPktsUnchecked */
-#define IXGBE_LSECRXDELAY 0x08F5C /* InPktsDelayed */
-#define IXGBE_LSECRXLATE 0x08F60 /* InPktsLate */
-#define IXGBE_LSECRXOK(_n) (0x08F64 + (0x04 * (_n))) /* InPktsOk */
-#define IXGBE_LSECRXINV(_n) (0x08F6C + (0x04 * (_n))) /* InPktsInvalid */
-#define IXGBE_LSECRXNV(_n) (0x08F74 + (0x04 * (_n))) /* InPktsNotValid */
-#define IXGBE_LSECRXUNSA 0x08F7C /* InPktsUnusedSa */
-#define IXGBE_LSECRXNUSA 0x08F80 /* InPktsNotUsingSa */
-
-/* LinkSec (MacSec) Bit Fields and Masks */
-#define IXGBE_LSECTXCAP_SUM_MASK 0x00FF0000
-#define IXGBE_LSECTXCAP_SUM_SHIFT 16
-#define IXGBE_LSECRXCAP_SUM_MASK 0x00FF0000
-#define IXGBE_LSECRXCAP_SUM_SHIFT 16
-
-#define IXGBE_LSECTXCTRL_EN_MASK 0x00000003
-#define IXGBE_LSECTXCTRL_DISABLE 0x0
-#define IXGBE_LSECTXCTRL_AUTH 0x1
-#define IXGBE_LSECTXCTRL_AUTH_ENCRYPT 0x2
-#define IXGBE_LSECTXCTRL_AISCI 0x00000020
-#define IXGBE_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00
-#define IXGBE_LSECTXCTRL_RSV_MASK 0x000000D8
-
-#define IXGBE_LSECRXCTRL_EN_MASK 0x0000000C
-#define IXGBE_LSECRXCTRL_EN_SHIFT 2
-#define IXGBE_LSECRXCTRL_DISABLE 0x0
-#define IXGBE_LSECRXCTRL_CHECK 0x1
-#define IXGBE_LSECRXCTRL_STRICT 0x2
-#define IXGBE_LSECRXCTRL_DROP 0x3
-#define IXGBE_LSECRXCTRL_PLSH 0x00000040
-#define IXGBE_LSECRXCTRL_RP 0x00000080
-#define IXGBE_LSECRXCTRL_RSV_MASK 0xFFFFFF33
-
-/* IpSec Registers */
-#define IXGBE_IPSTXIDX 0x08900
-#define IXGBE_IPSTXSALT 0x08904
-#define IXGBE_IPSTXKEY(_i) (0x08908 + (4 * (_i))) /* 4 of these (0-3) */
-#define IXGBE_IPSRXIDX 0x08E00
-#define IXGBE_IPSRXIPADDR(_i) (0x08E04 + (4 * (_i))) /* 4 of these (0-3) */
-#define IXGBE_IPSRXSPI 0x08E14
-#define IXGBE_IPSRXIPIDX 0x08E18
-#define IXGBE_IPSRXKEY(_i) (0x08E1C + (4 * (_i))) /* 4 of these (0-3) */
-#define IXGBE_IPSRXSALT 0x08E2C
-#define IXGBE_IPSRXMOD 0x08E30
-
-#define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE 0x4
-
-/* DCB registers */
-#define IXGBE_RTRPCS 0x02430
-#define IXGBE_RTTDCS 0x04900
-#define IXGBE_RTTDCS_ARBDIS 0x00000040 /* DCB arbiter disable */
-#define IXGBE_RTTPCS 0x0CD00
-#define IXGBE_RTRUP2TC 0x03020
-#define IXGBE_RTTUP2TC 0x0C800
-#define IXGBE_RTRPT4C(_i) (0x02140 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_TXLLQ(_i) (0x082E0 + ((_i) * 4)) /* 4 of these (0-3) */
-#define IXGBE_RTRPT4S(_i) (0x02160 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_RTTDT2C(_i) (0x04910 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_RTTDT2S(_i) (0x04930 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_RTTPT2C(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_RTTPT2S(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_RTTDQSEL 0x04904
-#define IXGBE_RTTDT1C 0x04908
-#define IXGBE_RTTDT1S 0x0490C
-#define IXGBE_RTTDTECC 0x04990
-#define IXGBE_RTTDTECC_NO_BCN 0x00000100
-
-#define IXGBE_RTTBCNRC 0x04984
-#define IXGBE_RTTBCNRC_RS_ENA 0x80000000
-#define IXGBE_RTTBCNRC_RF_DEC_MASK 0x00003FFF
-#define IXGBE_RTTBCNRC_RF_INT_SHIFT 14
-#define IXGBE_RTTBCNRC_RF_INT_MASK \
- (IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT)
-#define IXGBE_RTTBCNRM 0x04980
-
-/* FCoE DMA Context Registers */
-#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */
-#define IXGBE_FCPTRH 0x02414 /* FC USer Desc. PTR High */
-#define IXGBE_FCBUFF 0x02418 /* FC Buffer Control */
-#define IXGBE_FCDMARW 0x02420 /* FC Receive DMA RW */
-#define IXGBE_FCINVST0 0x03FC0 /* FC Invalid DMA Context Status Reg 0*/
-#define IXGBE_FCINVST(_i) (IXGBE_FCINVST0 + ((_i) * 4))
-#define IXGBE_FCBUFF_VALID (1 << 0) /* DMA Context Valid */
-#define IXGBE_FCBUFF_BUFFSIZE (3 << 3) /* User Buffer Size */
-#define IXGBE_FCBUFF_WRCONTX (1 << 7) /* 0: Initiator, 1: Target */
-#define IXGBE_FCBUFF_BUFFCNT 0x0000ff00 /* Number of User Buffers */
-#define IXGBE_FCBUFF_OFFSET 0xffff0000 /* User Buffer Offset */
-#define IXGBE_FCBUFF_BUFFSIZE_SHIFT 3
-#define IXGBE_FCBUFF_BUFFCNT_SHIFT 8
-#define IXGBE_FCBUFF_OFFSET_SHIFT 16
-#define IXGBE_FCDMARW_WE (1 << 14) /* Write enable */
-#define IXGBE_FCDMARW_RE (1 << 15) /* Read enable */
-#define IXGBE_FCDMARW_FCOESEL 0x000001ff /* FC X_ID: 11 bits */
-#define IXGBE_FCDMARW_LASTSIZE 0xffff0000 /* Last User Buffer Size */
-#define IXGBE_FCDMARW_LASTSIZE_SHIFT 16
-/* FCoE SOF/EOF */
-#define IXGBE_TEOFF 0x04A94 /* Tx FC EOF */
-#define IXGBE_TSOFF 0x04A98 /* Tx FC SOF */
-#define IXGBE_REOFF 0x05158 /* Rx FC EOF */
-#define IXGBE_RSOFF 0x051F8 /* Rx FC SOF */
-/* FCoE Filter Context Registers */
-#define IXGBE_FCFLT 0x05108 /* FC FLT Context */
-#define IXGBE_FCFLTRW 0x05110 /* FC Filter RW Control */
-#define IXGBE_FCPARAM 0x051d8 /* FC Offset Parameter */
-#define IXGBE_FCFLT_VALID (1 << 0) /* Filter Context Valid */
-#define IXGBE_FCFLT_FIRST (1 << 1) /* Filter First */
-#define IXGBE_FCFLT_SEQID 0x00ff0000 /* Sequence ID */
-#define IXGBE_FCFLT_SEQCNT 0xff000000 /* Sequence Count */
-#define IXGBE_FCFLTRW_RVALDT (1 << 13) /* Fast Re-Validation */
-#define IXGBE_FCFLTRW_WE (1 << 14) /* Write Enable */
-#define IXGBE_FCFLTRW_RE (1 << 15) /* Read Enable */
-/* FCoE Receive Control */
-#define IXGBE_FCRXCTRL 0x05100 /* FC Receive Control */
-#define IXGBE_FCRXCTRL_FCOELLI (1 << 0) /* Low latency interrupt */
-#define IXGBE_FCRXCTRL_SAVBAD (1 << 1) /* Save Bad Frames */
-#define IXGBE_FCRXCTRL_FRSTRDH (1 << 2) /* EN 1st Read Header */
-#define IXGBE_FCRXCTRL_LASTSEQH (1 << 3) /* EN Last Header in Seq */
-#define IXGBE_FCRXCTRL_ALLH (1 << 4) /* EN All Headers */
-#define IXGBE_FCRXCTRL_FRSTSEQH (1 << 5) /* EN 1st Seq. Header */
-#define IXGBE_FCRXCTRL_ICRC (1 << 6) /* Ignore Bad FC CRC */
-#define IXGBE_FCRXCTRL_FCCRCBO (1 << 7) /* FC CRC Byte Ordering */
-#define IXGBE_FCRXCTRL_FCOEVER 0x00000f00 /* FCoE Version: 4 bits */
-#define IXGBE_FCRXCTRL_FCOEVER_SHIFT 8
-/* FCoE Redirection */
-#define IXGBE_FCRECTL 0x0ED00 /* FC Redirection Control */
-#define IXGBE_FCRETA0 0x0ED10 /* FC Redirection Table 0 */
-#define IXGBE_FCRETA(_i) (IXGBE_FCRETA0 + ((_i) * 4)) /* FCoE Redir */
-#define IXGBE_FCRECTL_ENA 0x1 /* FCoE Redir Table Enable */
-#define IXGBE_FCRETASEL_ENA 0x2 /* FCoE FCRETASEL bit */
-#define IXGBE_FCRETA_SIZE 8 /* Max entries in FCRETA */
-#define IXGBE_FCRETA_ENTRY_MASK 0x0000007f /* 7 bits for the queue index */
-
-/* Stats registers */
-#define IXGBE_CRCERRS 0x04000
-#define IXGBE_ILLERRC 0x04004
-#define IXGBE_ERRBC 0x04008
-#define IXGBE_MSPDC 0x04010
-#define IXGBE_MPC(_i) (0x03FA0 + ((_i) * 4)) /* 8 of these 3FA0-3FBC*/
-#define IXGBE_MLFC 0x04034
-#define IXGBE_MRFC 0x04038
-#define IXGBE_RLEC 0x04040
-#define IXGBE_LXONTXC 0x03F60
-#define IXGBE_LXONRXC 0x0CF60
-#define IXGBE_LXOFFTXC 0x03F68
-#define IXGBE_LXOFFRXC 0x0CF68
-#define IXGBE_LXONRXCNT 0x041A4
-#define IXGBE_LXOFFRXCNT 0x041A8
-#define IXGBE_PXONRXCNT(_i) (0x04140 + ((_i) * 4)) /* 8 of these */
-#define IXGBE_PXOFFRXCNT(_i) (0x04160 + ((_i) * 4)) /* 8 of these */
-#define IXGBE_PXON2OFFCNT(_i) (0x03240 + ((_i) * 4)) /* 8 of these */
-#define IXGBE_PXONTXC(_i) (0x03F00 + ((_i) * 4)) /* 8 of these 3F00-3F1C*/
-#define IXGBE_PXONRXC(_i) (0x0CF00 + ((_i) * 4)) /* 8 of these CF00-CF1C*/
-#define IXGBE_PXOFFTXC(_i) (0x03F20 + ((_i) * 4)) /* 8 of these 3F20-3F3C*/
-#define IXGBE_PXOFFRXC(_i) (0x0CF20 + ((_i) * 4)) /* 8 of these CF20-CF3C*/
-#define IXGBE_PRC64 0x0405C
-#define IXGBE_PRC127 0x04060
-#define IXGBE_PRC255 0x04064
-#define IXGBE_PRC511 0x04068
-#define IXGBE_PRC1023 0x0406C
-#define IXGBE_PRC1522 0x04070
-#define IXGBE_GPRC 0x04074
-#define IXGBE_BPRC 0x04078
-#define IXGBE_MPRC 0x0407C
-#define IXGBE_GPTC 0x04080
-#define IXGBE_GORCL 0x04088
-#define IXGBE_GORCH 0x0408C
-#define IXGBE_GOTCL 0x04090
-#define IXGBE_GOTCH 0x04094
-#define IXGBE_RNBC(_i) (0x03FC0 + ((_i) * 4)) /* 8 of these 3FC0-3FDC*/
-#define IXGBE_RUC 0x040A4
-#define IXGBE_RFC 0x040A8
-#define IXGBE_ROC 0x040AC
-#define IXGBE_RJC 0x040B0
-#define IXGBE_MNGPRC 0x040B4
-#define IXGBE_MNGPDC 0x040B8
-#define IXGBE_MNGPTC 0x0CF90
-#define IXGBE_TORL 0x040C0
-#define IXGBE_TORH 0x040C4
-#define IXGBE_TPR 0x040D0
-#define IXGBE_TPT 0x040D4
-#define IXGBE_PTC64 0x040D8
-#define IXGBE_PTC127 0x040DC
-#define IXGBE_PTC255 0x040E0
-#define IXGBE_PTC511 0x040E4
-#define IXGBE_PTC1023 0x040E8
-#define IXGBE_PTC1522 0x040EC
-#define IXGBE_MPTC 0x040F0
-#define IXGBE_BPTC 0x040F4
-#define IXGBE_XEC 0x04120
-#define IXGBE_SSVPC 0x08780
-
-#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4))
-#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : \
- (0x08600 + ((_i) * 4)))
-#define IXGBE_TQSM(_i) (0x08600 + ((_i) * 4))
-
-#define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */
-#define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */
-#define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */
-#define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */
-#define IXGBE_QBRC_L(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */
-#define IXGBE_QBRC_H(_i) (0x01038 + ((_i) * 0x40)) /* 16 of these */
-#define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */
-#define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */
-#define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */
-#define IXGBE_FCCRC 0x05118 /* Num of Good Eth CRC w/ Bad FC CRC */
-#define IXGBE_FCOERPDC 0x0241C /* FCoE Rx Packets Dropped Count */
-#define IXGBE_FCLAST 0x02424 /* FCoE Last Error Count */
-#define IXGBE_FCOEPRC 0x02428 /* Number of FCoE Packets Received */
-#define IXGBE_FCOEDWRC 0x0242C /* Number of FCoE DWords Received */
-#define IXGBE_FCOEPTC 0x08784 /* Number of FCoE Packets Transmitted */
-#define IXGBE_FCOEDWTC 0x08788 /* Number of FCoE DWords Transmitted */
-#define IXGBE_FCCRC_CNT_MASK 0x0000FFFF /* CRC_CNT: bit 0 - 15 */
-#define IXGBE_FCLAST_CNT_MASK 0x0000FFFF /* Last_CNT: bit 0 - 15 */
-#define IXGBE_O2BGPTC 0x041C4
-#define IXGBE_O2BSPC 0x087B0
-#define IXGBE_B2OSPC 0x041C0
-#define IXGBE_B2OGPRC 0x02F90
-#define IXGBE_BUPRC 0x04180
-#define IXGBE_BMPRC 0x04184
-#define IXGBE_BBPRC 0x04188
-#define IXGBE_BUPTC 0x0418C
-#define IXGBE_BMPTC 0x04190
-#define IXGBE_BBPTC 0x04194
-#define IXGBE_BCRCERRS 0x04198
-#define IXGBE_BXONRXC 0x0419C
-#define IXGBE_BXOFFRXC 0x041E0
-#define IXGBE_BXONTXC 0x041E4
-#define IXGBE_BXOFFTXC 0x041E8
-#define IXGBE_PCRC8ECL 0x0E810
-#define IXGBE_PCRC8ECH 0x0E811
-#define IXGBE_PCRC8ECH_MASK 0x1F
-#define IXGBE_LDPCECL 0x0E820
-#define IXGBE_LDPCECH 0x0E821
-
-/* Management */
-#define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_MFUTP(_i) (0x05030 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_MANC 0x05820
-#define IXGBE_MFVAL 0x05824
-#define IXGBE_MANC2H 0x05860
-#define IXGBE_MDEF(_i) (0x05890 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_MIPAF 0x058B0
-#define IXGBE_MMAL(_i) (0x05910 + ((_i) * 8)) /* 4 of these (0-3) */
-#define IXGBE_MMAH(_i) (0x05914 + ((_i) * 8)) /* 4 of these (0-3) */
-#define IXGBE_FTFT 0x09400 /* 0x9400-0x97FC */
-#define IXGBE_METF(_i) (0x05190 + ((_i) * 4)) /* 4 of these (0-3) */
-#define IXGBE_MDEF_EXT(_i) (0x05160 + ((_i) * 4)) /* 8 of these (0-7) */
-#define IXGBE_LSWFW 0x15014
-#define IXGBE_BMCIP(_i) (0x05050 + ((_i) * 4)) /* 0x5050-0x505C */
-#define IXGBE_BMCIPVAL 0x05060
-#define IXGBE_BMCIP_IPADDR_TYPE 0x00000001
-#define IXGBE_BMCIP_IPADDR_VALID 0x00000002
-
-/* Management Bit Fields and Masks */
-#define IXGBE_MANC_EN_BMC2OS 0x10000000 /* Ena BMC2OS and OS2BMC traffic */
-#define IXGBE_MANC_EN_BMC2OS_SHIFT 28
-
-/* Firmware Semaphore Register */
-#define IXGBE_FWSM_MODE_MASK 0xE
-
-/* ARC Subsystem registers */
-#define IXGBE_HICR 0x15F00
-#define IXGBE_FWSTS 0x15F0C
-#define IXGBE_HSMC0R 0x15F04
-#define IXGBE_HSMC1R 0x15F08
-#define IXGBE_SWSR 0x15F10
-#define IXGBE_HFDR 0x15FE8
-#define IXGBE_FLEX_MNG 0x15800 /* 0x15800 - 0x15EFC */
-
-#define IXGBE_HICR_EN 0x01 /* Enable bit - RO */
-/* Driver sets this bit when done to put command in RAM */
-#define IXGBE_HICR_C 0x02
-#define IXGBE_HICR_SV 0x04 /* Status Validity */
-#define IXGBE_HICR_FW_RESET_ENABLE 0x40
-#define IXGBE_HICR_FW_RESET 0x80
-
-/* PCI-E registers */
-#define IXGBE_GCR 0x11000
-#define IXGBE_GTV 0x11004
-#define IXGBE_FUNCTAG 0x11008
-#define IXGBE_GLT 0x1100C
-#define IXGBE_PCIEPIPEADR 0x11004
-#define IXGBE_PCIEPIPEDAT 0x11008
-#define IXGBE_GSCL_1 0x11010
-#define IXGBE_GSCL_2 0x11014
-#define IXGBE_GSCL_3 0x11018
-#define IXGBE_GSCL_4 0x1101C
-#define IXGBE_GSCN_0 0x11020
-#define IXGBE_GSCN_1 0x11024
-#define IXGBE_GSCN_2 0x11028
-#define IXGBE_GSCN_3 0x1102C
-#define IXGBE_FACTPS 0x10150
-#define IXGBE_PCIEANACTL 0x11040
-#define IXGBE_SWSM 0x10140
-#define IXGBE_FWSM 0x10148
-#define IXGBE_GSSR 0x10160
-#define IXGBE_MREVID 0x11064
-#define IXGBE_DCA_ID 0x11070
-#define IXGBE_DCA_CTRL 0x11074
-#define IXGBE_SWFW_SYNC IXGBE_GSSR
-
-/* PCI-E registers 82599-Specific */
-#define IXGBE_GCR_EXT 0x11050
-#define IXGBE_GSCL_5_82599 0x11030
-#define IXGBE_GSCL_6_82599 0x11034
-#define IXGBE_GSCL_7_82599 0x11038
-#define IXGBE_GSCL_8_82599 0x1103C
-#define IXGBE_PHYADR_82599 0x11040
-#define IXGBE_PHYDAT_82599 0x11044
-#define IXGBE_PHYCTL_82599 0x11048
-#define IXGBE_PBACLR_82599 0x11068
-#define IXGBE_CIAA_82599 0x11088
-#define IXGBE_CIAD_82599 0x1108C
-#define IXGBE_PICAUSE 0x110B0
-#define IXGBE_PIENA 0x110B8
-#define IXGBE_CDQ_MBR_82599 0x110B4
-#define IXGBE_PCIESPARE 0x110BC
-#define IXGBE_MISC_REG_82599 0x110F0
-#define IXGBE_ECC_CTRL_0_82599 0x11100
-#define IXGBE_ECC_CTRL_1_82599 0x11104
-#define IXGBE_ECC_STATUS_82599 0x110E0
-#define IXGBE_BAR_CTRL_82599 0x110F4
-
-/* PCI Express Control */
-#define IXGBE_GCR_CMPL_TMOUT_MASK 0x0000F000
-#define IXGBE_GCR_CMPL_TMOUT_10ms 0x00001000
-#define IXGBE_GCR_CMPL_TMOUT_RESEND 0x00010000
-#define IXGBE_GCR_CAP_VER2 0x00040000
-
-#define IXGBE_GCR_EXT_MSIX_EN 0x80000000
-#define IXGBE_GCR_EXT_BUFFERS_CLEAR 0x40000000
-#define IXGBE_GCR_EXT_VT_MODE_16 0x00000001
-#define IXGBE_GCR_EXT_VT_MODE_32 0x00000002
-#define IXGBE_GCR_EXT_VT_MODE_64 0x00000003
-#define IXGBE_GCR_EXT_SRIOV (IXGBE_GCR_EXT_MSIX_EN | \
- IXGBE_GCR_EXT_VT_MODE_64)
-/* Time Sync Registers */
-#define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */
-#define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */
-#define IXGBE_RXSTMPL 0x051E8 /* Rx timestamp Low - RO */
-#define IXGBE_RXSTMPH 0x051A4 /* Rx timestamp High - RO */
-#define IXGBE_RXSATRL 0x051A0 /* Rx timestamp attribute low - RO */
-#define IXGBE_RXSATRH 0x051A8 /* Rx timestamp attribute high - RO */
-#define IXGBE_RXMTRL 0x05120 /* RX message type register low - RW */
-#define IXGBE_TXSTMPL 0x08C04 /* Tx timestamp value Low - RO */
-#define IXGBE_TXSTMPH 0x08C08 /* Tx timestamp value High - RO */
-#define IXGBE_SYSTIML 0x08C0C /* System time register Low - RO */
-#define IXGBE_SYSTIMH 0x08C10 /* System time register High - RO */
-#define IXGBE_TIMINCA 0x08C14 /* Increment attributes register - RW */
-#define IXGBE_TIMADJL 0x08C18 /* Time Adjustment Offset register Low - RW */
-#define IXGBE_TIMADJH 0x08C1C /* Time Adjustment Offset register High - RW */
-#define IXGBE_TSAUXC 0x08C20 /* TimeSync Auxiliary Control register - RW */
-#define IXGBE_TRGTTIML0 0x08C24 /* Target Time Register 0 Low - RW */
-#define IXGBE_TRGTTIMH0 0x08C28 /* Target Time Register 0 High - RW */
-#define IXGBE_TRGTTIML1 0x08C2C /* Target Time Register 1 Low - RW */
-#define IXGBE_TRGTTIMH1 0x08C30 /* Target Time Register 1 High - RW */
-#define IXGBE_FREQOUT0 0x08C34 /* Frequency Out 0 Control register - RW */
-#define IXGBE_FREQOUT1 0x08C38 /* Frequency Out 1 Control register - RW */
-#define IXGBE_AUXSTMPL0 0x08C3C /* Auxiliary Time Stamp 0 register Low - RO */
-#define IXGBE_AUXSTMPH0 0x08C40 /* Auxiliary Time Stamp 0 register High - RO */
-#define IXGBE_AUXSTMPL1 0x08C44 /* Auxiliary Time Stamp 1 register Low - RO */
-#define IXGBE_AUXSTMPH1 0x08C48 /* Auxiliary Time Stamp 1 register High - RO */
-
-/* Diagnostic Registers */
-#define IXGBE_RDSTATCTL 0x02C20
-#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
-#define IXGBE_RDHMPN 0x02F08
-#define IXGBE_RIC_DW(_i) (0x02F10 + ((_i) * 4))
-#define IXGBE_RDPROBE 0x02F20
-#define IXGBE_RDMAM 0x02F30
-#define IXGBE_RDMAD 0x02F34
-#define IXGBE_TDSTATCTL 0x07C20
-#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
-#define IXGBE_TDHMPN 0x07F08
-#define IXGBE_TDHMPN2 0x082FC
-#define IXGBE_TXDESCIC 0x082CC
-#define IXGBE_TIC_DW(_i) (0x07F10 + ((_i) * 4))
-#define IXGBE_TIC_DW2(_i) (0x082B0 + ((_i) * 4))
-#define IXGBE_TDPROBE 0x07F20
-#define IXGBE_TXBUFCTRL 0x0C600
-#define IXGBE_TXBUFDATA0 0x0C610
-#define IXGBE_TXBUFDATA1 0x0C614
-#define IXGBE_TXBUFDATA2 0x0C618
-#define IXGBE_TXBUFDATA3 0x0C61C
-#define IXGBE_RXBUFCTRL 0x03600
-#define IXGBE_RXBUFDATA0 0x03610
-#define IXGBE_RXBUFDATA1 0x03614
-#define IXGBE_RXBUFDATA2 0x03618
-#define IXGBE_RXBUFDATA3 0x0361C
-#define IXGBE_PCIE_DIAG(_i) (0x11090 + ((_i) * 4)) /* 8 of these */
-#define IXGBE_RFVAL 0x050A4
-#define IXGBE_MDFTC1 0x042B8
-#define IXGBE_MDFTC2 0x042C0
-#define IXGBE_MDFTFIFO1 0x042C4
-#define IXGBE_MDFTFIFO2 0x042C8
-#define IXGBE_MDFTS 0x042CC
-#define IXGBE_RXDATAWRPTR(_i) (0x03700 + ((_i) * 4)) /* 8 of these 3700-370C*/
-#define IXGBE_RXDESCWRPTR(_i) (0x03710 + ((_i) * 4)) /* 8 of these 3710-371C*/
-#define IXGBE_RXDATARDPTR(_i) (0x03720 + ((_i) * 4)) /* 8 of these 3720-372C*/
-#define IXGBE_RXDESCRDPTR(_i) (0x03730 + ((_i) * 4)) /* 8 of these 3730-373C*/
-#define IXGBE_TXDATAWRPTR(_i) (0x0C700 + ((_i) * 4)) /* 8 of these C700-C70C*/
-#define IXGBE_TXDESCWRPTR(_i) (0x0C710 + ((_i) * 4)) /* 8 of these C710-C71C*/
-#define IXGBE_TXDATARDPTR(_i) (0x0C720 + ((_i) * 4)) /* 8 of these C720-C72C*/
-#define IXGBE_TXDESCRDPTR(_i) (0x0C730 + ((_i) * 4)) /* 8 of these C730-C73C*/
-#define IXGBE_PCIEECCCTL 0x1106C
-#define IXGBE_RXWRPTR(_i) (0x03100 + ((_i) * 4)) /* 8 of these 3100-310C*/
-#define IXGBE_RXUSED(_i) (0x03120 + ((_i) * 4)) /* 8 of these 3120-312C*/
-#define IXGBE_RXRDPTR(_i) (0x03140 + ((_i) * 4)) /* 8 of these 3140-314C*/
-#define IXGBE_RXRDWRPTR(_i) (0x03160 + ((_i) * 4)) /* 8 of these 3160-310C*/
-#define IXGBE_TXWRPTR(_i) (0x0C100 + ((_i) * 4)) /* 8 of these C100-C10C*/
-#define IXGBE_TXUSED(_i) (0x0C120 + ((_i) * 4)) /* 8 of these C120-C12C*/
-#define IXGBE_TXRDPTR(_i) (0x0C140 + ((_i) * 4)) /* 8 of these C140-C14C*/
-#define IXGBE_TXRDWRPTR(_i) (0x0C160 + ((_i) * 4)) /* 8 of these C160-C10C*/
-#define IXGBE_PCIEECCCTL0 0x11100
-#define IXGBE_PCIEECCCTL1 0x11104
-#define IXGBE_RXDBUECC 0x03F70
-#define IXGBE_TXDBUECC 0x0CF70
-#define IXGBE_RXDBUEST 0x03F74
-#define IXGBE_TXDBUEST 0x0CF74
-#define IXGBE_PBTXECC 0x0C300
-#define IXGBE_PBRXECC 0x03300
-#define IXGBE_GHECCR 0x110B0
-
-/* MAC Registers */
-#define IXGBE_PCS1GCFIG 0x04200
-#define IXGBE_PCS1GLCTL 0x04208
-#define IXGBE_PCS1GLSTA 0x0420C
-#define IXGBE_PCS1GDBG0 0x04210
-#define IXGBE_PCS1GDBG1 0x04214
-#define IXGBE_PCS1GANA 0x04218
-#define IXGBE_PCS1GANLP 0x0421C
-#define IXGBE_PCS1GANNP 0x04220
-#define IXGBE_PCS1GANLPNP 0x04224
-#define IXGBE_HLREG0 0x04240
-#define IXGBE_HLREG1 0x04244
-#define IXGBE_PAP 0x04248
-#define IXGBE_MACA 0x0424C
-#define IXGBE_APAE 0x04250
-#define IXGBE_ARD 0x04254
-#define IXGBE_AIS 0x04258
-#define IXGBE_MSCA 0x0425C
-#define IXGBE_MSRWD 0x04260
-#define IXGBE_MLADD 0x04264
-#define IXGBE_MHADD 0x04268
-#define IXGBE_MAXFRS 0x04268
-#define IXGBE_TREG 0x0426C
-#define IXGBE_PCSS1 0x04288
-#define IXGBE_PCSS2 0x0428C
-#define IXGBE_XPCSS 0x04290
-#define IXGBE_MFLCN 0x04294
-#define IXGBE_SERDESC 0x04298
-#define IXGBE_MACS 0x0429C
-#define IXGBE_AUTOC 0x042A0
-#define IXGBE_LINKS 0x042A4
-#define IXGBE_LINKS2 0x04324
-#define IXGBE_AUTOC2 0x042A8
-#define IXGBE_AUTOC3 0x042AC
-#define IXGBE_ANLP1 0x042B0
-#define IXGBE_ANLP2 0x042B4
-#define IXGBE_MACC 0x04330
-#define IXGBE_ATLASCTL 0x04800
-#define IXGBE_MMNGC 0x042D0
-#define IXGBE_ANLPNP1 0x042D4
-#define IXGBE_ANLPNP2 0x042D8
-#define IXGBE_KRPCSFC 0x042E0
-#define IXGBE_KRPCSS 0x042E4
-#define IXGBE_FECS1 0x042E8
-#define IXGBE_FECS2 0x042EC
-#define IXGBE_SMADARCTL 0x14F10
-#define IXGBE_MPVC 0x04318
-#define IXGBE_SGMIIC 0x04314
-
-/* Statistics Registers */
-#define IXGBE_RXNFGPC 0x041B0
-#define IXGBE_RXNFGBCL 0x041B4
-#define IXGBE_RXNFGBCH 0x041B8
-#define IXGBE_RXDGPC 0x02F50
-#define IXGBE_RXDGBCL 0x02F54
-#define IXGBE_RXDGBCH 0x02F58
-#define IXGBE_RXDDGPC 0x02F5C
-#define IXGBE_RXDDGBCL 0x02F60
-#define IXGBE_RXDDGBCH 0x02F64
-#define IXGBE_RXLPBKGPC 0x02F68
-#define IXGBE_RXLPBKGBCL 0x02F6C
-#define IXGBE_RXLPBKGBCH 0x02F70
-#define IXGBE_RXDLPBKGPC 0x02F74
-#define IXGBE_RXDLPBKGBCL 0x02F78
-#define IXGBE_RXDLPBKGBCH 0x02F7C
-#define IXGBE_TXDGPC 0x087A0
-#define IXGBE_TXDGBCL 0x087A4
-#define IXGBE_TXDGBCH 0x087A8
-
-#define IXGBE_RXDSTATCTRL 0x02F40
-
-/* Copper Pond 2 link timeout */
-#define IXGBE_VALIDATE_LINK_READY_TIMEOUT 50
-
-/* Omer CORECTL */
-#define IXGBE_CORECTL 0x014F00
-/* BARCTRL */
-#define IXGBE_BARCTRL 0x110F4
-#define IXGBE_BARCTRL_FLSIZE 0x0700
-#define IXGBE_BARCTRL_FLSIZE_SHIFT 8
-#define IXGBE_BARCTRL_CSRSIZE 0x2000
-
-/* RSCCTL Bit Masks */
-#define IXGBE_RSCCTL_RSCEN 0x01
-#define IXGBE_RSCCTL_MAXDESC_1 0x00
-#define IXGBE_RSCCTL_MAXDESC_4 0x04
-#define IXGBE_RSCCTL_MAXDESC_8 0x08
-#define IXGBE_RSCCTL_MAXDESC_16 0x0C
-
-/* RSCDBU Bit Masks */
-#define IXGBE_RSCDBU_RSCSMALDIS_MASK 0x0000007F
-#define IXGBE_RSCDBU_RSCACKDIS 0x00000080
-
-/* RDRXCTL Bit Masks */
-#define IXGBE_RDRXCTL_RDMTS_1_2 0x00000000 /* Rx Desc Min THLD Size */
-#define IXGBE_RDRXCTL_CRCSTRIP 0x00000002 /* CRC Strip */
-#define IXGBE_RDRXCTL_MVMEN 0x00000020
-#define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */
-#define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */
-#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000 /* RSC First packet size */
-#define IXGBE_RDRXCTL_RSCLLIDIS 0x00800000 /* Disabl RSC compl on LLI */
-#define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC ena */
-#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC ena */
-
-/* RQTC Bit Masks and Shifts */
-#define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4)
-#define IXGBE_RQTC_TC0_MASK (0x7 << 0)
-#define IXGBE_RQTC_TC1_MASK (0x7 << 4)
-#define IXGBE_RQTC_TC2_MASK (0x7 << 8)
-#define IXGBE_RQTC_TC3_MASK (0x7 << 12)
-#define IXGBE_RQTC_TC4_MASK (0x7 << 16)
-#define IXGBE_RQTC_TC5_MASK (0x7 << 20)
-#define IXGBE_RQTC_TC6_MASK (0x7 << 24)
-#define IXGBE_RQTC_TC7_MASK (0x7 << 28)
-
-/* PSRTYPE.RQPL Bit masks and shift */
-#define IXGBE_PSRTYPE_RQPL_MASK 0x7
-#define IXGBE_PSRTYPE_RQPL_SHIFT 29
-
-/* CTRL Bit Masks */
-#define IXGBE_CTRL_GIO_DIS 0x00000004 /* Global IO Master Disable bit */
-#define IXGBE_CTRL_LNK_RST 0x00000008 /* Link Reset. Resets everything. */
-#define IXGBE_CTRL_RST 0x04000000 /* Reset (SW) */
-#define IXGBE_CTRL_RST_MASK (IXGBE_CTRL_LNK_RST | IXGBE_CTRL_RST)
-
-/* FACTPS */
-#define IXGBE_FACTPS_LFS 0x40000000 /* LAN Function Select */
-
-/* MHADD Bit Masks */
-#define IXGBE_MHADD_MFS_MASK 0xFFFF0000
-#define IXGBE_MHADD_MFS_SHIFT 16
-
-/* Extended Device Control */
-#define IXGBE_CTRL_EXT_PFRSTD 0x00004000 /* Physical Function Reset Done */
-#define IXGBE_CTRL_EXT_NS_DIS 0x00010000 /* No Snoop disable */
-#define IXGBE_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
-#define IXGBE_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
-
-/* Direct Cache Access (DCA) definitions */
-#define IXGBE_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */
-#define IXGBE_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */
-
-#define IXGBE_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */
-#define IXGBE_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
-
-#define IXGBE_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
-#define IXGBE_DCA_RXCTRL_CPUID_MASK_82599 0xFF000000 /* Rx CPUID Mask */
-#define IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599 24 /* Rx CPUID Shift */
-#define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* Rx Desc enable */
-#define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* Rx Desc header ena */
-#define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* Rx Desc payload ena */
-#define IXGBE_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* Rx rd Desc Relax Order */
-#define IXGBE_DCA_RXCTRL_DATA_WRO_EN (1 << 13) /* Rx wr data Relax Order */
-#define IXGBE_DCA_RXCTRL_HEAD_WRO_EN (1 << 15) /* Rx wr header RO */
-
-#define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
-#define IXGBE_DCA_TXCTRL_CPUID_MASK_82599 0xFF000000 /* Tx CPUID Mask */
-#define IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599 24 /* Tx CPUID Shift */
-#define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
-#define IXGBE_DCA_TXCTRL_DESC_RRO_EN (1 << 9) /* Tx rd Desc Relax Order */
-#define IXGBE_DCA_TXCTRL_DESC_WRO_EN (1 << 11) /* Tx Desc writeback RO bit */
-#define IXGBE_DCA_TXCTRL_DATA_RRO_EN (1 << 13) /* Tx rd data Relax Order */
-#define IXGBE_DCA_MAX_QUEUES_82598 16 /* DCA regs only on 16 queues */
-
-/* MSCA Bit Masks */
-#define IXGBE_MSCA_NP_ADDR_MASK 0x0000FFFF /* MDI Addr (new prot) */
-#define IXGBE_MSCA_NP_ADDR_SHIFT 0
-#define IXGBE_MSCA_DEV_TYPE_MASK 0x001F0000 /* Dev Type (new prot) */
-#define IXGBE_MSCA_DEV_TYPE_SHIFT 16 /* Register Address (old prot */
-#define IXGBE_MSCA_PHY_ADDR_MASK 0x03E00000 /* PHY Address mask */
-#define IXGBE_MSCA_PHY_ADDR_SHIFT 21 /* PHY Address shift*/
-#define IXGBE_MSCA_OP_CODE_MASK 0x0C000000 /* OP CODE mask */
-#define IXGBE_MSCA_OP_CODE_SHIFT 26 /* OP CODE shift */
-#define IXGBE_MSCA_ADDR_CYCLE 0x00000000 /* OP CODE 00 (addr cycle) */
-#define IXGBE_MSCA_WRITE 0x04000000 /* OP CODE 01 (wr) */
-#define IXGBE_MSCA_READ 0x0C000000 /* OP CODE 11 (rd) */
-#define IXGBE_MSCA_READ_AUTOINC 0x08000000 /* OP CODE 10 (rd auto inc)*/
-#define IXGBE_MSCA_ST_CODE_MASK 0x30000000 /* ST Code mask */
-#define IXGBE_MSCA_ST_CODE_SHIFT 28 /* ST Code shift */
-#define IXGBE_MSCA_NEW_PROTOCOL 0x00000000 /* ST CODE 00 (new prot) */
-#define IXGBE_MSCA_OLD_PROTOCOL 0x10000000 /* ST CODE 01 (old prot) */
-#define IXGBE_MSCA_MDI_COMMAND 0x40000000 /* Initiate MDI command */
-#define IXGBE_MSCA_MDI_IN_PROG_EN 0x80000000 /* MDI in progress ena */
-
-/* MSRWD bit masks */
-#define IXGBE_MSRWD_WRITE_DATA_MASK 0x0000FFFF
-#define IXGBE_MSRWD_WRITE_DATA_SHIFT 0
-#define IXGBE_MSRWD_READ_DATA_MASK 0xFFFF0000
-#define IXGBE_MSRWD_READ_DATA_SHIFT 16
-
-/* Atlas registers */
-#define IXGBE_ATLAS_PDN_LPBK 0x24
-#define IXGBE_ATLAS_PDN_10G 0xB
-#define IXGBE_ATLAS_PDN_1G 0xC
-#define IXGBE_ATLAS_PDN_AN 0xD
-
-/* Atlas bit masks */
-#define IXGBE_ATLASCTL_WRITE_CMD 0x00010000
-#define IXGBE_ATLAS_PDN_TX_REG_EN 0x10
-#define IXGBE_ATLAS_PDN_TX_10G_QL_ALL 0xF0
-#define IXGBE_ATLAS_PDN_TX_1G_QL_ALL 0xF0
-#define IXGBE_ATLAS_PDN_TX_AN_QL_ALL 0xF0
-
-/* Omer bit masks */
-#define IXGBE_CORECTL_WRITE_CMD 0x00010000
-
-/* Device Type definitions for new protocol MDIO commands */
-#define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1
-#define IXGBE_MDIO_PCS_DEV_TYPE 0x3
-#define IXGBE_MDIO_PHY_XS_DEV_TYPE 0x4
-#define IXGBE_MDIO_AUTO_NEG_DEV_TYPE 0x7
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE 0x1E /* Device 30 */
-#define IXGBE_TWINAX_DEV 1
-
-#define IXGBE_MDIO_COMMAND_TIMEOUT 100 /* PHY Timeout for 1 GB mode */
-
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL 0x0 /* VS1 Ctrl Reg */
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS 0x1 /* VS1 Status Reg */
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS 0x0008 /* 1 = Link Up */
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS 0x0010 /* 0-10G, 1-1G */
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_10G_SPEED 0x0018
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_1G_SPEED 0x0010
-
-#define IXGBE_MDIO_AUTO_NEG_CONTROL 0x0 /* AUTO_NEG Control Reg */
-#define IXGBE_MDIO_AUTO_NEG_STATUS 0x1 /* AUTO_NEG Status Reg */
-#define IXGBE_MDIO_AUTO_NEG_ADVT 0x10 /* AUTO_NEG Advt Reg */
-#define IXGBE_MDIO_AUTO_NEG_LP 0x13 /* AUTO_NEG LP Status Reg */
-#define IXGBE_MDIO_PHY_XS_CONTROL 0x0 /* PHY_XS Control Reg */
-#define IXGBE_MDIO_PHY_XS_RESET 0x8000 /* PHY_XS Reset */
-#define IXGBE_MDIO_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/
-#define IXGBE_MDIO_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/
-#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */
-#define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */
-#define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */
-#define IXGBE_MDIO_PHY_SPEED_100M 0x0020 /* 100M capable */
-#define IXGBE_MDIO_PHY_EXT_ABILITY 0xB /* Ext Ability Reg */
-#define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */
-#define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */
-#define IXGBE_MDIO_PHY_100BASETX_ABILITY 0x0080 /* 100BaseTX capable */
-#define IXGBE_MDIO_PHY_SET_LOW_POWER_MODE 0x0800 /* Set low power mode */
-
-#define IXGBE_MDIO_PMA_PMD_CONTROL_ADDR 0x0000 /* PMA/PMD Control Reg */
-#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */
-#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
-#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */
-
-/* MII clause 22/28 definitions */
-#define IXGBE_MDIO_PHY_LOW_POWER_MODE 0x0800
-
-#define IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG 0x20 /* 10G Control Reg */
-#define IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG 0xC400 /* 1G Provisioning 1 */
-#define IXGBE_MII_AUTONEG_XNP_TX_REG 0x17 /* 1G XNP Transmit */
-#define IXGBE_MII_AUTONEG_ADVERTISE_REG 0x10 /* 100M Advertisement */
-#define IXGBE_MII_10GBASE_T_ADVERTISE 0x1000 /* full duplex, bit:12*/
-#define IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX 0x4000 /* full duplex, bit:14*/
-#define IXGBE_MII_1GBASE_T_ADVERTISE 0x8000 /* full duplex, bit:15*/
-#define IXGBE_MII_100BASE_T_ADVERTISE 0x0100 /* full duplex, bit:8 */
-#define IXGBE_MII_100BASE_T_ADVERTISE_HALF 0x0080 /* half duplex, bit:7 */
-#define IXGBE_MII_RESTART 0x200
-#define IXGBE_MII_AUTONEG_COMPLETE 0x20
-#define IXGBE_MII_AUTONEG_LINK_UP 0x04
-#define IXGBE_MII_AUTONEG_REG 0x0
-
-#define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0
-#define IXGBE_MAX_PHY_ADDR 32
-
-/* PHY IDs*/
-#define TN1010_PHY_ID 0x00A19410
-#define TNX_FW_REV 0xB
-#define X540_PHY_ID 0x01540200
-#define AQ_FW_REV 0x20
-#define QT2022_PHY_ID 0x0043A400
-#define ATH_PHY_ID 0x03429050
-
-/* PHY Types */
-#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0
-
-/* Special PHY Init Routine */
-#define IXGBE_PHY_INIT_OFFSET_NL 0x002B
-#define IXGBE_PHY_INIT_END_NL 0xFFFF
-#define IXGBE_CONTROL_MASK_NL 0xF000
-#define IXGBE_DATA_MASK_NL 0x0FFF
-#define IXGBE_CONTROL_SHIFT_NL 12
-#define IXGBE_DELAY_NL 0
-#define IXGBE_DATA_NL 1
-#define IXGBE_CONTROL_NL 0x000F
-#define IXGBE_CONTROL_EOL_NL 0x0FFF
-#define IXGBE_CONTROL_SOL_NL 0x0000
-
-/* General purpose Interrupt Enable */
-#define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */
-#define IXGBE_SDP1_GPIEN 0x00000002 /* SDP1 */
-#define IXGBE_SDP2_GPIEN 0x00000004 /* SDP2 */
-#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */
-#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */
-#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */
-#define IXGBE_GPIE_EIAME 0x40000000
-#define IXGBE_GPIE_PBA_SUPPORT 0x80000000
-#define IXGBE_GPIE_RSC_DELAY_SHIFT 11
-#define IXGBE_GPIE_VTMODE_MASK 0x0000C000 /* VT Mode Mask */
-#define IXGBE_GPIE_VTMODE_16 0x00004000 /* 16 VFs 8 queues per VF */
-#define IXGBE_GPIE_VTMODE_32 0x00008000 /* 32 VFs 4 queues per VF */
-#define IXGBE_GPIE_VTMODE_64 0x0000C000 /* 64 VFs 2 queues per VF */
-
-/* Packet Buffer Initialization */
-#define IXGBE_MAX_PACKET_BUFFERS 8
-
-#define IXGBE_TXPBSIZE_20KB 0x00005000 /* 20KB Packet Buffer */
-#define IXGBE_TXPBSIZE_40KB 0x0000A000 /* 40KB Packet Buffer */
-#define IXGBE_RXPBSIZE_48KB 0x0000C000 /* 48KB Packet Buffer */
-#define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */
-#define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */
-#define IXGBE_RXPBSIZE_128KB 0x00020000 /* 128KB Packet Buffer */
-#define IXGBE_RXPBSIZE_MAX 0x00080000 /* 512KB Packet Buffer */
-#define IXGBE_TXPBSIZE_MAX 0x00028000 /* 160KB Packet Buffer */
-
-#define IXGBE_TXPKT_SIZE_MAX 0xA /* Max Tx Packet size */
-#define IXGBE_MAX_PB 8
-
-/* Packet buffer allocation strategies */
-enum {
- PBA_STRATEGY_EQUAL = 0, /* Distribute PB space equally */
-#define PBA_STRATEGY_EQUAL PBA_STRATEGY_EQUAL
- PBA_STRATEGY_WEIGHTED = 1, /* Weight front half of TCs */
-#define PBA_STRATEGY_WEIGHTED PBA_STRATEGY_WEIGHTED
-};
-
-/* Transmit Flow Control status */
-#define IXGBE_TFCS_TXOFF 0x00000001
-#define IXGBE_TFCS_TXOFF0 0x00000100
-#define IXGBE_TFCS_TXOFF1 0x00000200
-#define IXGBE_TFCS_TXOFF2 0x00000400
-#define IXGBE_TFCS_TXOFF3 0x00000800
-#define IXGBE_TFCS_TXOFF4 0x00001000
-#define IXGBE_TFCS_TXOFF5 0x00002000
-#define IXGBE_TFCS_TXOFF6 0x00004000
-#define IXGBE_TFCS_TXOFF7 0x00008000
-
-/* TCP Timer */
-#define IXGBE_TCPTIMER_KS 0x00000100
-#define IXGBE_TCPTIMER_COUNT_ENABLE 0x00000200
-#define IXGBE_TCPTIMER_COUNT_FINISH 0x00000400
-#define IXGBE_TCPTIMER_LOOP 0x00000800
-#define IXGBE_TCPTIMER_DURATION_MASK 0x000000FF
-
-/* HLREG0 Bit Masks */
-#define IXGBE_HLREG0_TXCRCEN 0x00000001 /* bit 0 */
-#define IXGBE_HLREG0_RXCRCSTRP 0x00000002 /* bit 1 */
-#define IXGBE_HLREG0_JUMBOEN 0x00000004 /* bit 2 */
-#define IXGBE_HLREG0_TXPADEN 0x00000400 /* bit 10 */
-#define IXGBE_HLREG0_TXPAUSEEN 0x00001000 /* bit 12 */
-#define IXGBE_HLREG0_RXPAUSEEN 0x00004000 /* bit 14 */
-#define IXGBE_HLREG0_LPBK 0x00008000 /* bit 15 */
-#define IXGBE_HLREG0_MDCSPD 0x00010000 /* bit 16 */
-#define IXGBE_HLREG0_CONTMDC 0x00020000 /* bit 17 */
-#define IXGBE_HLREG0_CTRLFLTR 0x00040000 /* bit 18 */
-#define IXGBE_HLREG0_PREPEND 0x00F00000 /* bits 20-23 */
-#define IXGBE_HLREG0_PRIPAUSEEN 0x01000000 /* bit 24 */
-#define IXGBE_HLREG0_RXPAUSERECDA 0x06000000 /* bits 25-26 */
-#define IXGBE_HLREG0_RXLNGTHERREN 0x08000000 /* bit 27 */
-#define IXGBE_HLREG0_RXPADSTRIPEN 0x10000000 /* bit 28 */
-
-/* VMD_CTL bitmasks */
-#define IXGBE_VMD_CTL_VMDQ_EN 0x00000001
-#define IXGBE_VMD_CTL_VMDQ_FILTER 0x00000002
-
-/* VT_CTL bitmasks */
-#define IXGBE_VT_CTL_DIS_DEFPL 0x20000000 /* disable default pool */
-#define IXGBE_VT_CTL_REPLEN 0x40000000 /* replication enabled */
-#define IXGBE_VT_CTL_VT_ENABLE 0x00000001 /* Enable VT Mode */
-#define IXGBE_VT_CTL_POOL_SHIFT 7
-#define IXGBE_VT_CTL_POOL_MASK (0x3F << IXGBE_VT_CTL_POOL_SHIFT)
-
-/* VMOLR bitmasks */
-#define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */
-#define IXGBE_VMOLR_ROMPE 0x02000000 /* accept packets in MTA tbl */
-#define IXGBE_VMOLR_ROPE 0x04000000 /* accept packets in UC tbl */
-#define IXGBE_VMOLR_BAM 0x08000000 /* accept broadcast packets */
-#define IXGBE_VMOLR_MPE 0x10000000 /* multicast promiscuous */
-
-/* VFRE bitmask */
-#define IXGBE_VFRE_ENABLE_ALL 0xFFFFFFFF
-
-#define IXGBE_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */
-
-/* RDHMPN and TDHMPN bitmasks */
-#define IXGBE_RDHMPN_RDICADDR 0x007FF800
-#define IXGBE_RDHMPN_RDICRDREQ 0x00800000
-#define IXGBE_RDHMPN_RDICADDR_SHIFT 11
-#define IXGBE_TDHMPN_TDICADDR 0x003FF800
-#define IXGBE_TDHMPN_TDICRDREQ 0x00800000
-#define IXGBE_TDHMPN_TDICADDR_SHIFT 11
-
-#define IXGBE_RDMAM_MEM_SEL_SHIFT 13
-#define IXGBE_RDMAM_DWORD_SHIFT 9
-#define IXGBE_RDMAM_DESC_COMP_FIFO 1
-#define IXGBE_RDMAM_DFC_CMD_FIFO 2
-#define IXGBE_RDMAM_RSC_HEADER_ADDR 3
-#define IXGBE_RDMAM_TCN_STATUS_RAM 4
-#define IXGBE_RDMAM_WB_COLL_FIFO 5
-#define IXGBE_RDMAM_QSC_CNT_RAM 6
-#define IXGBE_RDMAM_QSC_FCOE_RAM 7
-#define IXGBE_RDMAM_QSC_QUEUE_CNT 8
-#define IXGBE_RDMAM_QSC_QUEUE_RAM 0xA
-#define IXGBE_RDMAM_QSC_RSC_RAM 0xB
-#define IXGBE_RDMAM_DESC_COM_FIFO_RANGE 135
-#define IXGBE_RDMAM_DESC_COM_FIFO_COUNT 4
-#define IXGBE_RDMAM_DFC_CMD_FIFO_RANGE 48
-#define IXGBE_RDMAM_DFC_CMD_FIFO_COUNT 7
-#define IXGBE_RDMAM_RSC_HEADER_ADDR_RANGE 32
-#define IXGBE_RDMAM_RSC_HEADER_ADDR_COUNT 4
-#define IXGBE_RDMAM_TCN_STATUS_RAM_RANGE 256
-#define IXGBE_RDMAM_TCN_STATUS_RAM_COUNT 9
-#define IXGBE_RDMAM_WB_COLL_FIFO_RANGE 8
-#define IXGBE_RDMAM_WB_COLL_FIFO_COUNT 4
-#define IXGBE_RDMAM_QSC_CNT_RAM_RANGE 64
-#define IXGBE_RDMAM_QSC_CNT_RAM_COUNT 4
-#define IXGBE_RDMAM_QSC_FCOE_RAM_RANGE 512
-#define IXGBE_RDMAM_QSC_FCOE_RAM_COUNT 5
-#define IXGBE_RDMAM_QSC_QUEUE_CNT_RANGE 32
-#define IXGBE_RDMAM_QSC_QUEUE_CNT_COUNT 4
-#define IXGBE_RDMAM_QSC_QUEUE_RAM_RANGE 128
-#define IXGBE_RDMAM_QSC_QUEUE_RAM_COUNT 8
-#define IXGBE_RDMAM_QSC_RSC_RAM_RANGE 32
-#define IXGBE_RDMAM_QSC_RSC_RAM_COUNT 8
-
-#define IXGBE_TXDESCIC_READY 0x80000000
-
-/* Receive Checksum Control */
-#define IXGBE_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
-#define IXGBE_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
-
-/* FCRTL Bit Masks */
-#define IXGBE_FCRTL_XONE 0x80000000 /* XON enable */
-#define IXGBE_FCRTH_FCEN 0x80000000 /* Packet buffer fc enable */
-
-/* PAP bit masks*/
-#define IXGBE_PAP_TXPAUSECNT_MASK 0x0000FFFF /* Pause counter mask */
-
-/* RMCS Bit Masks */
-#define IXGBE_RMCS_RRM 0x00000002 /* Rx Recycle Mode enable */
-/* Receive Arbitration Control: 0 Round Robin, 1 DFP */
-#define IXGBE_RMCS_RAC 0x00000004
-/* Deficit Fixed Prio ena */
-#define IXGBE_RMCS_DFP IXGBE_RMCS_RAC
-#define IXGBE_RMCS_TFCE_802_3X 0x00000008 /* Tx Priority FC ena */
-#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority FC ena */
-#define IXGBE_RMCS_ARBDIS 0x00000040 /* Arbitration disable bit */
-
-/* FCCFG Bit Masks */
-#define IXGBE_FCCFG_TFCE_802_3X 0x00000008 /* Tx link FC enable */
-#define IXGBE_FCCFG_TFCE_PRIORITY 0x00000010 /* Tx priority FC enable */
-
-/* Interrupt register bitmasks */
-
-/* Extended Interrupt Cause Read */
-#define IXGBE_EICR_RTX_QUEUE 0x0000FFFF /* RTx Queue Interrupt */
-#define IXGBE_EICR_FLOW_DIR 0x00010000 /* FDir Exception */
-#define IXGBE_EICR_RX_MISS 0x00020000 /* Packet Buffer Overrun */
-#define IXGBE_EICR_PCI 0x00040000 /* PCI Exception */
-#define IXGBE_EICR_MAILBOX 0x00080000 /* VF to PF Mailbox Interrupt */
-#define IXGBE_EICR_LSC 0x00100000 /* Link Status Change */
-#define IXGBE_EICR_LINKSEC 0x00200000 /* PN Threshold */
-#define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */
-#define IXGBE_EICR_TS 0x00800000 /* Thermal Sensor Event */
-#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */
-#define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */
-#define IXGBE_EICR_GPI_SDP2 0x04000000 /* Gen Purpose Interrupt on SDP2 */
-#define IXGBE_EICR_ECC 0x10000000 /* ECC Error */
-#define IXGBE_EICR_PBUR 0x10000000 /* Packet Buffer Handler Error */
-#define IXGBE_EICR_DHER 0x20000000 /* Descriptor Handler Error */
-#define IXGBE_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
-#define IXGBE_EICR_OTHER 0x80000000 /* Interrupt Cause Active */
-
-/* Extended Interrupt Cause Set */
-#define IXGBE_EICS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
-#define IXGBE_EICS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */
-#define IXGBE_EICS_RX_MISS IXGBE_EICR_RX_MISS /* Pkt Buffer Overrun */
-#define IXGBE_EICS_PCI IXGBE_EICR_PCI /* PCI Exception */
-#define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
-#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */
-#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
-#define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
-#define IXGBE_EICS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
-#define IXGBE_EICS_ECC IXGBE_EICR_ECC /* ECC Error */
-#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
-#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */
-#define IXGBE_EICS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
-#define IXGBE_EICS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */
-
-/* Extended Interrupt Mask Set */
-#define IXGBE_EIMS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
-#define IXGBE_EIMS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */
-#define IXGBE_EIMS_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */
-#define IXGBE_EIMS_PCI IXGBE_EICR_PCI /* PCI Exception */
-#define IXGBE_EIMS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
-#define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */
-#define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EIMS_TS IXGBE_EICR_TS /* Thermal Sensor Event */
-#define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
-#define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
-#define IXGBE_EIMS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
-#define IXGBE_EIMS_ECC IXGBE_EICR_ECC /* ECC Error */
-#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
-#define IXGBE_EIMS_DHER IXGBE_EICR_DHER /* Descr Handler Error */
-#define IXGBE_EIMS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
-#define IXGBE_EIMS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */
-
-/* Extended Interrupt Mask Clear */
-#define IXGBE_EIMC_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
-#define IXGBE_EIMC_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */
-#define IXGBE_EIMC_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */
-#define IXGBE_EIMC_PCI IXGBE_EICR_PCI /* PCI Exception */
-#define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
-#define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */
-#define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
-#define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
-#define IXGBE_EIMC_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
-#define IXGBE_EIMC_ECC IXGBE_EICR_ECC /* ECC Error */
-#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
-#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Err */
-#define IXGBE_EIMC_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
-#define IXGBE_EIMC_OTHER IXGBE_EICR_OTHER /* INT Cause Active */
-
-#define IXGBE_EIMS_ENABLE_MASK ( \
- IXGBE_EIMS_RTX_QUEUE | \
- IXGBE_EIMS_LSC | \
- IXGBE_EIMS_TCP_TIMER | \
- IXGBE_EIMS_OTHER)
-
-/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
-#define IXGBE_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */
-#define IXGBE_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */
-#define IXGBE_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
-#define IXGBE_IMIREXT_CTRL_URG 0x00002000 /* Check URG bit in header */
-#define IXGBE_IMIREXT_CTRL_ACK 0x00004000 /* Check ACK bit in header */
-#define IXGBE_IMIREXT_CTRL_PSH 0x00008000 /* Check PSH bit in header */
-#define IXGBE_IMIREXT_CTRL_RST 0x00010000 /* Check RST bit in header */
-#define IXGBE_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */
-#define IXGBE_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */
-#define IXGBE_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of control bits */
-#define IXGBE_IMIR_SIZE_BP_82599 0x00001000 /* Packet size bypass */
-#define IXGBE_IMIR_CTRL_URG_82599 0x00002000 /* Check URG bit in header */
-#define IXGBE_IMIR_CTRL_ACK_82599 0x00004000 /* Check ACK bit in header */
-#define IXGBE_IMIR_CTRL_PSH_82599 0x00008000 /* Check PSH bit in header */
-#define IXGBE_IMIR_CTRL_RST_82599 0x00010000 /* Check RST bit in header */
-#define IXGBE_IMIR_CTRL_SYN_82599 0x00020000 /* Check SYN bit in header */
-#define IXGBE_IMIR_CTRL_FIN_82599 0x00040000 /* Check FIN bit in header */
-#define IXGBE_IMIR_CTRL_BP_82599 0x00080000 /* Bypass chk of ctrl bits */
-#define IXGBE_IMIR_LLI_EN_82599 0x00100000 /* Enables low latency Int */
-#define IXGBE_IMIR_RX_QUEUE_MASK_82599 0x0000007F /* Rx Queue Mask */
-#define IXGBE_IMIR_RX_QUEUE_SHIFT_82599 21 /* Rx Queue Shift */
-#define IXGBE_IMIRVP_PRIORITY_MASK 0x00000007 /* VLAN priority mask */
-#define IXGBE_IMIRVP_PRIORITY_EN 0x00000008 /* VLAN priority enable */
-
-#define IXGBE_MAX_FTQF_FILTERS 128
-#define IXGBE_FTQF_PROTOCOL_MASK 0x00000003
-#define IXGBE_FTQF_PROTOCOL_TCP 0x00000000
-#define IXGBE_FTQF_PROTOCOL_UDP 0x00000001
-#define IXGBE_FTQF_PROTOCOL_SCTP 2
-#define IXGBE_FTQF_PRIORITY_MASK 0x00000007
-#define IXGBE_FTQF_PRIORITY_SHIFT 2
-#define IXGBE_FTQF_POOL_MASK 0x0000003F
-#define IXGBE_FTQF_POOL_SHIFT 8
-#define IXGBE_FTQF_5TUPLE_MASK_MASK 0x0000001F
-#define IXGBE_FTQF_5TUPLE_MASK_SHIFT 25
-#define IXGBE_FTQF_SOURCE_ADDR_MASK 0x1E
-#define IXGBE_FTQF_DEST_ADDR_MASK 0x1D
-#define IXGBE_FTQF_SOURCE_PORT_MASK 0x1B
-#define IXGBE_FTQF_DEST_PORT_MASK 0x17
-#define IXGBE_FTQF_PROTOCOL_COMP_MASK 0x0F
-#define IXGBE_FTQF_POOL_MASK_EN 0x40000000
-#define IXGBE_FTQF_QUEUE_ENABLE 0x80000000
-
-/* Interrupt clear mask */
-#define IXGBE_IRQ_CLEAR_MASK 0xFFFFFFFF
-
-/* Interrupt Vector Allocation Registers */
-#define IXGBE_IVAR_REG_NUM 25
-#define IXGBE_IVAR_REG_NUM_82599 64
-#define IXGBE_IVAR_TXRX_ENTRY 96
-#define IXGBE_IVAR_RX_ENTRY 64
-#define IXGBE_IVAR_RX_QUEUE(_i) (0 + (_i))
-#define IXGBE_IVAR_TX_QUEUE(_i) (64 + (_i))
-#define IXGBE_IVAR_TX_ENTRY 32
-
-#define IXGBE_IVAR_TCP_TIMER_INDEX 96 /* 0 based index */
-#define IXGBE_IVAR_OTHER_CAUSES_INDEX 97 /* 0 based index */
-
-#define IXGBE_MSIX_VECTOR(_i) (0 + (_i))
-
-#define IXGBE_IVAR_ALLOC_VAL 0x80 /* Interrupt Allocation valid */
-
-/* ETYPE Queue Filter/Select Bit Masks */
-#define IXGBE_MAX_ETQF_FILTERS 8
-#define IXGBE_ETQF_FCOE 0x08000000 /* bit 27 */
-#define IXGBE_ETQF_BCN 0x10000000 /* bit 28 */
-#define IXGBE_ETQF_1588 0x40000000 /* bit 30 */
-#define IXGBE_ETQF_FILTER_EN 0x80000000 /* bit 31 */
-#define IXGBE_ETQF_POOL_ENABLE (1 << 26) /* bit 26 */
-
-#define IXGBE_ETQS_RX_QUEUE 0x007F0000 /* bits 22:16 */
-#define IXGBE_ETQS_RX_QUEUE_SHIFT 16
-#define IXGBE_ETQS_LLI 0x20000000 /* bit 29 */
-#define IXGBE_ETQS_QUEUE_EN 0x80000000 /* bit 31 */
-
-/*
- * ETQF filter list: one static filter per filter consumer. This is
- * to avoid filter collisions later. Add new filters
- * here!!
- *
- * Current filters:
- * EAPOL 802.1x (0x888e): Filter 0
- * FCoE (0x8906): Filter 2
- * 1588 (0x88f7): Filter 3
- * FIP (0x8914): Filter 4
- */
-#define IXGBE_ETQF_FILTER_EAPOL 0
-#define IXGBE_ETQF_FILTER_FCOE 2
-#define IXGBE_ETQF_FILTER_1588 3
-#define IXGBE_ETQF_FILTER_FIP 4
-/* VLAN Control Bit Masks */
-#define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */
-#define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */
-#define IXGBE_VLNCTRL_CFIEN 0x20000000 /* bit 29 */
-#define IXGBE_VLNCTRL_VFE 0x40000000 /* bit 30 */
-#define IXGBE_VLNCTRL_VME 0x80000000 /* bit 31 */
-
-/* VLAN pool filtering masks */
-#define IXGBE_VLVF_VIEN 0x80000000 /* filter is valid */
-#define IXGBE_VLVF_ENTRIES 64
-#define IXGBE_VLVF_VLANID_MASK 0x00000FFF
-/* Per VF Port VLAN insertion rules */
-#define IXGBE_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */
-#define IXGBE_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */
-
-#define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */
-
-/* STATUS Bit Masks */
-#define IXGBE_STATUS_LAN_ID 0x0000000C /* LAN ID */
-#define IXGBE_STATUS_LAN_ID_SHIFT 2 /* LAN ID Shift*/
-#define IXGBE_STATUS_GIO 0x00080000 /* GIO Master Ena Status */
-
-#define IXGBE_STATUS_LAN_ID_0 0x00000000 /* LAN ID 0 */
-#define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */
-
-/* ESDP Bit Masks */
-#define IXGBE_ESDP_SDP0 0x00000001 /* SDP0 Data Value */
-#define IXGBE_ESDP_SDP1 0x00000002 /* SDP1 Data Value */
-#define IXGBE_ESDP_SDP2 0x00000004 /* SDP2 Data Value */
-#define IXGBE_ESDP_SDP3 0x00000008 /* SDP3 Data Value */
-#define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */
-#define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */
-#define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */
-#define IXGBE_ESDP_SDP0_DIR 0x00000100 /* SDP0 IO direction */
-#define IXGBE_ESDP_SDP1_DIR 0x00000200 /* SDP1 IO direction */
-#define IXGBE_ESDP_SDP4_DIR 0x00001000 /* SDP4 IO direction */
-#define IXGBE_ESDP_SDP5_DIR 0x00002000 /* SDP5 IO direction */
-#define IXGBE_ESDP_SDP0_NATIVE 0x00010000 /* SDP0 IO mode */
-#define IXGBE_ESDP_SDP1_NATIVE 0x00020000 /* SDP1 IO mode */
-
-
-/* LEDCTL Bit Masks */
-#define IXGBE_LED_IVRT_BASE 0x00000040
-#define IXGBE_LED_BLINK_BASE 0x00000080
-#define IXGBE_LED_MODE_MASK_BASE 0x0000000F
-#define IXGBE_LED_OFFSET(_base, _i) (_base << (8 * (_i)))
-#define IXGBE_LED_MODE_SHIFT(_i) (8*(_i))
-#define IXGBE_LED_IVRT(_i) IXGBE_LED_OFFSET(IXGBE_LED_IVRT_BASE, _i)
-#define IXGBE_LED_BLINK(_i) IXGBE_LED_OFFSET(IXGBE_LED_BLINK_BASE, _i)
-#define IXGBE_LED_MODE_MASK(_i) IXGBE_LED_OFFSET(IXGBE_LED_MODE_MASK_BASE, _i)
-
-/* LED modes */
-#define IXGBE_LED_LINK_UP 0x0
-#define IXGBE_LED_LINK_10G 0x1
-#define IXGBE_LED_MAC 0x2
-#define IXGBE_LED_FILTER 0x3
-#define IXGBE_LED_LINK_ACTIVE 0x4
-#define IXGBE_LED_LINK_1G 0x5
-#define IXGBE_LED_ON 0xE
-#define IXGBE_LED_OFF 0xF
-
-/* AUTOC Bit Masks */
-#define IXGBE_AUTOC_KX4_KX_SUPP_MASK 0xC0000000
-#define IXGBE_AUTOC_KX4_SUPP 0x80000000
-#define IXGBE_AUTOC_KX_SUPP 0x40000000
-#define IXGBE_AUTOC_PAUSE 0x30000000
-#define IXGBE_AUTOC_ASM_PAUSE 0x20000000
-#define IXGBE_AUTOC_SYM_PAUSE 0x10000000
-#define IXGBE_AUTOC_RF 0x08000000
-#define IXGBE_AUTOC_PD_TMR 0x06000000
-#define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000
-#define IXGBE_AUTOC_AN_RX_DRIFT 0x00800000
-#define IXGBE_AUTOC_AN_RX_ALIGN 0x007C0000
-#define IXGBE_AUTOC_FECA 0x00040000
-#define IXGBE_AUTOC_FECR 0x00020000
-#define IXGBE_AUTOC_KR_SUPP 0x00010000
-#define IXGBE_AUTOC_AN_RESTART 0x00001000
-#define IXGBE_AUTOC_FLU 0x00000001
-#define IXGBE_AUTOC_LMS_SHIFT 13
-#define IXGBE_AUTOC_LMS_10G_SERIAL (0x3 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_KX_KR (0x4 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_SGMII_1G_100M (0x5 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII (0x7 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_1G_AN (0x2 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_AN (0x4 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-
-#define IXGBE_AUTOC_1G_PMA_PMD_MASK 0x00000200
-#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9
-#define IXGBE_AUTOC_10G_PMA_PMD_MASK 0x00000180
-#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7
-#define IXGBE_AUTOC_10G_XAUI (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC_10G_KX4 (0x1 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC_10G_CX4 (0x2 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC_1G_BX (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC_1G_KX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC_1G_SFI (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC_1G_KX_BX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
-
-#define IXGBE_AUTOC2_UPPER_MASK 0xFFFF0000
-#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK 0x00030000
-#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT 16
-#define IXGBE_AUTOC2_10G_KR (0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
-
-#define IXGBE_MACC_FLU 0x00000001
-#define IXGBE_MACC_FSV_10G 0x00030000
-#define IXGBE_MACC_FS 0x00040000
-#define IXGBE_MAC_RX2TX_LPBK 0x00000002
-
-/* LINKS Bit Masks */
-#define IXGBE_LINKS_KX_AN_COMP 0x80000000
-#define IXGBE_LINKS_UP 0x40000000
-#define IXGBE_LINKS_SPEED 0x20000000
-#define IXGBE_LINKS_MODE 0x18000000
-#define IXGBE_LINKS_RX_MODE 0x06000000
-#define IXGBE_LINKS_TX_MODE 0x01800000
-#define IXGBE_LINKS_XGXS_EN 0x00400000
-#define IXGBE_LINKS_SGMII_EN 0x02000000
-#define IXGBE_LINKS_PCS_1G_EN 0x00200000
-#define IXGBE_LINKS_1G_AN_EN 0x00100000
-#define IXGBE_LINKS_KX_AN_IDLE 0x00080000
-#define IXGBE_LINKS_1G_SYNC 0x00040000
-#define IXGBE_LINKS_10G_ALIGN 0x00020000
-#define IXGBE_LINKS_10G_LANE_SYNC 0x00017000
-#define IXGBE_LINKS_TL_FAULT 0x00001000
-#define IXGBE_LINKS_SIGNAL 0x00000F00
-
-#define IXGBE_LINKS_SPEED_82599 0x30000000
-#define IXGBE_LINKS_SPEED_10G_82599 0x30000000
-#define IXGBE_LINKS_SPEED_1G_82599 0x20000000
-#define IXGBE_LINKS_SPEED_100_82599 0x10000000
-#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
-#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */
-
-#define IXGBE_LINKS2_AN_SUPPORTED 0x00000040
-
-/* PCS1GLSTA Bit Masks */
-#define IXGBE_PCS1GLSTA_LINK_OK 1
-#define IXGBE_PCS1GLSTA_SYNK_OK 0x10
-#define IXGBE_PCS1GLSTA_AN_COMPLETE 0x10000
-#define IXGBE_PCS1GLSTA_AN_PAGE_RX 0x20000
-#define IXGBE_PCS1GLSTA_AN_TIMED_OUT 0x40000
-#define IXGBE_PCS1GLSTA_AN_REMOTE_FAULT 0x80000
-#define IXGBE_PCS1GLSTA_AN_ERROR_RWS 0x100000
-
-#define IXGBE_PCS1GANA_SYM_PAUSE 0x80
-#define IXGBE_PCS1GANA_ASM_PAUSE 0x100
-
-/* PCS1GLCTL Bit Masks */
-#define IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN 0x00040000 /* PCS 1G autoneg to en */
-#define IXGBE_PCS1GLCTL_FLV_LINK_UP 1
-#define IXGBE_PCS1GLCTL_FORCE_LINK 0x20
-#define IXGBE_PCS1GLCTL_LOW_LINK_LATCH 0x40
-#define IXGBE_PCS1GLCTL_AN_ENABLE 0x10000
-#define IXGBE_PCS1GLCTL_AN_RESTART 0x20000
-
-/* ANLP1 Bit Masks */
-#define IXGBE_ANLP1_PAUSE 0x0C00
-#define IXGBE_ANLP1_SYM_PAUSE 0x0400
-#define IXGBE_ANLP1_ASM_PAUSE 0x0800
-#define IXGBE_ANLP1_AN_STATE_MASK 0x000f0000
-
-/* SW Semaphore Register bitmasks */
-#define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
-#define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
-#define IXGBE_SWSM_WMNG 0x00000004 /* Wake MNG Clock */
-#define IXGBE_SWFW_REGSMP 0x80000000 /* Register Semaphore bit 31 */
-
-/* SW_FW_SYNC/GSSR definitions */
-#define IXGBE_GSSR_EEP_SM 0x0001
-#define IXGBE_GSSR_PHY0_SM 0x0002
-#define IXGBE_GSSR_PHY1_SM 0x0004
-#define IXGBE_GSSR_MAC_CSR_SM 0x0008
-#define IXGBE_GSSR_FLASH_SM 0x0010
-#define IXGBE_GSSR_SW_MNG_SM 0x0400
-
-/* FW Status register bitmask */
-#define IXGBE_FWSTS_FWRI 0x00000200 /* Firmware Reset Indication */
-
-/* EEC Register */
-#define IXGBE_EEC_SK 0x00000001 /* EEPROM Clock */
-#define IXGBE_EEC_CS 0x00000002 /* EEPROM Chip Select */
-#define IXGBE_EEC_DI 0x00000004 /* EEPROM Data In */
-#define IXGBE_EEC_DO 0x00000008 /* EEPROM Data Out */
-#define IXGBE_EEC_FWE_MASK 0x00000030 /* FLASH Write Enable */
-#define IXGBE_EEC_FWE_DIS 0x00000010 /* Disable FLASH writes */
-#define IXGBE_EEC_FWE_EN 0x00000020 /* Enable FLASH writes */
-#define IXGBE_EEC_FWE_SHIFT 4
-#define IXGBE_EEC_REQ 0x00000040 /* EEPROM Access Request */
-#define IXGBE_EEC_GNT 0x00000080 /* EEPROM Access Grant */
-#define IXGBE_EEC_PRES 0x00000100 /* EEPROM Present */
-#define IXGBE_EEC_ARD 0x00000200 /* EEPROM Auto Read Done */
-#define IXGBE_EEC_FLUP 0x00800000 /* Flash update command */
-#define IXGBE_EEC_SEC1VAL 0x02000000 /* Sector 1 Valid */
-#define IXGBE_EEC_FLUDONE 0x04000000 /* Flash update done */
-/* EEPROM Addressing bits based on type (0-small, 1-large) */
-#define IXGBE_EEC_ADDR_SIZE 0x00000400
-#define IXGBE_EEC_SIZE 0x00007800 /* EEPROM Size */
-#define IXGBE_EERD_MAX_ADDR 0x00003FFF /* EERD alows 14 bits for addr. */
-
-#define IXGBE_EEC_SIZE_SHIFT 11
-#define IXGBE_EEPROM_WORD_SIZE_SHIFT 6
-#define IXGBE_EEPROM_OPCODE_BITS 8
-
-/* Part Number String Length */
-#define IXGBE_PBANUM_LENGTH 11
-
-/* Checksum and EEPROM pointers */
-#define IXGBE_PBANUM_PTR_GUARD 0xFAFA
-#define IXGBE_EEPROM_CHECKSUM 0x3F
-#define IXGBE_EEPROM_SUM 0xBABA
-#define IXGBE_PCIE_ANALOG_PTR 0x03
-#define IXGBE_ATLAS0_CONFIG_PTR 0x04
-#define IXGBE_PHY_PTR 0x04
-#define IXGBE_ATLAS1_CONFIG_PTR 0x05
-#define IXGBE_OPTION_ROM_PTR 0x05
-#define IXGBE_PCIE_GENERAL_PTR 0x06
-#define IXGBE_PCIE_CONFIG0_PTR 0x07
-#define IXGBE_PCIE_CONFIG1_PTR 0x08
-#define IXGBE_CORE0_PTR 0x09
-#define IXGBE_CORE1_PTR 0x0A
-#define IXGBE_MAC0_PTR 0x0B
-#define IXGBE_MAC1_PTR 0x0C
-#define IXGBE_CSR0_CONFIG_PTR 0x0D
-#define IXGBE_CSR1_CONFIG_PTR 0x0E
-#define IXGBE_FW_PTR 0x0F
-#define IXGBE_PBANUM0_PTR 0x15
-#define IXGBE_PBANUM1_PTR 0x16
-#define IXGBE_ALT_MAC_ADDR_PTR 0x37
-#define IXGBE_FREE_SPACE_PTR 0X3E
-
-/* External Thermal Sensor Config */
-#define IXGBE_ETS_CFG 0x26
-#define IXGBE_ETS_LTHRES_DELTA_MASK 0x07C0
-#define IXGBE_ETS_LTHRES_DELTA_SHIFT 6
-#define IXGBE_ETS_TYPE_MASK 0x0038
-#define IXGBE_ETS_TYPE_SHIFT 3
-#define IXGBE_ETS_TYPE_EMC 0x000
-#define IXGBE_ETS_NUM_SENSORS_MASK 0x0007
-#define IXGBE_ETS_DATA_LOC_MASK 0x3C00
-#define IXGBE_ETS_DATA_LOC_SHIFT 10
-#define IXGBE_ETS_DATA_INDEX_MASK 0x0300
-#define IXGBE_ETS_DATA_INDEX_SHIFT 8
-#define IXGBE_ETS_DATA_HTHRESH_MASK 0x00FF
-
-#define IXGBE_SAN_MAC_ADDR_PTR 0x28
-#define IXGBE_DEVICE_CAPS 0x2C
-#define IXGBE_SERIAL_NUMBER_MAC_ADDR 0x11
-#define IXGBE_PCIE_MSIX_82599_CAPS 0x72
-#define IXGBE_MAX_MSIX_VECTORS_82599 0x40
-#define IXGBE_PCIE_MSIX_82598_CAPS 0x62
-#define IXGBE_MAX_MSIX_VECTORS_82598 0x13
-
-/* MSI-X capability fields masks */
-#define IXGBE_PCIE_MSIX_TBL_SZ_MASK 0x7FF
-
-/* Legacy EEPROM word offsets */
-#define IXGBE_ISCSI_BOOT_CAPS 0x0033
-#define IXGBE_ISCSI_SETUP_PORT_0 0x0030
-#define IXGBE_ISCSI_SETUP_PORT_1 0x0034
-
-/* EEPROM Commands - SPI */
-#define IXGBE_EEPROM_MAX_RETRY_SPI 5000 /* Max wait 5ms for RDY signal */
-#define IXGBE_EEPROM_STATUS_RDY_SPI 0x01
-#define IXGBE_EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */
-#define IXGBE_EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */
-#define IXGBE_EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = addr bit-8 */
-#define IXGBE_EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Ena latch */
-/* EEPROM reset Write Enable latch */
-#define IXGBE_EEPROM_WRDI_OPCODE_SPI 0x04
-#define IXGBE_EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status reg */
-#define IXGBE_EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status reg */
-#define IXGBE_EEPROM_ERASE4K_OPCODE_SPI 0x20 /* EEPROM ERASE 4KB */
-#define IXGBE_EEPROM_ERASE64K_OPCODE_SPI 0xD8 /* EEPROM ERASE 64KB */
-#define IXGBE_EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */
-
-/* EEPROM Read Register */
-#define IXGBE_EEPROM_RW_REG_DATA 16 /* data offset in EEPROM read reg */
-#define IXGBE_EEPROM_RW_REG_DONE 2 /* Offset to READ done bit */
-#define IXGBE_EEPROM_RW_REG_START 1 /* First bit to start operation */
-#define IXGBE_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
-#define IXGBE_NVM_POLL_WRITE 1 /* Flag for polling for wr complete */
-#define IXGBE_NVM_POLL_READ 0 /* Flag for polling for rd complete */
-
-#define IXGBE_ETH_LENGTH_OF_ADDRESS 6
-
-#define IXGBE_EEPROM_PAGE_SIZE_MAX 128
-#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 512 /* words rd in burst */
-#define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* words wr in burst */
-
-#ifndef IXGBE_EEPROM_GRANT_ATTEMPTS
-#define IXGBE_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM attempts to gain grant */
-#endif
-
-#ifndef IXGBE_EERD_EEWR_ATTEMPTS
-/* Number of 5 microseconds we wait for EERD read and
- * EERW write to complete */
-#define IXGBE_EERD_EEWR_ATTEMPTS 100000
-#endif
-
-#ifndef IXGBE_FLUDONE_ATTEMPTS
-/* # attempts we wait for flush update to complete */
-#define IXGBE_FLUDONE_ATTEMPTS 20000
-#endif
-
-#define IXGBE_PCIE_CTRL2 0x5 /* PCIe Control 2 Offset */
-#define IXGBE_PCIE_CTRL2_DUMMY_ENABLE 0x8 /* Dummy Function Enable */
-#define IXGBE_PCIE_CTRL2_LAN_DISABLE 0x2 /* LAN PCI Disable */
-#define IXGBE_PCIE_CTRL2_DISABLE_SELECT 0x1 /* LAN Disable Select */
-
-#define IXGBE_SAN_MAC_ADDR_PORT0_OFFSET 0x0
-#define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3
-#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1
-#define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2
-#define IXGBE_FW_LESM_PARAMETERS_PTR 0x2
-#define IXGBE_FW_LESM_STATE_1 0x1
-#define IXGBE_FW_LESM_STATE_ENABLED 0x8000 /* LESM Enable bit */
-#define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4
-#define IXGBE_FW_PATCH_VERSION_4 0x7
-#define IXGBE_FCOE_IBA_CAPS_BLK_PTR 0x33 /* iSCSI/FCOE block */
-#define IXGBE_FCOE_IBA_CAPS_FCOE 0x20 /* FCOE flags */
-#define IXGBE_ISCSI_FCOE_BLK_PTR 0x17 /* iSCSI/FCOE block */
-#define IXGBE_ISCSI_FCOE_FLAGS_OFFSET 0x0 /* FCOE flags */
-#define IXGBE_ISCSI_FCOE_FLAGS_ENABLE 0x1 /* FCOE flags enable bit */
-#define IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR 0x27 /* Alt. SAN MAC block */
-#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET 0x0 /* Alt SAN MAC capability */
-#define IXGBE_ALT_SAN_MAC_ADDR_PORT0_OFFSET 0x1 /* Alt SAN MAC 0 offset */
-#define IXGBE_ALT_SAN_MAC_ADDR_PORT1_OFFSET 0x4 /* Alt SAN MAC 1 offset */
-#define IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET 0x7 /* Alt WWNN prefix offset */
-#define IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET 0x8 /* Alt WWPN prefix offset */
-#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_SANMAC 0x0 /* Alt SAN MAC exists */
-#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN 0x1 /* Alt WWN base exists */
-
-#define IXGBE_DEVICE_CAPS_WOL_PORT0_1 0x4 /* WoL supported on ports 0 & 1 */
-#define IXGBE_DEVICE_CAPS_WOL_PORT0 0x8 /* WoL supported on port 0 */
-#define IXGBE_DEVICE_CAPS_WOL_MASK 0xC /* Mask for WoL capabilities */
-
-/* PCI Bus Info */
-#define IXGBE_PCI_DEVICE_STATUS 0xAA
-#define IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING 0x0020
-#define IXGBE_PCI_LINK_STATUS 0xB2
-#define IXGBE_PCI_DEVICE_CONTROL2 0xC8
-#define IXGBE_PCI_LINK_WIDTH 0x3F0
-#define IXGBE_PCI_LINK_WIDTH_1 0x10
-#define IXGBE_PCI_LINK_WIDTH_2 0x20
-#define IXGBE_PCI_LINK_WIDTH_4 0x40
-#define IXGBE_PCI_LINK_WIDTH_8 0x80
-#define IXGBE_PCI_LINK_SPEED 0xF
-#define IXGBE_PCI_LINK_SPEED_2500 0x1
-#define IXGBE_PCI_LINK_SPEED_5000 0x2
-#define IXGBE_PCI_LINK_SPEED_8000 0x3
-#define IXGBE_PCI_HEADER_TYPE_REGISTER 0x0E
-#define IXGBE_PCI_HEADER_TYPE_MULTIFUNC 0x80
-#define IXGBE_PCI_DEVICE_CONTROL2_16ms 0x0005
-
-/* Number of 100 microseconds we wait for PCI Express master disable */
-#define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800
-
-/* Check whether address is multicast. This is little-endian specific check.*/
-#define IXGBE_IS_MULTICAST(Address) \
- (bool)(((u8 *)(Address))[0] & ((u8)0x01))
-
-/* Check whether an address is broadcast. */
-#define IXGBE_IS_BROADCAST(Address) \
- ((((u8 *)(Address))[0] == ((u8)0xff)) && \
- (((u8 *)(Address))[1] == ((u8)0xff)))
-
-/* RAH */
-#define IXGBE_RAH_VIND_MASK 0x003C0000
-#define IXGBE_RAH_VIND_SHIFT 18
-#define IXGBE_RAH_AV 0x80000000
-#define IXGBE_CLEAR_VMDQ_ALL 0xFFFFFFFF
-
-/* Header split receive */
-#define IXGBE_RFCTL_ISCSI_DIS 0x00000001
-#define IXGBE_RFCTL_ISCSI_DWC_MASK 0x0000003E
-#define IXGBE_RFCTL_ISCSI_DWC_SHIFT 1
-#define IXGBE_RFCTL_RSC_DIS 0x00000010
-#define IXGBE_RFCTL_NFSW_DIS 0x00000040
-#define IXGBE_RFCTL_NFSR_DIS 0x00000080
-#define IXGBE_RFCTL_NFS_VER_MASK 0x00000300
-#define IXGBE_RFCTL_NFS_VER_SHIFT 8
-#define IXGBE_RFCTL_NFS_VER_2 0
-#define IXGBE_RFCTL_NFS_VER_3 1
-#define IXGBE_RFCTL_NFS_VER_4 2
-#define IXGBE_RFCTL_IPV6_DIS 0x00000400
-#define IXGBE_RFCTL_IPV6_XSUM_DIS 0x00000800
-#define IXGBE_RFCTL_IPFRSP_DIS 0x00004000
-#define IXGBE_RFCTL_IPV6_EX_DIS 0x00010000
-#define IXGBE_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
-
-/* Transmit Config masks */
-#define IXGBE_TXDCTL_ENABLE 0x02000000 /* Ena specific Tx Queue */
-#define IXGBE_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. wr-bk flushing */
-#define IXGBE_TXDCTL_WTHRESH_SHIFT 16 /* shift to WTHRESH bits */
-/* Enable short packet padding to 64 bytes */
-#define IXGBE_TX_PAD_ENABLE 0x00000400
-#define IXGBE_JUMBO_FRAME_ENABLE 0x00000004 /* Allow jumbo frames */
-/* This allows for 16K packets + 4k for vlan */
-#define IXGBE_MAX_FRAME_SZ 0x40040000
-
-#define IXGBE_TDWBAL_HEAD_WB_ENABLE 0x1 /* Tx head write-back enable */
-#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2 /* Tx seq# write-back enable */
-
-/* Receive Config masks */
-#define IXGBE_RXCTRL_RXEN 0x00000001 /* Enable Receiver */
-#define IXGBE_RXCTRL_DMBYPS 0x00000002 /* Desc Monitor Bypass */
-#define IXGBE_RXDCTL_ENABLE 0x02000000 /* Ena specific Rx Queue */
-#define IXGBE_RXDCTL_SWFLSH 0x04000000 /* Rx Desc wr-bk flushing */
-#define IXGBE_RXDCTL_RLPMLMASK 0x00003FFF /* X540 supported only */
-#define IXGBE_RXDCTL_RLPML_EN 0x00008000
-#define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */
-
-#define IXGBE_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
-#define IXGBE_TSYNCTXCTL_ENABLED 0x00000010 /* Tx timestamping enabled */
-
-#define IXGBE_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
-#define IXGBE_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
-#define IXGBE_TSYNCRXCTL_TYPE_L2_V2 0x00
-#define IXGBE_TSYNCRXCTL_TYPE_L4_V1 0x02
-#define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
-#define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
-#define IXGBE_TSYNCRXCTL_ENABLED 0x00000010 /* Rx Timestamping enabled */
-
-#define IXGBE_RXMTRL_V1_CTRLT_MASK 0x000000FF
-#define IXGBE_RXMTRL_V1_SYNC_MSG 0x00
-#define IXGBE_RXMTRL_V1_DELAY_REQ_MSG 0x01
-#define IXGBE_RXMTRL_V1_FOLLOWUP_MSG 0x02
-#define IXGBE_RXMTRL_V1_DELAY_RESP_MSG 0x03
-#define IXGBE_RXMTRL_V1_MGMT_MSG 0x04
-
-#define IXGBE_RXMTRL_V2_MSGID_MASK 0x0000FF00
-#define IXGBE_RXMTRL_V2_SYNC_MSG 0x0000
-#define IXGBE_RXMTRL_V2_DELAY_REQ_MSG 0x0100
-#define IXGBE_RXMTRL_V2_PDELAY_REQ_MSG 0x0200
-#define IXGBE_RXMTRL_V2_PDELAY_RESP_MSG 0x0300
-#define IXGBE_RXMTRL_V2_FOLLOWUP_MSG 0x0800
-#define IXGBE_RXMTRL_V2_DELAY_RESP_MSG 0x0900
-#define IXGBE_RXMTRL_V2_PDELAY_FOLLOWUP_MSG 0x0A00
-#define IXGBE_RXMTRL_V2_ANNOUNCE_MSG 0x0B00
-#define IXGBE_RXMTRL_V2_SIGNALLING_MSG 0x0C00
-#define IXGBE_RXMTRL_V2_MGMT_MSG 0x0D00
-
-#define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
-#define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/
-#define IXGBE_FCTRL_UPE 0x00000200 /* Unicast Promiscuous Ena */
-#define IXGBE_FCTRL_BAM 0x00000400 /* Broadcast Accept Mode */
-#define IXGBE_FCTRL_PMCF 0x00001000 /* Pass MAC Control Frames */
-#define IXGBE_FCTRL_DPF 0x00002000 /* Discard Pause Frame */
-/* Receive Priority Flow Control Enable */
-#define IXGBE_FCTRL_RPFCE 0x00004000
-#define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */
-#define IXGBE_MFLCN_PMCF 0x00000001 /* Pass MAC Control Frames */
-#define IXGBE_MFLCN_DPF 0x00000002 /* Discard Pause Frame */
-#define IXGBE_MFLCN_RPFCE 0x00000004 /* Receive Priority FC Enable */
-#define IXGBE_MFLCN_RFCE 0x00000008 /* Receive FC Enable */
-#define IXGBE_MFLCN_RPFCE_MASK 0x00000FF4 /* Rx Priority FC bitmap mask */
-#define IXGBE_MFLCN_RPFCE_SHIFT 4 /* Rx Priority FC bitmap shift */
-
-/* Multiple Receive Queue Control */
-#define IXGBE_MRQC_RSSEN 0x00000001 /* RSS Enable */
-#define IXGBE_MRQC_MRQE_MASK 0xF /* Bits 3:0 */
-#define IXGBE_MRQC_RT8TCEN 0x00000002 /* 8 TC no RSS */
-#define IXGBE_MRQC_RT4TCEN 0x00000003 /* 4 TC no RSS */
-#define IXGBE_MRQC_RTRSS8TCEN 0x00000004 /* 8 TC w/ RSS */
-#define IXGBE_MRQC_RTRSS4TCEN 0x00000005 /* 4 TC w/ RSS */
-#define IXGBE_MRQC_VMDQEN 0x00000008 /* VMDq2 64 pools no RSS */
-#define IXGBE_MRQC_VMDQRSS32EN 0x0000000A /* VMDq2 32 pools w/ RSS */
-#define IXGBE_MRQC_VMDQRSS64EN 0x0000000B /* VMDq2 64 pools w/ RSS */
-#define IXGBE_MRQC_VMDQRT8TCEN 0x0000000C /* VMDq2/RT 16 pool 8 TC */
-#define IXGBE_MRQC_VMDQRT4TCEN 0x0000000D /* VMDq2/RT 32 pool 4 TC */
-#define IXGBE_MRQC_RSS_FIELD_MASK 0xFFFF0000
-#define IXGBE_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
-#define IXGBE_MRQC_RSS_FIELD_IPV4 0x00020000
-#define IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP 0x00040000
-#define IXGBE_MRQC_RSS_FIELD_IPV6_EX 0x00080000
-#define IXGBE_MRQC_RSS_FIELD_IPV6 0x00100000
-#define IXGBE_MRQC_RSS_FIELD_IPV6_TCP 0x00200000
-#define IXGBE_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
-#define IXGBE_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
-#define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000
-#define IXGBE_MRQC_L3L4TXSWEN 0x00008000
-
-/* Queue Drop Enable */
-#define IXGBE_QDE_ENABLE 0x00000001
-#define IXGBE_QDE_IDX_MASK 0x00007F00
-#define IXGBE_QDE_IDX_SHIFT 8
-#define IXGBE_QDE_WRITE 0x00010000
-#define IXGBE_QDE_READ 0x00020000
-
-#define IXGBE_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
-#define IXGBE_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
-#define IXGBE_TXD_CMD_EOP 0x01000000 /* End of Packet */
-#define IXGBE_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
-#define IXGBE_TXD_CMD_IC 0x04000000 /* Insert Checksum */
-#define IXGBE_TXD_CMD_RS 0x08000000 /* Report Status */
-#define IXGBE_TXD_CMD_DEXT 0x20000000 /* Desc extension (0 = legacy) */
-#define IXGBE_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
-#define IXGBE_TXD_STAT_DD 0x00000001 /* Descriptor Done */
-
-#define IXGBE_RXDADV_IPSEC_STATUS_SECP 0x00020000
-#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL 0x08000000
-#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000
-#define IXGBE_RXDADV_IPSEC_ERROR_AUTH_FAILED 0x18000000
-#define IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK 0x18000000
-/* Multiple Transmit Queue Command Register */
-#define IXGBE_MTQC_RT_ENA 0x1 /* DCB Enable */
-#define IXGBE_MTQC_VT_ENA 0x2 /* VMDQ2 Enable */
-#define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */
-#define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */
-#define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */
-#define IXGBE_MTQC_4TC_4TQ 0x8 /* 4 TC if RT_ENA and VT_ENA */
-#define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
-
-/* Receive Descriptor bit definitions */
-#define IXGBE_RXD_STAT_DD 0x01 /* Descriptor Done */
-#define IXGBE_RXD_STAT_EOP 0x02 /* End of Packet */
-#define IXGBE_RXD_STAT_FLM 0x04 /* FDir Match */
-#define IXGBE_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define IXGBE_RXDADV_NEXTP_MASK 0x000FFFF0 /* Next Descriptor Index */
-#define IXGBE_RXDADV_NEXTP_SHIFT 0x00000004
-#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
-#define IXGBE_RXD_STAT_L4CS 0x20 /* L4 xsum calculated */
-#define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
-#define IXGBE_RXD_STAT_PIF 0x80 /* passed in-exact filter */
-#define IXGBE_RXD_STAT_CRCV 0x100 /* Speculative CRC Valid */
-#define IXGBE_RXD_STAT_VEXT 0x200 /* 1st VLAN found */
-#define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
-#define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
-#define IXGBE_RXD_STAT_LLINT 0x800 /* Pkt caused Low Latency Interrupt */
-#define IXGBE_RXD_STAT_TS 0x10000 /* Time Stamp */
-#define IXGBE_RXD_STAT_SECP 0x20000 /* Security Processing */
-#define IXGBE_RXD_STAT_LB 0x40000 /* Loopback Status */
-#define IXGBE_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
-#define IXGBE_RXD_ERR_CE 0x01 /* CRC Error */
-#define IXGBE_RXD_ERR_LE 0x02 /* Length Error */
-#define IXGBE_RXD_ERR_PE 0x08 /* Packet Error */
-#define IXGBE_RXD_ERR_OSE 0x10 /* Oversize Error */
-#define IXGBE_RXD_ERR_USE 0x20 /* Undersize Error */
-#define IXGBE_RXD_ERR_TCPE 0x40 /* TCP/UDP Checksum Error */
-#define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */
-#define IXGBE_RXDADV_ERR_MASK 0xfff00000 /* RDESC.ERRORS mask */
-#define IXGBE_RXDADV_ERR_SHIFT 20 /* RDESC.ERRORS shift */
-#define IXGBE_RXDADV_ERR_RXE 0x20000000 /* Any MAC Error */
-#define IXGBE_RXDADV_ERR_FCEOFE 0x80000000 /* FCoEFe/IPE */
-#define IXGBE_RXDADV_ERR_FCERR 0x00700000 /* FCERR/FDIRERR */
-#define IXGBE_RXDADV_ERR_FDIR_LEN 0x00100000 /* FDIR Length error */
-#define IXGBE_RXDADV_ERR_FDIR_DROP 0x00200000 /* FDIR Drop error */
-#define IXGBE_RXDADV_ERR_FDIR_COLL 0x00400000 /* FDIR Collision error */
-#define IXGBE_RXDADV_ERR_HBO 0x00800000 /*Header Buffer Overflow */
-#define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */
-#define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */
-#define IXGBE_RXDADV_ERR_PE 0x08000000 /* Packet Error */
-#define IXGBE_RXDADV_ERR_OSE 0x10000000 /* Oversize Error */
-#define IXGBE_RXDADV_ERR_USE 0x20000000 /* Undersize Error */
-#define IXGBE_RXDADV_ERR_TCPE 0x40000000 /* TCP/UDP Checksum Error */
-#define IXGBE_RXDADV_ERR_IPE 0x80000000 /* IP Checksum Error */
-#define IXGBE_RXD_VLAN_ID_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
-#define IXGBE_RXD_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
-#define IXGBE_RXD_PRI_SHIFT 13
-#define IXGBE_RXD_CFI_MASK 0x1000 /* CFI is bit 12 */
-#define IXGBE_RXD_CFI_SHIFT 12
-
-#define IXGBE_RXDADV_STAT_DD IXGBE_RXD_STAT_DD /* Done */
-#define IXGBE_RXDADV_STAT_EOP IXGBE_RXD_STAT_EOP /* End of Packet */
-#define IXGBE_RXDADV_STAT_FLM IXGBE_RXD_STAT_FLM /* FDir Match */
-#define IXGBE_RXDADV_STAT_VP IXGBE_RXD_STAT_VP /* IEEE VLAN Pkt */
-#define IXGBE_RXDADV_STAT_MASK 0x000fffff /* Stat/NEXTP: bit 0-19 */
-#define IXGBE_RXDADV_STAT_FCEOFS 0x00000040 /* FCoE EOF/SOF Stat */
-#define IXGBE_RXDADV_STAT_FCSTAT 0x00000030 /* FCoE Pkt Stat */
-#define IXGBE_RXDADV_STAT_FCSTAT_NOMTCH 0x00000000 /* 00: No Ctxt Match */
-#define IXGBE_RXDADV_STAT_FCSTAT_NODDP 0x00000010 /* 01: Ctxt w/o DDP */
-#define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */
-#define IXGBE_RXDADV_STAT_FCSTAT_DDP 0x00000030 /* 11: Ctxt w/ DDP */
-#define IXGBE_RXDADV_STAT_TS 0x00010000 /* IEEE1588 Time Stamp */
-
-/* PSRTYPE bit definitions */
-#define IXGBE_PSRTYPE_TCPHDR 0x00000010
-#define IXGBE_PSRTYPE_UDPHDR 0x00000020
-#define IXGBE_PSRTYPE_IPV4HDR 0x00000100
-#define IXGBE_PSRTYPE_IPV6HDR 0x00000200
-#define IXGBE_PSRTYPE_L2HDR 0x00001000
-
-/* SRRCTL bit definitions */
-#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
-#define IXGBE_SRRCTL_RDMTS_SHIFT 22
-#define IXGBE_SRRCTL_RDMTS_MASK 0x01C00000
-#define IXGBE_SRRCTL_DROP_EN 0x10000000
-#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F
-#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00
-#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000
-#define IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
-#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000
-#define IXGBE_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
-#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
-#define IXGBE_SRRCTL_DESCTYPE_MASK 0x0E000000
-
-#define IXGBE_RXDPS_HDRSTAT_HDRSP 0x00008000
-#define IXGBE_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
-
-#define IXGBE_RXDADV_RSSTYPE_MASK 0x0000000F
-#define IXGBE_RXDADV_PKTTYPE_MASK 0x0000FFF0
-#define IXGBE_RXDADV_PKTTYPE_MASK_EX 0x0001FFF0
-#define IXGBE_RXDADV_HDRBUFLEN_MASK 0x00007FE0
-#define IXGBE_RXDADV_RSCCNT_MASK 0x001E0000
-#define IXGBE_RXDADV_RSCCNT_SHIFT 17
-#define IXGBE_RXDADV_HDRBUFLEN_SHIFT 5
-#define IXGBE_RXDADV_SPLITHEADER_EN 0x00001000
-#define IXGBE_RXDADV_SPH 0x8000
-
-/* RSS Hash results */
-#define IXGBE_RXDADV_RSSTYPE_NONE 0x00000000
-#define IXGBE_RXDADV_RSSTYPE_IPV4_TCP 0x00000001
-#define IXGBE_RXDADV_RSSTYPE_IPV4 0x00000002
-#define IXGBE_RXDADV_RSSTYPE_IPV6_TCP 0x00000003
-#define IXGBE_RXDADV_RSSTYPE_IPV6_EX 0x00000004
-#define IXGBE_RXDADV_RSSTYPE_IPV6 0x00000005
-#define IXGBE_RXDADV_RSSTYPE_IPV6_TCP_EX 0x00000006
-#define IXGBE_RXDADV_RSSTYPE_IPV4_UDP 0x00000007
-#define IXGBE_RXDADV_RSSTYPE_IPV6_UDP 0x00000008
-#define IXGBE_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009
-
-/* RSS Packet Types as indicated in the receive descriptor. */
-#define IXGBE_RXDADV_PKTTYPE_NONE 0x00000000
-#define IXGBE_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPv4 hdr present */
-#define IXGBE_RXDADV_PKTTYPE_IPV4_EX 0x00000020 /* IPv4 hdr + extensions */
-#define IXGBE_RXDADV_PKTTYPE_IPV6 0x00000040 /* IPv6 hdr present */
-#define IXGBE_RXDADV_PKTTYPE_IPV6_EX 0x00000080 /* IPv6 hdr + extensions */
-#define IXGBE_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */
-#define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */
-#define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */
-#define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */
-#define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */
-#define IXGBE_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */
-#define IXGBE_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */
-#define IXGBE_RXDADV_PKTTYPE_ETQF 0x00008000 /* PKTTYPE is ETQF index */
-#define IXGBE_RXDADV_PKTTYPE_ETQF_MASK 0x00000070 /* ETQF has 8 indices */
-#define IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT 4 /* Right-shift 4 bits */
-
-/* Security Processing bit Indication */
-#define IXGBE_RXDADV_LNKSEC_STATUS_SECP 0x00020000
-#define IXGBE_RXDADV_LNKSEC_ERROR_NO_SA_MATCH 0x08000000
-#define IXGBE_RXDADV_LNKSEC_ERROR_REPLAY_ERROR 0x10000000
-#define IXGBE_RXDADV_LNKSEC_ERROR_BIT_MASK 0x18000000
-#define IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG 0x18000000
-
-/* Masks to determine if packets should be dropped due to frame errors */
-#define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
- IXGBE_RXD_ERR_CE | \
- IXGBE_RXD_ERR_LE | \
- IXGBE_RXD_ERR_PE | \
- IXGBE_RXD_ERR_OSE | \
- IXGBE_RXD_ERR_USE)
-
-#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK ( \
- IXGBE_RXDADV_ERR_CE | \
- IXGBE_RXDADV_ERR_LE | \
- IXGBE_RXDADV_ERR_PE | \
- IXGBE_RXDADV_ERR_OSE | \
- IXGBE_RXDADV_ERR_USE)
-
-#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK_82599 IXGBE_RXDADV_ERR_RXE
-
-/* Multicast bit mask */
-#define IXGBE_MCSTCTRL_MFE 0x4
-
-/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
-#define IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE 8
-#define IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE 8
-#define IXGBE_REQ_TX_BUFFER_GRANULARITY 1024
-
-/* Vlan-specific macros */
-#define IXGBE_RX_DESC_SPECIAL_VLAN_MASK 0x0FFF /* VLAN ID in lower 12 bits */
-#define IXGBE_RX_DESC_SPECIAL_PRI_MASK 0xE000 /* Priority in upper 3 bits */
-#define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority in upper 3 of 16 */
-#define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT IXGBE_RX_DESC_SPECIAL_PRI_SHIFT
-
-/* SR-IOV specific macros */
-#define IXGBE_MBVFICR_INDEX(vf_number) (vf_number >> 4)
-#define IXGBE_MBVFICR(_i) (0x00710 + ((_i) * 4))
-#define IXGBE_VFLRE(_i) (((_i & 1) ? 0x001C0 : 0x00600))
-#define IXGBE_VFLREC(_i) (0x00700 + ((_i) * 4))
-/* Translated register #defines */
-#define IXGBE_PVFCTRL(P) (0x00300 + (4 * (P)))
-#define IXGBE_PVFSTATUS(P) (0x00008 + (0 * (P)))
-#define IXGBE_PVFLINKS(P) (0x042A4 + (0 * (P)))
-#define IXGBE_PVFRTIMER(P) (0x00048 + (0 * (P)))
-#define IXGBE_PVFMAILBOX(P) (0x04C00 + (4 * (P)))
-#define IXGBE_PVFRXMEMWRAP(P) (0x03190 + (0 * (P)))
-#define IXGBE_PVTEICR(P) (0x00B00 + (4 * (P)))
-#define IXGBE_PVTEICS(P) (0x00C00 + (4 * (P)))
-#define IXGBE_PVTEIMS(P) (0x00D00 + (4 * (P)))
-#define IXGBE_PVTEIMC(P) (0x00E00 + (4 * (P)))
-#define IXGBE_PVTEIAC(P) (0x00F00 + (4 * (P)))
-#define IXGBE_PVTEIAM(P) (0x04D00 + (4 * (P)))
-#define IXGBE_PVTEITR(P) (((P) < 24) ? (0x00820 + ((P) * 4)) : \
- (0x012300 + (((P) - 24) * 4)))
-#define IXGBE_PVTIVAR(P) (0x12500 + (4 * (P)))
-#define IXGBE_PVTIVAR_MISC(P) (0x04E00 + (4 * (P)))
-#define IXGBE_PVTRSCINT(P) (0x12000 + (4 * (P)))
-#define IXGBE_VFPBACL(P) (0x110C8 + (4 * (P)))
-#define IXGBE_PVFRDBAL(P) ((P < 64) ? (0x01000 + (0x40 * (P))) \
- : (0x0D000 + (0x40 * ((P) - 64))))
-#define IXGBE_PVFRDBAH(P) ((P < 64) ? (0x01004 + (0x40 * (P))) \
- : (0x0D004 + (0x40 * ((P) - 64))))
-#define IXGBE_PVFRDLEN(P) ((P < 64) ? (0x01008 + (0x40 * (P))) \
- : (0x0D008 + (0x40 * ((P) - 64))))
-#define IXGBE_PVFRDH(P) ((P < 64) ? (0x01010 + (0x40 * (P))) \
- : (0x0D010 + (0x40 * ((P) - 64))))
-#define IXGBE_PVFRDT(P) ((P < 64) ? (0x01018 + (0x40 * (P))) \
- : (0x0D018 + (0x40 * ((P) - 64))))
-#define IXGBE_PVFRXDCTL(P) ((P < 64) ? (0x01028 + (0x40 * (P))) \
- : (0x0D028 + (0x40 * ((P) - 64))))
-#define IXGBE_PVFSRRCTL(P) ((P < 64) ? (0x01014 + (0x40 * (P))) \
- : (0x0D014 + (0x40 * ((P) - 64))))
-#define IXGBE_PVFPSRTYPE(P) (0x0EA00 + (4 * (P)))
-#define IXGBE_PVFTDBAL(P) (0x06000 + (0x40 * (P)))
-#define IXGBE_PVFTDBAH(P) (0x06004 + (0x40 * (P)))
-#define IXGBE_PVFTTDLEN(P) (0x06008 + (0x40 * (P)))
-#define IXGBE_PVFTDH(P) (0x06010 + (0x40 * (P)))
-#define IXGBE_PVFTDT(P) (0x06018 + (0x40 * (P)))
-#define IXGBE_PVFTXDCTL(P) (0x06028 + (0x40 * (P)))
-#define IXGBE_PVFTDWBAL(P) (0x06038 + (0x40 * (P)))
-#define IXGBE_PVFTDWBAH(P) (0x0603C + (0x40 * (P)))
-#define IXGBE_PVFDCA_RXCTRL(P) (((P) < 64) ? (0x0100C + (0x40 * (P))) \
- : (0x0D00C + (0x40 * ((P) - 64))))
-#define IXGBE_PVFDCA_TXCTRL(P) (0x0600C + (0x40 * (P)))
-#define IXGBE_PVFGPRC(x) (0x0101C + (0x40 * (x)))
-#define IXGBE_PVFGPTC(x) (0x08300 + (0x04 * (x)))
-#define IXGBE_PVFGORC_LSB(x) (0x01020 + (0x40 * (x)))
-#define IXGBE_PVFGORC_MSB(x) (0x0D020 + (0x40 * (x)))
-#define IXGBE_PVFGOTC_LSB(x) (0x08400 + (0x08 * (x)))
-#define IXGBE_PVFGOTC_MSB(x) (0x08404 + (0x08 * (x)))
-#define IXGBE_PVFMPRC(x) (0x0D01C + (0x40 * (x)))
-
-#define IXGBE_PVFTDWBALn(q_per_pool, vf_number, vf_q_index) \
- (IXGBE_PVFTDWBAL((q_per_pool)*(vf_number) + (vf_q_index)))
-#define IXGBE_PVFTDWBAHn(q_per_pool, vf_number, vf_q_index) \
- (IXGBE_PVFTDWBAH((q_per_pool)*(vf_number) + (vf_q_index)))
-
-/* Little Endian defines */
-#ifndef __le16
-#define __le16 u16
-#endif
-#ifndef __le32
-#define __le32 u32
-#endif
-#ifndef __le64
-#define __le64 u64
-
-#endif
-#ifndef __be16
-/* Big Endian defines */
-#define __be16 u16
-#define __be32 u32
-#define __be64 u64
-
-#endif
-enum ixgbe_fdir_pballoc_type {
- IXGBE_FDIR_PBALLOC_NONE = 0,
- IXGBE_FDIR_PBALLOC_64K = 1,
- IXGBE_FDIR_PBALLOC_128K = 2,
- IXGBE_FDIR_PBALLOC_256K = 3,
-};
-
-/* Flow Director register values */
-#define IXGBE_FDIRCTRL_PBALLOC_64K 0x00000001
-#define IXGBE_FDIRCTRL_PBALLOC_128K 0x00000002
-#define IXGBE_FDIRCTRL_PBALLOC_256K 0x00000003
-#define IXGBE_FDIRCTRL_INIT_DONE 0x00000008
-#define IXGBE_FDIRCTRL_PERFECT_MATCH 0x00000010
-#define IXGBE_FDIRCTRL_REPORT_STATUS 0x00000020
-#define IXGBE_FDIRCTRL_REPORT_STATUS_ALWAYS 0x00000080
-#define IXGBE_FDIRCTRL_DROP_Q_SHIFT 8
-#define IXGBE_FDIRCTRL_FLEX_SHIFT 16
-#define IXGBE_FDIRCTRL_SEARCHLIM 0x00800000
-#define IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT 24
-#define IXGBE_FDIRCTRL_FULL_THRESH_MASK 0xF0000000
-#define IXGBE_FDIRCTRL_FULL_THRESH_SHIFT 28
-
-#define IXGBE_FDIRTCPM_DPORTM_SHIFT 16
-#define IXGBE_FDIRUDPM_DPORTM_SHIFT 16
-#define IXGBE_FDIRIP6M_DIPM_SHIFT 16
-#define IXGBE_FDIRM_VLANID 0x00000001
-#define IXGBE_FDIRM_VLANP 0x00000002
-#define IXGBE_FDIRM_POOL 0x00000004
-#define IXGBE_FDIRM_L4P 0x00000008
-#define IXGBE_FDIRM_FLEX 0x00000010
-#define IXGBE_FDIRM_DIPv6 0x00000020
-
-#define IXGBE_FDIRFREE_FREE_MASK 0xFFFF
-#define IXGBE_FDIRFREE_FREE_SHIFT 0
-#define IXGBE_FDIRFREE_COLL_MASK 0x7FFF0000
-#define IXGBE_FDIRFREE_COLL_SHIFT 16
-#define IXGBE_FDIRLEN_MAXLEN_MASK 0x3F
-#define IXGBE_FDIRLEN_MAXLEN_SHIFT 0
-#define IXGBE_FDIRLEN_MAXHASH_MASK 0x7FFF0000
-#define IXGBE_FDIRLEN_MAXHASH_SHIFT 16
-#define IXGBE_FDIRUSTAT_ADD_MASK 0xFFFF
-#define IXGBE_FDIRUSTAT_ADD_SHIFT 0
-#define IXGBE_FDIRUSTAT_REMOVE_MASK 0xFFFF0000
-#define IXGBE_FDIRUSTAT_REMOVE_SHIFT 16
-#define IXGBE_FDIRFSTAT_FADD_MASK 0x00FF
-#define IXGBE_FDIRFSTAT_FADD_SHIFT 0
-#define IXGBE_FDIRFSTAT_FREMOVE_MASK 0xFF00
-#define IXGBE_FDIRFSTAT_FREMOVE_SHIFT 8
-#define IXGBE_FDIRPORT_DESTINATION_SHIFT 16
-#define IXGBE_FDIRVLAN_FLEX_SHIFT 16
-#define IXGBE_FDIRHASH_BUCKET_VALID_SHIFT 15
-#define IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT 16
-
-#define IXGBE_FDIRCMD_CMD_MASK 0x00000003
-#define IXGBE_FDIRCMD_CMD_ADD_FLOW 0x00000001
-#define IXGBE_FDIRCMD_CMD_REMOVE_FLOW 0x00000002
-#define IXGBE_FDIRCMD_CMD_QUERY_REM_FILT 0x00000003
-#define IXGBE_FDIRCMD_FILTER_VALID 0x00000004
-#define IXGBE_FDIRCMD_FILTER_UPDATE 0x00000008
-#define IXGBE_FDIRCMD_IPv6DMATCH 0x00000010
-#define IXGBE_FDIRCMD_L4TYPE_UDP 0x00000020
-#define IXGBE_FDIRCMD_L4TYPE_TCP 0x00000040
-#define IXGBE_FDIRCMD_L4TYPE_SCTP 0x00000060
-#define IXGBE_FDIRCMD_IPV6 0x00000080
-#define IXGBE_FDIRCMD_CLEARHT 0x00000100
-#define IXGBE_FDIRCMD_DROP 0x00000200
-#define IXGBE_FDIRCMD_INT 0x00000400
-#define IXGBE_FDIRCMD_LAST 0x00000800
-#define IXGBE_FDIRCMD_COLLISION 0x00001000
-#define IXGBE_FDIRCMD_QUEUE_EN 0x00008000
-#define IXGBE_FDIRCMD_FLOW_TYPE_SHIFT 5
-#define IXGBE_FDIRCMD_RX_QUEUE_SHIFT 16
-#define IXGBE_FDIRCMD_VT_POOL_SHIFT 24
-#define IXGBE_FDIR_INIT_DONE_POLL 10
-#define IXGBE_FDIRCMD_CMD_POLL 10
-
-#define IXGBE_FDIR_DROP_QUEUE 127
-
-#define IXGBE_STATUS_OVERHEATING_BIT 20 /* STATUS overtemp bit num */
-
-/* Manageablility Host Interface defines */
-#define IXGBE_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */
-#define IXGBE_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */
-#define IXGBE_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */
-
-/* CEM Support */
-#define FW_CEM_HDR_LEN 0x4
-#define FW_CEM_CMD_DRIVER_INFO 0xDD
-#define FW_CEM_CMD_DRIVER_INFO_LEN 0x5
-#define FW_CEM_CMD_RESERVED 0X0
-#define FW_CEM_UNUSED_VER 0x0
-#define FW_CEM_MAX_RETRIES 3
-#define FW_CEM_RESP_STATUS_SUCCESS 0x1
-
-/* Host Interface Command Structures */
-
-struct ixgbe_hic_hdr {
- u8 cmd;
- u8 buf_len;
- union {
- u8 cmd_resv;
- u8 ret_status;
- } cmd_or_resp;
- u8 checksum;
-};
-
-struct ixgbe_hic_drv_info {
- struct ixgbe_hic_hdr hdr;
- u8 port_num;
- u8 ver_sub;
- u8 ver_build;
- u8 ver_min;
- u8 ver_maj;
- u8 pad; /* end spacing to ensure length is mult. of dword */
- u16 pad2; /* end spacing to ensure length is mult. of dword2 */
-};
-
-/* Transmit Descriptor - Legacy */
-struct ixgbe_legacy_tx_desc {
- u64 buffer_addr; /* Address of the descriptor's data buffer */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 cso; /* Checksum offset */
- u8 cmd; /* Descriptor control */
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 css; /* Checksum start */
- __le16 vlan;
- } fields;
- } upper;
-};
-
-/* Transmit Descriptor - Advanced */
-union ixgbe_adv_tx_desc {
- struct {
- __le64 buffer_addr; /* Address of descriptor's data buf */
- __le32 cmd_type_len;
- __le32 olinfo_status;
- } read;
- struct {
- __le64 rsvd; /* Reserved */
- __le32 nxtseq_seed;
- __le32 status;
- } wb;
-};
-
-/* Receive Descriptor - Legacy */
-struct ixgbe_legacy_rx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- __le16 length; /* Length of data DMAed into data buffer */
- __le16 csum; /* Packet checksum */
- u8 status; /* Descriptor status */
- u8 errors; /* Descriptor Errors */
- __le16 vlan;
-};
-
-/* Receive Descriptor - Advanced */
-union ixgbe_adv_rx_desc {
- struct {
- __le64 pkt_addr; /* Packet buffer address */
- __le64 hdr_addr; /* Header buffer address */
- } read;
- struct {
- struct {
- union {
- __le32 data;
- struct {
- __le16 pkt_info; /* RSS, Pkt type */
- __le16 hdr_info; /* Splithdr, hdrlen */
- } hs_rss;
- } lo_dword;
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length; /* Packet length */
- __le16 vlan; /* VLAN tag */
- } upper;
- } wb; /* writeback */
-};
-
-/* Context descriptors */
-struct ixgbe_adv_tx_context_desc {
- __le32 vlan_macip_lens;
- __le32 seqnum_seed;
- __le32 type_tucmd_mlhl;
- __le32 mss_l4len_idx;
-};
-
-/* Adv Transmit Descriptor Config Masks */
-#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */
-#define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */
-#define IXGBE_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 time stamp */
-#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */
-#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */
-#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */
-#define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Adv Context Desc */
-#define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Adv Data Descriptor */
-#define IXGBE_ADVTXD_DCMD_EOP IXGBE_TXD_CMD_EOP /* End of Packet */
-#define IXGBE_ADVTXD_DCMD_IFCS IXGBE_TXD_CMD_IFCS /* Insert FCS */
-#define IXGBE_ADVTXD_DCMD_RS IXGBE_TXD_CMD_RS /* Report Status */
-#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
-#define IXGBE_ADVTXD_DCMD_DEXT IXGBE_TXD_CMD_DEXT /* Desc ext 1=Adv */
-#define IXGBE_ADVTXD_DCMD_VLE IXGBE_TXD_CMD_VLE /* VLAN pkt enable */
-#define IXGBE_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
-#define IXGBE_ADVTXD_STAT_DD IXGBE_TXD_STAT_DD /* Descriptor Done */
-#define IXGBE_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED pres in WB */
-#define IXGBE_ADVTXD_STAT_RSV 0x0000000C /* STA Reserved */
-#define IXGBE_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
-#define IXGBE_ADVTXD_CC 0x00000080 /* Check Context */
-#define IXGBE_ADVTXD_POPTS_SHIFT 8 /* Adv desc POPTS shift */
-#define IXGBE_ADVTXD_POPTS_IXSM (IXGBE_TXD_POPTS_IXSM << \
- IXGBE_ADVTXD_POPTS_SHIFT)
-#define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \
- IXGBE_ADVTXD_POPTS_SHIFT)
-#define IXGBE_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
-/* 1st&Last TSO-full iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800
-#define IXGBE_ADVTXD_POPTS_RSV 0x00002000 /* POPTS Reserved */
-#define IXGBE_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
-#define IXGBE_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
-#define IXGBE_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
-#define IXGBE_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
-#define IXGBE_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
-#define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
-#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
-#define IXGBE_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */
-#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /* req Markers and CRC */
-#define IXGBE_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */
-#define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
-#define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000/* ESP Encrypt Enable */
-#define IXGBE_ADVTXT_TUCMD_FCOE 0x00008000 /* FCoE Frame Type */
-#define IXGBE_ADVTXD_FCOEF_EOF_MASK (0x3 << 10) /* FC EOF index */
-#define IXGBE_ADVTXD_FCOEF_SOF ((1 << 2) << 10) /* FC SOF index */
-#define IXGBE_ADVTXD_FCOEF_PARINC ((1 << 3) << 10) /* Rel_Off in F_CTL */
-#define IXGBE_ADVTXD_FCOEF_ORIE ((1 << 4) << 10) /* Orientation End */
-#define IXGBE_ADVTXD_FCOEF_ORIS ((1 << 5) << 10) /* Orientation Start */
-#define IXGBE_ADVTXD_FCOEF_EOF_N (0x0 << 10) /* 00: EOFn */
-#define IXGBE_ADVTXD_FCOEF_EOF_T (0x1 << 10) /* 01: EOFt */
-#define IXGBE_ADVTXD_FCOEF_EOF_NI (0x2 << 10) /* 10: EOFni */
-#define IXGBE_ADVTXD_FCOEF_EOF_A (0x3 << 10) /* 11: EOFa */
-#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
-#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
-
-/* Autonegotiation advertised speeds */
-typedef u32 ixgbe_autoneg_advertised;
-/* Link speed */
-typedef u32 ixgbe_link_speed;
-#define IXGBE_LINK_SPEED_UNKNOWN 0
-#define IXGBE_LINK_SPEED_100_FULL 0x0008
-#define IXGBE_LINK_SPEED_1GB_FULL 0x0020
-#define IXGBE_LINK_SPEED_10GB_FULL 0x0080
-#define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \
- IXGBE_LINK_SPEED_10GB_FULL)
-#define IXGBE_LINK_SPEED_82599_AUTONEG (IXGBE_LINK_SPEED_100_FULL | \
- IXGBE_LINK_SPEED_1GB_FULL | \
- IXGBE_LINK_SPEED_10GB_FULL)
-
-
-/* Physical layer type */
-typedef u32 ixgbe_physical_layer;
-#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0
-#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001
-#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002
-#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x0004
-#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008
-#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010
-#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020
-#define IXGBE_PHYSICAL_LAYER_10GBASE_SR 0x0040
-#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4 0x0080
-#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100
-#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200
-#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400
-#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800
-#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000
-#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000
-#define IXGBE_PHYSICAL_LAYER_1000BASE_SX 0x4000
-
-/* Flow Control Data Sheet defined values
- * Calculation and defines taken from 802.1bb Annex O
- */
-
-/* BitTimes (BT) conversion */
-#define IXGBE_BT2KB(BT) ((BT + (8 * 1024 - 1)) / (8 * 1024))
-#define IXGBE_B2BT(BT) (BT * 8)
-
-/* Calculate Delay to respond to PFC */
-#define IXGBE_PFC_D 672
-
-/* Calculate Cable Delay */
-#define IXGBE_CABLE_DC 5556 /* Delay Copper */
-#define IXGBE_CABLE_DO 5000 /* Delay Optical */
-
-/* Calculate Interface Delay X540 */
-#define IXGBE_PHY_DC 25600 /* Delay 10G BASET */
-#define IXGBE_MAC_DC 8192 /* Delay Copper XAUI interface */
-#define IXGBE_XAUI_DC (2 * 2048) /* Delay Copper Phy */
-
-#define IXGBE_ID_X540 (IXGBE_MAC_DC + IXGBE_XAUI_DC + IXGBE_PHY_DC)
-
-/* Calculate Interface Delay 82598, 82599 */
-#define IXGBE_PHY_D 12800
-#define IXGBE_MAC_D 4096
-#define IXGBE_XAUI_D (2 * 1024)
-
-#define IXGBE_ID (IXGBE_MAC_D + IXGBE_XAUI_D + IXGBE_PHY_D)
-
-/* Calculate Delay incurred from higher layer */
-#define IXGBE_HD 6144
-
-/* Calculate PCI Bus delay for low thresholds */
-#define IXGBE_PCI_DELAY 10000
-
-/* Calculate X540 delay value in bit times */
-#define IXGBE_DV_X540(_max_frame_link, _max_frame_tc) \
- ((36 * \
- (IXGBE_B2BT(_max_frame_link) + \
- IXGBE_PFC_D + \
- (2 * IXGBE_CABLE_DC) + \
- (2 * IXGBE_ID_X540) + \
- IXGBE_HD) / 25 + 1) + \
- 2 * IXGBE_B2BT(_max_frame_tc))
-
-/* Calculate 82599, 82598 delay value in bit times */
-#define IXGBE_DV(_max_frame_link, _max_frame_tc) \
- ((36 * \
- (IXGBE_B2BT(_max_frame_link) + \
- IXGBE_PFC_D + \
- (2 * IXGBE_CABLE_DC) + \
- (2 * IXGBE_ID) + \
- IXGBE_HD) / 25 + 1) + \
- 2 * IXGBE_B2BT(_max_frame_tc))
-
-/* Calculate low threshold delay values */
-#define IXGBE_LOW_DV_X540(_max_frame_tc) \
- (2 * IXGBE_B2BT(_max_frame_tc) + \
- (36 * IXGBE_PCI_DELAY / 25) + 1)
-#define IXGBE_LOW_DV(_max_frame_tc) \
- (2 * IXGBE_LOW_DV_X540(_max_frame_tc))
-
-/* Software ATR hash keys */
-#define IXGBE_ATR_BUCKET_HASH_KEY 0x3DAD14E2
-#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x174D3614
-
-/* Software ATR input stream values and masks */
-#define IXGBE_ATR_HASH_MASK 0x7fff
-#define IXGBE_ATR_L4TYPE_MASK 0x3
-#define IXGBE_ATR_L4TYPE_UDP 0x1
-#define IXGBE_ATR_L4TYPE_TCP 0x2
-#define IXGBE_ATR_L4TYPE_SCTP 0x3
-#define IXGBE_ATR_L4TYPE_IPV6_MASK 0x4
-enum ixgbe_atr_flow_type {
- IXGBE_ATR_FLOW_TYPE_IPV4 = 0x0,
- IXGBE_ATR_FLOW_TYPE_UDPV4 = 0x1,
- IXGBE_ATR_FLOW_TYPE_TCPV4 = 0x2,
- IXGBE_ATR_FLOW_TYPE_SCTPV4 = 0x3,
- IXGBE_ATR_FLOW_TYPE_IPV6 = 0x4,
- IXGBE_ATR_FLOW_TYPE_UDPV6 = 0x5,
- IXGBE_ATR_FLOW_TYPE_TCPV6 = 0x6,
- IXGBE_ATR_FLOW_TYPE_SCTPV6 = 0x7,
-};
-
-/* Flow Director ATR input struct. */
-union ixgbe_atr_input {
- /*
- * Byte layout in order, all values with MSB first:
- *
- * vm_pool - 1 byte
- * flow_type - 1 byte
- * vlan_id - 2 bytes
- * src_ip - 16 bytes
- * dst_ip - 16 bytes
- * src_port - 2 bytes
- * dst_port - 2 bytes
- * flex_bytes - 2 bytes
- * bkt_hash - 2 bytes
- */
- struct {
- u8 vm_pool;
- u8 flow_type;
- __be16 vlan_id;
- __be32 dst_ip[4];
- __be32 src_ip[4];
- __be16 src_port;
- __be16 dst_port;
- __be16 flex_bytes;
- __be16 bkt_hash;
- } formatted;
- __be32 dword_stream[11];
-};
-
-/* Flow Director compressed ATR hash input struct */
-union ixgbe_atr_hash_dword {
- struct {
- u8 vm_pool;
- u8 flow_type;
- __be16 vlan_id;
- } formatted;
- __be32 ip;
- struct {
- __be16 src;
- __be16 dst;
- } port;
- __be16 flex_bytes;
- __be32 dword;
-};
-
-
-/*
- * Unavailable: The FCoE Boot Option ROM is not present in the flash.
- * Disabled: Present; boot order is not set for any targets on the port.
- * Enabled: Present; boot order is set for at least one target on the port.
- */
-enum ixgbe_fcoe_boot_status {
- ixgbe_fcoe_bootstatus_disabled = 0,
- ixgbe_fcoe_bootstatus_enabled = 1,
- ixgbe_fcoe_bootstatus_unavailable = 0xFFFF
-};
-
-enum ixgbe_eeprom_type {
- ixgbe_eeprom_uninitialized = 0,
- ixgbe_eeprom_spi,
- ixgbe_flash,
- ixgbe_eeprom_none /* No NVM support */
-};
-
-enum ixgbe_mac_type {
- ixgbe_mac_unknown = 0,
- ixgbe_mac_82598EB,
- ixgbe_mac_82599EB,
- ixgbe_mac_X540,
- ixgbe_num_macs
-};
-
-enum ixgbe_phy_type {
- ixgbe_phy_unknown = 0,
- ixgbe_phy_none,
- ixgbe_phy_tn,
- ixgbe_phy_aq,
- ixgbe_phy_cu_unknown,
- ixgbe_phy_qt,
- ixgbe_phy_xaui,
- ixgbe_phy_nl,
- ixgbe_phy_sfp_passive_tyco,
- ixgbe_phy_sfp_passive_unknown,
- ixgbe_phy_sfp_active_unknown,
- ixgbe_phy_sfp_avago,
- ixgbe_phy_sfp_ftl,
- ixgbe_phy_sfp_ftl_active,
- ixgbe_phy_sfp_unknown,
- ixgbe_phy_sfp_intel,
- ixgbe_phy_sfp_unsupported, /*Enforce bit set with unsupported module*/
- ixgbe_phy_generic
-};
-
-/*
- * SFP+ module type IDs:
- *
- * ID Module Type
- * =============
- * 0 SFP_DA_CU
- * 1 SFP_SR
- * 2 SFP_LR
- * 3 SFP_DA_CU_CORE0 - 82599-specific
- * 4 SFP_DA_CU_CORE1 - 82599-specific
- * 5 SFP_SR/LR_CORE0 - 82599-specific
- * 6 SFP_SR/LR_CORE1 - 82599-specific
- */
-enum ixgbe_sfp_type {
- ixgbe_sfp_type_da_cu = 0,
- ixgbe_sfp_type_sr = 1,
- ixgbe_sfp_type_lr = 2,
- ixgbe_sfp_type_da_cu_core0 = 3,
- ixgbe_sfp_type_da_cu_core1 = 4,
- ixgbe_sfp_type_srlr_core0 = 5,
- ixgbe_sfp_type_srlr_core1 = 6,
- ixgbe_sfp_type_da_act_lmt_core0 = 7,
- ixgbe_sfp_type_da_act_lmt_core1 = 8,
- ixgbe_sfp_type_1g_cu_core0 = 9,
- ixgbe_sfp_type_1g_cu_core1 = 10,
- ixgbe_sfp_type_1g_sx_core0 = 11,
- ixgbe_sfp_type_1g_sx_core1 = 12,
- ixgbe_sfp_type_not_present = 0xFFFE,
- ixgbe_sfp_type_unknown = 0xFFFF
-};
-
-enum ixgbe_media_type {
- ixgbe_media_type_unknown = 0,
- ixgbe_media_type_fiber,
- ixgbe_media_type_fiber_qsfp,
- ixgbe_media_type_fiber_lco,
- ixgbe_media_type_copper,
- ixgbe_media_type_backplane,
- ixgbe_media_type_cx4,
- ixgbe_media_type_virtual
-};
-
-/* Flow Control Settings */
-enum ixgbe_fc_mode {
- ixgbe_fc_none = 0,
- ixgbe_fc_rx_pause,
- ixgbe_fc_tx_pause,
- ixgbe_fc_full,
- ixgbe_fc_default
-};
-
-/* Smart Speed Settings */
-#define IXGBE_SMARTSPEED_MAX_RETRIES 3
-enum ixgbe_smart_speed {
- ixgbe_smart_speed_auto = 0,
- ixgbe_smart_speed_on,
- ixgbe_smart_speed_off
-};
-
-/* PCI bus types */
-enum ixgbe_bus_type {
- ixgbe_bus_type_unknown = 0,
- ixgbe_bus_type_pci,
- ixgbe_bus_type_pcix,
- ixgbe_bus_type_pci_express,
- ixgbe_bus_type_reserved
-};
-
-/* PCI bus speeds */
-enum ixgbe_bus_speed {
- ixgbe_bus_speed_unknown = 0,
- ixgbe_bus_speed_33 = 33,
- ixgbe_bus_speed_66 = 66,
- ixgbe_bus_speed_100 = 100,
- ixgbe_bus_speed_120 = 120,
- ixgbe_bus_speed_133 = 133,
- ixgbe_bus_speed_2500 = 2500,
- ixgbe_bus_speed_5000 = 5000,
- ixgbe_bus_speed_8000 = 8000,
- ixgbe_bus_speed_reserved
-};
-
-/* PCI bus widths */
-enum ixgbe_bus_width {
- ixgbe_bus_width_unknown = 0,
- ixgbe_bus_width_pcie_x1 = 1,
- ixgbe_bus_width_pcie_x2 = 2,
- ixgbe_bus_width_pcie_x4 = 4,
- ixgbe_bus_width_pcie_x8 = 8,
- ixgbe_bus_width_32 = 32,
- ixgbe_bus_width_64 = 64,
- ixgbe_bus_width_reserved
-};
-
-struct ixgbe_addr_filter_info {
- u32 num_mc_addrs;
- u32 rar_used_count;
- u32 mta_in_use;
- u32 overflow_promisc;
- bool user_set_promisc;
-};
-
-/* Bus parameters */
-struct ixgbe_bus_info {
- enum ixgbe_bus_speed speed;
- enum ixgbe_bus_width width;
- enum ixgbe_bus_type type;
-
- u16 func;
- u16 lan_id;
-};
-
-/* Flow control parameters */
-struct ixgbe_fc_info {
- u32 high_water[IXGBE_DCB_MAX_TRAFFIC_CLASS]; /* Flow Ctrl High-water */
- u32 low_water[IXGBE_DCB_MAX_TRAFFIC_CLASS]; /* Flow Ctrl Low-water */
- u16 pause_time; /* Flow Control Pause timer */
- bool send_xon; /* Flow control send XON */
- bool strict_ieee; /* Strict IEEE mode */
- bool disable_fc_autoneg; /* Do not autonegotiate FC */
- bool fc_was_autonegged; /* Is current_mode the result of autonegging? */
- enum ixgbe_fc_mode current_mode; /* FC mode in effect */
- enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */
-};
-
-/* Statistics counters collected by the MAC */
-struct ixgbe_hw_stats {
- u64 crcerrs;
- u64 illerrc;
- u64 errbc;
- u64 mspdc;
- u64 mpctotal;
- u64 mpc[8];
- u64 mlfc;
- u64 mrfc;
- u64 rlec;
- u64 lxontxc;
- u64 lxonrxc;
- u64 lxofftxc;
- u64 lxoffrxc;
- u64 pxontxc[8];
- u64 pxonrxc[8];
- u64 pxofftxc[8];
- u64 pxoffrxc[8];
- u64 prc64;
- u64 prc127;
- u64 prc255;
- u64 prc511;
- u64 prc1023;
- u64 prc1522;
- u64 gprc;
- u64 bprc;
- u64 mprc;
- u64 gptc;
- u64 gorc;
- u64 gotc;
- u64 rnbc[8];
- u64 ruc;
- u64 rfc;
- u64 roc;
- u64 rjc;
- u64 mngprc;
- u64 mngpdc;
- u64 mngptc;
- u64 tor;
- u64 tpr;
- u64 tpt;
- u64 ptc64;
- u64 ptc127;
- u64 ptc255;
- u64 ptc511;
- u64 ptc1023;
- u64 ptc1522;
- u64 mptc;
- u64 bptc;
- u64 xec;
- u64 qprc[16];
- u64 qptc[16];
- u64 qbrc[16];
- u64 qbtc[16];
- u64 qprdc[16];
- u64 pxon2offc[8];
- u64 fdirustat_add;
- u64 fdirustat_remove;
- u64 fdirfstat_fadd;
- u64 fdirfstat_fremove;
- u64 fdirmatch;
- u64 fdirmiss;
- u64 fccrc;
- u64 fclast;
- u64 fcoerpdc;
- u64 fcoeprc;
- u64 fcoeptc;
- u64 fcoedwrc;
- u64 fcoedwtc;
- u64 fcoe_noddp;
- u64 fcoe_noddp_ext_buff;
- u64 ldpcec;
- u64 pcrc8ec;
- u64 b2ospc;
- u64 b2ogprc;
- u64 o2bgptc;
- u64 o2bspc;
-};
-
-/* forward declaration */
-struct ixgbe_hw;
-
-/* iterator type for walking multicast address lists */
-typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
- u32 *vmdq);
-
-/* Function pointer table */
-struct ixgbe_eeprom_operations {
- s32 (*init_params)(struct ixgbe_hw *);
- s32 (*read)(struct ixgbe_hw *, u16, u16 *);
- s32 (*read_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
- s32 (*write)(struct ixgbe_hw *, u16, u16);
- s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
- s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
- s32 (*update_checksum)(struct ixgbe_hw *);
- u16 (*calc_checksum)(struct ixgbe_hw *);
-};
-
-struct ixgbe_mac_operations {
- s32 (*init_hw)(struct ixgbe_hw *);
- s32 (*reset_hw)(struct ixgbe_hw *);
- s32 (*start_hw)(struct ixgbe_hw *);
- s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
- enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
- u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
- s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
- s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *);
- s32 (*set_san_mac_addr)(struct ixgbe_hw *, u8 *);
- s32 (*get_device_caps)(struct ixgbe_hw *, u16 *);
- s32 (*get_wwn_prefix)(struct ixgbe_hw *, u16 *, u16 *);
- s32 (*get_fcoe_boot_status)(struct ixgbe_hw *, u16 *);
- s32 (*stop_adapter)(struct ixgbe_hw *);
- s32 (*get_bus_info)(struct ixgbe_hw *);
- void (*set_lan_id)(struct ixgbe_hw *);
- s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*);
- s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8);
- s32 (*setup_sfp)(struct ixgbe_hw *);
- s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
- s32 (*disable_sec_rx_path)(struct ixgbe_hw *);
- s32 (*enable_sec_rx_path)(struct ixgbe_hw *);
- s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u16);
- void (*release_swfw_sync)(struct ixgbe_hw *, u16);
-
- /* Link */
- void (*disable_tx_laser)(struct ixgbe_hw *);
- void (*enable_tx_laser)(struct ixgbe_hw *);
- void (*flap_tx_laser)(struct ixgbe_hw *);
- s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
- s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
- s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
- bool *);
-
- /* Packet Buffer manipulation */
- void (*setup_rxpba)(struct ixgbe_hw *, int, u32, int);
-
- /* LED */
- s32 (*led_on)(struct ixgbe_hw *, u32);
- s32 (*led_off)(struct ixgbe_hw *, u32);
- s32 (*blink_led_start)(struct ixgbe_hw *, u32);
- s32 (*blink_led_stop)(struct ixgbe_hw *, u32);
-
- /* RAR, Multicast, VLAN */
- s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32);
- s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *);
- s32 (*clear_rar)(struct ixgbe_hw *, u32);
- s32 (*insert_mac_addr)(struct ixgbe_hw *, u8 *, u32);
- s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32);
- s32 (*set_vmdq_san_mac)(struct ixgbe_hw *, u32);
- s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32);
- s32 (*init_rx_addrs)(struct ixgbe_hw *);
- s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32,
- ixgbe_mc_addr_itr);
- s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32,
- ixgbe_mc_addr_itr, bool clear);
- s32 (*enable_mc)(struct ixgbe_hw *);
- s32 (*disable_mc)(struct ixgbe_hw *);
- s32 (*clear_vfta)(struct ixgbe_hw *);
- s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
- s32 (*set_vlvf)(struct ixgbe_hw *, u32, u32, bool, bool *);
- s32 (*init_uta_tables)(struct ixgbe_hw *);
- void (*set_mac_anti_spoofing)(struct ixgbe_hw *, bool, int);
- void (*set_vlan_anti_spoofing)(struct ixgbe_hw *, bool, int);
-
- /* Flow Control */
- s32 (*fc_enable)(struct ixgbe_hw *);
-
- /* Manageability interface */
- s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8);
- s32 (*get_thermal_sensor_data)(struct ixgbe_hw *);
- s32 (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw);
-};
-
-struct ixgbe_phy_operations {
- s32 (*identify)(struct ixgbe_hw *);
- s32 (*identify_sfp)(struct ixgbe_hw *);
- s32 (*init)(struct ixgbe_hw *);
- s32 (*reset)(struct ixgbe_hw *);
- s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
- s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
- s32 (*setup_link)(struct ixgbe_hw *);
- s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
- bool);
- s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *);
- s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *);
- s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
- s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
- s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
- s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
- void (*i2c_bus_clear)(struct ixgbe_hw *);
- s32 (*check_overtemp)(struct ixgbe_hw *);
-};
-
-struct ixgbe_eeprom_info {
- struct ixgbe_eeprom_operations ops;
- enum ixgbe_eeprom_type type;
- u32 semaphore_delay;
- u16 word_size;
- u16 address_bits;
- u16 word_page_size;
-};
-
-#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01
-struct ixgbe_mac_info {
- struct ixgbe_mac_operations ops;
- enum ixgbe_mac_type type;
- u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
- u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
- u8 san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
- /* prefix for World Wide Node Name (WWNN) */
- u16 wwnn_prefix;
- /* prefix for World Wide Port Name (WWPN) */
- u16 wwpn_prefix;
-#define IXGBE_MAX_MTA 128
- u32 mta_shadow[IXGBE_MAX_MTA];
- s32 mc_filter_type;
- u32 mcft_size;
- u32 vft_size;
- u32 num_rar_entries;
- u32 rar_highwater;
- u32 rx_pb_size;
- u32 max_tx_queues;
- u32 max_rx_queues;
- u32 orig_autoc;
- u8 san_mac_rar_index;
- u32 orig_autoc2;
- u16 max_msix_vectors;
- bool arc_subsystem_valid;
- bool orig_link_settings_stored;
- bool autotry_restart;
- u8 flags;
- struct ixgbe_thermal_sensor_data thermal_sensor_data;
-};
-
-struct ixgbe_phy_info {
- struct ixgbe_phy_operations ops;
- enum ixgbe_phy_type type;
- u32 addr;
- u32 id;
- enum ixgbe_sfp_type sfp_type;
- bool sfp_setup_needed;
- u32 revision;
- enum ixgbe_media_type media_type;
- bool reset_disable;
- ixgbe_autoneg_advertised autoneg_advertised;
- enum ixgbe_smart_speed smart_speed;
- bool smart_speed_active;
- bool multispeed_fiber;
- bool reset_if_overtemp;
- bool qsfp_shared_i2c_bus;
-};
-
-#include "ixgbe_mbx.h"
-
-struct ixgbe_mbx_operations {
- void (*init_params)(struct ixgbe_hw *hw);
- s32 (*read)(struct ixgbe_hw *, u32 *, u16, u16);
- s32 (*write)(struct ixgbe_hw *, u32 *, u16, u16);
- s32 (*read_posted)(struct ixgbe_hw *, u32 *, u16, u16);
- s32 (*write_posted)(struct ixgbe_hw *, u32 *, u16, u16);
- s32 (*check_for_msg)(struct ixgbe_hw *, u16);
- s32 (*check_for_ack)(struct ixgbe_hw *, u16);
- s32 (*check_for_rst)(struct ixgbe_hw *, u16);
-};
-
-struct ixgbe_mbx_stats {
- u32 msgs_tx;
- u32 msgs_rx;
-
- u32 acks;
- u32 reqs;
- u32 rsts;
-};
-
-struct ixgbe_mbx_info {
- struct ixgbe_mbx_operations ops;
- struct ixgbe_mbx_stats stats;
- u32 timeout;
- u32 udelay;
- u32 v2p_mailbox;
- u16 size;
-};
-
-struct ixgbe_hw {
- u8 __iomem *hw_addr;
- void *back;
- struct ixgbe_mac_info mac;
- struct ixgbe_addr_filter_info addr_ctrl;
- struct ixgbe_fc_info fc;
- struct ixgbe_phy_info phy;
- struct ixgbe_eeprom_info eeprom;
- struct ixgbe_bus_info bus;
- struct ixgbe_mbx_info mbx;
- u16 device_id;
- u16 vendor_id;
- u16 subsystem_device_id;
- u16 subsystem_vendor_id;
- u8 revision_id;
- bool adapter_stopped;
- bool force_full_reset;
- bool allow_unsupported_sfp;
-};
-
-#define ixgbe_call_func(hw, func, params, error) \
- (func != NULL) ? func params : error
-
-
-/* Error Codes */
-#define IXGBE_ERR_EEPROM -1
-#define IXGBE_ERR_EEPROM_CHECKSUM -2
-#define IXGBE_ERR_PHY -3
-#define IXGBE_ERR_CONFIG -4
-#define IXGBE_ERR_PARAM -5
-#define IXGBE_ERR_MAC_TYPE -6
-#define IXGBE_ERR_UNKNOWN_PHY -7
-#define IXGBE_ERR_LINK_SETUP -8
-#define IXGBE_ERR_ADAPTER_STOPPED -9
-#define IXGBE_ERR_INVALID_MAC_ADDR -10
-#define IXGBE_ERR_DEVICE_NOT_SUPPORTED -11
-#define IXGBE_ERR_MASTER_REQUESTS_PENDING -12
-#define IXGBE_ERR_INVALID_LINK_SETTINGS -13
-#define IXGBE_ERR_AUTONEG_NOT_COMPLETE -14
-#define IXGBE_ERR_RESET_FAILED -15
-#define IXGBE_ERR_SWFW_SYNC -16
-#define IXGBE_ERR_PHY_ADDR_INVALID -17
-#define IXGBE_ERR_I2C -18
-#define IXGBE_ERR_SFP_NOT_SUPPORTED -19
-#define IXGBE_ERR_SFP_NOT_PRESENT -20
-#define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -21
-#define IXGBE_ERR_NO_SAN_ADDR_PTR -22
-#define IXGBE_ERR_FDIR_REINIT_FAILED -23
-#define IXGBE_ERR_EEPROM_VERSION -24
-#define IXGBE_ERR_NO_SPACE -25
-#define IXGBE_ERR_OVERTEMP -26
-#define IXGBE_ERR_FC_NOT_NEGOTIATED -27
-#define IXGBE_ERR_FC_NOT_SUPPORTED -28
-#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30
-#define IXGBE_ERR_PBA_SECTION -31
-#define IXGBE_ERR_INVALID_ARGUMENT -32
-#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33
-#define IXGBE_ERR_OUT_OF_MEM -34
-
-#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
-
-#define UNREFERENCED_XPARAMETER
-
-#endif /* _IXGBE_TYPE_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.c b/kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.c
deleted file mode 100644
index 07b219a1c..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.c
+++ /dev/null
@@ -1,922 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "ixgbe_x540.h"
-#include "ixgbe_type.h"
-#include "ixgbe_api.h"
-#include "ixgbe_common.h"
-#include "ixgbe_phy.h"
-
-static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw);
-static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
-static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw);
-static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw);
-
-/**
- * ixgbe_init_ops_X540 - Inits func ptrs and MAC type
- * @hw: pointer to hardware structure
- *
- * Initialize the function pointers and assign the MAC type for X540.
- * Does not touch the hardware.
- **/
-s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
-{
- struct ixgbe_mac_info *mac = &hw->mac;
- struct ixgbe_phy_info *phy = &hw->phy;
- struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
- s32 ret_val;
-
- ret_val = ixgbe_init_phy_ops_generic(hw);
- ret_val = ixgbe_init_ops_generic(hw);
-
-
- /* EEPROM */
- eeprom->ops.init_params = &ixgbe_init_eeprom_params_X540;
- eeprom->ops.read = &ixgbe_read_eerd_X540;
- eeprom->ops.read_buffer = &ixgbe_read_eerd_buffer_X540;
- eeprom->ops.write = &ixgbe_write_eewr_X540;
- eeprom->ops.write_buffer = &ixgbe_write_eewr_buffer_X540;
- eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_X540;
- eeprom->ops.validate_checksum = &ixgbe_validate_eeprom_checksum_X540;
- eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_X540;
-
- /* PHY */
- phy->ops.init = &ixgbe_init_phy_ops_generic;
- phy->ops.reset = NULL;
-
- /* MAC */
- mac->ops.reset_hw = &ixgbe_reset_hw_X540;
- mac->ops.get_media_type = &ixgbe_get_media_type_X540;
- mac->ops.get_supported_physical_layer =
- &ixgbe_get_supported_physical_layer_X540;
- mac->ops.read_analog_reg8 = NULL;
- mac->ops.write_analog_reg8 = NULL;
- mac->ops.start_hw = &ixgbe_start_hw_X540;
- mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic;
- mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_generic;
- mac->ops.get_device_caps = &ixgbe_get_device_caps_generic;
- mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic;
- mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic;
- mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540;
- mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync_X540;
- mac->ops.disable_sec_rx_path = &ixgbe_disable_sec_rx_path_generic;
- mac->ops.enable_sec_rx_path = &ixgbe_enable_sec_rx_path_generic;
-
- /* RAR, Multicast, VLAN */
- mac->ops.set_vmdq = &ixgbe_set_vmdq_generic;
- mac->ops.set_vmdq_san_mac = &ixgbe_set_vmdq_san_mac_generic;
- mac->ops.clear_vmdq = &ixgbe_clear_vmdq_generic;
- mac->ops.insert_mac_addr = &ixgbe_insert_mac_addr_generic;
- mac->rar_highwater = 1;
- mac->ops.set_vfta = &ixgbe_set_vfta_generic;
- mac->ops.set_vlvf = &ixgbe_set_vlvf_generic;
- mac->ops.clear_vfta = &ixgbe_clear_vfta_generic;
- mac->ops.init_uta_tables = &ixgbe_init_uta_tables_generic;
- mac->ops.set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing;
- mac->ops.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing;
-
- /* Link */
- mac->ops.get_link_capabilities =
- &ixgbe_get_copper_link_capabilities_generic;
- mac->ops.setup_link = &ixgbe_setup_mac_link_X540;
- mac->ops.setup_rxpba = &ixgbe_set_rxpba_generic;
- mac->ops.check_link = &ixgbe_check_mac_link_generic;
-
- mac->mcft_size = 128;
- mac->vft_size = 128;
- mac->num_rar_entries = 128;
- mac->rx_pb_size = 384;
- mac->max_tx_queues = 128;
- mac->max_rx_queues = 128;
- mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw);
-
- /*
- * FWSM register
- * ARC supported; valid only if manageability features are
- * enabled.
- */
- mac->arc_subsystem_valid = (IXGBE_READ_REG(hw, IXGBE_FWSM) &
- IXGBE_FWSM_MODE_MASK) ? true : false;
-
- //hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
-
- /* LEDs */
- mac->ops.blink_led_start = ixgbe_blink_led_start_X540;
- mac->ops.blink_led_stop = ixgbe_blink_led_stop_X540;
-
- /* Manageability interface */
- mac->ops.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic;
-
- return ret_val;
-}
-
-/**
- * ixgbe_get_link_capabilities_X540 - Determines link capabilities
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @autoneg: true when autoneg or autotry is enabled
- *
- * Determines the link capabilities by reading the AUTOC register.
- **/
-s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed,
- bool *autoneg)
-{
- ixgbe_get_copper_link_capabilities_generic(hw, speed, autoneg);
-
- return 0;
-}
-
-/**
- * ixgbe_get_media_type_X540 - Get media type
- * @hw: pointer to hardware structure
- *
- * Returns the media type (fiber, copper, backplane)
- **/
-enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw)
-{
- return ixgbe_media_type_copper;
-}
-
-/**
- * ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities
- * @hw: pointer to hardware structure
- * @speed: new link speed
- * @autoneg: true if autonegotiation enabled
- * @autoneg_wait_to_complete: true when waiting for completion is needed
- **/
-s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
- bool autoneg_wait_to_complete)
-{
- return hw->phy.ops.setup_link_speed(hw, speed, autoneg,
- autoneg_wait_to_complete);
-}
-
-/**
- * ixgbe_reset_hw_X540 - Perform hardware reset
- * @hw: pointer to hardware structure
- *
- * Resets the hardware by resetting the transmit and receive units, masks
- * and clears all interrupts, and perform a reset.
- **/
-s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
-{
- s32 status = 0;
-
- /*
- * Userland DPDK takes the ownershiop of device
- * Kernel driver here used as the simple path for ethtool only
- * Won't real reset device anyway
- */
-#if 0
- u32 ctrl, i;
-
- /* Call adapter stop to disable tx/rx and clear interrupts */
- status = hw->mac.ops.stop_adapter(hw);
- if (status != 0)
- goto reset_hw_out;
-
- /* flush pending Tx transactions */
- ixgbe_clear_tx_pending(hw);
-
-mac_reset_top:
- ctrl = IXGBE_CTRL_RST;
- ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
- IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
- IXGBE_WRITE_FLUSH(hw);
-
- /* Poll for reset bit to self-clear indicating reset is complete */
- for (i = 0; i < 10; i++) {
- udelay(1);
- ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
- if (!(ctrl & IXGBE_CTRL_RST_MASK))
- break;
- }
-
- if (ctrl & IXGBE_CTRL_RST_MASK) {
- status = IXGBE_ERR_RESET_FAILED;
- hw_dbg(hw, "Reset polling failed to complete.\n");
- }
- msleep(100);
-
- /*
- * Double resets are required for recovery from certain error
- * conditions. Between resets, it is necessary to stall to allow time
- * for any pending HW events to complete.
- */
- if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
- hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
- goto mac_reset_top;
- }
-
- /* Set the Rx packet buffer size. */
- IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT);
-
-#endif
-
- /* Store the permanent mac address */
- hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
-
- /*
- * Store MAC address from RAR0, clear receive address registers, and
- * clear the multicast table. Also reset num_rar_entries to 128,
- * since we modify this value when programming the SAN MAC address.
- */
- hw->mac.num_rar_entries = 128;
- hw->mac.ops.init_rx_addrs(hw);
-
- /* Store the permanent SAN mac address */
- hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
-
- /* Add the SAN MAC address to the RAR only if it's a valid address */
- if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
- hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
- hw->mac.san_addr, 0, IXGBE_RAH_AV);
-
- /* Save the SAN MAC RAR index */
- hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
-
- /* Reserve the last RAR for the SAN MAC address */
- hw->mac.num_rar_entries--;
- }
-
- /* Store the alternative WWNN/WWPN prefix */
- hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
- &hw->mac.wwpn_prefix);
-
-//reset_hw_out:
- return status;
-}
-
-/**
- * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx
- * @hw: pointer to hardware structure
- *
- * Starts the hardware using the generic start_hw function
- * and the generation start_hw function.
- * Then performs revision-specific operations, if any.
- **/
-s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
-{
- s32 ret_val = 0;
-
- ret_val = ixgbe_start_hw_generic(hw);
- if (ret_val != 0)
- goto out;
-
- ret_val = ixgbe_start_hw_gen2(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
- * @hw: pointer to hardware structure
- *
- * Determines physical layer capabilities of the current configuration.
- **/
-u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
-{
- u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- u16 ext_ability = 0;
-
- hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
- if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
- if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
- if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
- physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
-
- return physical_layer;
-}
-
-/**
- * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params
- * @hw: pointer to hardware structure
- *
- * Initializes the EEPROM parameters ixgbe_eeprom_info within the
- * ixgbe_hw struct in order to set up EEPROM access.
- **/
-s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
-{
- struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
- u32 eec;
- u16 eeprom_size;
-
- if (eeprom->type == ixgbe_eeprom_uninitialized) {
- eeprom->semaphore_delay = 10;
- eeprom->type = ixgbe_flash;
-
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
- eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
- IXGBE_EEC_SIZE_SHIFT);
- eeprom->word_size = 1 << (eeprom_size +
- IXGBE_EEPROM_WORD_SIZE_SHIFT);
-
- hw_dbg(hw, "Eeprom params: type = %d, size = %d\n",
- eeprom->type, eeprom->word_size);
- }
-
- return 0;
-}
-
-/**
- * ixgbe_read_eerd_X540- Read EEPROM word using EERD
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @data: word read from the EEPROM
- *
- * Reads a 16 bit word from the EEPROM using the EERD register.
- **/
-s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
-{
- s32 status = 0;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- 0)
- status = ixgbe_read_eerd_generic(hw, offset, data);
- else
- status = IXGBE_ERR_SWFW_SYNC;
-
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- return status;
-}
-
-/**
- * ixgbe_read_eerd_buffer_X540- Read EEPROM word(s) using EERD
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @words: number of words
- * @data: word(s) read from the EEPROM
- *
- * Reads a 16 bit word(s) from the EEPROM using the EERD register.
- **/
-s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
- u16 offset, u16 words, u16 *data)
-{
- s32 status = 0;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- 0)
- status = ixgbe_read_eerd_buffer_generic(hw, offset,
- words, data);
- else
- status = IXGBE_ERR_SWFW_SYNC;
-
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- return status;
-}
-
-/**
- * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to write
- * @data: word write to the EEPROM
- *
- * Write a 16 bit word to the EEPROM using the EEWR register.
- **/
-s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
-{
- s32 status = 0;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- 0)
- status = ixgbe_write_eewr_generic(hw, offset, data);
- else
- status = IXGBE_ERR_SWFW_SYNC;
-
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- return status;
-}
-
-/**
- * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to write
- * @words: number of words
- * @data: word(s) write to the EEPROM
- *
- * Write a 16 bit word(s) to the EEPROM using the EEWR register.
- **/
-s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
- u16 offset, u16 words, u16 *data)
-{
- s32 status = 0;
-
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- 0)
- status = ixgbe_write_eewr_buffer_generic(hw, offset,
- words, data);
- else
- status = IXGBE_ERR_SWFW_SYNC;
-
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- return status;
-}
-
-/**
- * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
- *
- * This function does not use synchronization for EERD and EEWR. It can
- * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540.
- *
- * @hw: pointer to hardware structure
- **/
-u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
-{
- u16 i;
- u16 j;
- u16 checksum = 0;
- u16 length = 0;
- u16 pointer = 0;
- u16 word = 0;
-
- /*
- * Do not use hw->eeprom.ops.read because we do not want to take
- * the synchronization semaphores here. Instead use
- * ixgbe_read_eerd_generic
- */
-
- /* Include 0x0-0x3F in the checksum */
- for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
- if (ixgbe_read_eerd_generic(hw, i, &word) != 0) {
- hw_dbg(hw, "EEPROM read failed\n");
- break;
- }
- checksum += word;
- }
-
- /*
- * Include all data from pointers 0x3, 0x6-0xE. This excludes the
- * FW, PHY module, and PCIe Expansion/Option ROM pointers.
- */
- for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
- if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
- continue;
-
- if (ixgbe_read_eerd_generic(hw, i, &pointer) != 0) {
- hw_dbg(hw, "EEPROM read failed\n");
- break;
- }
-
- /* Skip pointer section if the pointer is invalid. */
- if (pointer == 0xFFFF || pointer == 0 ||
- pointer >= hw->eeprom.word_size)
- continue;
-
- if (ixgbe_read_eerd_generic(hw, pointer, &length) !=
- 0) {
- hw_dbg(hw, "EEPROM read failed\n");
- break;
- }
-
- /* Skip pointer section if length is invalid. */
- if (length == 0xFFFF || length == 0 ||
- (pointer + length) >= hw->eeprom.word_size)
- continue;
-
- for (j = pointer+1; j <= pointer+length; j++) {
- if (ixgbe_read_eerd_generic(hw, j, &word) !=
- 0) {
- hw_dbg(hw, "EEPROM read failed\n");
- break;
- }
- checksum += word;
- }
- }
-
- checksum = (u16)IXGBE_EEPROM_SUM - checksum;
-
- return checksum;
-}
-
-/**
- * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum
- * @hw: pointer to hardware structure
- * @checksum_val: calculated checksum
- *
- * Performs checksum calculation and validates the EEPROM checksum. If the
- * caller does not need checksum_val, the value can be NULL.
- **/
-s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
- u16 *checksum_val)
-{
- s32 status;
- u16 checksum;
- u16 read_checksum = 0;
-
- /*
- * Read the first word from the EEPROM. If this times out or fails, do
- * not continue or we could be in for a very long wait while every
- * EEPROM read fails
- */
- status = hw->eeprom.ops.read(hw, 0, &checksum);
-
- if (status != 0) {
- hw_dbg(hw, "EEPROM read failed\n");
- goto out;
- }
-
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- 0) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
-
- /*
- * Do not use hw->eeprom.ops.read because we do not want to take
- * the synchronization semaphores twice here.
- */
- ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
- &read_checksum);
-
- /*
- * Verify read checksum from EEPROM is the same as
- * calculated checksum
- */
- if (read_checksum != checksum)
- status = IXGBE_ERR_EEPROM_CHECKSUM;
-
- /* If the user cares, return the calculated checksum */
- if (checksum_val)
- *checksum_val = checksum;
- } else {
- status = IXGBE_ERR_SWFW_SYNC;
- }
-
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
-out:
- return status;
-}
-
-/**
- * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash
- * @hw: pointer to hardware structure
- *
- * After writing EEPROM to shadow RAM using EEWR register, software calculates
- * checksum and updates the EEPROM and instructs the hardware to update
- * the flash.
- **/
-s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
-{
- s32 status;
- u16 checksum;
-
- /*
- * Read the first word from the EEPROM. If this times out or fails, do
- * not continue or we could be in for a very long wait while every
- * EEPROM read fails
- */
- status = hw->eeprom.ops.read(hw, 0, &checksum);
-
- if (status != 0)
- hw_dbg(hw, "EEPROM read failed\n");
-
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- 0) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
-
- /*
- * Do not use hw->eeprom.ops.write because we do not want to
- * take the synchronization semaphores twice here.
- */
- status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM,
- checksum);
-
- if (status == 0)
- status = ixgbe_update_flash_X540(hw);
- else
- status = IXGBE_ERR_SWFW_SYNC;
- }
-
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
-
- return status;
-}
-
-/**
- * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device
- * @hw: pointer to hardware structure
- *
- * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy
- * EEPROM from shadow RAM to the flash device.
- **/
-static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
-{
- u32 flup;
- s32 status = IXGBE_ERR_EEPROM;
-
- status = ixgbe_poll_flash_update_done_X540(hw);
- if (status == IXGBE_ERR_EEPROM) {
- hw_dbg(hw, "Flash update time out\n");
- goto out;
- }
-
- flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
-
- status = ixgbe_poll_flash_update_done_X540(hw);
- if (status == 0)
- hw_dbg(hw, "Flash update complete\n");
- else
- hw_dbg(hw, "Flash update time out\n");
-
- if (hw->revision_id == 0) {
- flup = IXGBE_READ_REG(hw, IXGBE_EEC);
-
- if (flup & IXGBE_EEC_SEC1VAL) {
- flup |= IXGBE_EEC_FLUP;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
- }
-
- status = ixgbe_poll_flash_update_done_X540(hw);
- if (status == 0)
- hw_dbg(hw, "Flash update complete\n");
- else
- hw_dbg(hw, "Flash update time out\n");
- }
-out:
- return status;
-}
-
-/**
- * ixgbe_poll_flash_update_done_X540 - Poll flash update status
- * @hw: pointer to hardware structure
- *
- * Polls the FLUDONE (bit 26) of the EEC Register to determine when the
- * flash update is done.
- **/
-static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
-{
- u32 i;
- u32 reg;
- s32 status = IXGBE_ERR_EEPROM;
-
- for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) {
- reg = IXGBE_READ_REG(hw, IXGBE_EEC);
- if (reg & IXGBE_EEC_FLUDONE) {
- status = 0;
- break;
- }
- udelay(5);
- }
- return status;
-}
-
-/**
- * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore
- * @hw: pointer to hardware structure
- * @mask: Mask to specify which semaphore to acquire
- *
- * Acquires the SWFW semaphore thought the SW_FW_SYNC register for
- * the specified function (CSR, PHY0, PHY1, NVM, Flash)
- **/
-s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
-{
- u32 swfw_sync;
- u32 swmask = mask;
- u32 fwmask = mask << 5;
- u32 hwmask = 0;
- u32 timeout = 200;
- u32 i;
- s32 ret_val = 0;
-
- if (swmask == IXGBE_GSSR_EEP_SM)
- hwmask = IXGBE_GSSR_FLASH_SM;
-
- /* SW only mask doesn't have FW bit pair */
- if (swmask == IXGBE_GSSR_SW_MNG_SM)
- fwmask = 0;
-
- for (i = 0; i < timeout; i++) {
- /*
- * SW NVM semaphore bit is used for access to all
- * SW_FW_SYNC bits (not just NVM)
- */
- if (ixgbe_get_swfw_sync_semaphore(hw)) {
- ret_val = IXGBE_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
- if (!(swfw_sync & (fwmask | swmask | hwmask))) {
- swfw_sync |= swmask;
- IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
- ixgbe_release_swfw_sync_semaphore(hw);
- msleep(5);
- goto out;
- } else {
- /*
- * Firmware currently using resource (fwmask), hardware
- * currently using resource (hwmask), or other software
- * thread currently using resource (swmask)
- */
- ixgbe_release_swfw_sync_semaphore(hw);
- msleep(5);
- }
- }
-
- /* Failed to get SW only semaphore */
- if (swmask == IXGBE_GSSR_SW_MNG_SM) {
- ret_val = IXGBE_ERR_SWFW_SYNC;
- goto out;
- }
-
- /* If the resource is not released by the FW/HW the SW can assume that
- * the FW/HW malfunctions. In that case the SW should sets the SW bit(s)
- * of the requested resource(s) while ignoring the corresponding FW/HW
- * bits in the SW_FW_SYNC register.
- */
- swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
- if (swfw_sync & (fwmask | hwmask)) {
- if (ixgbe_get_swfw_sync_semaphore(hw)) {
- ret_val = IXGBE_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync |= swmask;
- IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
- ixgbe_release_swfw_sync_semaphore(hw);
- msleep(5);
- }
-
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore
- * @hw: pointer to hardware structure
- * @mask: Mask to specify which semaphore to release
- *
- * Releases the SWFW semaphore through the SW_FW_SYNC register
- * for the specified function (CSR, PHY0, PHY1, EVM, Flash)
- **/
-void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
-{
- u32 swfw_sync;
- u32 swmask = mask;
-
- ixgbe_get_swfw_sync_semaphore(hw);
-
- swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
- swfw_sync &= ~swmask;
- IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
-
- ixgbe_release_swfw_sync_semaphore(hw);
- msleep(5);
-}
-
-/**
- * ixgbe_get_nvm_semaphore - Get hardware semaphore
- * @hw: pointer to hardware structure
- *
- * Sets the hardware semaphores so SW/FW can gain control of shared resources
- **/
-static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
-{
- s32 status = IXGBE_ERR_EEPROM;
- u32 timeout = 2000;
- u32 i;
- u32 swsm;
-
- /* Get SMBI software semaphore between device drivers first */
- for (i = 0; i < timeout; i++) {
- /*
- * If the SMBI bit is 0 when we read it, then the bit will be
- * set and we have the semaphore
- */
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- if (!(swsm & IXGBE_SWSM_SMBI)) {
- status = 0;
- break;
- }
- udelay(50);
- }
-
- /* Now get the semaphore between SW/FW through the REGSMP bit */
- if (status == 0) {
- for (i = 0; i < timeout; i++) {
- swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
- if (!(swsm & IXGBE_SWFW_REGSMP))
- break;
-
- udelay(50);
- }
-
- /*
- * Release semaphores and return error if SW NVM semaphore
- * was not granted because we don't have access to the EEPROM
- */
- if (i >= timeout) {
- hw_dbg(hw, "REGSMP Software NVM semaphore not "
- "granted.\n");
- ixgbe_release_swfw_sync_semaphore(hw);
- status = IXGBE_ERR_EEPROM;
- }
- } else {
- hw_dbg(hw, "Software semaphore SMBI between device drivers "
- "not granted.\n");
- }
-
- return status;
-}
-
-/**
- * ixgbe_release_nvm_semaphore - Release hardware semaphore
- * @hw: pointer to hardware structure
- *
- * This function clears hardware semaphore bits.
- **/
-static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
-{
- u32 swsm;
-
- /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */
-
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- swsm &= ~IXGBE_SWSM_SMBI;
- IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
-
- swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
- swsm &= ~IXGBE_SWFW_REGSMP;
- IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm);
-
- IXGBE_WRITE_FLUSH(hw);
-}
-
-/**
- * ixgbe_blink_led_start_X540 - Blink LED based on index.
- * @hw: pointer to hardware structure
- * @index: led number to blink
- *
- * Devices that implement the version 2 interface:
- * X540
- **/
-s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
-{
- u32 macc_reg;
- u32 ledctl_reg;
- ixgbe_link_speed speed;
- bool link_up;
-
- /*
- * Link should be up in order for the blink bit in the LED control
- * register to work. Force link and speed in the MAC if link is down.
- * This will be reversed when we stop the blinking.
- */
- hw->mac.ops.check_link(hw, &speed, &link_up, false);
- if (link_up == false) {
- macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
- macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS;
- IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
- }
- /* Set the LED to LINK_UP + BLINK. */
- ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
- ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
- ledctl_reg |= IXGBE_LED_BLINK(index);
- IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
- IXGBE_WRITE_FLUSH(hw);
-
- return 0;
-}
-
-/**
- * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index.
- * @hw: pointer to hardware structure
- * @index: led number to stop blinking
- *
- * Devices that implement the version 2 interface:
- * X540
- **/
-s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
-{
- u32 macc_reg;
- u32 ledctl_reg;
-
- /* Restore the LED to its default value. */
- ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
- ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
- ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
- ledctl_reg &= ~IXGBE_LED_BLINK(index);
- IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
-
- /* Unforce link and speed in the MAC. */
- macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
- macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS);
- IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
- IXGBE_WRITE_FLUSH(hw);
-
- return 0;
-}
diff --git a/kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.h b/kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.h
deleted file mode 100644
index 96020911d..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _IXGBE_X540_H_
-#define _IXGBE_X540_H_
-
-#include "ixgbe_type.h"
-
-s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw,
- ixgbe_link_speed *speed, bool *autoneg);
-enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw);
-s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool link_up_wait_to_complete);
-s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw);
-s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw);
-u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw);
-
-s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw);
-s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data);
-s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, u16 offset, u16 words,
- u16 *data);
-s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data);
-s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, u16 offset, u16 words,
- u16 *data);
-s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw);
-s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, u16 *checksum_val);
-u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw);
-
-s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask);
-void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask);
-
-s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index);
-#endif /* _IXGBE_X540_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/kcompat.c b/kernel/linux/kni/ethtool/ixgbe/kcompat.c
deleted file mode 100644
index 6c9945764..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/kcompat.c
+++ /dev/null
@@ -1,1231 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "ixgbe.h"
-#include "kcompat.h"
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8) )
-/* From lib/vsprintf.c */
-#include <asm/div64.h>
-
-static int skip_atoi(const char **s)
-{
- int i=0;
-
- while (isdigit(**s))
- i = i*10 + *((*s)++) - '0';
- return i;
-}
-
-#define _kc_ZEROPAD 1 /* pad with zero */
-#define _kc_SIGN 2 /* unsigned/signed long */
-#define _kc_PLUS 4 /* show plus */
-#define _kc_SPACE 8 /* space if plus */
-#define _kc_LEFT 16 /* left justified */
-#define _kc_SPECIAL 32 /* 0x */
-#define _kc_LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
-
-static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type)
-{
- char c,sign,tmp[66];
- const char *digits;
- const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
- const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- int i;
-
- digits = (type & _kc_LARGE) ? large_digits : small_digits;
- if (type & _kc_LEFT)
- type &= ~_kc_ZEROPAD;
- if (base < 2 || base > 36)
- return 0;
- c = (type & _kc_ZEROPAD) ? '0' : ' ';
- sign = 0;
- if (type & _kc_SIGN) {
- if (num < 0) {
- sign = '-';
- num = -num;
- size--;
- } else if (type & _kc_PLUS) {
- sign = '+';
- size--;
- } else if (type & _kc_SPACE) {
- sign = ' ';
- size--;
- }
- }
- if (type & _kc_SPECIAL) {
- if (base == 16)
- size -= 2;
- else if (base == 8)
- size--;
- }
- i = 0;
- if (num == 0)
- tmp[i++]='0';
- else while (num != 0)
- tmp[i++] = digits[do_div(num,base)];
- if (i > precision)
- precision = i;
- size -= precision;
- if (!(type&(_kc_ZEROPAD+_kc_LEFT))) {
- while(size-->0) {
- if (buf <= end)
- *buf = ' ';
- ++buf;
- }
- }
- if (sign) {
- if (buf <= end)
- *buf = sign;
- ++buf;
- }
- if (type & _kc_SPECIAL) {
- if (base==8) {
- if (buf <= end)
- *buf = '0';
- ++buf;
- } else if (base==16) {
- if (buf <= end)
- *buf = '0';
- ++buf;
- if (buf <= end)
- *buf = digits[33];
- ++buf;
- }
- }
- if (!(type & _kc_LEFT)) {
- while (size-- > 0) {
- if (buf <= end)
- *buf = c;
- ++buf;
- }
- }
- while (i < precision--) {
- if (buf <= end)
- *buf = '0';
- ++buf;
- }
- while (i-- > 0) {
- if (buf <= end)
- *buf = tmp[i];
- ++buf;
- }
- while (size-- > 0) {
- if (buf <= end)
- *buf = ' ';
- ++buf;
- }
- return buf;
-}
-
-int _kc_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
- int len;
- unsigned long long num;
- int i, base;
- char *str, *end, c;
- const char *s;
-
- int flags; /* flags to number() */
-
- int field_width; /* width of output field */
- int precision; /* min. # of digits for integers; max
- number of chars for from string */
- int qualifier; /* 'h', 'l', or 'L' for integer fields */
- /* 'z' support added 23/7/1999 S.H. */
- /* 'z' changed to 'Z' --davidm 1/25/99 */
-
- str = buf;
- end = buf + size - 1;
-
- if (end < buf - 1) {
- end = ((void *) -1);
- size = end - buf + 1;
- }
-
- for (; *fmt ; ++fmt) {
- if (*fmt != '%') {
- if (str <= end)
- *str = *fmt;
- ++str;
- continue;
- }
-
- /* process flags */
- flags = 0;
- repeat:
- ++fmt; /* this also skips first '%' */
- switch (*fmt) {
- case '-': flags |= _kc_LEFT; goto repeat;
- case '+': flags |= _kc_PLUS; goto repeat;
- case ' ': flags |= _kc_SPACE; goto repeat;
- case '#': flags |= _kc_SPECIAL; goto repeat;
- case '0': flags |= _kc_ZEROPAD; goto repeat;
- }
-
- /* get field width */
- field_width = -1;
- if (isdigit(*fmt))
- field_width = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- field_width = va_arg(args, int);
- if (field_width < 0) {
- field_width = -field_width;
- flags |= _kc_LEFT;
- }
- }
-
- /* get the precision */
- precision = -1;
- if (*fmt == '.') {
- ++fmt;
- if (isdigit(*fmt))
- precision = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- precision = va_arg(args, int);
- }
- if (precision < 0)
- precision = 0;
- }
-
- /* get the conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
- qualifier = *fmt;
- ++fmt;
- }
-
- /* default base */
- base = 10;
-
- switch (*fmt) {
- case 'c':
- if (!(flags & _kc_LEFT)) {
- while (--field_width > 0) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- }
- c = (unsigned char) va_arg(args, int);
- if (str <= end)
- *str = c;
- ++str;
- while (--field_width > 0) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- continue;
-
- case 's':
- s = va_arg(args, char *);
- if (!s)
- s = "<NULL>";
-
- len = strnlen(s, precision);
-
- if (!(flags & _kc_LEFT)) {
- while (len < field_width--) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- }
- for (i = 0; i < len; ++i) {
- if (str <= end)
- *str = *s;
- ++str; ++s;
- }
- while (len < field_width--) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- continue;
-
- case 'p':
- if (field_width == -1) {
- field_width = 2*sizeof(void *);
- flags |= _kc_ZEROPAD;
- }
- str = number(str, end,
- (unsigned long) va_arg(args, void *),
- 16, field_width, precision, flags);
- continue;
-
-
- case 'n':
- /* FIXME:
- * What does C99 say about the overflow case here? */
- if (qualifier == 'l') {
- long * ip = va_arg(args, long *);
- *ip = (str - buf);
- } else if (qualifier == 'Z') {
- size_t * ip = va_arg(args, size_t *);
- *ip = (str - buf);
- } else {
- int * ip = va_arg(args, int *);
- *ip = (str - buf);
- }
- continue;
-
- case '%':
- if (str <= end)
- *str = '%';
- ++str;
- continue;
-
- /* integer number formats - set up the flags and "break" */
- case 'o':
- base = 8;
- break;
-
- case 'X':
- flags |= _kc_LARGE;
- case 'x':
- base = 16;
- break;
-
- case 'd':
- case 'i':
- flags |= _kc_SIGN;
- case 'u':
- break;
-
- default:
- if (str <= end)
- *str = '%';
- ++str;
- if (*fmt) {
- if (str <= end)
- *str = *fmt;
- ++str;
- } else {
- --fmt;
- }
- continue;
- }
- if (qualifier == 'L')
- num = va_arg(args, long long);
- else if (qualifier == 'l') {
- num = va_arg(args, unsigned long);
- if (flags & _kc_SIGN)
- num = (signed long) num;
- } else if (qualifier == 'Z') {
- num = va_arg(args, size_t);
- } else if (qualifier == 'h') {
- num = (unsigned short) va_arg(args, int);
- if (flags & _kc_SIGN)
- num = (signed short) num;
- } else {
- num = va_arg(args, unsigned int);
- if (flags & _kc_SIGN)
- num = (signed int) num;
- }
- str = number(str, end, num, base,
- field_width, precision, flags);
- }
- if (str <= end)
- *str = '\0';
- else if (size > 0)
- /* don't write out a null byte if the buf size is zero */
- *end = '\0';
- /* the trailing null byte doesn't count towards the total
- * ++str;
- */
- return str-buf;
-}
-
-int _kc_snprintf(char * buf, size_t size, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i = _kc_vsnprintf(buf,size,fmt,args);
- va_end(args);
- return i;
-}
-#endif /* < 2.4.8 */
-
-
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) )
-#ifdef CONFIG_PCI_IOV
-int __kc_pci_vfs_assigned(struct pci_dev *dev)
-{
- unsigned int vfs_assigned = 0;
-#ifdef HAVE_PCI_DEV_FLAGS_ASSIGNED
- int pos;
- struct pci_dev *vfdev;
- unsigned short dev_id;
-
- /* only search if we are a PF */
- if (!dev->is_physfn)
- return 0;
-
- /* find SR-IOV capability */
- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
- if (!pos)
- return 0;
-
- /*
- * * determine the device ID for the VFs, the vendor ID will be the
- * * same as the PF so there is no need to check for that one
- * */
- pci_read_config_word(dev, pos + PCI_SRIOV_VF_DID, &dev_id);
-
- /* loop through all the VFs to see if we own any that are assigned */
- vfdev = pci_get_device(dev->vendor, dev_id, NULL);
- while (vfdev) {
- /*
- * * It is considered assigned if it is a virtual function with
- * * our dev as the physical function and the assigned bit is set
- * */
- if (vfdev->is_virtfn && (vfdev->physfn == dev) &&
- (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED))
- vfs_assigned++;
-
- vfdev = pci_get_device(dev->vendor, dev_id, vfdev);
- }
-
-#endif /* HAVE_PCI_DEV_FLAGS_ASSIGNED */
- return vfs_assigned;
-}
-
-#endif /* CONFIG_PCI_IOV */
-#endif /* 3.10.0 */
-
-
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) )
-
-/**************************************/
-/* PCI DMA MAPPING */
-
-#if defined(CONFIG_HIGHMEM)
-
-#ifndef PCI_DRAM_OFFSET
-#define PCI_DRAM_OFFSET 0
-#endif
-
-u64
-_kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset,
- size_t size, int direction)
-{
- return ((u64) (page - mem_map) << PAGE_SHIFT) + offset +
- PCI_DRAM_OFFSET;
-}
-
-#else /* CONFIG_HIGHMEM */
-
-u64
-_kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset,
- size_t size, int direction)
-{
- return pci_map_single(dev, (void *)page_address(page) + offset, size,
- direction);
-}
-
-#endif /* CONFIG_HIGHMEM */
-
-void
-_kc_pci_unmap_page(struct pci_dev *dev, u64 dma_addr, size_t size,
- int direction)
-{
- return pci_unmap_single(dev, dma_addr, size, direction);
-}
-
-#endif /* 2.4.13 => 2.4.3 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) )
-
-/**************************************/
-/* PCI DRIVER API */
-
-int
-_kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask)
-{
- if (!pci_dma_supported(dev, mask))
- return -EIO;
- dev->dma_mask = mask;
- return 0;
-}
-
-int
-_kc_pci_request_regions(struct pci_dev *dev, char *res_name)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- if (pci_resource_len(dev, i) == 0)
- continue;
-
- if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
- if (!request_region(pci_resource_start(dev, i), pci_resource_len(dev, i), res_name)) {
- pci_release_regions(dev);
- return -EBUSY;
- }
- } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
- if (!request_mem_region(pci_resource_start(dev, i), pci_resource_len(dev, i), res_name)) {
- pci_release_regions(dev);
- return -EBUSY;
- }
- }
- }
- return 0;
-}
-
-void
-_kc_pci_release_regions(struct pci_dev *dev)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- if (pci_resource_len(dev, i) == 0)
- continue;
-
- if (pci_resource_flags(dev, i) & IORESOURCE_IO)
- release_region(pci_resource_start(dev, i), pci_resource_len(dev, i));
-
- else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
- release_mem_region(pci_resource_start(dev, i), pci_resource_len(dev, i));
- }
-}
-
-/**************************************/
-/* NETWORK DRIVER API */
-
-struct net_device *
-_kc_alloc_etherdev(int sizeof_priv)
-{
- struct net_device *dev;
- int alloc_size;
-
- alloc_size = sizeof(*dev) + sizeof_priv + IFNAMSIZ + 31;
- dev = kzalloc(alloc_size, GFP_KERNEL);
- if (!dev)
- return NULL;
-
- if (sizeof_priv)
- dev->priv = (void *) (((unsigned long)(dev + 1) + 31) & ~31);
- dev->name[0] = '\0';
- ether_setup(dev);
-
- return dev;
-}
-
-int
-_kc_is_valid_ether_addr(u8 *addr)
-{
- const char zaddr[6] = { 0, };
-
- return !(addr[0] & 1) && memcmp(addr, zaddr, 6);
-}
-
-#endif /* 2.4.3 => 2.4.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) )
-
-int
-_kc_pci_set_power_state(struct pci_dev *dev, int state)
-{
- return 0;
-}
-
-int
-_kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable)
-{
- return 0;
-}
-
-#endif /* 2.4.6 => 2.4.3 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page,
- int off, int size)
-{
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- frag->page = page;
- frag->page_offset = off;
- frag->size = size;
- skb_shinfo(skb)->nr_frags = i + 1;
-}
-
-/*
- * Original Copyright:
- * find_next_bit.c: fallback find next bit implementation
- *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- */
-
-/**
- * find_next_bit - find the next set bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
- */
-unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
-{
- const unsigned long *p = addr + BITOP_WORD(offset);
- unsigned long result = offset & ~(BITS_PER_LONG-1);
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset %= BITS_PER_LONG;
- if (offset) {
- tmp = *(p++);
- tmp &= (~0UL << offset);
- if (size < BITS_PER_LONG)
- goto found_first;
- if (tmp)
- goto found_middle;
- size -= BITS_PER_LONG;
- result += BITS_PER_LONG;
- }
- while (size & ~(BITS_PER_LONG-1)) {
- if ((tmp = *(p++)))
- goto found_middle;
- result += BITS_PER_LONG;
- size -= BITS_PER_LONG;
- }
- if (!size)
- return result;
- tmp = *p;
-
-found_first:
- tmp &= (~0UL >> (BITS_PER_LONG - size));
- if (tmp == 0UL) /* Are any bits set? */
- return result + size; /* Nope. */
-found_middle:
- return result + ffs(tmp);
-}
-
-size_t _kc_strlcpy(char *dest, const char *src, size_t size)
-{
- size_t ret = strlen(src);
-
- if (size) {
- size_t len = (ret >= size) ? size - 1 : ret;
- memcpy(dest, src, len);
- dest[len] = '\0';
- }
- return ret;
-}
-
-#endif /* 2.6.0 => 2.4.6 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) )
-int _kc_scnprintf(char * buf, size_t size, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i = vsnprintf(buf, size, fmt, args);
- va_end(args);
- return (i >= size) ? (size - 1) : i;
-}
-#endif /* < 2.6.4 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
-DECLARE_BITMAP(_kcompat_node_online_map, MAX_NUMNODES) = {1};
-#endif /* < 2.6.10 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
-char *_kc_kstrdup(const char *s, unsigned int gfp)
-{
- size_t len;
- char *buf;
-
- if (!s)
- return NULL;
-
- len = strlen(s) + 1;
- buf = kmalloc(len, gfp);
- if (buf)
- memcpy(buf, s, len);
- return buf;
-}
-#endif /* < 2.6.13 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) )
-void *_kc_kzalloc(size_t size, int flags)
-{
- void *ret = kmalloc(size, flags);
- if (ret)
- memset(ret, 0, size);
- return ret;
-}
-#endif /* <= 2.6.13 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) )
-int _kc_skb_pad(struct sk_buff *skb, int pad)
-{
- int ntail;
-
- /* If the skbuff is non linear tailroom is always zero.. */
- if(!skb_cloned(skb) && skb_tailroom(skb) >= pad) {
- memset(skb->data+skb->len, 0, pad);
- return 0;
- }
-
- ntail = skb->data_len + pad - (skb->end - skb->tail);
- if (likely(skb_cloned(skb) || ntail > 0)) {
- if (pskb_expand_head(skb, 0, ntail, GFP_ATOMIC));
- goto free_skb;
- }
-
-#ifdef MAX_SKB_FRAGS
- if (skb_is_nonlinear(skb) &&
- !__pskb_pull_tail(skb, skb->data_len))
- goto free_skb;
-
-#endif
- memset(skb->data + skb->len, 0, pad);
- return 0;
-
-free_skb:
- kfree_skb(skb);
- return -ENOMEM;
-}
-
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,4)))
-int _kc_pci_save_state(struct pci_dev *pdev)
-{
- struct adapter_struct *adapter = pci_get_drvdata(pdev);
- int size = PCI_CONFIG_SPACE_LEN, i;
- u16 pcie_cap_offset, pcie_link_status;
-
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) )
- /* no ->dev for 2.4 kernels */
- WARN_ON(pdev->dev.driver_data == NULL);
-#endif
- pcie_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (pcie_cap_offset) {
- if (!pci_read_config_word(pdev,
- pcie_cap_offset + PCIE_LINK_STATUS,
- &pcie_link_status))
- size = PCIE_CONFIG_SPACE_LEN;
- }
- pci_config_space_ich8lan();
-#ifdef HAVE_PCI_ERS
- if (adapter->config_space == NULL)
-#else
- WARN_ON(adapter->config_space != NULL);
-#endif
- adapter->config_space = kmalloc(size, GFP_KERNEL);
- if (!adapter->config_space) {
- printk(KERN_ERR "Out of memory in pci_save_state\n");
- return -ENOMEM;
- }
- for (i = 0; i < (size / 4); i++)
- pci_read_config_dword(pdev, i * 4, &adapter->config_space[i]);
- return 0;
-}
-
-void _kc_pci_restore_state(struct pci_dev *pdev)
-{
- struct adapter_struct *adapter = pci_get_drvdata(pdev);
- int size = PCI_CONFIG_SPACE_LEN, i;
- u16 pcie_cap_offset;
- u16 pcie_link_status;
-
- if (adapter->config_space != NULL) {
- pcie_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (pcie_cap_offset &&
- !pci_read_config_word(pdev,
- pcie_cap_offset + PCIE_LINK_STATUS,
- &pcie_link_status))
- size = PCIE_CONFIG_SPACE_LEN;
-
- pci_config_space_ich8lan();
- for (i = 0; i < (size / 4); i++)
- pci_write_config_dword(pdev, i * 4, adapter->config_space[i]);
-#ifndef HAVE_PCI_ERS
- kfree(adapter->config_space);
- adapter->config_space = NULL;
-#endif
- }
-}
-#endif /* !(RHEL_RELEASE_CODE >= RHEL 5.4) */
-
-#ifdef HAVE_PCI_ERS
-void _kc_free_netdev(struct net_device *netdev)
-{
- struct adapter_struct *adapter = netdev_priv(netdev);
-
- if (adapter->config_space != NULL)
- kfree(adapter->config_space);
-#ifdef CONFIG_SYSFS
- if (netdev->reg_state == NETREG_UNINITIALIZED) {
- kfree((char *)netdev - netdev->padded);
- } else {
- BUG_ON(netdev->reg_state != NETREG_UNREGISTERED);
- netdev->reg_state = NETREG_RELEASED;
- class_device_put(&netdev->class_dev);
- }
-#else
- kfree((char *)netdev - netdev->padded);
-#endif
-}
-#endif
-
-void *_kc_kmemdup(const void *src, size_t len, unsigned gfp)
-{
- void *p;
-
- p = kzalloc(len, gfp);
- if (p)
- memcpy(p, src, len);
- return p;
-}
-#endif /* <= 2.6.19 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) )
-/* hexdump code taken from lib/hexdump.c */
-static void _kc_hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
- int groupsize, unsigned char *linebuf,
- size_t linebuflen, bool ascii)
-{
- const u8 *ptr = buf;
- u8 ch;
- int j, lx = 0;
- int ascii_column;
-
- if (rowsize != 16 && rowsize != 32)
- rowsize = 16;
-
- if (!len)
- goto nil;
- if (len > rowsize) /* limit to one line at a time */
- len = rowsize;
- if ((len % groupsize) != 0) /* no mixed size output */
- groupsize = 1;
-
- switch (groupsize) {
- case 8: {
- const u64 *ptr8 = buf;
- int ngroups = len / groupsize;
-
- for (j = 0; j < ngroups; j++)
- lx += scnprintf((char *)(linebuf + lx), linebuflen - lx,
- "%s%16.16llx", j ? " " : "",
- (unsigned long long)*(ptr8 + j));
- ascii_column = 17 * ngroups + 2;
- break;
- }
-
- case 4: {
- const u32 *ptr4 = buf;
- int ngroups = len / groupsize;
-
- for (j = 0; j < ngroups; j++)
- lx += scnprintf((char *)(linebuf + lx), linebuflen - lx,
- "%s%8.8x", j ? " " : "", *(ptr4 + j));
- ascii_column = 9 * ngroups + 2;
- break;
- }
-
- case 2: {
- const u16 *ptr2 = buf;
- int ngroups = len / groupsize;
-
- for (j = 0; j < ngroups; j++)
- lx += scnprintf((char *)(linebuf + lx), linebuflen - lx,
- "%s%4.4x", j ? " " : "", *(ptr2 + j));
- ascii_column = 5 * ngroups + 2;
- break;
- }
-
- default:
- for (j = 0; (j < len) && (lx + 3) <= linebuflen; j++) {
- ch = ptr[j];
- linebuf[lx++] = hex_asc(ch >> 4);
- linebuf[lx++] = hex_asc(ch & 0x0f);
- linebuf[lx++] = ' ';
- }
- if (j)
- lx--;
-
- ascii_column = 3 * rowsize + 2;
- break;
- }
- if (!ascii)
- goto nil;
-
- while (lx < (linebuflen - 1) && lx < (ascii_column - 1))
- linebuf[lx++] = ' ';
- for (j = 0; (j < len) && (lx + 2) < linebuflen; j++)
- linebuf[lx++] = (isascii(ptr[j]) && isprint(ptr[j])) ? ptr[j]
- : '.';
-nil:
- linebuf[lx++] = '\0';
-}
-
-void _kc_print_hex_dump(const char *level,
- const char *prefix_str, int prefix_type,
- int rowsize, int groupsize,
- const void *buf, size_t len, bool ascii)
-{
- const u8 *ptr = buf;
- int i, linelen, remaining = len;
- unsigned char linebuf[200];
-
- if (rowsize != 16 && rowsize != 32)
- rowsize = 16;
-
- for (i = 0; i < len; i += rowsize) {
- linelen = min(remaining, rowsize);
- remaining -= rowsize;
- _kc_hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
- linebuf, sizeof(linebuf), ascii);
-
- switch (prefix_type) {
- case DUMP_PREFIX_ADDRESS:
- printk("%s%s%*p: %s\n", level, prefix_str,
- (int)(2 * sizeof(void *)), ptr + i, linebuf);
- break;
- case DUMP_PREFIX_OFFSET:
- printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf);
- break;
- default:
- printk("%s%s%s\n", level, prefix_str, linebuf);
- break;
- }
- }
-}
-#endif /* < 2.6.22 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) )
-int ixgbe_dcb_netlink_register(void)
-{
- return 0;
-}
-
-int ixgbe_dcb_netlink_unregister(void)
-{
- return 0;
-}
-
-int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max)
-{
- return 0;
-}
-#endif /* < 2.6.23 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) )
-#ifdef NAPI
-struct net_device *napi_to_poll_dev(struct napi_struct *napi)
-{
- struct adapter_q_vector *q_vector = container_of(napi,
- struct adapter_q_vector,
- napi);
- return &q_vector->poll_dev;
-}
-
-int __kc_adapter_clean(struct net_device *netdev, int *budget)
-{
- int work_done;
- int work_to_do = min(*budget, netdev->quota);
- /* kcompat.h netif_napi_add puts napi struct in "fake netdev->priv" */
- struct napi_struct *napi = netdev->priv;
- work_done = napi->poll(napi, work_to_do);
- *budget -= work_done;
- netdev->quota -= work_done;
- return (work_done >= work_to_do) ? 1 : 0;
-}
-#endif /* NAPI */
-#endif /* <= 2.6.24 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) )
-void _kc_pci_disable_link_state(struct pci_dev *pdev, int state)
-{
- struct pci_dev *parent = pdev->bus->self;
- u16 link_state;
- int pos;
-
- if (!parent)
- return;
-
- pos = pci_find_capability(parent, PCI_CAP_ID_EXP);
- if (pos) {
- pci_read_config_word(parent, pos + PCI_EXP_LNKCTL, &link_state);
- link_state &= ~state;
- pci_write_config_word(parent, pos + PCI_EXP_LNKCTL, link_state);
- }
-}
-#endif /* < 2.6.26 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) )
-#ifdef HAVE_TX_MQ
-void _kc_netif_tx_stop_all_queues(struct net_device *netdev)
-{
- struct adapter_struct *adapter = netdev_priv(netdev);
- int i;
-
- netif_stop_queue(netdev);
- if (netif_is_multiqueue(netdev))
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_stop_subqueue(netdev, i);
-}
-void _kc_netif_tx_wake_all_queues(struct net_device *netdev)
-{
- struct adapter_struct *adapter = netdev_priv(netdev);
- int i;
-
- netif_wake_queue(netdev);
- if (netif_is_multiqueue(netdev))
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_wake_subqueue(netdev, i);
-}
-void _kc_netif_tx_start_all_queues(struct net_device *netdev)
-{
- struct adapter_struct *adapter = netdev_priv(netdev);
- int i;
-
- netif_start_queue(netdev);
- if (netif_is_multiqueue(netdev))
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_start_subqueue(netdev, i);
-}
-#endif /* HAVE_TX_MQ */
-
-#ifndef __WARN_printf
-void __kc_warn_slowpath(const char *file, int line, const char *fmt, ...)
-{
- va_list args;
-
- printk(KERN_WARNING "------------[ cut here ]------------\n");
- printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file, line);
- va_start(args, fmt);
- vprintk(fmt, args);
- va_end(args);
-
- dump_stack();
-}
-#endif /* __WARN_printf */
-#endif /* < 2.6.27 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) )
-
-int
-_kc_pci_prepare_to_sleep(struct pci_dev *dev)
-{
- pci_power_t target_state;
- int error;
-
- target_state = pci_choose_state(dev, PMSG_SUSPEND);
-
- pci_enable_wake(dev, target_state, true);
-
- error = pci_set_power_state(dev, target_state);
-
- if (error)
- pci_enable_wake(dev, target_state, false);
-
- return error;
-}
-
-int
-_kc_pci_wake_from_d3(struct pci_dev *dev, bool enable)
-{
- int err;
-
- err = pci_enable_wake(dev, PCI_D3cold, enable);
- if (err)
- goto out;
-
- err = pci_enable_wake(dev, PCI_D3hot, enable);
-
-out:
- return err;
-}
-#endif /* < 2.6.28 */
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) )
-void _kc_skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
- int off, int size)
-{
- skb_fill_page_desc(skb, i, page, off, size);
- skb->len += size;
- skb->data_len += size;
- skb->truesize += size;
-}
-#endif /* < 3.4.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) )
-#ifdef HAVE_NETDEV_SELECT_QUEUE
-#include <net/ip.h>
-static u32 _kc_simple_tx_hashrnd;
-static u32 _kc_simple_tx_hashrnd_initialized;
-
-u16 _kc_skb_tx_hash(struct net_device *dev, struct sk_buff *skb)
-{
- u32 addr1, addr2, ports;
- u32 hash, ihl;
- u8 ip_proto = 0;
-
- if (unlikely(!_kc_simple_tx_hashrnd_initialized)) {
- get_random_bytes(&_kc_simple_tx_hashrnd, 4);
- _kc_simple_tx_hashrnd_initialized = 1;
- }
-
- switch (skb->protocol) {
- case htons(ETH_P_IP):
- if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
- ip_proto = ip_hdr(skb)->protocol;
- addr1 = ip_hdr(skb)->saddr;
- addr2 = ip_hdr(skb)->daddr;
- ihl = ip_hdr(skb)->ihl;
- break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- case htons(ETH_P_IPV6):
- ip_proto = ipv6_hdr(skb)->nexthdr;
- addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
- addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
- ihl = (40 >> 2);
- break;
-#endif
- default:
- return 0;
- }
-
-
- switch (ip_proto) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- case IPPROTO_DCCP:
- case IPPROTO_ESP:
- case IPPROTO_AH:
- case IPPROTO_SCTP:
- case IPPROTO_UDPLITE:
- ports = *((u32 *) (skb_network_header(skb) + (ihl * 4)));
- break;
-
- default:
- ports = 0;
- break;
- }
-
- hash = jhash_3words(addr1, addr2, ports, _kc_simple_tx_hashrnd);
-
- return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
-}
-#endif /* HAVE_NETDEV_SELECT_QUEUE */
-#endif /* < 2.6.30 */
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) )
-#ifdef HAVE_TX_MQ
-#ifndef CONFIG_NETDEVICES_MULTIQUEUE
-void _kc_netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
-{
- unsigned int real_num = dev->real_num_tx_queues;
- struct Qdisc *qdisc;
- int i;
-
- if (unlikely(txq > dev->num_tx_queues))
- ;
- else if (txq > real_num)
- dev->real_num_tx_queues = txq;
- else if ( txq < real_num) {
- dev->real_num_tx_queues = txq;
- for (i = txq; i < dev->num_tx_queues; i++) {
- qdisc = netdev_get_tx_queue(dev, i)->qdisc;
- if (qdisc) {
- spin_lock_bh(qdisc_lock(qdisc));
- qdisc_reset(qdisc);
- spin_unlock_bh(qdisc_lock(qdisc));
- }
- }
- }
-}
-#endif /* CONFIG_NETDEVICES_MULTIQUEUE */
-#endif /* HAVE_TX_MQ */
-#endif /* < 2.6.35 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) )
-static const u32 _kc_flags_dup_features =
- (ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH);
-
-u32 _kc_ethtool_op_get_flags(struct net_device *dev)
-{
- return dev->features & _kc_flags_dup_features;
-}
-
-int _kc_ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported)
-{
- if (data & ~supported)
- return -EINVAL;
-
- dev->features = ((dev->features & ~_kc_flags_dup_features) |
- (data & _kc_flags_dup_features));
- return 0;
-}
-#endif /* < 2.6.36 */
-
-/******************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) )
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)))
-u8 _kc_netdev_get_num_tc(struct net_device *dev)
-{
- struct adapter_struct *kc_adapter = netdev_priv(dev);
- if (kc_adapter->flags & IXGBE_FLAG_DCB_ENABLED)
- return kc_adapter->tc;
- else
- return 0;
-}
-
-u8 _kc_netdev_get_prio_tc_map(struct net_device *dev, u8 up)
-{
- struct adapter_struct *kc_adapter = netdev_priv(dev);
- int tc;
- u8 map;
-
- for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
- map = kc_adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap;
-
- if (map & (1 << up))
- return tc;
- }
-
- return 0;
-}
-#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)) */
-#endif /* < 2.6.39 */
diff --git a/kernel/linux/kni/ethtool/ixgbe/kcompat.h b/kernel/linux/kni/ethtool/ixgbe/kcompat.h
deleted file mode 100644
index 7c7d6c317..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/kcompat.h
+++ /dev/null
@@ -1,3140 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*******************************************************************************
-
- Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2012 Intel Corporation.
-
- Contact Information:
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _KCOMPAT_H_
-#define _KCOMPAT_H_
-
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#else
-#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/udp.h>
-#include <linux/mii.h>
-#include <linux/vmalloc.h>
-#include <asm/io.h>
-#include <linux/ethtool.h>
-#include <linux/if_vlan.h>
-
-/* NAPI enable/disable flags here */
-/* enable NAPI for ixgbe by default */
-#undef CONFIG_IXGBE_NAPI
-#define CONFIG_IXGBE_NAPI
-#define NAPI
-#ifdef CONFIG_IXGBE_NAPI
-#undef NAPI
-#define NAPI
-#endif /* CONFIG_IXGBE_NAPI */
-#ifdef IXGBE_NAPI
-#undef NAPI
-#define NAPI
-#endif /* IXGBE_NAPI */
-#ifdef IXGBE_NO_NAPI
-#undef NAPI
-#endif /* IXGBE_NO_NAPI */
-
-#define adapter_struct ixgbe_adapter
-#define adapter_q_vector ixgbe_q_vector
-
-/* and finally set defines so that the code sees the changes */
-#ifdef NAPI
-#ifndef CONFIG_IXGBE_NAPI
-#define CONFIG_IXGBE_NAPI
-#endif
-#else
-#undef CONFIG_IXGBE_NAPI
-#endif /* NAPI */
-
-/* packet split disable/enable */
-#ifdef DISABLE_PACKET_SPLIT
-#ifndef CONFIG_IXGBE_DISABLE_PACKET_SPLIT
-#define CONFIG_IXGBE_DISABLE_PACKET_SPLIT
-#endif
-#endif /* DISABLE_PACKET_SPLIT */
-
-/* MSI compatibility code for all kernels and drivers */
-#ifdef DISABLE_PCI_MSI
-#undef CONFIG_PCI_MSI
-#endif
-#ifndef CONFIG_PCI_MSI
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) )
-struct msix_entry {
- u16 vector; /* kernel uses to write allocated vector */
- u16 entry; /* driver uses to specify entry, OS writes */
-};
-#endif
-#undef pci_enable_msi
-#define pci_enable_msi(a) -ENOTSUPP
-#undef pci_disable_msi
-#define pci_disable_msi(a) do {} while (0)
-#undef pci_enable_msix
-#define pci_enable_msix(a, b, c) -ENOTSUPP
-#undef pci_disable_msix
-#define pci_disable_msix(a) do {} while (0)
-#define msi_remove_pci_irq_vectors(a) do {} while (0)
-#endif /* CONFIG_PCI_MSI */
-#ifdef DISABLE_PM
-#undef CONFIG_PM
-#endif
-
-#ifdef DISABLE_NET_POLL_CONTROLLER
-#undef CONFIG_NET_POLL_CONTROLLER
-#endif
-
-#ifndef PMSG_SUSPEND
-#define PMSG_SUSPEND 3
-#endif
-
-/* generic boolean compatibility */
-#undef TRUE
-#undef FALSE
-#define TRUE true
-#define FALSE false
-#ifdef GCC_VERSION
-#if ( GCC_VERSION < 3000 )
-#define _Bool char
-#endif
-#else
-#define _Bool char
-#endif
-
-/* kernels less than 2.4.14 don't have this */
-#ifndef ETH_P_8021Q
-#define ETH_P_8021Q 0x8100
-#endif
-
-#ifndef module_param
-#define module_param(v,t,p) MODULE_PARM(v, "i");
-#endif
-
-#ifndef DMA_64BIT_MASK
-#define DMA_64BIT_MASK 0xffffffffffffffffULL
-#endif
-
-#ifndef DMA_32BIT_MASK
-#define DMA_32BIT_MASK 0x00000000ffffffffULL
-#endif
-
-#ifndef PCI_CAP_ID_EXP
-#define PCI_CAP_ID_EXP 0x10
-#endif
-
-#ifndef PCIE_LINK_STATE_L0S
-#define PCIE_LINK_STATE_L0S 1
-#endif
-#ifndef PCIE_LINK_STATE_L1
-#define PCIE_LINK_STATE_L1 2
-#endif
-
-#ifndef mmiowb
-#ifdef CONFIG_IA64
-#define mmiowb() asm volatile ("mf.a" ::: "memory")
-#else
-#define mmiowb()
-#endif
-#endif
-
-#ifndef SET_NETDEV_DEV
-#define SET_NETDEV_DEV(net, pdev)
-#endif
-
-#if !defined(HAVE_FREE_NETDEV) && ( LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) )
-#define free_netdev(x) kfree(x)
-#endif
-
-#ifdef HAVE_POLL_CONTROLLER
-#define CONFIG_NET_POLL_CONTROLLER
-#endif
-
-#ifndef SKB_DATAREF_SHIFT
-/* if we do not have the infrastructure to detect if skb_header is cloned
- just return false in all cases */
-#define skb_header_cloned(x) 0
-#endif
-
-#ifndef NETIF_F_GSO
-#define gso_size tso_size
-#define gso_segs tso_segs
-#endif
-
-#ifndef NETIF_F_GRO
-#define vlan_gro_receive(_napi, _vlgrp, _vlan, _skb) \
- vlan_hwaccel_receive_skb(_skb, _vlgrp, _vlan)
-#define napi_gro_receive(_napi, _skb) netif_receive_skb(_skb)
-#endif
-
-#ifndef NETIF_F_SCTP_CSUM
-#define NETIF_F_SCTP_CSUM 0
-#endif
-
-#ifndef NETIF_F_LRO
-#define NETIF_F_LRO (1 << 15)
-#endif
-
-#ifndef NETIF_F_NTUPLE
-#define NETIF_F_NTUPLE (1 << 27)
-#endif
-
-#ifndef IPPROTO_SCTP
-#define IPPROTO_SCTP 132
-#endif
-
-#ifndef CHECKSUM_PARTIAL
-#define CHECKSUM_PARTIAL CHECKSUM_HW
-#define CHECKSUM_COMPLETE CHECKSUM_HW
-#endif
-
-#ifndef __read_mostly
-#define __read_mostly
-#endif
-
-#ifndef MII_RESV1
-#define MII_RESV1 0x17 /* Reserved... */
-#endif
-
-#ifndef unlikely
-#define unlikely(_x) _x
-#define likely(_x) _x
-#endif
-
-#ifndef WARN_ON
-#define WARN_ON(x)
-#endif
-
-#ifndef PCI_DEVICE
-#define PCI_DEVICE(vend,dev) \
- .vendor = (vend), .device = (dev), \
- .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-#endif
-
-#ifndef node_online
-#define node_online(node) ((node) == 0)
-#endif
-
-#ifndef num_online_cpus
-#define num_online_cpus() smp_num_cpus
-#endif
-
-#ifndef cpu_online
-#define cpu_online(cpuid) test_bit((cpuid), &cpu_online_map)
-#endif
-
-#ifndef _LINUX_RANDOM_H
-#include <linux/random.h>
-#endif
-
-#ifndef DECLARE_BITMAP
-#ifndef BITS_TO_LONGS
-#define BITS_TO_LONGS(bits) (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
-#endif
-#define DECLARE_BITMAP(name,bits) long name[BITS_TO_LONGS(bits)]
-#endif
-
-#ifndef VLAN_HLEN
-#define VLAN_HLEN 4
-#endif
-
-#ifndef VLAN_ETH_HLEN
-#define VLAN_ETH_HLEN 18
-#endif
-
-#ifndef VLAN_ETH_FRAME_LEN
-#define VLAN_ETH_FRAME_LEN 1518
-#endif
-
-#if !defined(IXGBE_DCA) && !defined(IGB_DCA)
-#define dca_get_tag(b) 0
-#define dca_add_requester(a) -1
-#define dca_remove_requester(b) do { } while(0)
-#define DCA_PROVIDER_ADD 0x0001
-#define DCA_PROVIDER_REMOVE 0x0002
-#endif
-
-#ifndef DCA_GET_TAG_TWO_ARGS
-#define dca3_get_tag(a,b) dca_get_tag(b)
-#endif
-
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-#if defined(__i386__) || defined(__x86_64__)
-#define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-#endif
-#endif
-
-/* taken from 2.6.24 definition in linux/kernel.h */
-#ifndef IS_ALIGNED
-#define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0)
-#endif
-
-#ifndef NETIF_F_HW_VLAN_TX
-struct _kc_vlan_ethhdr {
- unsigned char h_dest[ETH_ALEN];
- unsigned char h_source[ETH_ALEN];
- __be16 h_vlan_proto;
- __be16 h_vlan_TCI;
- __be16 h_vlan_encapsulated_proto;
-};
-#define vlan_ethhdr _kc_vlan_ethhdr
-struct _kc_vlan_hdr {
- __be16 h_vlan_TCI;
- __be16 h_vlan_encapsulated_proto;
-};
-#define vlan_hdr _kc_vlan_hdr
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) )
-#define vlan_tx_tag_present(_skb) 0
-#define vlan_tx_tag_get(_skb) 0
-#endif
-#endif
-
-#ifndef VLAN_PRIO_SHIFT
-#define VLAN_PRIO_SHIFT 13
-#endif
-
-
-#ifndef __GFP_COLD
-#define __GFP_COLD 0
-#endif
-
-/*****************************************************************************/
-/* Installations with ethtool version without eeprom, adapter id, or statistics
- * support */
-
-#ifndef ETH_GSTRING_LEN
-#define ETH_GSTRING_LEN 32
-#endif
-
-#ifndef ETHTOOL_GSTATS
-#define ETHTOOL_GSTATS 0x1d
-#undef ethtool_drvinfo
-#define ethtool_drvinfo k_ethtool_drvinfo
-struct k_ethtool_drvinfo {
- u32 cmd;
- char driver[32];
- char version[32];
- char fw_version[32];
- char bus_info[32];
- char reserved1[32];
- char reserved2[16];
- u32 n_stats;
- u32 testinfo_len;
- u32 eedump_len;
- u32 regdump_len;
-};
-
-struct ethtool_stats {
- u32 cmd;
- u32 n_stats;
- u64 data[0];
-};
-#endif /* ETHTOOL_GSTATS */
-
-#ifndef ETHTOOL_PHYS_ID
-#define ETHTOOL_PHYS_ID 0x1c
-#endif /* ETHTOOL_PHYS_ID */
-
-#ifndef ETHTOOL_GSTRINGS
-#define ETHTOOL_GSTRINGS 0x1b
-enum ethtool_stringset {
- ETH_SS_TEST = 0,
- ETH_SS_STATS,
-};
-struct ethtool_gstrings {
- u32 cmd; /* ETHTOOL_GSTRINGS */
- u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/
- u32 len; /* number of strings in the string set */
- u8 data[0];
-};
-#endif /* ETHTOOL_GSTRINGS */
-
-#ifndef ETHTOOL_TEST
-#define ETHTOOL_TEST 0x1a
-enum ethtool_test_flags {
- ETH_TEST_FL_OFFLINE = (1 << 0),
- ETH_TEST_FL_FAILED = (1 << 1),
-};
-struct ethtool_test {
- u32 cmd;
- u32 flags;
- u32 reserved;
- u32 len;
- u64 data[0];
-};
-#endif /* ETHTOOL_TEST */
-
-#ifndef ETHTOOL_GEEPROM
-#define ETHTOOL_GEEPROM 0xb
-#undef ETHTOOL_GREGS
-struct ethtool_eeprom {
- u32 cmd;
- u32 magic;
- u32 offset;
- u32 len;
- u8 data[0];
-};
-
-struct ethtool_value {
- u32 cmd;
- u32 data;
-};
-#endif /* ETHTOOL_GEEPROM */
-
-#ifndef ETHTOOL_GLINK
-#define ETHTOOL_GLINK 0xa
-#endif /* ETHTOOL_GLINK */
-
-#ifndef ETHTOOL_GWOL
-#define ETHTOOL_GWOL 0x5
-#define ETHTOOL_SWOL 0x6
-#define SOPASS_MAX 6
-struct ethtool_wolinfo {
- u32 cmd;
- u32 supported;
- u32 wolopts;
- u8 sopass[SOPASS_MAX]; /* SecureOn(tm) password */
-};
-#endif /* ETHTOOL_GWOL */
-
-#ifndef ETHTOOL_GREGS
-#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers */
-#define ethtool_regs _kc_ethtool_regs
-/* for passing big chunks of data */
-struct _kc_ethtool_regs {
- u32 cmd;
- u32 version; /* driver-specific, indicates different chips/revs */
- u32 len; /* bytes */
- u8 data[0];
-};
-#endif /* ETHTOOL_GREGS */
-
-#ifndef ETHTOOL_GMSGLVL
-#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */
-#endif
-#ifndef ETHTOOL_SMSGLVL
-#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */
-#endif
-#ifndef ETHTOOL_NWAY_RST
-#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv */
-#endif
-#ifndef ETHTOOL_GLINK
-#define ETHTOOL_GLINK 0x0000000a /* Get link status */
-#endif
-#ifndef ETHTOOL_GEEPROM
-#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */
-#endif
-#ifndef ETHTOOL_SEEPROM
-#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */
-#endif
-#ifndef ETHTOOL_GCOALESCE
-#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */
-/* for configuring coalescing parameters of chip */
-#define ethtool_coalesce _kc_ethtool_coalesce
-struct _kc_ethtool_coalesce {
- u32 cmd; /* ETHTOOL_{G,S}COALESCE */
-
- /* How many usecs to delay an RX interrupt after
- * a packet arrives. If 0, only rx_max_coalesced_frames
- * is used.
- */
- u32 rx_coalesce_usecs;
-
- /* How many packets to delay an RX interrupt after
- * a packet arrives. If 0, only rx_coalesce_usecs is
- * used. It is illegal to set both usecs and max frames
- * to zero as this would cause RX interrupts to never be
- * generated.
- */
- u32 rx_max_coalesced_frames;
-
- /* Same as above two parameters, except that these values
- * apply while an IRQ is being serviced by the host. Not
- * all cards support this feature and the values are ignored
- * in that case.
- */
- u32 rx_coalesce_usecs_irq;
- u32 rx_max_coalesced_frames_irq;
-
- /* How many usecs to delay a TX interrupt after
- * a packet is sent. If 0, only tx_max_coalesced_frames
- * is used.
- */
- u32 tx_coalesce_usecs;
-
- /* How many packets to delay a TX interrupt after
- * a packet is sent. If 0, only tx_coalesce_usecs is
- * used. It is illegal to set both usecs and max frames
- * to zero as this would cause TX interrupts to never be
- * generated.
- */
- u32 tx_max_coalesced_frames;
-
- /* Same as above two parameters, except that these values
- * apply while an IRQ is being serviced by the host. Not
- * all cards support this feature and the values are ignored
- * in that case.
- */
- u32 tx_coalesce_usecs_irq;
- u32 tx_max_coalesced_frames_irq;
-
- /* How many usecs to delay in-memory statistics
- * block updates. Some drivers do not have an in-memory
- * statistic block, and in such cases this value is ignored.
- * This value must not be zero.
- */
- u32 stats_block_coalesce_usecs;
-
- /* Adaptive RX/TX coalescing is an algorithm implemented by
- * some drivers to improve latency under low packet rates and
- * improve throughput under high packet rates. Some drivers
- * only implement one of RX or TX adaptive coalescing. Anything
- * not implemented by the driver causes these values to be
- * silently ignored.
- */
- u32 use_adaptive_rx_coalesce;
- u32 use_adaptive_tx_coalesce;
-
- /* When the packet rate (measured in packets per second)
- * is below pkt_rate_low, the {rx,tx}_*_low parameters are
- * used.
- */
- u32 pkt_rate_low;
- u32 rx_coalesce_usecs_low;
- u32 rx_max_coalesced_frames_low;
- u32 tx_coalesce_usecs_low;
- u32 tx_max_coalesced_frames_low;
-
- /* When the packet rate is below pkt_rate_high but above
- * pkt_rate_low (both measured in packets per second) the
- * normal {rx,tx}_* coalescing parameters are used.
- */
-
- /* When the packet rate is (measured in packets per second)
- * is above pkt_rate_high, the {rx,tx}_*_high parameters are
- * used.
- */
- u32 pkt_rate_high;
- u32 rx_coalesce_usecs_high;
- u32 rx_max_coalesced_frames_high;
- u32 tx_coalesce_usecs_high;
- u32 tx_max_coalesced_frames_high;
-
- /* How often to do adaptive coalescing packet rate sampling,
- * measured in seconds. Must not be zero.
- */
- u32 rate_sample_interval;
-};
-#endif /* ETHTOOL_GCOALESCE */
-
-#ifndef ETHTOOL_SCOALESCE
-#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */
-#endif
-#ifndef ETHTOOL_GRINGPARAM
-#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */
-/* for configuring RX/TX ring parameters */
-#define ethtool_ringparam _kc_ethtool_ringparam
-struct _kc_ethtool_ringparam {
- u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */
-
- /* Read only attributes. These indicate the maximum number
- * of pending RX/TX ring entries the driver will allow the
- * user to set.
- */
- u32 rx_max_pending;
- u32 rx_mini_max_pending;
- u32 rx_jumbo_max_pending;
- u32 tx_max_pending;
-
- /* Values changeable by the user. The valid values are
- * in the range 1 to the "*_max_pending" counterpart above.
- */
- u32 rx_pending;
- u32 rx_mini_pending;
- u32 rx_jumbo_pending;
- u32 tx_pending;
-};
-#endif /* ETHTOOL_GRINGPARAM */
-
-#ifndef ETHTOOL_SRINGPARAM
-#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */
-#endif
-#ifndef ETHTOOL_GPAUSEPARAM
-#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */
-/* for configuring link flow control parameters */
-#define ethtool_pauseparam _kc_ethtool_pauseparam
-struct _kc_ethtool_pauseparam {
- u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */
-
- /* If the link is being auto-negotiated (via ethtool_cmd.autoneg
- * being true) the user may set 'autoneg' here non-zero to have the
- * pause parameters be auto-negotiated too. In such a case, the
- * {rx,tx}_pause values below determine what capabilities are
- * advertised.
- *
- * If 'autoneg' is zero or the link is not being auto-negotiated,
- * then {rx,tx}_pause force the driver to use/not-use pause
- * flow control.
- */
- u32 autoneg;
- u32 rx_pause;
- u32 tx_pause;
-};
-#endif /* ETHTOOL_GPAUSEPARAM */
-
-#ifndef ETHTOOL_SPAUSEPARAM
-#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */
-#endif
-#ifndef ETHTOOL_GRXCSUM
-#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_SRXCSUM
-#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_GTXCSUM
-#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_STXCSUM
-#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_GSG
-#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable
- * (ethtool_value) */
-#endif
-#ifndef ETHTOOL_SSG
-#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable
- * (ethtool_value). */
-#endif
-#ifndef ETHTOOL_TEST
-#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */
-#endif
-#ifndef ETHTOOL_GSTRINGS
-#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */
-#endif
-#ifndef ETHTOOL_PHYS_ID
-#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */
-#endif
-#ifndef ETHTOOL_GSTATS
-#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
-#endif
-#ifndef ETHTOOL_GTSO
-#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */
-#endif
-#ifndef ETHTOOL_STSO
-#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */
-#endif
-
-#ifndef ETHTOOL_BUSINFO_LEN
-#define ETHTOOL_BUSINFO_LEN 32
-#endif
-
-#ifndef RHEL_RELEASE_CODE
-/* NOTE: RHEL_RELEASE_* introduced in RHEL4.5 */
-#define RHEL_RELEASE_CODE 0
-#endif
-#ifndef RHEL_RELEASE_VERSION
-#define RHEL_RELEASE_VERSION(a,b) (((a) << 8) + (b))
-#endif
-#ifndef AX_RELEASE_CODE
-#define AX_RELEASE_CODE 0
-#endif
-#ifndef AX_RELEASE_VERSION
-#define AX_RELEASE_VERSION(a,b) (((a) << 8) + (b))
-#endif
-
-/* SuSE version macro is the same as Linux kernel version */
-#ifndef SLE_VERSION
-#define SLE_VERSION(a,b,c) KERNEL_VERSION(a,b,c)
-#endif
-#ifndef SLE_VERSION_CODE
-#ifdef CONFIG_SUSE_KERNEL
-/* SLES11 GA is 2.6.27 based */
-#if ( LINUX_VERSION_CODE == KERNEL_VERSION(2,6,27) )
-#define SLE_VERSION_CODE SLE_VERSION(11,0,0)
-#elif ( LINUX_VERSION_CODE == KERNEL_VERSION(2,6,32) )
-/* SLES11 SP1 is 2.6.32 based */
-#define SLE_VERSION_CODE SLE_VERSION(11,1,0)
-#else
-#define SLE_VERSION_CODE 0
-#endif
-#else /* CONFIG_SUSE_KERNEL */
-#define SLE_VERSION_CODE 0
-#endif /* CONFIG_SUSE_KERNEL */
-#endif /* SLE_VERSION_CODE */
-
-#ifdef __KLOCWORK__
-#ifdef ARRAY_SIZE
-#undef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#endif
-#endif /* __KLOCWORK__ */
-
-/*****************************************************************************/
-/* 2.4.3 => 2.4.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) )
-
-/**************************************/
-/* PCI DRIVER API */
-
-#ifndef pci_set_dma_mask
-#define pci_set_dma_mask _kc_pci_set_dma_mask
-extern int _kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask);
-#endif
-
-#ifndef pci_request_regions
-#define pci_request_regions _kc_pci_request_regions
-extern int _kc_pci_request_regions(struct pci_dev *pdev, char *res_name);
-#endif
-
-#ifndef pci_release_regions
-#define pci_release_regions _kc_pci_release_regions
-extern void _kc_pci_release_regions(struct pci_dev *pdev);
-#endif
-
-/**************************************/
-/* NETWORK DRIVER API */
-
-#ifndef alloc_etherdev
-#define alloc_etherdev _kc_alloc_etherdev
-extern struct net_device * _kc_alloc_etherdev(int sizeof_priv);
-#endif
-
-#ifndef is_valid_ether_addr
-#define is_valid_ether_addr _kc_is_valid_ether_addr
-extern int _kc_is_valid_ether_addr(u8 *addr);
-#endif
-
-/**************************************/
-/* MISCELLANEOUS */
-
-#ifndef INIT_TQUEUE
-#define INIT_TQUEUE(_tq, _routine, _data) \
- do { \
- INIT_LIST_HEAD(&(_tq)->list); \
- (_tq)->sync = 0; \
- (_tq)->routine = _routine; \
- (_tq)->data = _data; \
- } while (0)
-#endif
-
-#endif /* 2.4.3 => 2.4.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5) )
-/* Generic MII registers. */
-#define MII_BMCR 0x00 /* Basic mode control register */
-#define MII_BMSR 0x01 /* Basic mode status register */
-#define MII_PHYSID1 0x02 /* PHYS ID 1 */
-#define MII_PHYSID2 0x03 /* PHYS ID 2 */
-#define MII_ADVERTISE 0x04 /* Advertisement control reg */
-#define MII_LPA 0x05 /* Link partner ability reg */
-#define MII_EXPANSION 0x06 /* Expansion register */
-/* Basic mode control register. */
-#define BMCR_FULLDPLX 0x0100 /* Full duplex */
-#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
-/* Basic mode status register. */
-#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
-#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
-#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
-#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
-#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
-#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
-/* Advertisement control register. */
-#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
-#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
- ADVERTISE_100HALF | ADVERTISE_100FULL)
-/* Expansion register for auto-negotiation. */
-#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
-#endif
-
-/*****************************************************************************/
-/* 2.4.6 => 2.4.3 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) )
-
-#ifndef pci_set_power_state
-#define pci_set_power_state _kc_pci_set_power_state
-extern int _kc_pci_set_power_state(struct pci_dev *dev, int state);
-#endif
-
-#ifndef pci_enable_wake
-#define pci_enable_wake _kc_pci_enable_wake
-extern int _kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable);
-#endif
-
-#ifndef pci_disable_device
-#define pci_disable_device _kc_pci_disable_device
-extern void _kc_pci_disable_device(struct pci_dev *pdev);
-#endif
-
-/* PCI PM entry point syntax changed, so don't support suspend/resume */
-#undef CONFIG_PM
-
-#endif /* 2.4.6 => 2.4.3 */
-
-#ifndef HAVE_PCI_SET_MWI
-#define pci_set_mwi(X) pci_write_config_word(X, \
- PCI_COMMAND, adapter->hw.bus.pci_cmd_word | \
- PCI_COMMAND_INVALIDATE);
-#define pci_clear_mwi(X) pci_write_config_word(X, \
- PCI_COMMAND, adapter->hw.bus.pci_cmd_word & \
- ~PCI_COMMAND_INVALIDATE);
-#endif
-
-/*****************************************************************************/
-/* 2.4.10 => 2.4.9 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) )
-
-/**************************************/
-/* MODULE API */
-
-#ifndef MODULE_LICENSE
- #define MODULE_LICENSE(X)
-#endif
-
-/**************************************/
-/* OTHER */
-
-#undef min
-#define min(x,y) ({ \
- const typeof(x) _x = (x); \
- const typeof(y) _y = (y); \
- (void) (&_x == &_y); \
- _x < _y ? _x : _y; })
-
-#undef max
-#define max(x,y) ({ \
- const typeof(x) _x = (x); \
- const typeof(y) _y = (y); \
- (void) (&_x == &_y); \
- _x > _y ? _x : _y; })
-
-#define min_t(type,x,y) ({ \
- type _x = (x); \
- type _y = (y); \
- _x < _y ? _x : _y; })
-
-#define max_t(type,x,y) ({ \
- type _x = (x); \
- type _y = (y); \
- _x > _y ? _x : _y; })
-
-#ifndef list_for_each_safe
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-#endif
-
-#ifndef ____cacheline_aligned_in_smp
-#ifdef CONFIG_SMP
-#define ____cacheline_aligned_in_smp ____cacheline_aligned
-#else
-#define ____cacheline_aligned_in_smp
-#endif /* CONFIG_SMP */
-#endif
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8) )
-extern int _kc_snprintf(char * buf, size_t size, const char *fmt, ...);
-#define snprintf(buf, size, fmt, args...) _kc_snprintf(buf, size, fmt, ##args)
-extern int _kc_vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
-#define vsnprintf(buf, size, fmt, args) _kc_vsnprintf(buf, size, fmt, args)
-#else /* 2.4.8 => 2.4.9 */
-extern int snprintf(char * buf, size_t size, const char *fmt, ...);
-extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
-#endif
-#endif /* 2.4.10 -> 2.4.6 */
-
-
-/*****************************************************************************/
-/* 2.4.12 => 2.4.10 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,12) )
-#ifndef HAVE_NETIF_MSG
-#define HAVE_NETIF_MSG 1
-enum {
- NETIF_MSG_DRV = 0x0001,
- NETIF_MSG_PROBE = 0x0002,
- NETIF_MSG_LINK = 0x0004,
- NETIF_MSG_TIMER = 0x0008,
- NETIF_MSG_IFDOWN = 0x0010,
- NETIF_MSG_IFUP = 0x0020,
- NETIF_MSG_RX_ERR = 0x0040,
- NETIF_MSG_TX_ERR = 0x0080,
- NETIF_MSG_TX_QUEUED = 0x0100,
- NETIF_MSG_INTR = 0x0200,
- NETIF_MSG_TX_DONE = 0x0400,
- NETIF_MSG_RX_STATUS = 0x0800,
- NETIF_MSG_PKTDATA = 0x1000,
- NETIF_MSG_HW = 0x2000,
- NETIF_MSG_WOL = 0x4000,
-};
-
-#define netif_msg_drv(p) ((p)->msg_enable & NETIF_MSG_DRV)
-#define netif_msg_probe(p) ((p)->msg_enable & NETIF_MSG_PROBE)
-#define netif_msg_link(p) ((p)->msg_enable & NETIF_MSG_LINK)
-#define netif_msg_timer(p) ((p)->msg_enable & NETIF_MSG_TIMER)
-#define netif_msg_ifdown(p) ((p)->msg_enable & NETIF_MSG_IFDOWN)
-#define netif_msg_ifup(p) ((p)->msg_enable & NETIF_MSG_IFUP)
-#define netif_msg_rx_err(p) ((p)->msg_enable & NETIF_MSG_RX_ERR)
-#define netif_msg_tx_err(p) ((p)->msg_enable & NETIF_MSG_TX_ERR)
-#define netif_msg_tx_queued(p) ((p)->msg_enable & NETIF_MSG_TX_QUEUED)
-#define netif_msg_intr(p) ((p)->msg_enable & NETIF_MSG_INTR)
-#define netif_msg_tx_done(p) ((p)->msg_enable & NETIF_MSG_TX_DONE)
-#define netif_msg_rx_status(p) ((p)->msg_enable & NETIF_MSG_RX_STATUS)
-#define netif_msg_pktdata(p) ((p)->msg_enable & NETIF_MSG_PKTDATA)
-#endif /* !HAVE_NETIF_MSG */
-#endif /* 2.4.12 => 2.4.10 */
-
-/*****************************************************************************/
-/* 2.4.13 => 2.4.12 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) )
-
-/**************************************/
-/* PCI DMA MAPPING */
-
-#ifndef virt_to_page
- #define virt_to_page(v) (mem_map + (virt_to_phys(v) >> PAGE_SHIFT))
-#endif
-
-#ifndef pci_map_page
-#define pci_map_page _kc_pci_map_page
-extern u64 _kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset, size_t size, int direction);
-#endif
-
-#ifndef pci_unmap_page
-#define pci_unmap_page _kc_pci_unmap_page
-extern void _kc_pci_unmap_page(struct pci_dev *dev, u64 dma_addr, size_t size, int direction);
-#endif
-
-/* pci_set_dma_mask takes dma_addr_t, which is only 32-bits prior to 2.4.13 */
-
-#undef DMA_32BIT_MASK
-#define DMA_32BIT_MASK 0xffffffff
-#undef DMA_64BIT_MASK
-#define DMA_64BIT_MASK 0xffffffff
-
-/**************************************/
-/* OTHER */
-
-#ifndef cpu_relax
-#define cpu_relax() rep_nop()
-#endif
-
-struct vlan_ethhdr {
- unsigned char h_dest[ETH_ALEN];
- unsigned char h_source[ETH_ALEN];
- unsigned short h_vlan_proto;
- unsigned short h_vlan_TCI;
- unsigned short h_vlan_encapsulated_proto;
-};
-#endif /* 2.4.13 => 2.4.12 */
-
-/*****************************************************************************/
-/* 2.4.17 => 2.4.12 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17) )
-
-#ifndef __devexit_p
- #define __devexit_p(x) &(x)
-#endif
-
-#endif /* 2.4.17 => 2.4.13 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) )
-#define NETIF_MSG_HW 0x2000
-#define NETIF_MSG_WOL 0x4000
-
-#ifndef netif_msg_hw
-#define netif_msg_hw(p) ((p)->msg_enable & NETIF_MSG_HW)
-#endif
-#ifndef netif_msg_wol
-#define netif_msg_wol(p) ((p)->msg_enable & NETIF_MSG_WOL)
-#endif
-#endif /* 2.4.18 */
-
-/*****************************************************************************/
-
-/*****************************************************************************/
-/* 2.4.20 => 2.4.19 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20) )
-
-/* we won't support NAPI on less than 2.4.20 */
-#ifdef NAPI
-#undef NAPI
-#undef CONFIG_IXGBE_NAPI
-#endif
-
-#endif /* 2.4.20 => 2.4.19 */
-
-/*****************************************************************************/
-/* 2.4.22 => 2.4.17 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) )
-#define pci_name(x) ((x)->slot_name)
-#endif
-
-/*****************************************************************************/
-/* 2.4.22 => 2.4.17 */
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) )
-#ifndef IXGBE_NO_LRO
-/* Don't enable LRO for these legacy kernels */
-#define IXGBE_NO_LRO
-#endif
-#endif
-
-/*****************************************************************************/
-/*****************************************************************************/
-/* 2.4.23 => 2.4.22 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) )
-/*****************************************************************************/
-#ifdef NAPI
-#ifndef netif_poll_disable
-#define netif_poll_disable(x) _kc_netif_poll_disable(x)
-static inline void _kc_netif_poll_disable(struct net_device *netdev)
-{
- while (test_and_set_bit(__LINK_STATE_RX_SCHED, &netdev->state)) {
- /* No hurry */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
-}
-#endif
-#ifndef netif_poll_enable
-#define netif_poll_enable(x) _kc_netif_poll_enable(x)
-static inline void _kc_netif_poll_enable(struct net_device *netdev)
-{
- clear_bit(__LINK_STATE_RX_SCHED, &netdev->state);
-}
-#endif
-#endif /* NAPI */
-#ifndef netif_tx_disable
-#define netif_tx_disable(x) _kc_netif_tx_disable(x)
-static inline void _kc_netif_tx_disable(struct net_device *dev)
-{
- spin_lock_bh(&dev->xmit_lock);
- netif_stop_queue(dev);
- spin_unlock_bh(&dev->xmit_lock);
-}
-#endif
-#else /* 2.4.23 => 2.4.22 */
-#define HAVE_SCTP
-#endif /* 2.4.23 => 2.4.22 */
-
-/*****************************************************************************/
-/* 2.6.4 => 2.6.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25) || \
- ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \
- LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) )
-#define ETHTOOL_OPS_COMPAT
-#endif /* 2.6.4 => 2.6.0 */
-
-/*****************************************************************************/
-/* 2.5.71 => 2.4.x */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,71) )
-#define sk_protocol protocol
-#define pci_get_device pci_find_device
-#endif /* 2.5.70 => 2.4.x */
-
-/*****************************************************************************/
-/* < 2.4.27 or 2.6.0 <= 2.6.5 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) || \
- ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \
- LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ) )
-
-#ifndef netif_msg_init
-#define netif_msg_init _kc_netif_msg_init
-static inline u32 _kc_netif_msg_init(int debug_value, int default_msg_enable_bits)
-{
- /* use default */
- if (debug_value < 0 || debug_value >= (sizeof(u32) * 8))
- return default_msg_enable_bits;
- if (debug_value == 0) /* no output */
- return 0;
- /* set low N bits */
- return (1 << debug_value) -1;
-}
-#endif
-
-#endif /* < 2.4.27 or 2.6.0 <= 2.6.5 */
-/*****************************************************************************/
-#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) || \
- (( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) && \
- ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) )))
-#define netdev_priv(x) x->priv
-#endif
-
-/*****************************************************************************/
-/* <= 2.5.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) )
-#include <linux/rtnetlink.h>
-#undef pci_register_driver
-#define pci_register_driver pci_module_init
-
-/*
- * Most of the dma compat code is copied/modified from the 2.4.37
- * /include/linux/libata-compat.h header file
- */
-/* These definitions mirror those in pci.h, so they can be used
- * interchangeably with their PCI_ counterparts */
-enum dma_data_direction {
- DMA_BIDIRECTIONAL = 0,
- DMA_TO_DEVICE = 1,
- DMA_FROM_DEVICE = 2,
- DMA_NONE = 3,
-};
-
-struct device {
- struct pci_dev pdev;
-};
-
-static inline struct pci_dev *to_pci_dev (struct device *dev)
-{
- return (struct pci_dev *) dev;
-}
-static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
-{
- return (struct device *) pdev;
-}
-
-#define pdev_printk(lvl, pdev, fmt, args...) \
- printk("%s %s: " fmt, lvl, pci_name(pdev), ## args)
-#define dev_err(dev, fmt, args...) \
- pdev_printk(KERN_ERR, to_pci_dev(dev), fmt, ## args)
-#define dev_info(dev, fmt, args...) \
- pdev_printk(KERN_INFO, to_pci_dev(dev), fmt, ## args)
-#define dev_warn(dev, fmt, args...) \
- pdev_printk(KERN_WARNING, to_pci_dev(dev), fmt, ## args)
-
-/* NOTE: dangerous! we ignore the 'gfp' argument */
-#define dma_alloc_coherent(dev,sz,dma,gfp) \
- pci_alloc_consistent(to_pci_dev(dev),(sz),(dma))
-#define dma_free_coherent(dev,sz,addr,dma_addr) \
- pci_free_consistent(to_pci_dev(dev),(sz),(addr),(dma_addr))
-
-#define dma_map_page(dev,a,b,c,d) \
- pci_map_page(to_pci_dev(dev),(a),(b),(c),(d))
-#define dma_unmap_page(dev,a,b,c) \
- pci_unmap_page(to_pci_dev(dev),(a),(b),(c))
-
-#define dma_map_single(dev,a,b,c) \
- pci_map_single(to_pci_dev(dev),(a),(b),(c))
-#define dma_unmap_single(dev,a,b,c) \
- pci_unmap_single(to_pci_dev(dev),(a),(b),(c))
-
-#define dma_sync_single(dev,a,b,c) \
- pci_dma_sync_single(to_pci_dev(dev),(a),(b),(c))
-
-/* for range just sync everything, that's all the pci API can do */
-#define dma_sync_single_range(dev,addr,off,sz,dir) \
- pci_dma_sync_single(to_pci_dev(dev),(addr),(off)+(sz),(dir))
-
-#define dma_set_mask(dev,mask) \
- pci_set_dma_mask(to_pci_dev(dev),(mask))
-
-/* hlist_* code - double linked lists */
-struct hlist_head {
- struct hlist_node *first;
-};
-
-struct hlist_node {
- struct hlist_node *next, **pprev;
-};
-
-static inline void __hlist_del(struct hlist_node *n)
-{
- struct hlist_node *next = n->next;
- struct hlist_node **pprev = n->pprev;
- *pprev = next;
- if (next)
- next->pprev = pprev;
-}
-
-static inline void hlist_del(struct hlist_node *n)
-{
- __hlist_del(n);
- n->next = NULL;
- n->pprev = NULL;
-}
-
-static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
-{
- struct hlist_node *first = h->first;
- n->next = first;
- if (first)
- first->pprev = &n->next;
- h->first = n;
- n->pprev = &h->first;
-}
-
-static inline int hlist_empty(const struct hlist_head *h)
-{
- return !h->first;
-}
-#define HLIST_HEAD_INIT { .first = NULL }
-#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
-#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
-static inline void INIT_HLIST_NODE(struct hlist_node *h)
-{
- h->next = NULL;
- h->pprev = NULL;
-}
-#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
-
-#define hlist_for_each_entry(tpos, pos, head, member) \
- for (pos = (head)->first; \
- pos && ({ prefetch(pos->next); 1;}) && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = pos->next)
-
-#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
- for (pos = (head)->first; \
- pos && ({ n = pos->next; 1; }) && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = n)
-
-#ifndef might_sleep
-#define might_sleep()
-#endif
-#else
-static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
-{
- return &pdev->dev;
-}
-#endif /* <= 2.5.0 */
-
-/*****************************************************************************/
-/* 2.5.28 => 2.4.23 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) )
-
-static inline void _kc_synchronize_irq(void)
-{
- synchronize_irq();
-}
-#undef synchronize_irq
-#define synchronize_irq(X) _kc_synchronize_irq()
-
-#include <linux/tqueue.h>
-#define work_struct tq_struct
-#undef INIT_WORK
-#define INIT_WORK(a,b) INIT_TQUEUE(a,(void (*)(void *))b,a)
-#undef container_of
-#define container_of list_entry
-#define schedule_work schedule_task
-#define flush_scheduled_work flush_scheduled_tasks
-#define cancel_work_sync(x) flush_scheduled_work()
-
-#endif /* 2.5.28 => 2.4.17 */
-
-/*****************************************************************************/
-/* 2.6.0 => 2.5.28 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-#undef get_cpu
-#define get_cpu() smp_processor_id()
-#undef put_cpu
-#define put_cpu() do { } while(0)
-#define MODULE_INFO(version, _version)
-#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
-#define CONFIG_E1000_DISABLE_PACKET_SPLIT 1
-#endif
-#define CONFIG_IGB_DISABLE_PACKET_SPLIT 1
-
-#define dma_set_coherent_mask(dev,mask) 1
-
-#undef dev_put
-#define dev_put(dev) __dev_put(dev)
-
-#ifndef skb_fill_page_desc
-#define skb_fill_page_desc _kc_skb_fill_page_desc
-extern void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size);
-#endif
-
-#undef ALIGN
-#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
-
-#ifndef page_count
-#define page_count(p) atomic_read(&(p)->count)
-#endif
-
-#ifdef MAX_NUMNODES
-#undef MAX_NUMNODES
-#endif
-#define MAX_NUMNODES 1
-
-/* find_first_bit and find_next bit are not defined for most
- * 2.4 kernels (except for the redhat 2.4.21 kernels
- */
-#include <linux/bitops.h>
-#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
-#undef find_next_bit
-#define find_next_bit _kc_find_next_bit
-extern unsigned long _kc_find_next_bit(const unsigned long *addr,
- unsigned long size,
- unsigned long offset);
-#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
-
-
-#ifndef netdev_name
-static inline const char *_kc_netdev_name(const struct net_device *dev)
-{
- if (strchr(dev->name, '%'))
- return "(unregistered net_device)";
- return dev->name;
-}
-#define netdev_name(netdev) _kc_netdev_name(netdev)
-#endif /* netdev_name */
-
-#ifndef strlcpy
-#define strlcpy _kc_strlcpy
-extern size_t _kc_strlcpy(char *dest, const char *src, size_t size);
-#endif /* strlcpy */
-
-#endif /* 2.6.0 => 2.5.28 */
-
-/*****************************************************************************/
-/* 2.6.4 => 2.6.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) )
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif /* 2.6.4 => 2.6.0 */
-
-/*****************************************************************************/
-/* 2.6.5 => 2.6.0 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) )
-#define dma_sync_single_for_cpu dma_sync_single
-#define dma_sync_single_for_device dma_sync_single
-#define dma_sync_single_range_for_cpu dma_sync_single_range
-#define dma_sync_single_range_for_device dma_sync_single_range
-#ifndef pci_dma_mapping_error
-#define pci_dma_mapping_error _kc_pci_dma_mapping_error
-static inline int _kc_pci_dma_mapping_error(dma_addr_t dma_addr)
-{
- return dma_addr == 0;
-}
-#endif
-#endif /* 2.6.5 => 2.6.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) )
-extern int _kc_scnprintf(char * buf, size_t size, const char *fmt, ...);
-#define scnprintf(buf, size, fmt, args...) _kc_scnprintf(buf, size, fmt, ##args)
-#endif /* < 2.6.4 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,6) )
-/* taken from 2.6 include/linux/bitmap.h */
-#undef bitmap_zero
-#define bitmap_zero _kc_bitmap_zero
-static inline void _kc_bitmap_zero(unsigned long *dst, int nbits)
-{
- if (nbits <= BITS_PER_LONG)
- *dst = 0UL;
- else {
- int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
- memset(dst, 0, len);
- }
-}
-#define random_ether_addr _kc_random_ether_addr
-static inline void _kc_random_ether_addr(u8 *addr)
-{
- get_random_bytes(addr, ETH_ALEN);
- addr[0] &= 0xfe; /* clear multicast */
- addr[0] |= 0x02; /* set local assignment */
-}
-#define page_to_nid(x) 0
-
-#endif /* < 2.6.6 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) )
-#undef if_mii
-#define if_mii _kc_if_mii
-static inline struct mii_ioctl_data *_kc_if_mii(struct ifreq *rq)
-{
- return (struct mii_ioctl_data *) &rq->ifr_ifru;
-}
-
-#ifndef __force
-#define __force
-#endif
-#endif /* < 2.6.7 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) )
-#ifndef PCI_EXP_DEVCTL
-#define PCI_EXP_DEVCTL 8
-#endif
-#ifndef PCI_EXP_DEVCTL_CERE
-#define PCI_EXP_DEVCTL_CERE 0x0001
-#endif
-#define msleep(x) do { set_current_state(TASK_UNINTERRUPTIBLE); \
- schedule_timeout((x * HZ)/1000 + 2); \
- } while (0)
-
-#endif /* < 2.6.8 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
-#include <net/dsfield.h>
-#define __iomem
-
-#ifndef kcalloc
-#define kcalloc(n, size, flags) _kc_kzalloc(((n) * (size)), flags)
-extern void *_kc_kzalloc(size_t size, int flags);
-#endif
-#define MSEC_PER_SEC 1000L
-static inline unsigned int _kc_jiffies_to_msecs(const unsigned long j)
-{
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
- return (MSEC_PER_SEC / HZ) * j;
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
- return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
-#else
- return (j * MSEC_PER_SEC) / HZ;
-#endif
-}
-static inline unsigned long _kc_msecs_to_jiffies(const unsigned int m)
-{
- if (m > _kc_jiffies_to_msecs(MAX_JIFFY_OFFSET))
- return MAX_JIFFY_OFFSET;
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
- return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
- return m * (HZ / MSEC_PER_SEC);
-#else
- return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC;
-#endif
-}
-
-#define msleep_interruptible _kc_msleep_interruptible
-static inline unsigned long _kc_msleep_interruptible(unsigned int msecs)
-{
- unsigned long timeout = _kc_msecs_to_jiffies(msecs) + 1;
-
- while (timeout && !signal_pending(current)) {
- __set_current_state(TASK_INTERRUPTIBLE);
- timeout = schedule_timeout(timeout);
- }
- return _kc_jiffies_to_msecs(timeout);
-}
-
-/* Basic mode control register. */
-#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
-
-#ifndef __le16
-#define __le16 u16
-#endif
-#ifndef __le32
-#define __le32 u32
-#endif
-#ifndef __le64
-#define __le64 u64
-#endif
-#ifndef __be16
-#define __be16 u16
-#endif
-#ifndef __be32
-#define __be32 u32
-#endif
-#ifndef __be64
-#define __be64 u64
-#endif
-
-static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
-{
- return (struct vlan_ethhdr *)skb->mac.raw;
-}
-
-/* Wake-On-Lan options. */
-#define WAKE_PHY (1 << 0)
-#define WAKE_UCAST (1 << 1)
-#define WAKE_MCAST (1 << 2)
-#define WAKE_BCAST (1 << 3)
-#define WAKE_ARP (1 << 4)
-#define WAKE_MAGIC (1 << 5)
-#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
-
-#define skb_header_pointer _kc_skb_header_pointer
-static inline void *_kc_skb_header_pointer(const struct sk_buff *skb,
- int offset, int len, void *buffer)
-{
- int hlen = skb_headlen(skb);
-
- if (hlen - offset >= len)
- return skb->data + offset;
-
-#ifdef MAX_SKB_FRAGS
- if (skb_copy_bits(skb, offset, buffer, len) < 0)
- return NULL;
-
- return buffer;
-#else
- return NULL;
-#endif
-
-#ifndef NETDEV_TX_OK
-#define NETDEV_TX_OK 0
-#endif
-#ifndef NETDEV_TX_BUSY
-#define NETDEV_TX_BUSY 1
-#endif
-#ifndef NETDEV_TX_LOCKED
-#define NETDEV_TX_LOCKED -1
-#endif
-}
-
-#ifndef __bitwise
-#define __bitwise
-#endif
-#endif /* < 2.6.9 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
-#ifdef module_param_array_named
-#undef module_param_array_named
-#define module_param_array_named(name, array, type, nump, perm) \
- static struct kparam_array __param_arr_##name \
- = { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type, \
- sizeof(array[0]), array }; \
- module_param_call(name, param_array_set, param_array_get, \
- &__param_arr_##name, perm)
-#endif /* module_param_array_named */
-/*
- * num_online is broken for all < 2.6.10 kernels. This is needed to support
- * Node module parameter of ixgbe.
- */
-#undef num_online_nodes
-#define num_online_nodes(n) 1
-extern DECLARE_BITMAP(_kcompat_node_online_map, MAX_NUMNODES);
-#undef node_online_map
-#define node_online_map _kcompat_node_online_map
-#endif /* < 2.6.10 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
-#define PCI_D0 0
-#define PCI_D1 1
-#define PCI_D2 2
-#define PCI_D3hot 3
-#define PCI_D3cold 4
-typedef int pci_power_t;
-#define pci_choose_state(pdev,state) state
-#define PMSG_SUSPEND 3
-#define PCI_EXP_LNKCTL 16
-
-#undef NETIF_F_LLTX
-
-#ifndef ARCH_HAS_PREFETCH
-#define prefetch(X)
-#endif
-
-#ifndef NET_IP_ALIGN
-#define NET_IP_ALIGN 2
-#endif
-
-#define KC_USEC_PER_SEC 1000000L
-#define usecs_to_jiffies _kc_usecs_to_jiffies
-static inline unsigned int _kc_jiffies_to_usecs(const unsigned long j)
-{
-#if HZ <= KC_USEC_PER_SEC && !(KC_USEC_PER_SEC % HZ)
- return (KC_USEC_PER_SEC / HZ) * j;
-#elif HZ > KC_USEC_PER_SEC && !(HZ % KC_USEC_PER_SEC)
- return (j + (HZ / KC_USEC_PER_SEC) - 1)/(HZ / KC_USEC_PER_SEC);
-#else
- return (j * KC_USEC_PER_SEC) / HZ;
-#endif
-}
-static inline unsigned long _kc_usecs_to_jiffies(const unsigned int m)
-{
- if (m > _kc_jiffies_to_usecs(MAX_JIFFY_OFFSET))
- return MAX_JIFFY_OFFSET;
-#if HZ <= KC_USEC_PER_SEC && !(KC_USEC_PER_SEC % HZ)
- return (m + (KC_USEC_PER_SEC / HZ) - 1) / (KC_USEC_PER_SEC / HZ);
-#elif HZ > KC_USEC_PER_SEC && !(HZ % KC_USEC_PER_SEC)
- return m * (HZ / KC_USEC_PER_SEC);
-#else
- return (m * HZ + KC_USEC_PER_SEC - 1) / KC_USEC_PER_SEC;
-#endif
-}
-#endif /* < 2.6.11 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) )
-#include <linux/reboot.h>
-#define USE_REBOOT_NOTIFIER
-
-/* Generic MII registers. */
-#define MII_CTRL1000 0x09 /* 1000BASE-T control */
-#define MII_STAT1000 0x0a /* 1000BASE-T status */
-/* Advertisement control register. */
-#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
-#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymmetric pause */
-/* 1000BASE-T Control register */
-#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
-#ifndef is_zero_ether_addr
-#define is_zero_ether_addr _kc_is_zero_ether_addr
-static inline int _kc_is_zero_ether_addr(const u8 *addr)
-{
- return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
-}
-#endif /* is_zero_ether_addr */
-#ifndef is_multicast_ether_addr
-#define is_multicast_ether_addr _kc_is_multicast_ether_addr
-static inline int _kc_is_multicast_ether_addr(const u8 *addr)
-{
- return addr[0] & 0x01;
-}
-#endif /* is_multicast_ether_addr */
-#endif /* < 2.6.12 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
-#ifndef kstrdup
-#define kstrdup _kc_kstrdup
-extern char *_kc_kstrdup(const char *s, unsigned int gfp);
-#endif
-#endif /* < 2.6.13 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) )
-#define pm_message_t u32
-#ifndef kzalloc
-#define kzalloc _kc_kzalloc
-extern void *_kc_kzalloc(size_t size, int flags);
-#endif
-
-/* Generic MII registers. */
-#define MII_ESTATUS 0x0f /* Extended Status */
-/* Basic mode status register. */
-#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
-/* Extended status register. */
-#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
-#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
-
-#define ADVERTISED_Pause (1 << 13)
-#define ADVERTISED_Asym_Pause (1 << 14)
-
-#if (!(RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(4,3)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0))))
-#if ((LINUX_VERSION_CODE == KERNEL_VERSION(2,6,9)) && !defined(gfp_t))
-#define gfp_t unsigned
-#else
-typedef unsigned gfp_t;
-#endif
-#endif /* !RHEL4.3->RHEL5.0 */
-
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) )
-#ifdef CONFIG_X86_64
-#define dma_sync_single_range_for_cpu(dev, dma_handle, offset, size, dir) \
- dma_sync_single_for_cpu(dev, dma_handle, size, dir)
-#define dma_sync_single_range_for_device(dev, dma_handle, offset, size, dir) \
- dma_sync_single_for_device(dev, dma_handle, size, dir)
-#endif
-#endif
-#endif /* < 2.6.14 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) )
-#ifndef vmalloc_node
-#define vmalloc_node(a,b) vmalloc(a)
-#endif /* vmalloc_node*/
-
-#define setup_timer(_timer, _function, _data) \
-do { \
- (_timer)->function = _function; \
- (_timer)->data = _data; \
- init_timer(_timer); \
-} while (0)
-#ifndef device_can_wakeup
-#define device_can_wakeup(dev) (1)
-#endif
-#ifndef device_set_wakeup_enable
-#define device_set_wakeup_enable(dev, val) do{}while(0)
-#endif
-#ifndef device_init_wakeup
-#define device_init_wakeup(dev,val) do {} while (0)
-#endif
-static inline unsigned _kc_compare_ether_addr(const u8 *addr1, const u8 *addr2)
-{
- const u16 *a = (const u16 *) addr1;
- const u16 *b = (const u16 *) addr2;
-
- return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
-}
-#undef compare_ether_addr
-#define compare_ether_addr(addr1, addr2) _kc_compare_ether_addr(addr1, addr2)
-#endif /* < 2.6.15 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) )
-#undef DEFINE_MUTEX
-#define DEFINE_MUTEX(x) DECLARE_MUTEX(x)
-#define mutex_lock(x) down_interruptible(x)
-#define mutex_unlock(x) up(x)
-
-#ifndef ____cacheline_internodealigned_in_smp
-#ifdef CONFIG_SMP
-#define ____cacheline_internodealigned_in_smp ____cacheline_aligned_in_smp
-#else
-#define ____cacheline_internodealigned_in_smp
-#endif /* CONFIG_SMP */
-#endif /* ____cacheline_internodealigned_in_smp */
-#undef HAVE_PCI_ERS
-#else /* 2.6.16 and above */
-#undef HAVE_PCI_ERS
-#define HAVE_PCI_ERS
-#endif /* < 2.6.16 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) )
-#ifndef first_online_node
-#define first_online_node 0
-#endif
-#ifndef NET_SKB_PAD
-#define NET_SKB_PAD 16
-#endif
-#endif /* < 2.6.17 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) )
-
-#ifndef IRQ_HANDLED
-#define irqreturn_t void
-#define IRQ_HANDLED
-#define IRQ_NONE
-#endif
-
-#ifndef IRQF_PROBE_SHARED
-#ifdef SA_PROBEIRQ
-#define IRQF_PROBE_SHARED SA_PROBEIRQ
-#else
-#define IRQF_PROBE_SHARED 0
-#endif
-#endif
-
-#ifndef IRQF_SHARED
-#define IRQF_SHARED SA_SHIRQ
-#endif
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#endif
-
-#ifndef FIELD_SIZEOF
-#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
-#endif
-
-#ifndef skb_is_gso
-#ifdef NETIF_F_TSO
-#define skb_is_gso _kc_skb_is_gso
-static inline int _kc_skb_is_gso(const struct sk_buff *skb)
-{
- return skb_shinfo(skb)->gso_size;
-}
-#else
-#define skb_is_gso(a) 0
-#endif
-#endif
-
-#ifndef resource_size_t
-#define resource_size_t unsigned long
-#endif
-
-#ifdef skb_pad
-#undef skb_pad
-#endif
-#define skb_pad(x,y) _kc_skb_pad(x, y)
-int _kc_skb_pad(struct sk_buff *skb, int pad);
-#ifdef skb_padto
-#undef skb_padto
-#endif
-#define skb_padto(x,y) _kc_skb_padto(x, y)
-static inline int _kc_skb_padto(struct sk_buff *skb, unsigned int len)
-{
- unsigned int size = skb->len;
- if(likely(size >= len))
- return 0;
- return _kc_skb_pad(skb, len - size);
-}
-
-#ifndef DECLARE_PCI_UNMAP_ADDR
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- u32 LEN_NAME
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-#endif /* DECLARE_PCI_UNMAP_ADDR */
-#endif /* < 2.6.18 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) )
-
-#ifndef DIV_ROUND_UP
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-#endif
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) )
-#if (!((RHEL_RELEASE_CODE && \
- ((RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(4,4) && \
- RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0)) || \
- (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,0)))) || \
- (AX_RELEASE_CODE && AX_RELEASE_CODE > AX_RELEASE_VERSION(3,0))))
-typedef irqreturn_t (*irq_handler_t)(int, void*, struct pt_regs *);
-#endif
-#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(6,0))
-#undef CONFIG_INET_LRO
-#undef CONFIG_INET_LRO_MODULE
-#undef CONFIG_FCOE
-#undef CONFIG_FCOE_MODULE
-#endif
-typedef irqreturn_t (*new_handler_t)(int, void*);
-static inline irqreturn_t _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id)
-#else /* 2.4.x */
-typedef void (*irq_handler_t)(int, void*, struct pt_regs *);
-typedef void (*new_handler_t)(int, void*);
-static inline int _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id)
-#endif /* >= 2.5.x */
-{
- irq_handler_t new_handler = (irq_handler_t) handler;
- return request_irq(irq, new_handler, flags, devname, dev_id);
-}
-
-#undef request_irq
-#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
-/* 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
-#define PCI_CONFIG_SPACE_LEN 64
-#define PCIE_LINK_STATUS 0x12
-#define pci_config_space_ich8lan() do {} while(0)
-#undef pci_save_state
-extern int _kc_pci_save_state(struct pci_dev *);
-#define pci_save_state(pdev) _kc_pci_save_state(pdev)
-#undef pci_restore_state
-extern void _kc_pci_restore_state(struct pci_dev *);
-#define pci_restore_state(pdev) _kc_pci_restore_state(pdev)
-#endif /* !(RHEL_RELEASE_CODE >= RHEL 5.4) */
-
-#ifdef HAVE_PCI_ERS
-#undef free_netdev
-extern void _kc_free_netdev(struct net_device *);
-#define free_netdev(netdev) _kc_free_netdev(netdev)
-#endif
-static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
-{
- return 0;
-}
-#define pci_disable_pcie_error_reporting(dev) do {} while (0)
-#define pci_cleanup_aer_uncorrect_error_status(dev) do {} while (0)
-
-extern void *_kc_kmemdup(const void *src, size_t len, unsigned gfp);
-#define kmemdup(src, len, gfp) _kc_kmemdup(src, len, gfp)
-#ifndef bool
-#define bool _Bool
-#define true 1
-#define false 0
-#endif
-#else /* 2.6.19 */
-#include <linux/aer.h>
-#include <linux/string.h>
-#endif /* < 2.6.19 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) )
-#undef INIT_WORK
-#define INIT_WORK(_work, _func) \
-do { \
- INIT_LIST_HEAD(&(_work)->entry); \
- (_work)->pending = 0; \
- (_work)->func = (void (*)(void *))_func; \
- (_work)->data = _work; \
- init_timer(&(_work)->timer); \
-} while (0)
-#endif
-
-#ifndef PCI_VDEVICE
-#define PCI_VDEVICE(ven, dev) \
- PCI_VENDOR_ID_##ven, (dev), \
- PCI_ANY_ID, PCI_ANY_ID, 0, 0
-#endif
-
-#ifndef round_jiffies
-#define round_jiffies(x) x
-#endif
-
-#define csum_offset csum
-
-#define HAVE_EARLY_VMALLOC_NODE
-#define dev_to_node(dev) -1
-#undef set_dev_node
-/* remove compiler warning with b=b, for unused variable */
-#define set_dev_node(a, b) do { (b) = (b); } while(0)
-
-#if (!(RHEL_RELEASE_CODE && \
- (((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(4,7)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0))) || \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,6)))) && \
- !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(10,2,0)))
-typedef __u16 __bitwise __sum16;
-typedef __u32 __bitwise __wsum;
-#endif
-
-#if (!(RHEL_RELEASE_CODE && \
- (((RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(4,7)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0))) || \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5,4)))) && \
- !(SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(10,2,0)))
-static inline __wsum csum_unfold(__sum16 n)
-{
- return (__force __wsum)n;
-}
-#endif
-
-#else /* < 2.6.20 */
-#define HAVE_DEVICE_NUMA_NODE
-#endif /* < 2.6.20 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) )
-#define to_net_dev(class) container_of(class, struct net_device, class_dev)
-#define NETDEV_CLASS_DEV
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5)))
-#define vlan_group_get_device(vg, id) (vg->vlan_devices[id])
-#define vlan_group_set_device(vg, id, dev) \
- do { \
- if (vg) vg->vlan_devices[id] = dev; \
- } while (0)
-#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,5)) */
-#define pci_channel_offline(pdev) (pdev->error_state && \
- pdev->error_state != pci_channel_io_normal)
-#define pci_request_selected_regions(pdev, bars, name) \
- pci_request_regions(pdev, name)
-#define pci_release_selected_regions(pdev, bars) pci_release_regions(pdev);
-#endif /* < 2.6.21 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) )
-#define tcp_hdr(skb) (skb->h.th)
-#define tcp_hdrlen(skb) (skb->h.th->doff << 2)
-#define skb_transport_offset(skb) (skb->h.raw - skb->data)
-#define skb_transport_header(skb) (skb->h.raw)
-#define ipv6_hdr(skb) (skb->nh.ipv6h)
-#define ip_hdr(skb) (skb->nh.iph)
-#define skb_network_offset(skb) (skb->nh.raw - skb->data)
-#define skb_network_header(skb) (skb->nh.raw)
-#define skb_tail_pointer(skb) skb->tail
-#define skb_reset_tail_pointer(skb) \
- do { \
- skb->tail = skb->data; \
- } while (0)
-#define skb_copy_to_linear_data(skb, from, len) \
- memcpy(skb->data, from, len)
-#define skb_copy_to_linear_data_offset(skb, offset, from, len) \
- memcpy(skb->data + offset, from, len)
-#define skb_network_header_len(skb) (skb->h.raw - skb->nh.raw)
-#define pci_register_driver pci_module_init
-#define skb_mac_header(skb) skb->mac.raw
-
-#ifdef NETIF_F_MULTI_QUEUE
-#ifndef alloc_etherdev_mq
-#define alloc_etherdev_mq(_a, _b) alloc_etherdev(_a)
-#endif
-#endif /* NETIF_F_MULTI_QUEUE */
-
-#ifndef ETH_FCS_LEN
-#define ETH_FCS_LEN 4
-#endif
-#define cancel_work_sync(x) flush_scheduled_work()
-#ifndef udp_hdr
-#define udp_hdr _udp_hdr
-static inline struct udphdr *_udp_hdr(const struct sk_buff *skb)
-{
- return (struct udphdr *)skb_transport_header(skb);
-}
-#endif
-
-#ifdef cpu_to_be16
-#undef cpu_to_be16
-#endif
-#define cpu_to_be16(x) __constant_htons(x)
-
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,1)))
-enum {
- DUMP_PREFIX_NONE,
- DUMP_PREFIX_ADDRESS,
- DUMP_PREFIX_OFFSET
-};
-#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,1)) */
-#ifndef hex_asc
-#define hex_asc(x) "0123456789abcdef"[x]
-#endif
-#include <linux/ctype.h>
-extern void _kc_print_hex_dump(const char *level, const char *prefix_str,
- int prefix_type, int rowsize, int groupsize,
- const void *buf, size_t len, bool ascii);
-#define print_hex_dump(lvl, s, t, r, g, b, l, a) \
- _kc_print_hex_dump(lvl, s, t, r, g, b, l, a)
-#else /* 2.6.22 */
-#define ETH_TYPE_TRANS_SETS_DEV
-#define HAVE_NETDEV_STATS_IN_NETDEV
-#endif /* < 2.6.22 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) )
-#endif /* > 2.6.22 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) )
-#define netif_subqueue_stopped(_a, _b) 0
-#ifndef PTR_ALIGN
-#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
-#endif
-
-#ifndef CONFIG_PM_SLEEP
-#define CONFIG_PM_SLEEP CONFIG_PM
-#endif
-
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) )
-#define HAVE_ETHTOOL_GET_PERM_ADDR
-#endif /* 2.6.14 through 2.6.22 */
-#endif /* < 2.6.23 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) )
-#ifndef ETH_FLAG_LRO
-#define ETH_FLAG_LRO NETIF_F_LRO
-#endif
-
-/* if GRO is supported then the napi struct must already exist */
-#ifndef NETIF_F_GRO
-/* NAPI API changes in 2.6.24 break everything */
-struct napi_struct {
- /* used to look up the real NAPI polling routine */
- int (*poll)(struct napi_struct *, int);
- struct net_device *dev;
- int weight;
-};
-#endif
-
-#ifdef NAPI
-extern int __kc_adapter_clean(struct net_device *, int *);
-extern struct net_device *napi_to_poll_dev(struct napi_struct *napi);
-#define netif_napi_add(_netdev, _napi, _poll, _weight) \
- do { \
- struct napi_struct *__napi = (_napi); \
- struct net_device *poll_dev = napi_to_poll_dev(__napi); \
- poll_dev->poll = &(__kc_adapter_clean); \
- poll_dev->priv = (_napi); \
- poll_dev->weight = (_weight); \
- set_bit(__LINK_STATE_RX_SCHED, &poll_dev->state); \
- set_bit(__LINK_STATE_START, &poll_dev->state);\
- dev_hold(poll_dev); \
- __napi->poll = &(_poll); \
- __napi->weight = (_weight); \
- __napi->dev = (_netdev); \
- } while (0)
-#define netif_napi_del(_napi) \
- do { \
- struct net_device *poll_dev = napi_to_poll_dev(_napi); \
- WARN_ON(!test_bit(__LINK_STATE_RX_SCHED, &poll_dev->state)); \
- dev_put(poll_dev); \
- memset(poll_dev, 0, sizeof(struct net_device));\
- } while (0)
-#define napi_schedule_prep(_napi) \
- (netif_running((_napi)->dev) && netif_rx_schedule_prep(napi_to_poll_dev(_napi)))
-#define napi_schedule(_napi) \
- do { \
- if (napi_schedule_prep(_napi)) \
- __netif_rx_schedule(napi_to_poll_dev(_napi)); \
- } while (0)
-#define napi_enable(_napi) netif_poll_enable(napi_to_poll_dev(_napi))
-#define napi_disable(_napi) netif_poll_disable(napi_to_poll_dev(_napi))
-#define __napi_schedule(_napi) __netif_rx_schedule(napi_to_poll_dev(_napi))
-#ifndef NETIF_F_GRO
-#define napi_complete(_napi) netif_rx_complete(napi_to_poll_dev(_napi))
-#else
-#define napi_complete(_napi) \
- do { \
- napi_gro_flush(_napi); \
- netif_rx_complete(napi_to_poll_dev(_napi)); \
- } while (0)
-#endif /* NETIF_F_GRO */
-#else /* NAPI */
-#define netif_napi_add(_netdev, _napi, _poll, _weight) \
- do { \
- struct napi_struct *__napi = _napi; \
- _netdev->poll = &(_poll); \
- _netdev->weight = (_weight); \
- __napi->poll = &(_poll); \
- __napi->weight = (_weight); \
- __napi->dev = (_netdev); \
- } while (0)
-#define netif_napi_del(_a) do {} while (0)
-#endif /* NAPI */
-
-#undef dev_get_by_name
-#define dev_get_by_name(_a, _b) dev_get_by_name(_b)
-#define __netif_subqueue_stopped(_a, _b) netif_subqueue_stopped(_a, _b)
-#ifndef DMA_BIT_MASK
-#define DMA_BIT_MASK(n) (((n) == 64) ? DMA_64BIT_MASK : ((1ULL<<(n))-1))
-#endif
-
-#ifdef NETIF_F_TSO6
-#define skb_is_gso_v6 _kc_skb_is_gso_v6
-static inline int _kc_skb_is_gso_v6(const struct sk_buff *skb)
-{
- return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;
-}
-#endif /* NETIF_F_TSO6 */
-
-#ifndef KERN_CONT
-#define KERN_CONT ""
-#endif
-#else /* < 2.6.24 */
-#define HAVE_ETHTOOL_GET_SSET_COUNT
-#define HAVE_NETDEV_NAPI_LIST
-#endif /* < 2.6.24 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24) )
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) )
-#include <linux/pm_qos_params.h>
-#else /* >= 3.2.0 */
-#include <linux/pm_qos.h>
-#endif /* else >= 3.2.0 */
-#endif /* > 2.6.24 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) )
-#define PM_QOS_CPU_DMA_LATENCY 1
-
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) )
-#include <linux/latency.h>
-#define PM_QOS_DEFAULT_VALUE INFINITE_LATENCY
-#define pm_qos_add_requirement(pm_qos_class, name, value) \
- set_acceptable_latency(name, value)
-#define pm_qos_remove_requirement(pm_qos_class, name) \
- remove_acceptable_latency(name)
-#define pm_qos_update_requirement(pm_qos_class, name, value) \
- modify_acceptable_latency(name, value)
-#else
-#define PM_QOS_DEFAULT_VALUE -1
-#define pm_qos_add_requirement(pm_qos_class, name, value)
-#define pm_qos_remove_requirement(pm_qos_class, name)
-#define pm_qos_update_requirement(pm_qos_class, name, value) { \
- if (value != PM_QOS_DEFAULT_VALUE) { \
- printk(KERN_WARNING "%s: unable to set PM QoS requirement\n", \
- pci_name(adapter->pdev)); \
- } \
-}
-
-#endif /* > 2.6.18 */
-
-#define pci_enable_device_mem(pdev) pci_enable_device(pdev)
-
-#ifndef DEFINE_PCI_DEVICE_TABLE
-#define DEFINE_PCI_DEVICE_TABLE(_table) struct pci_device_id _table[]
-#endif /* DEFINE_PCI_DEVICE_TABLE */
-
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) )
-#ifndef IXGBE_PROCFS
-#define IXGBE_PROCFS
-#endif /* IXGBE_PROCFS */
-#endif /* >= 2.6.0 */
-
-
-#else /* < 2.6.25 */
-
-#ifndef IXGBE_SYSFS
-#define IXGBE_SYSFS
-#endif /* IXGBE_SYSFS */
-
-
-#endif /* < 2.6.25 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) )
-#ifndef clamp_t
-#define clamp_t(type, val, min, max) ({ \
- type __val = (val); \
- type __min = (min); \
- type __max = (max); \
- __val = __val < __min ? __min : __val; \
- __val > __max ? __max : __val; })
-#endif /* clamp_t */
-#ifdef NETIF_F_TSO
-#ifdef NETIF_F_TSO6
-#define netif_set_gso_max_size(_netdev, size) \
- do { \
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { \
- _netdev->features &= ~NETIF_F_TSO; \
- _netdev->features &= ~NETIF_F_TSO6; \
- } else { \
- _netdev->features |= NETIF_F_TSO; \
- _netdev->features |= NETIF_F_TSO6; \
- } \
- } while (0)
-#else /* NETIF_F_TSO6 */
-#define netif_set_gso_max_size(_netdev, size) \
- do { \
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) \
- _netdev->features &= ~NETIF_F_TSO; \
- else \
- _netdev->features |= NETIF_F_TSO; \
- } while (0)
-#endif /* NETIF_F_TSO6 */
-#else
-#define netif_set_gso_max_size(_netdev, size) do {} while (0)
-#endif /* NETIF_F_TSO */
-#undef kzalloc_node
-#define kzalloc_node(_size, _flags, _node) kzalloc(_size, _flags)
-
-extern void _kc_pci_disable_link_state(struct pci_dev *dev, int state);
-#define pci_disable_link_state(p, s) _kc_pci_disable_link_state(p, s)
-#else /* < 2.6.26 */
-#include <linux/pci-aspm.h>
-#define HAVE_NETDEV_VLAN_FEATURES
-#endif /* < 2.6.26 */
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) )
-static inline void _kc_ethtool_cmd_speed_set(struct ethtool_cmd *ep,
- __u32 speed)
-{
- ep->speed = (__u16)speed;
- /* ep->speed_hi = (__u16)(speed >> 16); */
-}
-#define ethtool_cmd_speed_set _kc_ethtool_cmd_speed_set
-
-static inline __u32 _kc_ethtool_cmd_speed(struct ethtool_cmd *ep)
-{
- /* no speed_hi before 2.6.27, and probably no need for it yet */
- return (__u32)ep->speed;
-}
-#define ethtool_cmd_speed _kc_ethtool_cmd_speed
-
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) )
-#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) && defined(CONFIG_PM))
-#define ANCIENT_PM 1
-#elif ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) && \
- (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) && \
- defined(CONFIG_PM_SLEEP))
-#define NEWER_PM 1
-#endif
-#if defined(ANCIENT_PM) || defined(NEWER_PM)
-#undef device_set_wakeup_enable
-#define device_set_wakeup_enable(dev, val) \
- do { \
- u16 pmc = 0; \
- int pm = pci_find_capability(adapter->pdev, PCI_CAP_ID_PM); \
- if (pm) { \
- pci_read_config_word(adapter->pdev, pm + PCI_PM_PMC, \
- &pmc); \
- } \
- (dev)->power.can_wakeup = !!(pmc >> 11); \
- (dev)->power.should_wakeup = (val && (pmc >> 11)); \
- } while (0)
-#endif /* 2.6.15-2.6.22 and CONFIG_PM or 2.6.23-2.6.25 and CONFIG_PM_SLEEP */
-#endif /* 2.6.15 through 2.6.27 */
-#ifndef netif_napi_del
-#define netif_napi_del(_a) do {} while (0)
-#ifdef NAPI
-#ifdef CONFIG_NETPOLL
-#undef netif_napi_del
-#define netif_napi_del(_a) list_del(&(_a)->dev_list);
-#endif
-#endif
-#endif /* netif_napi_del */
-#ifdef dma_mapping_error
-#undef dma_mapping_error
-#endif
-#define dma_mapping_error(dev, dma_addr) pci_dma_mapping_error(dma_addr)
-
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
-#define HAVE_TX_MQ
-#endif
-
-#ifdef HAVE_TX_MQ
-extern void _kc_netif_tx_stop_all_queues(struct net_device *);
-extern void _kc_netif_tx_wake_all_queues(struct net_device *);
-extern void _kc_netif_tx_start_all_queues(struct net_device *);
-#define netif_tx_stop_all_queues(a) _kc_netif_tx_stop_all_queues(a)
-#define netif_tx_wake_all_queues(a) _kc_netif_tx_wake_all_queues(a)
-#define netif_tx_start_all_queues(a) _kc_netif_tx_start_all_queues(a)
-#undef netif_stop_subqueue
-#define netif_stop_subqueue(_ndev,_qi) do { \
- if (netif_is_multiqueue((_ndev))) \
- netif_stop_subqueue((_ndev), (_qi)); \
- else \
- netif_stop_queue((_ndev)); \
- } while (0)
-#undef netif_start_subqueue
-#define netif_start_subqueue(_ndev,_qi) do { \
- if (netif_is_multiqueue((_ndev))) \
- netif_start_subqueue((_ndev), (_qi)); \
- else \
- netif_start_queue((_ndev)); \
- } while (0)
-#else /* HAVE_TX_MQ */
-#define netif_tx_stop_all_queues(a) netif_stop_queue(a)
-#define netif_tx_wake_all_queues(a) netif_wake_queue(a)
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) )
-#define netif_tx_start_all_queues(a) netif_start_queue(a)
-#else
-#define netif_tx_start_all_queues(a) do {} while (0)
-#endif
-#define netif_stop_subqueue(_ndev,_qi) netif_stop_queue((_ndev))
-#define netif_start_subqueue(_ndev,_qi) netif_start_queue((_ndev))
-#endif /* HAVE_TX_MQ */
-#ifndef NETIF_F_MULTI_QUEUE
-#define NETIF_F_MULTI_QUEUE 0
-#define netif_is_multiqueue(a) 0
-#define netif_wake_subqueue(a, b)
-#endif /* NETIF_F_MULTI_QUEUE */
-
-#ifndef __WARN_printf
-extern void __kc_warn_slowpath(const char *file, const int line,
- const char *fmt, ...) __attribute__((format(printf, 3, 4)));
-#define __WARN_printf(arg...) __kc_warn_slowpath(__FILE__, __LINE__, arg)
-#endif /* __WARN_printf */
-
-#ifndef WARN
-#define WARN(condition, format...) ({ \
- int __ret_warn_on = !!(condition); \
- if (unlikely(__ret_warn_on)) \
- __WARN_printf(format); \
- unlikely(__ret_warn_on); \
-})
-#endif /* WARN */
-#else /* < 2.6.27 */
-#define HAVE_TX_MQ
-#define HAVE_NETDEV_SELECT_QUEUE
-#endif /* < 2.6.27 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) )
-#define pci_ioremap_bar(pdev, bar) ioremap(pci_resource_start(pdev, bar), \
- pci_resource_len(pdev, bar))
-#define pci_wake_from_d3 _kc_pci_wake_from_d3
-#define pci_prepare_to_sleep _kc_pci_prepare_to_sleep
-extern int _kc_pci_wake_from_d3(struct pci_dev *dev, bool enable);
-extern int _kc_pci_prepare_to_sleep(struct pci_dev *dev);
-#define netdev_alloc_page(a) alloc_page(GFP_ATOMIC)
-#ifndef __skb_queue_head_init
-static inline void __kc_skb_queue_head_init(struct sk_buff_head *list)
-{
- list->prev = list->next = (struct sk_buff *)list;
- list->qlen = 0;
-}
-#define __skb_queue_head_init(_q) __kc_skb_queue_head_init(_q)
-#endif
-#endif /* < 2.6.28 */
-
-#ifndef skb_add_rx_frag
-#define skb_add_rx_frag _kc_skb_add_rx_frag
-extern void _kc_skb_add_rx_frag(struct sk_buff *, int, struct page *, int, int);
-#endif
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) )
-#ifndef swap
-#define swap(a, b) \
- do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
-#endif
-#define pci_request_selected_regions_exclusive(pdev, bars, name) \
- pci_request_selected_regions(pdev, bars, name)
-#ifndef CONFIG_NR_CPUS
-#define CONFIG_NR_CPUS 1
-#endif /* CONFIG_NR_CPUS */
-#ifndef pcie_aspm_enabled
-#define pcie_aspm_enabled() (1)
-#endif /* pcie_aspm_enabled */
-#else /* < 2.6.29 */
-#ifndef HAVE_NET_DEVICE_OPS
-#define HAVE_NET_DEVICE_OPS
-#endif
-#ifdef CONFIG_DCB
-#define HAVE_PFC_MODE_ENABLE
-#endif /* CONFIG_DCB */
-#endif /* < 2.6.29 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) )
-#define skb_rx_queue_recorded(a) false
-#define skb_get_rx_queue(a) 0
-#undef CONFIG_FCOE
-#undef CONFIG_FCOE_MODULE
-extern u16 _kc_skb_tx_hash(struct net_device *dev, struct sk_buff *skb);
-#define skb_tx_hash(n, s) _kc_skb_tx_hash(n, s)
-#define skb_record_rx_queue(a, b) do {} while (0)
-#ifndef CONFIG_PCI_IOV
-#undef pci_enable_sriov
-#define pci_enable_sriov(a, b) -ENOTSUPP
-#undef pci_disable_sriov
-#define pci_disable_sriov(a) do {} while (0)
-#endif /* CONFIG_PCI_IOV */
-#ifndef pr_cont
-#define pr_cont(fmt, ...) \
- printk(KERN_CONT fmt, ##__VA_ARGS__)
-#endif /* pr_cont */
-#else
-#define HAVE_ASPM_QUIRKS
-#endif /* < 2.6.30 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) )
-#define ETH_P_1588 0x88F7
-#define ETH_P_FIP 0x8914
-#ifndef netdev_uc_count
-#define netdev_uc_count(dev) ((dev)->uc_count)
-#endif
-#ifndef netdev_for_each_uc_addr
-#define netdev_for_each_uc_addr(uclist, dev) \
- for (uclist = dev->uc_list; uclist; uclist = uclist->next)
-#endif
-#else
-#ifndef HAVE_NETDEV_STORAGE_ADDRESS
-#define HAVE_NETDEV_STORAGE_ADDRESS
-#endif
-#ifndef HAVE_NETDEV_HW_ADDR
-#define HAVE_NETDEV_HW_ADDR
-#endif
-#ifndef HAVE_TRANS_START_IN_QUEUE
-#define HAVE_TRANS_START_IN_QUEUE
-#endif
-#endif /* < 2.6.31 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) )
-#undef netdev_tx_t
-#define netdev_tx_t int
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef NETIF_F_FCOE_MTU
-#define NETIF_F_FCOE_MTU (1 << 26)
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-
-#ifndef pm_runtime_get_sync
-#define pm_runtime_get_sync(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_put
-#define pm_runtime_put(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_put_sync
-#define pm_runtime_put_sync(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_resume
-#define pm_runtime_resume(dev) do {} while (0)
-#endif
-#ifndef pm_schedule_suspend
-#define pm_schedule_suspend(dev, t) do {} while (0)
-#endif
-#ifndef pm_runtime_set_suspended
-#define pm_runtime_set_suspended(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_disable
-#define pm_runtime_disable(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_put_noidle
-#define pm_runtime_put_noidle(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_set_active
-#define pm_runtime_set_active(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_enable
-#define pm_runtime_enable(dev) do {} while (0)
-#endif
-#ifndef pm_runtime_get_noresume
-#define pm_runtime_get_noresume(dev) do {} while (0)
-#endif
-#else /* < 2.6.32 */
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef HAVE_NETDEV_OPS_FCOE_ENABLE
-#define HAVE_NETDEV_OPS_FCOE_ENABLE
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-#ifdef CONFIG_DCB
-#ifndef HAVE_DCBNL_OPS_GETAPP
-#define HAVE_DCBNL_OPS_GETAPP
-#endif
-#endif /* CONFIG_DCB */
-#include <linux/pm_runtime.h>
-/* IOV bad DMA target work arounds require at least this kernel rev support */
-#define HAVE_PCIE_TYPE
-#endif /* < 2.6.32 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) )
-#ifndef pci_pcie_cap
-#define pci_pcie_cap(pdev) pci_find_capability(pdev, PCI_CAP_ID_EXP)
-#endif
-#ifndef IPV4_FLOW
-#define IPV4_FLOW 0x10
-#endif /* IPV4_FLOW */
-#ifndef IPV6_FLOW
-#define IPV6_FLOW 0x11
-#endif /* IPV6_FLOW */
-/* Features back-ported to RHEL6 or SLES11 SP1 after 2.6.32 */
-#if ( (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,0)) || \
- (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11,1,0)) )
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef HAVE_NETDEV_OPS_FCOE_GETWWN
-#define HAVE_NETDEV_OPS_FCOE_GETWWN
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-#endif /* RHEL6 or SLES11 SP1 */
-#ifndef __percpu
-#define __percpu
-#endif /* __percpu */
-#else /* < 2.6.33 */
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef HAVE_NETDEV_OPS_FCOE_GETWWN
-#define HAVE_NETDEV_OPS_FCOE_GETWWN
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-#define HAVE_ETHTOOL_SFP_DISPLAY_PORT
-#endif /* < 2.6.33 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) )
-#ifndef ETH_FLAG_NTUPLE
-#define ETH_FLAG_NTUPLE NETIF_F_NTUPLE
-#endif
-
-#ifndef netdev_mc_count
-#define netdev_mc_count(dev) ((dev)->mc_count)
-#endif
-#ifndef netdev_mc_empty
-#define netdev_mc_empty(dev) (netdev_mc_count(dev) == 0)
-#endif
-#ifndef netdev_for_each_mc_addr
-#define netdev_for_each_mc_addr(mclist, dev) \
- for (mclist = dev->mc_list; mclist; mclist = mclist->next)
-#endif
-#ifndef netdev_uc_count
-#define netdev_uc_count(dev) ((dev)->uc.count)
-#endif
-#ifndef netdev_uc_empty
-#define netdev_uc_empty(dev) (netdev_uc_count(dev) == 0)
-#endif
-#ifndef netdev_for_each_uc_addr
-#define netdev_for_each_uc_addr(ha, dev) \
- list_for_each_entry(ha, &dev->uc.list, list)
-#endif
-#ifndef dma_set_coherent_mask
-#define dma_set_coherent_mask(dev,mask) \
- pci_set_consistent_dma_mask(to_pci_dev(dev),(mask))
-#endif
-#ifndef pci_dev_run_wake
-#define pci_dev_run_wake(pdev) (0)
-#endif
-
-/* netdev logging taken from include/linux/netdevice.h */
-#ifndef netdev_name
-static inline const char *_kc_netdev_name(const struct net_device *dev)
-{
- if (dev->reg_state != NETREG_REGISTERED)
- return "(unregistered net_device)";
- return dev->name;
-}
-#define netdev_name(netdev) _kc_netdev_name(netdev)
-#endif /* netdev_name */
-
-#undef netdev_printk
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-#define netdev_printk(level, netdev, format, args...) \
-do { \
- struct adapter_struct *kc_adapter = netdev_priv(netdev);\
- struct pci_dev *pdev = kc_adapter->pdev; \
- printk("%s %s: " format, level, pci_name(pdev), \
- ##args); \
-} while(0)
-#elif ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) )
-#define netdev_printk(level, netdev, format, args...) \
-do { \
- struct adapter_struct *kc_adapter = netdev_priv(netdev);\
- struct pci_dev *pdev = kc_adapter->pdev; \
- struct device *dev = pci_dev_to_dev(pdev); \
- dev_printk(level, dev, "%s: " format, \
- netdev_name(netdev), ##args); \
-} while(0)
-#else /* 2.6.21 => 2.6.34 */
-#define netdev_printk(level, netdev, format, args...) \
- dev_printk(level, (netdev)->dev.parent, \
- "%s: " format, \
- netdev_name(netdev), ##args)
-#endif /* <2.6.0 <2.6.21 <2.6.34 */
-#undef netdev_emerg
-#define netdev_emerg(dev, format, args...) \
- netdev_printk(KERN_EMERG, dev, format, ##args)
-#undef netdev_alert
-#define netdev_alert(dev, format, args...) \
- netdev_printk(KERN_ALERT, dev, format, ##args)
-#undef netdev_crit
-#define netdev_crit(dev, format, args...) \
- netdev_printk(KERN_CRIT, dev, format, ##args)
-#undef netdev_err
-#define netdev_err(dev, format, args...) \
- netdev_printk(KERN_ERR, dev, format, ##args)
-#undef netdev_warn
-#define netdev_warn(dev, format, args...) \
- netdev_printk(KERN_WARNING, dev, format, ##args)
-#undef netdev_notice
-#define netdev_notice(dev, format, args...) \
- netdev_printk(KERN_NOTICE, dev, format, ##args)
-#undef netdev_info
-#define netdev_info(dev, format, args...) \
- netdev_printk(KERN_INFO, dev, format, ##args)
-#undef netdev_dbg
-#if defined(DEBUG)
-#define netdev_dbg(__dev, format, args...) \
- netdev_printk(KERN_DEBUG, __dev, format, ##args)
-#elif defined(CONFIG_DYNAMIC_DEBUG)
-#define netdev_dbg(__dev, format, args...) \
-do { \
- dynamic_dev_dbg((__dev)->dev.parent, "%s: " format, \
- netdev_name(__dev), ##args); \
-} while (0)
-#else /* DEBUG */
-#define netdev_dbg(__dev, format, args...) \
-({ \
- if (0) \
- netdev_printk(KERN_DEBUG, __dev, format, ##args); \
- 0; \
-})
-#endif /* DEBUG */
-
-#undef netif_printk
-#define netif_printk(priv, type, level, dev, fmt, args...) \
-do { \
- if (netif_msg_##type(priv)) \
- netdev_printk(level, (dev), fmt, ##args); \
-} while (0)
-
-#undef netif_emerg
-#define netif_emerg(priv, type, dev, fmt, args...) \
- netif_level(emerg, priv, type, dev, fmt, ##args)
-#undef netif_alert
-#define netif_alert(priv, type, dev, fmt, args...) \
- netif_level(alert, priv, type, dev, fmt, ##args)
-#undef netif_crit
-#define netif_crit(priv, type, dev, fmt, args...) \
- netif_level(crit, priv, type, dev, fmt, ##args)
-#undef netif_err
-#define netif_err(priv, type, dev, fmt, args...) \
- netif_level(err, priv, type, dev, fmt, ##args)
-#undef netif_warn
-#define netif_warn(priv, type, dev, fmt, args...) \
- netif_level(warn, priv, type, dev, fmt, ##args)
-#undef netif_notice
-#define netif_notice(priv, type, dev, fmt, args...) \
- netif_level(notice, priv, type, dev, fmt, ##args)
-#undef netif_info
-#define netif_info(priv, type, dev, fmt, args...) \
- netif_level(info, priv, type, dev, fmt, ##args)
-
-#ifdef SET_SYSTEM_SLEEP_PM_OPS
-#define HAVE_SYSTEM_SLEEP_PM_OPS
-#endif
-
-#ifndef for_each_set_bit
-#define for_each_set_bit(bit, addr, size) \
- for ((bit) = find_first_bit((addr), (size)); \
- (bit) < (size); \
- (bit) = find_next_bit((addr), (size), (bit) + 1))
-#endif /* for_each_set_bit */
-
-#ifndef DEFINE_DMA_UNMAP_ADDR
-#define DEFINE_DMA_UNMAP_ADDR DECLARE_PCI_UNMAP_ADDR
-#define DEFINE_DMA_UNMAP_LEN DECLARE_PCI_UNMAP_LEN
-#define dma_unmap_addr pci_unmap_addr
-#define dma_unmap_addr_set pci_unmap_addr_set
-#define dma_unmap_len pci_unmap_len
-#define dma_unmap_len_set pci_unmap_len_set
-#endif /* DEFINE_DMA_UNMAP_ADDR */
-#else /* < 2.6.34 */
-#define HAVE_SYSTEM_SLEEP_PM_OPS
-#ifndef HAVE_SET_RX_MODE
-#define HAVE_SET_RX_MODE
-#endif
-
-#endif /* < 2.6.34 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) )
-#ifndef numa_node_id
-#define numa_node_id() 0
-#endif
-#ifdef HAVE_TX_MQ
-#include <net/sch_generic.h>
-#ifndef CONFIG_NETDEVICES_MULTIQUEUE
-void _kc_netif_set_real_num_tx_queues(struct net_device *, unsigned int);
-#define netif_set_real_num_tx_queues _kc_netif_set_real_num_tx_queues
-#else /* CONFIG_NETDEVICES_MULTI_QUEUE */
-#define netif_set_real_num_tx_queues(_netdev, _count) \
- do { \
- (_netdev)->egress_subqueue_count = _count; \
- } while (0)
-#endif /* CONFIG_NETDEVICES_MULTI_QUEUE */
-#else
-#define netif_set_real_num_tx_queues(_netdev, _count) do {} while(0)
-#endif /* HAVE_TX_MQ */
-#ifndef ETH_FLAG_RXHASH
-#define ETH_FLAG_RXHASH (1<<28)
-#endif /* ETH_FLAG_RXHASH */
-#else /* < 2.6.35 */
-#define HAVE_PM_QOS_REQUEST_LIST
-#define HAVE_IRQ_AFFINITY_HINT
-#endif /* < 2.6.35 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) )
-extern int _kc_ethtool_op_set_flags(struct net_device *, u32, u32);
-#define ethtool_op_set_flags _kc_ethtool_op_set_flags
-extern u32 _kc_ethtool_op_get_flags(struct net_device *);
-#define ethtool_op_get_flags _kc_ethtool_op_get_flags
-
-#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-#ifdef NET_IP_ALIGN
-#undef NET_IP_ALIGN
-#endif
-#define NET_IP_ALIGN 0
-#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
-
-#ifdef NET_SKB_PAD
-#undef NET_SKB_PAD
-#endif
-
-#if (L1_CACHE_BYTES > 32)
-#define NET_SKB_PAD L1_CACHE_BYTES
-#else
-#define NET_SKB_PAD 32
-#endif
-
-static inline struct sk_buff *_kc_netdev_alloc_skb_ip_align(struct net_device *dev,
- unsigned int length)
-{
- struct sk_buff *skb;
-
- skb = alloc_skb(length + NET_SKB_PAD + NET_IP_ALIGN, GFP_ATOMIC);
- if (skb) {
-#if (NET_IP_ALIGN + NET_SKB_PAD)
- skb_reserve(skb, NET_IP_ALIGN + NET_SKB_PAD);
-#endif
- skb->dev = dev;
- }
- return skb;
-}
-
-#ifdef netdev_alloc_skb_ip_align
-#undef netdev_alloc_skb_ip_align
-#endif
-#define netdev_alloc_skb_ip_align(n, l) _kc_netdev_alloc_skb_ip_align(n, l)
-
-#undef netif_level
-#define netif_level(level, priv, type, dev, fmt, args...) \
-do { \
- if (netif_msg_##type(priv)) \
- netdev_##level(dev, fmt, ##args); \
-} while (0)
-
-#undef usleep_range
-#define usleep_range(min, max) msleep(DIV_ROUND_UP(min, 1000))
-
-#else /* < 2.6.36 */
-#define HAVE_PM_QOS_REQUEST_ACTIVE
-#define HAVE_8021P_SUPPORT
-#define HAVE_NDO_GET_STATS64
-#endif /* < 2.6.36 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) )
-#ifndef ETHTOOL_RXNTUPLE_ACTION_CLEAR
-#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2)
-#endif
-#ifndef VLAN_N_VID
-#define VLAN_N_VID VLAN_GROUP_ARRAY_LEN
-#endif /* VLAN_N_VID */
-#ifndef ETH_FLAG_TXVLAN
-#define ETH_FLAG_TXVLAN (1 << 7)
-#endif /* ETH_FLAG_TXVLAN */
-#ifndef ETH_FLAG_RXVLAN
-#define ETH_FLAG_RXVLAN (1 << 8)
-#endif /* ETH_FLAG_RXVLAN */
-
-static inline void _kc_skb_checksum_none_assert(struct sk_buff *skb)
-{
- WARN_ON(skb->ip_summed != CHECKSUM_NONE);
-}
-#define skb_checksum_none_assert(skb) _kc_skb_checksum_none_assert(skb)
-
-static inline void *_kc_vzalloc_node(unsigned long size, int node)
-{
- void *addr = vmalloc_node(size, node);
- if (addr)
- memset(addr, 0, size);
- return addr;
-}
-#define vzalloc_node(_size, _node) _kc_vzalloc_node(_size, _node)
-
-static inline void *_kc_vzalloc(unsigned long size)
-{
- void *addr = vmalloc(size);
- if (addr)
- memset(addr, 0, size);
- return addr;
-}
-#define vzalloc(_size) _kc_vzalloc(_size)
-
-#ifndef vlan_get_protocol
-static inline __be16 __kc_vlan_get_protocol(const struct sk_buff *skb)
-{
- if (vlan_tx_tag_present(skb) ||
- skb->protocol != cpu_to_be16(ETH_P_8021Q))
- return skb->protocol;
-
- if (skb_headlen(skb) < sizeof(struct vlan_ethhdr))
- return 0;
-
- return ((struct vlan_ethhdr*)skb->data)->h_vlan_encapsulated_proto;
-}
-#define vlan_get_protocol(_skb) __kc_vlan_get_protocol(_skb)
-#endif
-#ifdef HAVE_HW_TIME_STAMP
-#define SKBTX_HW_TSTAMP (1 << 0)
-#define SKBTX_IN_PROGRESS (1 << 2)
-#define SKB_SHARED_TX_IS_UNION
-#endif
-#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,4,18) )
-#ifndef HAVE_VLAN_RX_REGISTER
-#define HAVE_VLAN_RX_REGISTER
-#endif
-#endif /* > 2.4.18 */
-#endif /* < 2.6.37 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) )
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) )
-#define skb_checksum_start_offset(skb) skb_transport_offset(skb)
-#else /* 2.6.22 -> 2.6.37 */
-static inline int _kc_skb_checksum_start_offset(const struct sk_buff *skb)
-{
- return skb->csum_start - skb_headroom(skb);
-}
-#define skb_checksum_start_offset(skb) _kc_skb_checksum_start_offset(skb)
-#endif /* 2.6.22 -> 2.6.37 */
-#ifdef CONFIG_DCB
-#ifndef IEEE_8021QAZ_MAX_TCS
-#define IEEE_8021QAZ_MAX_TCS 8
-#endif
-#ifndef DCB_CAP_DCBX_HOST
-#define DCB_CAP_DCBX_HOST 0x01
-#endif
-#ifndef DCB_CAP_DCBX_LLD_MANAGED
-#define DCB_CAP_DCBX_LLD_MANAGED 0x02
-#endif
-#ifndef DCB_CAP_DCBX_VER_CEE
-#define DCB_CAP_DCBX_VER_CEE 0x04
-#endif
-#ifndef DCB_CAP_DCBX_VER_IEEE
-#define DCB_CAP_DCBX_VER_IEEE 0x08
-#endif
-#ifndef DCB_CAP_DCBX_STATIC
-#define DCB_CAP_DCBX_STATIC 0x10
-#endif
-#endif /* CONFIG_DCB */
-#else /* < 2.6.38 */
-#endif /* < 2.6.38 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) )
-#ifndef skb_queue_reverse_walk_safe
-#define skb_queue_reverse_walk_safe(queue, skb, tmp) \
- for (skb = (queue)->prev, tmp = skb->prev; \
- skb != (struct sk_buff *)(queue); \
- skb = tmp, tmp = skb->prev)
-#endif
-#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)))
-extern u8 _kc_netdev_get_num_tc(struct net_device *dev);
-#define netdev_get_num_tc(dev) _kc_netdev_get_num_tc(dev)
-extern u8 _kc_netdev_get_prio_tc_map(struct net_device *dev, u8 up);
-#define netdev_get_prio_tc_map(dev, up) _kc_netdev_get_prio_tc_map(dev, up)
-#define netdev_set_prio_tc_map(dev, up, tc) do {} while (0)
-#else /* RHEL6.1 or greater */
-#ifndef HAVE_MQPRIO
-#define HAVE_MQPRIO
-#endif /* HAVE_MQPRIO */
-#ifdef CONFIG_DCB
-#ifndef HAVE_DCBNL_IEEE
-#define HAVE_DCBNL_IEEE
-#ifndef IEEE_8021QAZ_TSA_STRICT
-#define IEEE_8021QAZ_TSA_STRICT 0
-#endif
-#ifndef IEEE_8021QAZ_TSA_ETS
-#define IEEE_8021QAZ_TSA_ETS 2
-#endif
-#ifndef IEEE_8021QAZ_APP_SEL_ETHERTYPE
-#define IEEE_8021QAZ_APP_SEL_ETHERTYPE 1
-#endif
-#endif
-#endif /* CONFIG_DCB */
-#endif /* !(RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,0)) */
-#else /* < 2.6.39 */
-#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
-#ifndef HAVE_NETDEV_OPS_FCOE_DDP_TARGET
-#define HAVE_NETDEV_OPS_FCOE_DDP_TARGET
-#endif
-#endif /* CONFIG_FCOE || CONFIG_FCOE_MODULE */
-#ifndef HAVE_MQPRIO
-#define HAVE_MQPRIO
-#endif
-#ifndef HAVE_SETUP_TC
-#define HAVE_SETUP_TC
-#endif
-#ifdef CONFIG_DCB
-#ifndef HAVE_DCBNL_IEEE
-#define HAVE_DCBNL_IEEE
-#endif
-#endif /* CONFIG_DCB */
-#ifndef HAVE_NDO_SET_FEATURES
-#define HAVE_NDO_SET_FEATURES
-#endif
-#endif /* < 2.6.39 */
-
-/*****************************************************************************/
-/* use < 2.6.40 because of a Fedora 15 kernel update where they
- * updated the kernel version to 2.6.40.x and they back-ported 3.0 features
- * like set_phys_id for ethtool.
- */
-#undef ETHTOOL_GRXRINGS
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,40) )
-#ifdef ETHTOOL_GRXRINGS
-#ifndef FLOW_EXT
-#define FLOW_EXT 0x80000000
-union _kc_ethtool_flow_union {
- struct ethtool_tcpip4_spec tcp_ip4_spec;
- struct ethtool_usrip4_spec usr_ip4_spec;
- __u8 hdata[60];
-};
-struct _kc_ethtool_flow_ext {
- __be16 vlan_etype;
- __be16 vlan_tci;
- __be32 data[2];
-};
-struct _kc_ethtool_rx_flow_spec {
- __u32 flow_type;
- union _kc_ethtool_flow_union h_u;
- struct _kc_ethtool_flow_ext h_ext;
- union _kc_ethtool_flow_union m_u;
- struct _kc_ethtool_flow_ext m_ext;
- __u64 ring_cookie;
- __u32 location;
-};
-#define ethtool_rx_flow_spec _kc_ethtool_rx_flow_spec
-#endif /* FLOW_EXT */
-#endif
-
-#define pci_disable_link_state_locked pci_disable_link_state
-
-#ifndef PCI_LTR_VALUE_MASK
-#define PCI_LTR_VALUE_MASK 0x000003ff
-#endif
-#ifndef PCI_LTR_SCALE_MASK
-#define PCI_LTR_SCALE_MASK 0x00001c00
-#endif
-#ifndef PCI_LTR_SCALE_SHIFT
-#define PCI_LTR_SCALE_SHIFT 10
-#endif
-
-#else /* < 2.6.40 */
-#define HAVE_ETHTOOL_SET_PHYS_ID
-#endif /* < 2.6.40 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) )
-#ifndef __netdev_alloc_skb_ip_align
-#define __netdev_alloc_skb_ip_align(d,l,_g) netdev_alloc_skb_ip_align(d,l)
-#endif /* __netdev_alloc_skb_ip_align */
-#define dcb_ieee_setapp(dev, app) dcb_setapp(dev, app)
-#define dcb_ieee_delapp(dev, app) 0
-#define dcb_ieee_getapp_mask(dev, app) (1 << app->priority)
-#else /* < 3.1.0 */
-#ifndef HAVE_DCBNL_IEEE_DELAPP
-#define HAVE_DCBNL_IEEE_DELAPP
-#endif
-#endif /* < 3.1.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) )
-#ifdef ETHTOOL_GRXRINGS
-#define HAVE_ETHTOOL_GET_RXNFC_VOID_RULE_LOCS
-#endif /* ETHTOOL_GRXRINGS */
-
-#ifndef skb_frag_size
-#define skb_frag_size(frag) _kc_skb_frag_size(frag)
-static inline unsigned int _kc_skb_frag_size(const skb_frag_t *frag)
-{
- return frag->size;
-}
-#endif /* skb_frag_size */
-
-#ifndef skb_frag_size_sub
-#define skb_frag_size_sub(frag, delta) _kc_skb_frag_size_sub(frag, delta)
-static inline void _kc_skb_frag_size_sub(skb_frag_t *frag, int delta)
-{
- frag->size -= delta;
-}
-#endif /* skb_frag_size_sub */
-
-#ifndef skb_frag_page
-#define skb_frag_page(frag) _kc_skb_frag_page(frag)
-static inline struct page *_kc_skb_frag_page(const skb_frag_t *frag)
-{
- return frag->page;
-}
-#endif /* skb_frag_page */
-
-#ifndef skb_frag_address
-#define skb_frag_address(frag) _kc_skb_frag_address(frag)
-static inline void *_kc_skb_frag_address(const skb_frag_t *frag)
-{
- return page_address(skb_frag_page(frag)) + frag->page_offset;
-}
-#endif /* skb_frag_address */
-
-#ifndef skb_frag_dma_map
-#define skb_frag_dma_map(dev,frag,offset,size,dir) \
- _kc_skb_frag_dma_map(dev,frag,offset,size,dir)
-static inline dma_addr_t _kc_skb_frag_dma_map(struct device *dev,
- const skb_frag_t *frag,
- size_t offset, size_t size,
- enum dma_data_direction dir)
-{
- return dma_map_page(dev, skb_frag_page(frag),
- frag->page_offset + offset, size, dir);
-}
-#endif /* skb_frag_dma_map */
-
-#ifndef __skb_frag_unref
-#define __skb_frag_unref(frag) __kc_skb_frag_unref(frag)
-static inline void __kc_skb_frag_unref(skb_frag_t *frag)
-{
- put_page(skb_frag_page(frag));
-}
-#endif /* __skb_frag_unref */
-#else /* < 3.2.0 */
-#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED
-#define HAVE_PCI_DEV_FLAGS_ASSIGNED
-#define HAVE_VF_SPOOFCHK_CONFIGURE
-#endif
-#endif /* < 3.2.0 */
-
-#if (RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6,2)) && \
- (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)))
-#undef ixgbe_get_netdev_tc_txq
-#define ixgbe_get_netdev_tc_txq(dev, tc) (&netdev_extended(dev)->qos_data.tc_to_txq[tc])
-#endif
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) )
-typedef u32 kni_netdev_features_t;
-#else /* ! < 3.3.0 */
-typedef netdev_features_t kni_netdev_features_t;
-#define HAVE_INT_NDO_VLAN_RX_ADD_VID
-#ifdef ETHTOOL_SRXNTUPLE
-#undef ETHTOOL_SRXNTUPLE
-#endif
-#endif /* < 3.3.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) )
-#ifndef NETIF_F_RXFCS
-#define NETIF_F_RXFCS 0
-#endif /* NETIF_F_RXFCS */
-#ifndef NETIF_F_RXALL
-#define NETIF_F_RXALL 0
-#endif /* NETIF_F_RXALL */
-
-#define NUMTCS_RETURNS_U8
-
-
-#endif /* < 3.4.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) )
-static inline bool __kc_ether_addr_equal(const u8 *addr1, const u8 *addr2)
-{
- return !compare_ether_addr(addr1, addr2);
-}
-#define ether_addr_equal(_addr1, _addr2) __kc_ether_addr_equal((_addr1),(_addr2))
-#else
-#define HAVE_FDB_OPS
-#endif /* < 3.5.0 */
-
-/*****************************************************************************/
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) )
-#define NETIF_F_HW_VLAN_TX NETIF_F_HW_VLAN_CTAG_TX
-#define NETIF_F_HW_VLAN_RX NETIF_F_HW_VLAN_CTAG_RX
-#define NETIF_F_HW_VLAN_FILTER NETIF_F_HW_VLAN_CTAG_FILTER
-#endif /* >= 3.10.0 */
-
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) )
-#ifdef CONFIG_PCI_IOV
-extern int __kc_pci_vfs_assigned(struct pci_dev *dev);
-#else
-static inline int __kc_pci_vfs_assigned(struct pci_dev *dev)
-{
- return 0;
-}
-#endif
-#define pci_vfs_assigned(dev) __kc_pci_vfs_assigned(dev)
-
-#endif
-
-#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) )
-#define SET_ETHTOOL_OPS(netdev, ops) ((netdev)->ethtool_ops = (ops))
-#endif /* >= 3.16.0 */
-
-/*
- * vlan_tx_tag_* macros renamed to skb_vlan_tag_* (Linux commit: df8a39defad4)
- * For older kernels backported this commit, need to use renamed functions.
- * This fix is specific to RedHat/CentOS kernels.
- */
-#if (defined(RHEL_RELEASE_CODE) && \
- RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6, 8) && \
- LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
-#define vlan_tx_tag_get skb_vlan_tag_get
-#define vlan_tx_tag_present skb_vlan_tag_present
-#endif
-
-#endif /* _KCOMPAT_H_ */
diff --git a/kernel/linux/kni/ethtool/ixgbe/meson.build b/kernel/linux/kni/ethtool/ixgbe/meson.build
deleted file mode 100644
index 73248b13e..000000000
--- a/kernel/linux/kni/ethtool/ixgbe/meson.build
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
-
-kni_ixgbe_sources = files(
- 'ixgbe_82598.c',
- 'ixgbe_82599.c',
- 'ixgbe_api.c',
- 'ixgbe_common.c',
- 'ixgbe_ethtool.c',
- 'ixgbe_main.c',
- 'ixgbe_phy.c',
- 'ixgbe_x540.c',
- 'kcompat.c')
diff --git a/kernel/linux/kni/ethtool/meson.build b/kernel/linux/kni/ethtool/meson.build
deleted file mode 100644
index 7a8458ddc..000000000
--- a/kernel/linux/kni/ethtool/meson.build
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
-
-subdir('igb')
-subdir('ixgbe')
diff --git a/kernel/linux/kni/kni_dev.h b/kernel/linux/kni/kni_dev.h
index 688f574a4..a21978cea 100644
--- a/kernel/linux/kni/kni_dev.h
+++ b/kernel/linux/kni/kni_dev.h
@@ -55,8 +55,6 @@ struct kni_dev {
/* kni device */
struct net_device *net_dev;
- struct net_device *lad_dev;
- struct pci_dev *pci_dev;
/* queue for packets to be sent out */
void *tx_q;
@@ -100,11 +98,5 @@ void kni_net_rx(struct kni_dev *kni);
void kni_net_init(struct net_device *dev);
void kni_net_config_lo_mode(char *lo_str);
void kni_net_poll_resp(struct kni_dev *kni);
-void kni_set_ethtool_ops(struct net_device *netdev);
-
-int ixgbe_kni_probe(struct pci_dev *pdev, struct net_device **lad_dev);
-void ixgbe_kni_remove(struct pci_dev *pdev);
-int igb_kni_probe(struct pci_dev *pdev, struct net_device **lad_dev);
-void igb_kni_remove(struct pci_dev *pdev);
#endif
diff --git a/kernel/linux/kni/kni_ethtool.c b/kernel/linux/kni/kni_ethtool.c
deleted file mode 100644
index b1c84f8f0..000000000
--- a/kernel/linux/kni/kni_ethtool.c
+++ /dev/null
@@ -1,229 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright(c) 2010-2014 Intel Corporation.
- */
-
-#include <linux/device.h>
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include "kni_dev.h"
-
-static int
-kni_check_if_running(struct net_device *dev)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- if (priv->lad_dev)
- return 0;
- else
- return -EOPNOTSUPP;
-}
-
-static void
-kni_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- priv->lad_dev->ethtool_ops->get_drvinfo(priv->lad_dev, info);
-}
-
-/* ETHTOOL_GLINKSETTINGS replaces ETHTOOL_GSET */
-#ifndef ETHTOOL_GLINKSETTINGS
-static int
-kni_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->get_settings(priv->lad_dev, ecmd);
-}
-#endif
-
-/* ETHTOOL_SLINKSETTINGS replaces ETHTOOL_SSET */
-#ifndef ETHTOOL_SLINKSETTINGS
-static int
-kni_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->set_settings(priv->lad_dev, ecmd);
-}
-#endif
-
-static void
-kni_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- priv->lad_dev->ethtool_ops->get_wol(priv->lad_dev, wol);
-}
-
-static int
-kni_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->set_wol(priv->lad_dev, wol);
-}
-
-static int
-kni_nway_reset(struct net_device *dev)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->nway_reset(priv->lad_dev);
-}
-
-static int
-kni_get_eeprom_len(struct net_device *dev)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->get_eeprom_len(priv->lad_dev);
-}
-
-static int
-kni_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
- u8 *bytes)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->get_eeprom(priv->lad_dev, eeprom,
- bytes);
-}
-
-static int
-kni_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
- u8 *bytes)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->set_eeprom(priv->lad_dev, eeprom,
- bytes);
-}
-
-static void
-kni_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- priv->lad_dev->ethtool_ops->get_ringparam(priv->lad_dev, ring);
-}
-
-static int
-kni_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->set_ringparam(priv->lad_dev, ring);
-}
-
-static void
-kni_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- priv->lad_dev->ethtool_ops->get_pauseparam(priv->lad_dev, pause);
-}
-
-static int
-kni_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->set_pauseparam(priv->lad_dev,
- pause);
-}
-
-static u32
-kni_get_msglevel(struct net_device *dev)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->get_msglevel(priv->lad_dev);
-}
-
-static void
-kni_set_msglevel(struct net_device *dev, u32 data)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- priv->lad_dev->ethtool_ops->set_msglevel(priv->lad_dev, data);
-}
-
-static int
-kni_get_regs_len(struct net_device *dev)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->get_regs_len(priv->lad_dev);
-}
-
-static void
-kni_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- priv->lad_dev->ethtool_ops->get_regs(priv->lad_dev, regs, p);
-}
-
-static void
-kni_get_strings(struct net_device *dev, u32 stringset, u8 *data)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- priv->lad_dev->ethtool_ops->get_strings(priv->lad_dev, stringset,
- data);
-}
-
-static int
-kni_get_sset_count(struct net_device *dev, int sset)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- return priv->lad_dev->ethtool_ops->get_sset_count(priv->lad_dev, sset);
-}
-
-static void
-kni_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats,
- u64 *data)
-{
- struct kni_dev *priv = netdev_priv(dev);
-
- priv->lad_dev->ethtool_ops->get_ethtool_stats(priv->lad_dev, stats,
- data);
-}
-
-struct ethtool_ops kni_ethtool_ops = {
- .begin = kni_check_if_running,
- .get_drvinfo = kni_get_drvinfo,
-#ifndef ETHTOOL_GLINKSETTINGS
- .get_settings = kni_get_settings,
-#endif
-#ifndef ETHTOOL_SLINKSETTINGS
- .set_settings = kni_set_settings,
-#endif
- .get_regs_len = kni_get_regs_len,
- .get_regs = kni_get_regs,
- .get_wol = kni_get_wol,
- .set_wol = kni_set_wol,
- .nway_reset = kni_nway_reset,
- .get_link = ethtool_op_get_link,
- .get_eeprom_len = kni_get_eeprom_len,
- .get_eeprom = kni_get_eeprom,
- .set_eeprom = kni_set_eeprom,
- .get_ringparam = kni_get_ringparam,
- .set_ringparam = kni_set_ringparam,
- .get_pauseparam = kni_get_pauseparam,
- .set_pauseparam = kni_set_pauseparam,
- .get_msglevel = kni_get_msglevel,
- .set_msglevel = kni_set_msglevel,
- .get_strings = kni_get_strings,
- .get_sset_count = kni_get_sset_count,
- .get_ethtool_stats = kni_get_ethtool_stats,
-};
-
-void
-kni_set_ethtool_ops(struct net_device *netdev)
-{
- netdev->ethtool_ops = &kni_ethtool_ops;
-}
diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c
index 522ae23b9..ba4fc7116 100644
--- a/kernel/linux/kni/kni_misc.c
+++ b/kernel/linux/kni/kni_misc.c
@@ -29,9 +29,6 @@ MODULE_DESCRIPTION("Kernel Module for managing kni devices");
#define KNI_MAX_DEVICES 32
-extern const struct pci_device_id ixgbe_pci_tbl[];
-extern const struct pci_device_id igb_pci_tbl[];
-
/* loopback mode */
static char *lo_mode;
@@ -182,15 +179,6 @@ kni_dev_remove(struct kni_dev *dev)
if (!dev)
return -ENODEV;
-#ifdef RTE_KNI_KMOD_ETHTOOL
- if (dev->pci_dev) {
- if (pci_match_id(ixgbe_pci_tbl, dev->pci_dev))
- ixgbe_kni_remove(dev->pci_dev);
- else if (pci_match_id(igb_pci_tbl, dev->pci_dev))
- igb_kni_remove(dev->pci_dev);
- }
-#endif
-
if (dev->net_dev) {
unregister_netdev(dev->net_dev);
free_netdev(dev->net_dev);
@@ -306,11 +294,6 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
struct rte_kni_device_info dev_info;
struct net_device *net_dev = NULL;
struct kni_dev *kni, *dev, *n;
-#ifdef RTE_KNI_KMOD_ETHTOOL
- struct pci_dev *found_pci = NULL;
- struct net_device *lad_dev = NULL;
- struct pci_dev *pci = NULL;
-#endif
pr_info("Creating kni...\n");
/* Check the buffer size, to avoid warning */
@@ -400,62 +383,15 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
dev_info.function,
dev_info.vendor_id,
dev_info.device_id);
-#ifdef RTE_KNI_KMOD_ETHTOOL
- pci = pci_get_device(dev_info.vendor_id, dev_info.device_id, NULL);
-
- /* Support Ethtool */
- while (pci) {
- pr_debug("pci_bus: %02x:%02x:%02x\n",
- pci->bus->number,
- PCI_SLOT(pci->devfn),
- PCI_FUNC(pci->devfn));
-
- if ((pci->bus->number == dev_info.bus) &&
- (PCI_SLOT(pci->devfn) == dev_info.devid) &&
- (PCI_FUNC(pci->devfn) == dev_info.function)) {
- found_pci = pci;
-
- if (pci_match_id(ixgbe_pci_tbl, found_pci))
- ret = ixgbe_kni_probe(found_pci, &lad_dev);
- else if (pci_match_id(igb_pci_tbl, found_pci))
- ret = igb_kni_probe(found_pci, &lad_dev);
- else
- ret = -1;
-
- pr_debug("PCI found: pci=0x%p, lad_dev=0x%p\n",
- pci, lad_dev);
- if (ret == 0) {
- kni->lad_dev = lad_dev;
- kni_set_ethtool_ops(kni->net_dev);
- } else {
- pr_err("Device not supported by ethtool");
- kni->lad_dev = NULL;
- }
-
- kni->pci_dev = found_pci;
- kni->device_id = dev_info.device_id;
- break;
- }
- pci = pci_get_device(dev_info.vendor_id,
- dev_info.device_id, pci);
- }
- if (pci)
- pci_dev_put(pci);
-#endif
-
- if (kni->lad_dev)
- ether_addr_copy(net_dev->dev_addr, kni->lad_dev->dev_addr);
- else {
- /* if user has provided a valid mac address */
- if (is_valid_ether_addr((unsigned char *)(dev_info.mac_addr)))
- memcpy(net_dev->dev_addr, dev_info.mac_addr, ETH_ALEN);
- else
- /*
- * Generate random mac address. eth_random_addr() is the
- * newer version of generating mac address in kernel.
- */
- random_ether_addr(net_dev->dev_addr);
- }
+ /* if user has provided a valid mac address */
+ if (is_valid_ether_addr((unsigned char *)(dev_info.mac_addr)))
+ memcpy(net_dev->dev_addr, dev_info.mac_addr, ETH_ALEN);
+ else
+ /*
+ * Generate random mac address. eth_random_addr() is the
+ * newer version of generating mac address in kernel.
+ */
+ random_ether_addr(net_dev->dev_addr);
if (dev_info.mtu)
net_dev->mtu = dev_info.mtu;
diff --git a/kernel/linux/kni/meson.build b/kernel/linux/kni/meson.build
index a09af5aa5..d7ea0b2ae 100644
--- a/kernel/linux/kni/meson.build
+++ b/kernel/linux/kni/meson.build
@@ -1,20 +1,17 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
-subdir('ethtool')
-
kni_mkfile = custom_target('rte_kni_makefile',
output: 'Makefile',
command: ['touch', '@OUTPUT@'])
kni_sources = files(
- 'kni_ethtool.c',
'kni_misc.c',
'kni_net.c',
'Kbuild')
custom_target('rte_kni',
- input: kni_sources + kni_igb_sources + kni_ixgbe_sources,
+ input: kni_sources,
output: 'rte_kni.ko',
command: ['make', '-j4', '-C', kernel_dir,
'M=' + meson.current_build_dir(),
@@ -23,9 +20,7 @@ custom_target('rte_kni',
' -I' + meson.source_root() + '/lib/librte_eal/common/include' +
' -I' + meson.source_root() + '/lib/librte_eal/linuxapp/eal/include' +
' -I' + meson.build_root() +
- ' -I' + meson.current_source_dir() +
- ' -I' + meson.current_source_dir() + '/ethtool/ixgbe' +
- ' -I' + meson.current_source_dir() + '/ethtool/igb',
+ ' -I' + meson.current_source_dir(),
'modules'],
depends: kni_mkfile,
console: true,
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 73aeccccf..c01a9a228 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -242,11 +242,6 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
kni->ops.port_id = UINT16_MAX;
memset(&dev_info, 0, sizeof(dev_info));
- dev_info.bus = conf->addr.bus;
- dev_info.devid = conf->addr.devid;
- dev_info.function = conf->addr.function;
- dev_info.vendor_id = conf->id.vendor_id;
- dev_info.device_id = conf->id.device_id;
dev_info.core_id = conf->core_id;
dev_info.force_bind = conf->force_bind;
dev_info.group_id = conf->group_id;
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 02ca43b4b..3720d92c4 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -63,8 +63,8 @@ struct rte_kni_conf {
uint32_t core_id; /* Core ID to bind kernel thread on */
uint16_t group_id; /* Group ID */
unsigned mbuf_size; /* mbuf size */
- struct rte_pci_addr addr;
- struct rte_pci_id id;
+ struct rte_pci_addr addr; /* depreciated */
+ struct rte_pci_id id; /* depreciated */
__extension__
uint8_t force_bind : 1; /* Flag to bind kernel thread */
--
2.17.2
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH v8 2/6] Move common functions in eal.c
@ 2018-12-18 1:42 0% ` Ferruh Yigit
2018-12-18 1:43 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-12-18 1:42 UTC (permalink / raw)
To: Ravi Kerur; +Cc: dpdk-dev, Thomas Monjalon
On 4/29/2015 12:46 AM, rkerur at gmail.com (Ravi Kerur) wrote:
> Changes in v8
> Fix ABI warnings by reordering compilation of
> eal_common_sysfs.c
> eal_common_mem_cfg.c
> eal_common_proc_type.c
> eal_common_app_usage.c
>
> Changes in v7
> Fix compilation errors in clang.
>
> Changes in v6
> Split eal_common_system.c and eal_common_runtime.c into
> eal_common_sysfs.c
> eal_common_mem_cfg.c
> eal_common_proc_type.c
> eal_common_app_usage.c
> based on functionality.
>
> Changes in v5
> Rebase to latest code.
>
> Changes in v4
> Remove eal_externs.h file, instead use _get_ and _set_ APIS
> to access those variables.
> Split eal_common.c into eal_common_system.c and
> and eal_common_runtime.c
> rte_eal prefix functions are moved to _runtime_ and
> eal prefix functions are moved to _system_ files respectively.
>
> Changes in v3
> Changed subject to be more explicit on file name inclusion.
>
> Changes in v2
> In function rte_eal_config_create remove #ifdef _BSDAPP_
> and initialize mem_cfg_addr unconditionally.
>
> Changes in v1
> Move common functions in eal.c to librte_eal/common/eal_common.c.
>
> Following functions are moved to eal_common.c file.
>
> struct rte_config *rte_eal_get_configuration(void);
> int eal_parse_sysfs_value(const char *filename, unsigned long *val);
> static void rte_eal_config_create(void);
> enum rte_proc_type_t eal_proc_type_detect(void);
> void rte_eal_config_init(void);
> rte_usage_hook_t rte_set_application_usage_hook(rte_usage_hook_t
> usage_func);
> inline size_t eal_get_hugepage_mem_size(void);
> void eal_check_mem_on_local_socket(void);
> int sync_func(__attribute__((unused)) void *arg);
> inline void rte_eal_mcfg_complete(void);
> int rte_eal_has_hugepages(void);
> enum rte_lcore_role_t rte_eal_lcore_role(unsigned lcore_id);
> enum rte_proc_type_t rte_eal_process_type(void);
>
> Makefile changes to reflect new files added.
> Fix checkpatch warnings and errors.
>
> Signed-off-by: Ravi Kerur <rkerur at gmail.com>
Hi Ravi,
This patch is sitting on patchwork since 2015, I am updating it as rejected, if
it is still relevant please let us know.
Sorry for any inconvenience caused.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v8 2/6] Move common functions in eal.c
2018-12-18 1:42 0% ` Ferruh Yigit
@ 2018-12-18 1:43 0% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-12-18 1:43 UTC (permalink / raw)
To: Ravi Kerur; +Cc: dpdk-dev, Thomas Monjalon
On 12/18/2018 1:42 AM, Ferruh Yigit wrote:
> On 4/29/2015 12:46 AM, rkerur at gmail.com (Ravi Kerur) wrote:
>> Changes in v8
>> Fix ABI warnings by reordering compilation of
>> eal_common_sysfs.c
>> eal_common_mem_cfg.c
>> eal_common_proc_type.c
>> eal_common_app_usage.c
>>
>> Changes in v7
>> Fix compilation errors in clang.
>>
>> Changes in v6
>> Split eal_common_system.c and eal_common_runtime.c into
>> eal_common_sysfs.c
>> eal_common_mem_cfg.c
>> eal_common_proc_type.c
>> eal_common_app_usage.c
>> based on functionality.
>>
>> Changes in v5
>> Rebase to latest code.
>>
>> Changes in v4
>> Remove eal_externs.h file, instead use _get_ and _set_ APIS
>> to access those variables.
>> Split eal_common.c into eal_common_system.c and
>> and eal_common_runtime.c
>> rte_eal prefix functions are moved to _runtime_ and
>> eal prefix functions are moved to _system_ files respectively.
>>
>> Changes in v3
>> Changed subject to be more explicit on file name inclusion.
>>
>> Changes in v2
>> In function rte_eal_config_create remove #ifdef _BSDAPP_
>> and initialize mem_cfg_addr unconditionally.
>>
>> Changes in v1
>> Move common functions in eal.c to librte_eal/common/eal_common.c.
>>
>> Following functions are moved to eal_common.c file.
>>
>> struct rte_config *rte_eal_get_configuration(void);
>> int eal_parse_sysfs_value(const char *filename, unsigned long *val);
>> static void rte_eal_config_create(void);
>> enum rte_proc_type_t eal_proc_type_detect(void);
>> void rte_eal_config_init(void);
>> rte_usage_hook_t rte_set_application_usage_hook(rte_usage_hook_t
>> usage_func);
>> inline size_t eal_get_hugepage_mem_size(void);
>> void eal_check_mem_on_local_socket(void);
>> int sync_func(__attribute__((unused)) void *arg);
>> inline void rte_eal_mcfg_complete(void);
>> int rte_eal_has_hugepages(void);
>> enum rte_lcore_role_t rte_eal_lcore_role(unsigned lcore_id);
>> enum rte_proc_type_t rte_eal_process_type(void);
>>
>> Makefile changes to reflect new files added.
>> Fix checkpatch warnings and errors.
>>
>> Signed-off-by: Ravi Kerur <rkerur at gmail.com>
>
> Hi Ravi,
>
> This patch is sitting on patchwork since 2015, I am updating it as rejected, if
> it is still relevant please let us know.
>
> Sorry for any inconvenience caused.
>
for record, it is: https://patches.dpdk.org/patch/4487/
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4 2/2] mbuf: implement generic format for sched field
@ 2018-12-18 15:40 1% ` Reshma Pattan
1 sibling, 0 replies; 200+ results
From: Reshma Pattan @ 2018-12-18 15:40 UTC (permalink / raw)
To: dev, jerin.jacob, nikhil.rao, jasvinder.singh, cristian.dumitrescu
Cc: Reshma Pattan
This patch implements the changes proposed in the deprecation
notes [1][2].
librte_mbuf changes:
The mbuf::hash::sched field is updated to support generic
definition in line with the ethdev TM and MTR APIs. The new generic
format contains: queue ID, traffic class, color.
Added public APIs to set and get these new fields to and from mbuf.
librte_sched changes:
In addtion, following API functions of the sched library have
been modified with an additional parameter of type struct
rte_sched_port to accommodate the changes made to mbuf sched field.
(i)rte_sched_port_pkt_write()
(ii) rte_sched_port_pkt_read_tree_path()
librte_pipeline, qos_sched UT, qos_sched app are updated
to make use of new changes.
Also mbuf::hash::txadapter has been added for eventdev txq,
rte_event_eth_tx_adapter_txq_set and rte_event_eth_tx_adapter_txq_get()
are updated to use uses mbuf::hash::txadapter.txq.
doc:
Release notes updated.
Removed deprecation notice for mbuf::hash::sched and sched API.
[1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
[2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
---
v4: converted mbuf::hash::sched as instantiation of rte_mbuf_sched.
v3: addressed review comments given in the below link.
http://patches.dpdk.org/patch/48587/
Updated library ABI versioning in meson build.
---
---
doc/guides/rel_notes/deprecation.rst | 10 --
doc/guides/rel_notes/release_19_02.rst | 4 +-
examples/qos_sched/app_thread.c | 7 +-
examples/qos_sched/main.c | 1 +
lib/Makefile | 2 +-
.../rte_event_eth_tx_adapter.h | 18 ++-
lib/librte_mbuf/Makefile | 4 +-
lib/librte_mbuf/meson.build | 4 +-
lib/librte_mbuf/rte_mbuf.h | 118 +++++++++++++++++-
lib/librte_pipeline/rte_table_action.c | 43 ++-----
lib/librte_sched/Makefile | 2 +-
lib/librte_sched/meson.build | 1 +
lib/librte_sched/rte_sched.c | 90 ++++++-------
lib/librte_sched/rte_sched.h | 10 +-
test/test/test_sched.c | 9 +-
15 files changed, 198 insertions(+), 125 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index b48486d36..60e081a54 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,16 +49,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* mbuf: The opaque ``mbuf->hash.sched`` field will be updated to support generic
- definition in line with the ethdev TM and MTR APIs. Currently, this field
- is defined in librte_sched in a non-generic way. The new generic format
- will contain: queue ID, traffic class, color. Field size will not change.
-
-* sched: Some API functions will change prototype due to the above
- deprecation note for mbuf->hash.sched, e.g. ``rte_sched_port_pkt_write()``
- and ``rte_sched_port_pkt_read()`` will likely have an additional parameter
- of type ``struct rte_sched_port``.
-
* mbuf: the macro ``RTE_MBUF_INDIRECT()`` will be removed in v18.08 or later and
replaced with ``RTE_MBUF_CLONED()`` which is already added in v18.05. As
``EXT_ATTACHED_MBUF`` is newly introduced in v18.05, ``RTE_MBUF_INDIRECT()``
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index e86ef9511..39951b398 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -152,7 +152,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_kvargs.so.1
librte_latencystats.so.1
librte_lpm.so.2
- librte_mbuf.so.4
+ + librte_mbuf.so.5
librte_member.so.1
librte_mempool.so.5
librte_meter.so.2
@@ -174,7 +174,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_rawdev.so.1
librte_reorder.so.1
librte_ring.so.2
- librte_sched.so.1
+ + librte_sched.so.2
librte_security.so.1
librte_table.so.3
librte_timer.so.1
diff --git a/examples/qos_sched/app_thread.c b/examples/qos_sched/app_thread.c
index a59274236..bec4deee3 100644
--- a/examples/qos_sched/app_thread.c
+++ b/examples/qos_sched/app_thread.c
@@ -73,8 +73,11 @@ app_rx_thread(struct thread_conf **confs)
for(i = 0; i < nb_rx; i++) {
get_pkt_sched(rx_mbufs[i],
&subport, &pipe, &traffic_class, &queue, &color);
- rte_sched_port_pkt_write(rx_mbufs[i], subport, pipe,
- traffic_class, queue, (enum rte_meter_color) color);
+ rte_sched_port_pkt_write(conf->sched_port,
+ rx_mbufs[i],
+ subport, pipe,
+ traffic_class, queue,
+ (enum rte_meter_color) color);
}
if (unlikely(rte_ring_sp_enqueue_bulk(conf->rx_ring,
diff --git a/examples/qos_sched/main.c b/examples/qos_sched/main.c
index e7c97bd64..c0ed16b68 100644
--- a/examples/qos_sched/main.c
+++ b/examples/qos_sched/main.c
@@ -55,6 +55,7 @@ app_main_loop(__attribute__((unused))void *dummy)
flow->rx_thread.rx_port = flow->rx_port;
flow->rx_thread.rx_ring = flow->rx_ring;
flow->rx_thread.rx_queue = flow->rx_queue;
+ flow->rx_thread.sched_port = flow->sched_port;
rx_confs[rx_idx++] = &flow->rx_thread;
diff --git a/lib/Makefile b/lib/Makefile
index 8dbdc9bca..d243c0b64 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -15,7 +15,7 @@ DEPDIRS-librte_ring := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
DEPDIRS-librte_mempool := librte_eal librte_ring
DIRS-$(CONFIG_RTE_LIBRTE_MBUF) += librte_mbuf
-DEPDIRS-librte_mbuf := librte_eal librte_mempool
+DEPDIRS-librte_mbuf := librte_eal librte_mempool librte_meter
DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
DEPDIRS-librte_timer := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index 81456d4a9..2a50656d9 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -63,13 +63,11 @@
* function can be used to retrieve the adapter's service function ID.
*
* The ethernet port and transmit queue index to transmit the mbuf on are
- * specified using the mbuf port and the higher 16 bits of
- * struct rte_mbuf::hash::sched:hi. The application should use the
- * rte_event_eth_tx_adapter_txq_set() and rte_event_eth_tx_adapter_txq_get()
- * functions to access the transmit queue index since it is expected that the
- * transmit queue will be eventually defined within struct rte_mbuf and using
- * these macros will help with minimizing application impact due to
- * a change in how the transmit queue index is specified.
+ * specified using the mbuf port struct rte_mbuf::hash::txadapter:txq.
+ * The application should use the rte_event_eth_tx_adapter_txq_set()
+ * and rte_event_eth_tx_adapter_txq_get() functions to access the transmit
+ * queue index, using these macros will help with minimizing application
+ * impact due to a change in how the transmit queue index is specified.
*/
#ifdef __cplusplus
@@ -300,8 +298,7 @@ rte_event_eth_tx_adapter_queue_del(uint8_t id,
static __rte_always_inline void __rte_experimental
rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- p[1] = queue;
+ pkt->hash.txadapter.txq = queue;
}
/**
@@ -320,8 +317,7 @@ rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
static __rte_always_inline uint16_t __rte_experimental
rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- return p[1];
+ return pkt->hash.txadapter.txq;
}
/**
diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
index e2b98a254..eb1b5e6a1 100644
--- a/lib/librte_mbuf/Makefile
+++ b/lib/librte_mbuf/Makefile
@@ -7,11 +7,11 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_mbuf.a
CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
-LDLIBS += -lrte_eal -lrte_mempool
+LDLIBS += -lrte_eal -lrte_mempool -lrte_meter
EXPORT_MAP := rte_mbuf_version.map
-LIBABIVER := 4
+LIBABIVER := 5
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
index 94d9c4c96..d87785818 100644
--- a/lib/librte_mbuf/meson.build
+++ b/lib/librte_mbuf/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 4
+version = 5
sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
-deps += ['mempool']
+deps += ['mempool', 'meter']
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 3dbc6695e..7397e3cf5 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -37,6 +37,7 @@
#include <rte_config.h>
#include <rte_mempool.h>
#include <rte_memory.h>
+#include <rte_meter.h>
#include <rte_atomic.h>
#include <rte_prefetch.h>
#include <rte_branch_prediction.h>
@@ -574,14 +575,25 @@ struct rte_mbuf {
* on PKT_RX_FDIR_* flag in ol_flags.
*/
} fdir; /**< Filter identifier if FDIR enabled */
+ struct rte_mbuf_sched {
+ uint32_t queue_id; /**< Queue ID. */
+ uint8_t traffic_class;
+ /**< Traffic class ID. Traffic class 0
+ * is the highest priority traffic class.
+ */
+ uint8_t color;
+ /**< Color. @see enum rte_color.*/
+ uint16_t reserved; /**< Reserved. */
+ } sched; /**< Hierarchical scheduler */
struct {
- uint32_t lo;
- uint32_t hi;
+ uint32_t reserved1;
+ uint16_t reserved2;
+ uint16_t txq;
/**< The event eth Tx adapter uses this field
* to store Tx queue id.
* @see rte_event_eth_tx_adapter_txq_set()
*/
- } sched; /**< Hierarchical scheduler */
+ } txadapter; /**< Eventdev ethdev Tx adapter */
/**< User defined tags. See rte_distributor_process() */
uint32_t usr;
} hash; /**< hash information */
@@ -2289,6 +2301,106 @@ rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
*/
void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
+/**
+ * Get the value of mbuf sched queue_id field.
+ */
+static inline uint32_t
+rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.queue_id;
+}
+
+/**
+ * Get the value of mbuf sched traffic_class field.
+ */
+static inline uint8_t
+rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.traffic_class;
+}
+
+/**
+ * Get the value of mbuf sched color field.
+ */
+static inline enum rte_color
+rte_mbuf_sched_color_get(const struct rte_mbuf *m)
+{
+ return (enum rte_color)m->hash.sched.color;
+}
+
+/**
+ * Get the values of mbuf sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to read
+ * @param queue_id
+ * Returns the queue id
+ * @param traffic_class
+ * Returns the traffic class id
+ * @param color
+ * Returns the colour id
+ */
+static inline void
+rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
+ uint8_t *traffic_class,
+ enum rte_color *color)
+{
+ struct rte_mbuf_sched sched = m->hash.sched;
+
+ *queue_id = sched.queue_id;
+ *traffic_class = sched.traffic_class;
+ *color = (enum rte_color)sched.color;
+}
+
+/**
+ * Set the mbuf sched queue_id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
+{
+ m->hash.sched.queue_id = queue_id;
+}
+
+/**
+ * Set the mbuf sched traffic_class id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
+{
+ m->hash.sched.traffic_class = traffic_class;
+}
+
+/**
+ * Set the mbuf sched color id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_color_set(struct rte_mbuf *m, enum rte_color color)
+{
+ m->hash.sched.color = (uint8_t)color;
+}
+
+/**
+ * Set the mbuf sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to set
+ * @param queue_id
+ * Queue id value to be set
+ * @param traffic_class
+ * Traffic class id value to be set
+ * @param color
+ * Color id to be set
+ */
+static inline void
+rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t queue_id,
+ uint8_t traffic_class,
+ enum rte_color color)
+{
+ m->hash.sched = (struct rte_mbuf_sched){
+ .queue_id = queue_id,
+ .traffic_class = traffic_class,
+ .color = (uint8_t)color,
+ };
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 7c7c8dd82..3158301ff 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -107,14 +107,6 @@ mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
return 0;
}
-#define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
- ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
- ((((uint64_t)(tc)) & 0x3) << 2) | \
- ((((uint64_t)(color)) & 0x3) << 4)))
-
-#define MBUF_SCHED_COLOR(sched, color) \
- (((sched) & (~0x30LLU)) | ((color) << 4))
-
struct mtr_trtcm_data {
struct rte_meter_trtcm trtcm;
uint64_t stats[e_RTE_METER_COLORS];
@@ -176,7 +168,7 @@ mtr_data_size(struct rte_table_action_mtr_config *mtr)
struct dscp_table_entry_data {
enum rte_meter_color color;
uint16_t tc;
- uint16_t queue_tc_color;
+ uint16_t tc_queue;
};
struct dscp_table_data {
@@ -319,8 +311,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
uint32_t dscp,
uint16_t total_length)
{
- uint64_t drop_mask, sched;
- uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
+ uint64_t drop_mask;
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
enum rte_meter_color color_in, color_meter, color_policer;
uint32_t tc, mp_id;
@@ -329,7 +320,6 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
color_in = dscp_entry->color;
data += tc;
mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
- sched = *sched_ptr;
/* Meter */
color_meter = rte_meter_trtcm_color_aware_check(
@@ -346,7 +336,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
color_policer =
MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- *sched_ptr = MBUF_SCHED_COLOR(sched, color_policer);
+ rte_mbuf_sched_color_set(mbuf, color_policer);
return drop_mask;
}
@@ -368,9 +358,8 @@ tm_cfg_check(struct rte_table_action_tm_config *tm)
}
struct tm_data {
- uint16_t queue_tc_color;
- uint16_t subport;
- uint32_t pipe;
+ uint32_t queue_id;
+ uint32_t reserved;
} __attribute__((__packed__));
static int
@@ -397,9 +386,9 @@ tm_apply(struct tm_data *data,
return status;
/* Apply */
- data->queue_tc_color = 0;
- data->subport = (uint16_t) p->subport_id;
- data->pipe = p->pipe_id;
+ data->queue_id = p->subport_id <<
+ (__builtin_ctz(cfg->n_pipes_per_subport) + 4) |
+ p->pipe_id << 4;
return 0;
}
@@ -411,12 +400,10 @@ pkt_work_tm(struct rte_mbuf *mbuf,
uint32_t dscp)
{
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
- struct tm_data sched;
-
- sched = *data;
- sched.queue_tc_color = dscp_entry->queue_tc_color;
- *sched_ptr = sched;
+ uint32_t queue_id = data->queue_id |
+ (dscp_entry->tc << 2) |
+ dscp_entry->tc_queue;
+ rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc, dscp_entry->color);
}
/**
@@ -2580,17 +2567,13 @@ rte_table_action_dscp_table_update(struct rte_table_action *action,
&action->dscp_table.entry[i];
struct rte_table_action_dscp_table_entry *entry =
&table->entry[i];
- uint16_t queue_tc_color =
- MBUF_SCHED_QUEUE_TC_COLOR(entry->tc_queue_id,
- entry->tc_id,
- entry->color);
if ((dscp_mask & (1LLU << i)) == 0)
continue;
data->color = entry->color;
data->tc = entry->tc_id;
- data->queue_tc_color = queue_tc_color;
+ data->tc_queue = entry->tc_queue_id;
}
return 0;
diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile
index 46c53ed71..644fd9d15 100644
--- a/lib/librte_sched/Makefile
+++ b/lib/librte_sched/Makefile
@@ -18,7 +18,7 @@ LDLIBS += -lrte_timer
EXPORT_MAP := rte_sched_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build
index f85d64df8..8e989e5f6 100644
--- a/lib/librte_sched/meson.build
+++ b/lib/librte_sched/meson.build
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
+version = 2
sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c')
headers = files('rte_sched.h', 'rte_sched_common.h',
'rte_red.h', 'rte_approx.h')
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 587d5e602..14290ee44 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -128,22 +128,6 @@ enum grinder_state {
e_GRINDER_READ_MBUF
};
-/*
- * Path through the scheduler hierarchy used by the scheduler enqueue
- * operation to identify the destination queue for the current
- * packet. Stored in the field pkt.hash.sched of struct rte_mbuf of
- * each packet, typically written by the classification stage and read
- * by scheduler enqueue.
- */
-struct rte_sched_port_hierarchy {
- uint16_t queue:2; /**< Queue ID (0 .. 3) */
- uint16_t traffic_class:2; /**< Traffic class ID (0 .. 3)*/
- uint32_t color:2; /**< Color */
- uint16_t unused:10;
- uint16_t subport; /**< Subport ID */
- uint32_t pipe; /**< Pipe ID */
-};
-
struct rte_sched_grinder {
/* Pipe cache */
uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
@@ -185,6 +169,7 @@ struct rte_sched_port {
/* User parameters */
uint32_t n_subports_per_port;
uint32_t n_pipes_per_subport;
+ uint32_t n_pipes_per_subport_log2;
uint32_t rate;
uint32_t mtu;
uint32_t frame_overhead;
@@ -645,6 +630,8 @@ rte_sched_port_config(struct rte_sched_port_params *params)
/* User parameters */
port->n_subports_per_port = params->n_subports_per_port;
port->n_pipes_per_subport = params->n_pipes_per_subport;
+ port->n_pipes_per_subport_log2 =
+ __builtin_ctz(params->n_pipes_per_subport);
port->rate = params->rate;
port->mtu = params->mtu + params->frame_overhead;
port->frame_overhead = params->frame_overhead;
@@ -1006,44 +993,52 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port,
return 0;
}
+static inline uint32_t
+rte_sched_port_qindex(struct rte_sched_port *port,
+ uint32_t subport,
+ uint32_t pipe,
+ uint32_t traffic_class,
+ uint32_t queue)
+{
+ return ((subport & (port->n_subports_per_port - 1)) <<
+ (port->n_pipes_per_subport_log2 + 4)) |
+ ((pipe & (port->n_pipes_per_subport - 1)) << 4) |
+ ((traffic_class &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << 2) |
+ (queue & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1));
+}
+
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
- uint32_t subport, uint32_t pipe, uint32_t traffic_class,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
+ uint32_t subport, uint32_t pipe,
+ uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color)
{
- struct rte_sched_port_hierarchy *sched
- = (struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- RTE_BUILD_BUG_ON(sizeof(*sched) > sizeof(pkt->hash.sched));
-
- sched->color = (uint32_t) color;
- sched->subport = subport;
- sched->pipe = pipe;
- sched->traffic_class = traffic_class;
- sched->queue = queue;
+ uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe,
+ traffic_class, queue);
+ rte_mbuf_sched_set(pkt, queue_id, traffic_class, (enum rte_color)color);
}
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
+ uint32_t queue_id = rte_mbuf_sched_queue_get(pkt);
- *subport = sched->subport;
- *pipe = sched->pipe;
- *traffic_class = sched->traffic_class;
- *queue = sched->queue;
+ *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4);
+ *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1);
+ *traffic_class = (queue_id >> 2) &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1);
+ *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1);
}
enum rte_meter_color
rte_sched_port_pkt_read_color(const struct rte_mbuf *pkt)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- return (enum rte_meter_color) sched->color;
+ return rte_mbuf_sched_color_get(pkt);
}
int
@@ -1100,18 +1095,6 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
return 0;
}
-static inline uint32_t
-rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport, uint32_t pipe, uint32_t traffic_class, uint32_t queue)
-{
- uint32_t result;
-
- result = subport * port->n_pipes_per_subport + pipe;
- result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + traffic_class;
- result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
-
- return result;
-}
-
#ifdef RTE_SCHED_DEBUG
static inline int
@@ -1272,11 +1255,8 @@ rte_sched_port_enqueue_qptrs_prefetch0(struct rte_sched_port *port,
#ifdef RTE_SCHED_COLLECT_STATS
struct rte_sched_queue_extra *qe;
#endif
- uint32_t subport, pipe, traffic_class, queue, qindex;
-
- rte_sched_port_pkt_read_tree_path(pkt, &subport, &pipe, &traffic_class, &queue);
+ uint32_t qindex = rte_mbuf_sched_queue_get(pkt);
- qindex = rte_sched_port_qindex(port, subport, pipe, traffic_class, queue);
q = port->queue + qindex;
rte_prefetch0(q);
#ifdef RTE_SCHED_COLLECT_STATS
diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
index 84fa896de..243efa1d4 100644
--- a/lib/librte_sched/rte_sched.h
+++ b/lib/librte_sched/rte_sched.h
@@ -355,6 +355,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Scheduler hierarchy path write to packet descriptor. Typically
* called by the packet classification stage.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -369,7 +371,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Packet color set
*/
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
uint32_t subport, uint32_t pipe, uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color);
@@ -379,6 +382,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
* enqueue operation. The subport, pipe, traffic class and queue
* parameters need to be pre-allocated by the caller.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -392,7 +397,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
*
*/
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue);
diff --git a/test/test/test_sched.c b/test/test/test_sched.c
index 32e500ba9..40e411cab 100644
--- a/test/test/test_sched.c
+++ b/test/test/test_sched.c
@@ -76,7 +76,7 @@ create_mempool(void)
}
static void
-prepare_pkt(struct rte_mbuf *mbuf)
+prepare_pkt(struct rte_sched_port *port, struct rte_mbuf *mbuf)
{
struct ether_hdr *eth_hdr;
struct vlan_hdr *vlan1, *vlan2;
@@ -95,7 +95,8 @@ prepare_pkt(struct rte_mbuf *mbuf)
ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);
- rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW);
+ rte_sched_port_pkt_write(port, mbuf, SUBPORT, PIPE, TC, QUEUE,
+ e_RTE_METER_YELLOW);
/* 64 byte packet */
mbuf->pkt_len = 60;
@@ -138,7 +139,7 @@ test_sched(void)
for (i = 0; i < 10; i++) {
in_mbufs[i] = rte_pktmbuf_alloc(mp);
TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation failed\n");
- prepare_pkt(in_mbufs[i]);
+ prepare_pkt(port, in_mbufs[i]);
}
@@ -155,7 +156,7 @@ test_sched(void)
color = rte_sched_port_pkt_read_color(out_mbufs[i]);
TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong color\n");
- rte_sched_port_pkt_read_tree_path(out_mbufs[i],
+ rte_sched_port_pkt_read_tree_path(port, out_mbufs[i],
&subport, &pipe, &traffic_class, &queue);
TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong subport\n");
--
2.17.1
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH] pdump: remove deprecated APIs
2018-12-13 17:15 0% ` Pattan, Reshma
@ 2018-12-19 0:28 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-12-19 0:28 UTC (permalink / raw)
To: Bie, Tiwei; +Cc: dev, Pattan, Reshma, Mcnamara, John, Kovacevic, Marko
13/12/2018 18:15, Pattan, Reshma:
> Hi,
>
> From: Bie, Tiwei
> >
> > We already changed to use generic IPC in pdump since below commit:
> >
> > commit 660098d61f57 ("pdump: use generic multi-process channel")
> >
> > The `rte_pdump_set_socket_dir()`, the `path` parameter of `rte_pdump_init()`
> > and the `enum rte_pdump_socktype` have been deprecated since then. This
> > commit removes these deprecated APIs and also bumps the pdump ABI.
> >
> > Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> >
> Reviewed-by: Reshma Pattan <reshma.pattan@intel.com>
> Acked-by: Reshma Pattan <reshma.pattan@intel.com>
Applied, thanks
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-14 13:11 1% ` [dpdk-dev] [PATCH v3] " Liang Ma
@ 2018-12-19 3:18 0% ` Thomas Monjalon
2018-12-19 9:09 0% ` Hunt, David
2018-12-20 14:43 1% ` [dpdk-dev] [PATCH v4] " Liang Ma
1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-12-19 3:18 UTC (permalink / raw)
To: Liang Ma, david.hunt; +Cc: dev, anatoly.burakov
14/12/2018 14:11, Liang Ma:
> Previously, in order to use the power library, it was necessary
> for the user to disable the intel_pstate driver by adding
> “intel_pstate=disable” to the kernel command line for the system,
> which causes the acpi_cpufreq driver to be loaded in its place.
>
> This patch adds the ability for the power library use the intel-pstate
> driver.
>
> It adds a new suite of functions behind the current power library API,
> and will seamlessly set up the user facing API function pointers to
> the relevant functions depending on whether the system is running with
> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
> using kvm. The library API and ABI is unchanged.
>
> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
>
> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
Please write a changelog when sending a new version.
Dave, any comment on this patch?
> --- /dev/null
> +++ b/lib/librte_power/power_pstate_cpufreq.c
> @@ -0,0 +1,770 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2018-2018 Intel Corporation
Something wrong here :)
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 0/2] Timer library changes
2018-12-13 22:26 4% ` [dpdk-dev] [PATCH v3 0/2] Timer library changes Erik Gabriel Carrillo
@ 2018-12-19 3:35 0% ` Thomas Monjalon
2018-12-19 7:33 0% ` Mattias Rönnblom
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-12-19 3:35 UTC (permalink / raw)
To: dev; +Cc: Erik Gabriel Carrillo, rsanford, stephen, jerin.jacob, pbhagavatula
13/12/2018 23:26, Erik Gabriel Carrillo:
> This patch series modifies the timer library in such a way that
> structures that used to be statically allocated in a process's data
> segment are now allocated in shared memory. As these structures contain
> lists of timers, new APIs are introduced that allow a caller to specify
> the particular structure instance into which a timer should be inserted
> or from which a timer should be removed. This enables primary and
> secondary processes to modify the same timer list, which enables some
> multi-process use cases that were not previously possible; e.g. a
> secondary process can start a timer whose expiration is detected in a
> primary process running a new flavor of timer_manage().
>
> The original library API is mostly unchanged, though implementations are
> updated to call into newly added functions with a default structure
> instance ID that provides the original behavior. New functions are
> introduced to enable applications to allocate structure instances to
> house timer lists, and to reference them with an identifier when
> starting and stopping timers, and finally, to manage the timer lists
> referenced with an identifier.
>
> My initial performance testing with the "timer_perf_autotest" test shows
> no performance regression or improvement, and inspection of the
> generated optimized code shows that the extra function call gets inlined
> in the functions that now have an extra function call.
>
> Depends on: https://patches.dpdk.org/patch/48417/
>
> Changes in v3:
> - remove C++ style comment in first patch in series (Stephen)
>
> Changes in v2:
> - split these changes out into their own series
> - version the symbols where the existing ABI was updated, and
> provide alternate implementation with behavior equivalent to original
> behavior. Validated ABI compatibility with validate-abi.sh
> - refactor changes to simplify patches
>
> Erik Gabriel Carrillo (2):
> timer: allow timer management in shared memory
> timer: add function to stop all timers in a list
>
> lib/librte_timer/Makefile | 1 +
> lib/librte_timer/rte_timer.c | 558 ++++++++++++++++++++++++++++++---
> lib/librte_timer/rte_timer.h | 258 ++++++++++++++-
> lib/librte_timer/rte_timer_version.map | 23 ++
> 4 files changed, 795 insertions(+), 45 deletions(-)
It is a lot of changes!
Anyone to review please?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 0/2] Timer library changes
2018-12-19 3:35 0% ` Thomas Monjalon
@ 2018-12-19 7:33 0% ` Mattias Rönnblom
0 siblings, 0 replies; 200+ results
From: Mattias Rönnblom @ 2018-12-19 7:33 UTC (permalink / raw)
To: Thomas Monjalon, dev
Cc: Erik Gabriel Carrillo, rsanford, stephen, jerin.jacob, pbhagavatula
On 2018-12-19 04:35, Thomas Monjalon wrote:
> 13/12/2018 23:26, Erik Gabriel Carrillo:
>> This patch series modifies the timer library in such a way that
>> structures that used to be statically allocated in a process's data
>> segment are now allocated in shared memory. As these structures contain
>> lists of timers, new APIs are introduced that allow a caller to specify
>> the particular structure instance into which a timer should be inserted
>> or from which a timer should be removed. This enables primary and
>> secondary processes to modify the same timer list, which enables some
>> multi-process use cases that were not previously possible; e.g. a
>> secondary process can start a timer whose expiration is detected in a
>> primary process running a new flavor of timer_manage().
>>
>> The original library API is mostly unchanged, though implementations are
>> updated to call into newly added functions with a default structure
>> instance ID that provides the original behavior. New functions are
>> introduced to enable applications to allocate structure instances to
>> house timer lists, and to reference them with an identifier when
>> starting and stopping timers, and finally, to manage the timer lists
>> referenced with an identifier.
>>
>> My initial performance testing with the "timer_perf_autotest" test shows
>> no performance regression or improvement, and inspection of the
>> generated optimized code shows that the extra function call gets inlined
>> in the functions that now have an extra function call.
>>
>> Depends on: https://patches.dpdk.org/patch/48417/
>>
>> Changes in v3:
>> - remove C++ style comment in first patch in series (Stephen)
>>
>> Changes in v2:
>> - split these changes out into their own series
>> - version the symbols where the existing ABI was updated, and
>> provide alternate implementation with behavior equivalent to original
>> behavior. Validated ABI compatibility with validate-abi.sh
>> - refactor changes to simplify patches
>>
>> Erik Gabriel Carrillo (2):
>> timer: allow timer management in shared memory
>> timer: add function to stop all timers in a list
>>
>> lib/librte_timer/Makefile | 1 +
>> lib/librte_timer/rte_timer.c | 558 ++++++++++++++++++++++++++++++---
>> lib/librte_timer/rte_timer.h | 258 ++++++++++++++-
>> lib/librte_timer/rte_timer_version.map | 23 ++
>> 4 files changed, 795 insertions(+), 45 deletions(-)
>
> It is a lot of changes!
> Anyone to review please?
>
>
I can give reviewing the overall aim with the patch set a try: Do we
really want DPDK to support more secondary process-based use cases? I
would rather see it supporting fewer, with the long term goal of
dropping support for secondary processes altogether.
DPDK secondary processes are a horrible mess, in my opinion, to put it
bluntly.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-19 3:18 0% ` Thomas Monjalon
@ 2018-12-19 9:09 0% ` Hunt, David
2018-12-19 20:31 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Hunt, David @ 2018-12-19 9:09 UTC (permalink / raw)
To: Thomas Monjalon, Liang Ma; +Cc: dev, anatoly.burakov
On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
> 14/12/2018 14:11, Liang Ma:
>> Previously, in order to use the power library, it was necessary
>> for the user to disable the intel_pstate driver by adding
>> “intel_pstate=disable” to the kernel command line for the system,
>> which causes the acpi_cpufreq driver to be loaded in its place.
>>
>> This patch adds the ability for the power library use the intel-pstate
>> driver.
>>
>> It adds a new suite of functions behind the current power library API,
>> and will seamlessly set up the user facing API function pointers to
>> the relevant functions depending on whether the system is running with
>> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
>> using kvm. The library API and ABI is unchanged.
>>
>> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
>>
>> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
>> ---
> Please write a changelog when sending a new version.
>
> Dave, any comment on this patch?
Looks good to me.
Acked-by: David Hunt <david.hunt@intel.com>
>> --- /dev/null
>> +++ b/lib/librte_power/power_pstate_cpufreq.c
>> @@ -0,0 +1,770 @@
>> +/* SPDX-License-Identifier: BSD-3-Clause
>> + * Copyright(c) 2018-2018 Intel Corporation
> Something wrong here :)
Yes, should simply be "Copyright(c) 2018 Intel Corporation"
>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [RFC 1/2] doc: clean ABI/API policy guide
@ 2018-12-19 12:52 35% Ferruh Yigit
2018-12-20 8:02 4% ` Luca Boccassi
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Ferruh Yigit @ 2018-12-19 12:52 UTC (permalink / raw)
To: dev, John McNamara, Marko Kovacevic
Cc: Ferruh Yigit, Luca Boccassi, Kevin Traynor, Yongseok Koh, Neil Horman
The original document written from the point of ABI versioning but later
additions make document confusing, convert document into a ABI/API
policy documentation and organize the document in subsections:
- ABI/API Deprecation
- Experimental APIs
- Library versioning
- ABI versioning
Aim to clarify confusion between deprecation versioned ABI and overall
ABI/API deprecation, also ABI versioning and Library versioning by
organizing the sections.
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
Cc: Luca Boccassi <bluca@debian.org>
Cc: Kevin Traynor <ktraynor@redhat.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
---
doc/guides/contributing/versioning.rst | 132 +++++++++++++------------
1 file changed, 71 insertions(+), 61 deletions(-)
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 01b36247e..19af56cd2 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -1,33 +1,31 @@
.. SPDX-License-Identifier: BSD-3-Clause
Copyright 2018 The DPDK contributors
-Managing ABI updates
-====================
+DPDK ABI/API policy
+===================
Description
-----------
This document details some methods for handling ABI management in the DPDK.
-Note this document is not exhaustive, in that C library versioning is flexible
-allowing multiple methods to achieve various goals, but it will provide the user
-with some introductory methods
General Guidelines
------------------
#. Whenever possible, ABI should be preserved
-#. Libraries or APIs marked in ``experimental`` state may change without constraint.
+#. ABI/API may be changed with a deprecation process
+#. The modification of symbols can generally be managed with versioning
+#. Libraries or APIs marked in ``experimental`` state may change without constraint
#. New APIs will be marked as ``experimental`` for at least one release to allow
any issues found by users of the new API to be fixed quickly
#. The addition of symbols is generally not problematic
-#. The modification of symbols can generally be managed with versioning
#. The removal of symbols generally is an ABI break and requires bumping of the
LIBABIVER macro
#. Updates to the minimum hardware requirements, which drop support for hardware which
was previously supported, should be treated as an ABI change.
What is an ABI
---------------
+~~~~~~~~~~~~~~
An ABI (Application Binary Interface) is the set of runtime interfaces exposed
by a library. It is similar to an API (Application Programming Interface) but
@@ -39,9 +37,13 @@ Therefore, in the case of dynamic linking, it is critical that an ABI is
preserved, or (when modified), done in such a way that the application is unable
to behave improperly or in an unexpected fashion.
-The DPDK ABI policy
+
+ABI/API Deprecation
-------------------
+The DPDK ABI policy
+~~~~~~~~~~~~~~~~~~~
+
ABI versions are set at the time of major release labeling, and the ABI may
change multiple times, without warning, between the last release label and the
HEAD label of the git tree.
@@ -99,8 +101,36 @@ readability purposes should be avoided.
follow the relevant deprecation policy procedures as above: 3 acks and
announcement at least one release in advance.
+Examples of Deprecation Notices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+ to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+ in version 2.0. Backwards compatibility will be maintained for this function
+ until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+ performance reasons. Existing binary applications will have backwards
+ compatibility in release 2.0, while newly built binaries will need to
+ reference the new structure variant ``struct rte_foo2``. Compatibility will
+ be removed in release 2.2, and all applications will require updating and
+ rebuilding to the new structure at that time, which will be renamed to the
+ original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+ upcoming release 2.0 will not contain these changes, but release 2.1 will,
+ and no backwards compatibility is planned due to the extensive nature of
+ these changes. Binaries using this library built prior to version 2.1 will
+ require updating and recompilation.
+
+
Experimental APIs
-~~~~~~~~~~~~~~~~~
+-----------------
APIs marked as ``experimental`` are not considered part of the ABI and may
change without warning at any time. Since changes to APIs are most likely
@@ -130,35 +160,38 @@ is not required. Though, an API should remain in experimental state for at least
one release. Thereafter, normal process of posting patch for review to mailing
list can be followed.
-Examples of Deprecation Notices
--------------------------------
-The following are some examples of ABI deprecation notices which would be
-added to the Release Notes:
+Library versioning
+------------------
-* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
- to be replaced with the inline function ``rte_foo()``.
+Downstreams might want to provide different DPDK releases at the same time to
+support multiple consumers of DPDK linked against older and newer sonames.
-* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
- in version 2.0. Backwards compatibility will be maintained for this function
- until the release of version 2.1
+Also due to the interdependencies that DPDK libraries can have applications
+might end up with an executable space in which multiple versions of a library
+are mapped by ld.so.
-* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
- performance reasons. Existing binary applications will have backwards
- compatibility in release 2.0, while newly built binaries will need to
- reference the new structure variant ``struct rte_foo2``. Compatibility will
- be removed in release 2.2, and all applications will require updating and
- rebuilding to the new structure at that time, which will be renamed to the
- original ``struct rte_foo``.
+Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
+depending on LibA.
-* Significant ABI changes are planned for the ``librte_dostuff`` library. The
- upcoming release 2.0 will not contain these changes, but release 2.1 will,
- and no backwards compatibility is planned due to the extensive nature of
- these changes. Binaries using this library built prior to version 2.1 will
- require updating and recompilation.
+.. note::
+
+ Application
+ \-> LibA.old
+ \-> LibB.new -> LibA.new
+
+That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
+If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
+library - versions defined in the libraries ``LIBABIVER``.
+An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
+``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
+
+
+ABI versioning
+--------------
Versioning Macros
------------------
+~~~~~~~~~~~~~~~~~
When a symbol is exported from a library to provide an API, it also provides a
calling convention (ABI) that is embodied in its name, return type and
@@ -186,36 +219,11 @@ The macros exported are:
fully qualified function ``p``, so that if a symbol becomes versioned, it
can still be mapped back to the public symbol name.
-Setting a Major ABI version
----------------------------
-
-Downstreams might want to provide different DPDK releases at the same time to
-support multiple consumers of DPDK linked against older and newer sonames.
-
-Also due to the interdependencies that DPDK libraries can have applications
-might end up with an executable space in which multiple versions of a library
-are mapped by ld.so.
-
-Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
-depending on LibA.
-
-.. note::
-
- Application
- \-> LibA.old
- \-> LibB.new -> LibA.new
-
-That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
-If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
-library - versions defined in the libraries ``LIBABIVER``.
-An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
-``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
-
Examples of ABI Macro use
--------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^
Updating a public API
-~~~~~~~~~~~~~~~~~~~~~
+_____________________
Assume we have a function as follows
@@ -425,7 +433,7 @@ and a new DPDK_2.1 version, used by future built applications.
Deprecating part of a public API
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+________________________________
Lets assume that you've done the above update, and after a few releases have
passed you decide you would like to retire the old version of the function.
@@ -483,7 +491,7 @@ possibly incompatible library version:
+LIBABIVER := 2
Deprecating an entire ABI version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+_________________________________
While removing a symbol from and ABI may be useful, it is often more practical
to remove an entire version node at once. If a version node completely
@@ -532,6 +540,7 @@ Lastly, any VERSION_SYMBOL macros that point to the old version node should be
removed, taking care to keep, where need old code in place to support newer
versions of the symbol.
+
Running the ABI Validator
-------------------------
@@ -571,3 +580,4 @@ compile both tags) it will create compatibility reports in the
follows::
grep -lr Incompatible compat_reports/
+
--
2.17.2
^ permalink raw reply [relevance 35%]
* [dpdk-dev] [PATCH v5 2/2] mbuf: implement generic format for sched field
@ 2018-12-19 15:34 1% ` Reshma Pattan
1 sibling, 0 replies; 200+ results
From: Reshma Pattan @ 2018-12-19 15:34 UTC (permalink / raw)
To: dev, jerin.jacob, nikhil.rao, olivier.matz, thomas,
jasvinder.singh, cristian.dumitrescu
Cc: Reshma Pattan
This patch implements the changes proposed in the deprecation
notes [1][2].
librte_mbuf changes:
The mbuf::hash::sched field is updated to support generic
definition in line with the ethdev TM and MTR APIs. The new generic
format contains: queue ID, traffic class, color.
Added public APIs to set and get these new fields to and from mbuf.
librte_sched changes:
In addtion, following API functions of the sched library have
been modified with an additional parameter of type struct
rte_sched_port to accommodate the changes made to mbuf sched field.
(i)rte_sched_port_pkt_write()
(ii) rte_sched_port_pkt_read_tree_path()
librte_pipeline, qos_sched UT, qos_sched app are updated
to make use of new changes.
Also mbuf::hash::txadapter has been added for eventdev txq,
rte_event_eth_tx_adapter_txq_set and rte_event_eth_tx_adapter_txq_get()
are updated to use uses mbuf::hash::txadapter.txq.
doc:
Release notes updated.
Removed deprecation notice for mbuf::hash::sched and sched API.
[1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
[2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
v5:
Removed librte_meter from librte_mbuf dependency list.
Changed the mbuf set/get functions to use uint8_t for color.
v4: converted mbuf::hash::sched as instantiation of rte_mbuf_sched.
v3: addressed review comments given in the below link.
http://patches.dpdk.org/patch/48587/
Updated library ABI versioning in meson build.
---
---
doc/guides/rel_notes/deprecation.rst | 10 --
doc/guides/rel_notes/release_19_02.rst | 4 +-
examples/qos_sched/app_thread.c | 7 +-
examples/qos_sched/main.c | 1 +
.../rte_event_eth_tx_adapter.h | 18 ++-
lib/librte_mbuf/Makefile | 2 +-
lib/librte_mbuf/meson.build | 2 +-
lib/librte_mbuf/rte_mbuf.h | 119 +++++++++++++++++-
lib/librte_pipeline/rte_table_action.c | 44 +++----
lib/librte_sched/Makefile | 2 +-
lib/librte_sched/meson.build | 1 +
lib/librte_sched/rte_sched.c | 90 ++++++-------
lib/librte_sched/rte_sched.h | 10 +-
test/test/test_sched.c | 9 +-
14 files changed, 197 insertions(+), 122 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index ac7fb29a7..ec80dcc7b 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,16 +49,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* mbuf: The opaque ``mbuf->hash.sched`` field will be updated to support generic
- definition in line with the ethdev TM and MTR APIs. Currently, this field
- is defined in librte_sched in a non-generic way. The new generic format
- will contain: queue ID, traffic class, color. Field size will not change.
-
-* sched: Some API functions will change prototype due to the above
- deprecation note for mbuf->hash.sched, e.g. ``rte_sched_port_pkt_write()``
- and ``rte_sched_port_pkt_read()`` will likely have an additional parameter
- of type ``struct rte_sched_port``.
-
* mbuf: the macro ``RTE_MBUF_INDIRECT()`` will be removed in v18.08 or later and
replaced with ``RTE_MBUF_CLONED()`` which is already added in v18.05. As
``EXT_ATTACHED_MBUF`` is newly introduced in v18.05, ``RTE_MBUF_INDIRECT()``
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 8deb68b9a..1f9ec9fc1 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -156,7 +156,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_kvargs.so.1
librte_latencystats.so.1
librte_lpm.so.2
- librte_mbuf.so.4
+ + librte_mbuf.so.5
librte_member.so.1
librte_mempool.so.5
librte_meter.so.2
@@ -178,7 +178,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_rawdev.so.1
librte_reorder.so.1
librte_ring.so.2
- librte_sched.so.1
+ + librte_sched.so.2
librte_security.so.1
librte_table.so.3
librte_timer.so.1
diff --git a/examples/qos_sched/app_thread.c b/examples/qos_sched/app_thread.c
index a59274236..bec4deee3 100644
--- a/examples/qos_sched/app_thread.c
+++ b/examples/qos_sched/app_thread.c
@@ -73,8 +73,11 @@ app_rx_thread(struct thread_conf **confs)
for(i = 0; i < nb_rx; i++) {
get_pkt_sched(rx_mbufs[i],
&subport, &pipe, &traffic_class, &queue, &color);
- rte_sched_port_pkt_write(rx_mbufs[i], subport, pipe,
- traffic_class, queue, (enum rte_meter_color) color);
+ rte_sched_port_pkt_write(conf->sched_port,
+ rx_mbufs[i],
+ subport, pipe,
+ traffic_class, queue,
+ (enum rte_meter_color) color);
}
if (unlikely(rte_ring_sp_enqueue_bulk(conf->rx_ring,
diff --git a/examples/qos_sched/main.c b/examples/qos_sched/main.c
index e7c97bd64..c0ed16b68 100644
--- a/examples/qos_sched/main.c
+++ b/examples/qos_sched/main.c
@@ -55,6 +55,7 @@ app_main_loop(__attribute__((unused))void *dummy)
flow->rx_thread.rx_port = flow->rx_port;
flow->rx_thread.rx_ring = flow->rx_ring;
flow->rx_thread.rx_queue = flow->rx_queue;
+ flow->rx_thread.sched_port = flow->sched_port;
rx_confs[rx_idx++] = &flow->rx_thread;
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index 81456d4a9..2a50656d9 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -63,13 +63,11 @@
* function can be used to retrieve the adapter's service function ID.
*
* The ethernet port and transmit queue index to transmit the mbuf on are
- * specified using the mbuf port and the higher 16 bits of
- * struct rte_mbuf::hash::sched:hi. The application should use the
- * rte_event_eth_tx_adapter_txq_set() and rte_event_eth_tx_adapter_txq_get()
- * functions to access the transmit queue index since it is expected that the
- * transmit queue will be eventually defined within struct rte_mbuf and using
- * these macros will help with minimizing application impact due to
- * a change in how the transmit queue index is specified.
+ * specified using the mbuf port struct rte_mbuf::hash::txadapter:txq.
+ * The application should use the rte_event_eth_tx_adapter_txq_set()
+ * and rte_event_eth_tx_adapter_txq_get() functions to access the transmit
+ * queue index, using these macros will help with minimizing application
+ * impact due to a change in how the transmit queue index is specified.
*/
#ifdef __cplusplus
@@ -300,8 +298,7 @@ rte_event_eth_tx_adapter_queue_del(uint8_t id,
static __rte_always_inline void __rte_experimental
rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- p[1] = queue;
+ pkt->hash.txadapter.txq = queue;
}
/**
@@ -320,8 +317,7 @@ rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
static __rte_always_inline uint16_t __rte_experimental
rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- return p[1];
+ return pkt->hash.txadapter.txq;
}
/**
diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
index e2b98a254..8c4c7d790 100644
--- a/lib/librte_mbuf/Makefile
+++ b/lib/librte_mbuf/Makefile
@@ -11,7 +11,7 @@ LDLIBS += -lrte_eal -lrte_mempool
EXPORT_MAP := rte_mbuf_version.map
-LIBABIVER := 4
+LIBABIVER := 5
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
index 94d9c4c96..e37da0250 100644
--- a/lib/librte_mbuf/meson.build
+++ b/lib/librte_mbuf/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 4
+version = 5
sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
deps += ['mempool']
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 3dbc6695e..8e06187ff 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -468,6 +468,17 @@ __extension__
typedef uint64_t MARKER64[0]; /**< marker that allows us to overwrite 8 bytes
* with a single assignment */
+struct rte_mbuf_sched {
+ uint32_t queue_id; /**< Queue ID. */
+ uint8_t traffic_class;
+ /**< Traffic class ID. Traffic class 0
+ * is the highest priority traffic class.
+ */
+ uint8_t color;
+ /**< Color. @see enum rte_color.*/
+ uint16_t reserved; /**< Reserved. */
+};
+
/**
* The generic rte_mbuf, containing a packet mbuf.
*/
@@ -574,14 +585,16 @@ struct rte_mbuf {
* on PKT_RX_FDIR_* flag in ol_flags.
*/
} fdir; /**< Filter identifier if FDIR enabled */
+ struct rte_mbuf_sched sched;
struct {
- uint32_t lo;
- uint32_t hi;
+ uint32_t reserved1;
+ uint16_t reserved2;
+ uint16_t txq;
/**< The event eth Tx adapter uses this field
* to store Tx queue id.
* @see rte_event_eth_tx_adapter_txq_set()
*/
- } sched; /**< Hierarchical scheduler */
+ } txadapter; /**< Eventdev ethdev Tx adapter */
/**< User defined tags. See rte_distributor_process() */
uint32_t usr;
} hash; /**< hash information */
@@ -2289,6 +2302,106 @@ rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
*/
void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
+/**
+ * Get the value of mbuf sched queue_id field.
+ */
+static inline uint32_t
+rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.queue_id;
+}
+
+/**
+ * Get the value of mbuf sched traffic_class field.
+ */
+static inline uint8_t
+rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.traffic_class;
+}
+
+/**
+ * Get the value of mbuf sched color field.
+ */
+static inline uint8_t
+rte_mbuf_sched_color_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.color;
+}
+
+/**
+ * Get the values of mbuf sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to read
+ * @param queue_id
+ * Returns the queue id
+ * @param traffic_class
+ * Returns the traffic class id
+ * @param color
+ * Returns the colour id
+ */
+static inline void
+rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
+ uint8_t *traffic_class,
+ uint8_t *color)
+{
+ struct rte_mbuf_sched sched = m->hash.sched;
+
+ *queue_id = sched.queue_id;
+ *traffic_class = sched.traffic_class;
+ *color = sched.color;
+}
+
+/**
+ * Set the mbuf sched queue_id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
+{
+ m->hash.sched.queue_id = queue_id;
+}
+
+/**
+ * Set the mbuf sched traffic_class id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
+{
+ m->hash.sched.traffic_class = traffic_class;
+}
+
+/**
+ * Set the mbuf sched color id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_color_set(struct rte_mbuf *m, uint8_t color)
+{
+ m->hash.sched.color = color;
+}
+
+/**
+ * Set the mbuf sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to set
+ * @param queue_id
+ * Queue id value to be set
+ * @param traffic_class
+ * Traffic class id value to be set
+ * @param color
+ * Color id to be set
+ */
+static inline void
+rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t queue_id,
+ uint8_t traffic_class,
+ uint8_t color)
+{
+ m->hash.sched = (struct rte_mbuf_sched){
+ .queue_id = queue_id,
+ .traffic_class = traffic_class,
+ .color = color,
+ };
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 7c7c8dd82..8a2bb13dc 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -107,14 +107,6 @@ mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
return 0;
}
-#define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
- ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
- ((((uint64_t)(tc)) & 0x3) << 2) | \
- ((((uint64_t)(color)) & 0x3) << 4)))
-
-#define MBUF_SCHED_COLOR(sched, color) \
- (((sched) & (~0x30LLU)) | ((color) << 4))
-
struct mtr_trtcm_data {
struct rte_meter_trtcm trtcm;
uint64_t stats[e_RTE_METER_COLORS];
@@ -176,7 +168,7 @@ mtr_data_size(struct rte_table_action_mtr_config *mtr)
struct dscp_table_entry_data {
enum rte_meter_color color;
uint16_t tc;
- uint16_t queue_tc_color;
+ uint16_t tc_queue;
};
struct dscp_table_data {
@@ -319,8 +311,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
uint32_t dscp,
uint16_t total_length)
{
- uint64_t drop_mask, sched;
- uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
+ uint64_t drop_mask;
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
enum rte_meter_color color_in, color_meter, color_policer;
uint32_t tc, mp_id;
@@ -329,7 +320,6 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
color_in = dscp_entry->color;
data += tc;
mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
- sched = *sched_ptr;
/* Meter */
color_meter = rte_meter_trtcm_color_aware_check(
@@ -346,7 +336,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
color_policer =
MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- *sched_ptr = MBUF_SCHED_COLOR(sched, color_policer);
+ rte_mbuf_sched_color_set(mbuf, (uint8_t)color_policer);
return drop_mask;
}
@@ -368,9 +358,8 @@ tm_cfg_check(struct rte_table_action_tm_config *tm)
}
struct tm_data {
- uint16_t queue_tc_color;
- uint16_t subport;
- uint32_t pipe;
+ uint32_t queue_id;
+ uint32_t reserved;
} __attribute__((__packed__));
static int
@@ -397,9 +386,9 @@ tm_apply(struct tm_data *data,
return status;
/* Apply */
- data->queue_tc_color = 0;
- data->subport = (uint16_t) p->subport_id;
- data->pipe = p->pipe_id;
+ data->queue_id = p->subport_id <<
+ (__builtin_ctz(cfg->n_pipes_per_subport) + 4) |
+ p->pipe_id << 4;
return 0;
}
@@ -411,12 +400,11 @@ pkt_work_tm(struct rte_mbuf *mbuf,
uint32_t dscp)
{
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
- struct tm_data sched;
-
- sched = *data;
- sched.queue_tc_color = dscp_entry->queue_tc_color;
- *sched_ptr = sched;
+ uint32_t queue_id = data->queue_id |
+ (dscp_entry->tc << 2) |
+ dscp_entry->tc_queue;
+ rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc,
+ (uint8_t)dscp_entry->color);
}
/**
@@ -2580,17 +2568,13 @@ rte_table_action_dscp_table_update(struct rte_table_action *action,
&action->dscp_table.entry[i];
struct rte_table_action_dscp_table_entry *entry =
&table->entry[i];
- uint16_t queue_tc_color =
- MBUF_SCHED_QUEUE_TC_COLOR(entry->tc_queue_id,
- entry->tc_id,
- entry->color);
if ((dscp_mask & (1LLU << i)) == 0)
continue;
data->color = entry->color;
data->tc = entry->tc_id;
- data->queue_tc_color = queue_tc_color;
+ data->tc_queue = entry->tc_queue_id;
}
return 0;
diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile
index 46c53ed71..644fd9d15 100644
--- a/lib/librte_sched/Makefile
+++ b/lib/librte_sched/Makefile
@@ -18,7 +18,7 @@ LDLIBS += -lrte_timer
EXPORT_MAP := rte_sched_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build
index f85d64df8..8e989e5f6 100644
--- a/lib/librte_sched/meson.build
+++ b/lib/librte_sched/meson.build
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
+version = 2
sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c')
headers = files('rte_sched.h', 'rte_sched_common.h',
'rte_red.h', 'rte_approx.h')
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 587d5e602..dd7739172 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -128,22 +128,6 @@ enum grinder_state {
e_GRINDER_READ_MBUF
};
-/*
- * Path through the scheduler hierarchy used by the scheduler enqueue
- * operation to identify the destination queue for the current
- * packet. Stored in the field pkt.hash.sched of struct rte_mbuf of
- * each packet, typically written by the classification stage and read
- * by scheduler enqueue.
- */
-struct rte_sched_port_hierarchy {
- uint16_t queue:2; /**< Queue ID (0 .. 3) */
- uint16_t traffic_class:2; /**< Traffic class ID (0 .. 3)*/
- uint32_t color:2; /**< Color */
- uint16_t unused:10;
- uint16_t subport; /**< Subport ID */
- uint32_t pipe; /**< Pipe ID */
-};
-
struct rte_sched_grinder {
/* Pipe cache */
uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
@@ -185,6 +169,7 @@ struct rte_sched_port {
/* User parameters */
uint32_t n_subports_per_port;
uint32_t n_pipes_per_subport;
+ uint32_t n_pipes_per_subport_log2;
uint32_t rate;
uint32_t mtu;
uint32_t frame_overhead;
@@ -645,6 +630,8 @@ rte_sched_port_config(struct rte_sched_port_params *params)
/* User parameters */
port->n_subports_per_port = params->n_subports_per_port;
port->n_pipes_per_subport = params->n_pipes_per_subport;
+ port->n_pipes_per_subport_log2 =
+ __builtin_ctz(params->n_pipes_per_subport);
port->rate = params->rate;
port->mtu = params->mtu + params->frame_overhead;
port->frame_overhead = params->frame_overhead;
@@ -1006,44 +993,52 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port,
return 0;
}
+static inline uint32_t
+rte_sched_port_qindex(struct rte_sched_port *port,
+ uint32_t subport,
+ uint32_t pipe,
+ uint32_t traffic_class,
+ uint32_t queue)
+{
+ return ((subport & (port->n_subports_per_port - 1)) <<
+ (port->n_pipes_per_subport_log2 + 4)) |
+ ((pipe & (port->n_pipes_per_subport - 1)) << 4) |
+ ((traffic_class &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << 2) |
+ (queue & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1));
+}
+
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
- uint32_t subport, uint32_t pipe, uint32_t traffic_class,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
+ uint32_t subport, uint32_t pipe,
+ uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color)
{
- struct rte_sched_port_hierarchy *sched
- = (struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- RTE_BUILD_BUG_ON(sizeof(*sched) > sizeof(pkt->hash.sched));
-
- sched->color = (uint32_t) color;
- sched->subport = subport;
- sched->pipe = pipe;
- sched->traffic_class = traffic_class;
- sched->queue = queue;
+ uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe,
+ traffic_class, queue);
+ rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color);
}
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
+ uint32_t queue_id = rte_mbuf_sched_queue_get(pkt);
- *subport = sched->subport;
- *pipe = sched->pipe;
- *traffic_class = sched->traffic_class;
- *queue = sched->queue;
+ *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4);
+ *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1);
+ *traffic_class = (queue_id >> 2) &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1);
+ *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1);
}
enum rte_meter_color
rte_sched_port_pkt_read_color(const struct rte_mbuf *pkt)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- return (enum rte_meter_color) sched->color;
+ return (enum rte_meter_color)rte_mbuf_sched_color_get(pkt);
}
int
@@ -1100,18 +1095,6 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
return 0;
}
-static inline uint32_t
-rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport, uint32_t pipe, uint32_t traffic_class, uint32_t queue)
-{
- uint32_t result;
-
- result = subport * port->n_pipes_per_subport + pipe;
- result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + traffic_class;
- result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
-
- return result;
-}
-
#ifdef RTE_SCHED_DEBUG
static inline int
@@ -1272,11 +1255,8 @@ rte_sched_port_enqueue_qptrs_prefetch0(struct rte_sched_port *port,
#ifdef RTE_SCHED_COLLECT_STATS
struct rte_sched_queue_extra *qe;
#endif
- uint32_t subport, pipe, traffic_class, queue, qindex;
-
- rte_sched_port_pkt_read_tree_path(pkt, &subport, &pipe, &traffic_class, &queue);
+ uint32_t qindex = rte_mbuf_sched_queue_get(pkt);
- qindex = rte_sched_port_qindex(port, subport, pipe, traffic_class, queue);
q = port->queue + qindex;
rte_prefetch0(q);
#ifdef RTE_SCHED_COLLECT_STATS
diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
index 84fa896de..243efa1d4 100644
--- a/lib/librte_sched/rte_sched.h
+++ b/lib/librte_sched/rte_sched.h
@@ -355,6 +355,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Scheduler hierarchy path write to packet descriptor. Typically
* called by the packet classification stage.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -369,7 +371,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Packet color set
*/
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
uint32_t subport, uint32_t pipe, uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color);
@@ -379,6 +382,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
* enqueue operation. The subport, pipe, traffic class and queue
* parameters need to be pre-allocated by the caller.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -392,7 +397,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
*
*/
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue);
diff --git a/test/test/test_sched.c b/test/test/test_sched.c
index 32e500ba9..40e411cab 100644
--- a/test/test/test_sched.c
+++ b/test/test/test_sched.c
@@ -76,7 +76,7 @@ create_mempool(void)
}
static void
-prepare_pkt(struct rte_mbuf *mbuf)
+prepare_pkt(struct rte_sched_port *port, struct rte_mbuf *mbuf)
{
struct ether_hdr *eth_hdr;
struct vlan_hdr *vlan1, *vlan2;
@@ -95,7 +95,8 @@ prepare_pkt(struct rte_mbuf *mbuf)
ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);
- rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW);
+ rte_sched_port_pkt_write(port, mbuf, SUBPORT, PIPE, TC, QUEUE,
+ e_RTE_METER_YELLOW);
/* 64 byte packet */
mbuf->pkt_len = 60;
@@ -138,7 +139,7 @@ test_sched(void)
for (i = 0; i < 10; i++) {
in_mbufs[i] = rte_pktmbuf_alloc(mp);
TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation failed\n");
- prepare_pkt(in_mbufs[i]);
+ prepare_pkt(port, in_mbufs[i]);
}
@@ -155,7 +156,7 @@ test_sched(void)
color = rte_sched_port_pkt_read_color(out_mbufs[i]);
TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong color\n");
- rte_sched_port_pkt_read_tree_path(out_mbufs[i],
+ rte_sched_port_pkt_read_tree_path(port, out_mbufs[i],
&subport, &pipe, &traffic_class, &queue);
TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong subport\n");
--
2.17.1
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v6 2/2] mbuf: implement generic format for sched field
@ 2018-12-19 15:42 1% ` Reshma Pattan
2018-12-19 18:14 0% ` Ananyev, Konstantin
1 sibling, 1 reply; 200+ results
From: Reshma Pattan @ 2018-12-19 15:42 UTC (permalink / raw)
To: dev, jerin.jacob, nikhil.rao, olivier.matz, thomas,
jasvinder.singh, cristian.dumitrescu
Cc: Reshma Pattan
This patch implements the changes proposed in the deprecation
notes [1][2].
librte_mbuf changes:
The mbuf::hash::sched field is updated to support generic
definition in line with the ethdev TM and MTR APIs. The new generic
format contains: queue ID, traffic class, color.
Added public APIs to set and get these new fields to and from mbuf.
librte_sched changes:
In addtion, following API functions of the sched library have
been modified with an additional parameter of type struct
rte_sched_port to accommodate the changes made to mbuf sched field.
(i)rte_sched_port_pkt_write()
(ii) rte_sched_port_pkt_read_tree_path()
librte_pipeline, qos_sched UT, qos_sched app are updated
to make use of new changes.
Also mbuf::hash::txadapter has been added for eventdev txq,
rte_event_eth_tx_adapter_txq_set and rte_event_eth_tx_adapter_txq_get()
are updated to use uses mbuf::hash::txadapter.txq.
doc:
Release notes updated.
Removed deprecation notice for mbuf::hash::sched and sched API.
[1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
[2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
v6: added scheduler comment
v5:
Removed librte_meter from librte_mbuf dependency list.
Changed the mbuf set/get functions to use uint8_t for color.
v4: converted mbuf::hash::sched as instantiation of rte_mbuf_sched.
v3: addressed review comments given in the below link.
http://patches.dpdk.org/patch/48587/
Updated library ABI versioning in meson build.
---
---
doc/guides/rel_notes/deprecation.rst | 10 --
doc/guides/rel_notes/release_19_02.rst | 4 +-
examples/qos_sched/app_thread.c | 7 +-
examples/qos_sched/main.c | 1 +
.../rte_event_eth_tx_adapter.h | 18 ++-
lib/librte_mbuf/Makefile | 2 +-
lib/librte_mbuf/meson.build | 2 +-
lib/librte_mbuf/rte_mbuf.h | 119 +++++++++++++++++-
lib/librte_pipeline/rte_table_action.c | 44 +++----
lib/librte_sched/Makefile | 2 +-
lib/librte_sched/meson.build | 1 +
lib/librte_sched/rte_sched.c | 90 ++++++-------
lib/librte_sched/rte_sched.h | 10 +-
test/test/test_sched.c | 9 +-
14 files changed, 197 insertions(+), 122 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index ac7fb29a7..ec80dcc7b 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,16 +49,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* mbuf: The opaque ``mbuf->hash.sched`` field will be updated to support generic
- definition in line with the ethdev TM and MTR APIs. Currently, this field
- is defined in librte_sched in a non-generic way. The new generic format
- will contain: queue ID, traffic class, color. Field size will not change.
-
-* sched: Some API functions will change prototype due to the above
- deprecation note for mbuf->hash.sched, e.g. ``rte_sched_port_pkt_write()``
- and ``rte_sched_port_pkt_read()`` will likely have an additional parameter
- of type ``struct rte_sched_port``.
-
* mbuf: the macro ``RTE_MBUF_INDIRECT()`` will be removed in v18.08 or later and
replaced with ``RTE_MBUF_CLONED()`` which is already added in v18.05. As
``EXT_ATTACHED_MBUF`` is newly introduced in v18.05, ``RTE_MBUF_INDIRECT()``
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 8deb68b9a..1f9ec9fc1 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -156,7 +156,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_kvargs.so.1
librte_latencystats.so.1
librte_lpm.so.2
- librte_mbuf.so.4
+ + librte_mbuf.so.5
librte_member.so.1
librte_mempool.so.5
librte_meter.so.2
@@ -178,7 +178,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_rawdev.so.1
librte_reorder.so.1
librte_ring.so.2
- librte_sched.so.1
+ + librte_sched.so.2
librte_security.so.1
librte_table.so.3
librte_timer.so.1
diff --git a/examples/qos_sched/app_thread.c b/examples/qos_sched/app_thread.c
index a59274236..bec4deee3 100644
--- a/examples/qos_sched/app_thread.c
+++ b/examples/qos_sched/app_thread.c
@@ -73,8 +73,11 @@ app_rx_thread(struct thread_conf **confs)
for(i = 0; i < nb_rx; i++) {
get_pkt_sched(rx_mbufs[i],
&subport, &pipe, &traffic_class, &queue, &color);
- rte_sched_port_pkt_write(rx_mbufs[i], subport, pipe,
- traffic_class, queue, (enum rte_meter_color) color);
+ rte_sched_port_pkt_write(conf->sched_port,
+ rx_mbufs[i],
+ subport, pipe,
+ traffic_class, queue,
+ (enum rte_meter_color) color);
}
if (unlikely(rte_ring_sp_enqueue_bulk(conf->rx_ring,
diff --git a/examples/qos_sched/main.c b/examples/qos_sched/main.c
index e7c97bd64..c0ed16b68 100644
--- a/examples/qos_sched/main.c
+++ b/examples/qos_sched/main.c
@@ -55,6 +55,7 @@ app_main_loop(__attribute__((unused))void *dummy)
flow->rx_thread.rx_port = flow->rx_port;
flow->rx_thread.rx_ring = flow->rx_ring;
flow->rx_thread.rx_queue = flow->rx_queue;
+ flow->rx_thread.sched_port = flow->sched_port;
rx_confs[rx_idx++] = &flow->rx_thread;
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index 81456d4a9..2a50656d9 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -63,13 +63,11 @@
* function can be used to retrieve the adapter's service function ID.
*
* The ethernet port and transmit queue index to transmit the mbuf on are
- * specified using the mbuf port and the higher 16 bits of
- * struct rte_mbuf::hash::sched:hi. The application should use the
- * rte_event_eth_tx_adapter_txq_set() and rte_event_eth_tx_adapter_txq_get()
- * functions to access the transmit queue index since it is expected that the
- * transmit queue will be eventually defined within struct rte_mbuf and using
- * these macros will help with minimizing application impact due to
- * a change in how the transmit queue index is specified.
+ * specified using the mbuf port struct rte_mbuf::hash::txadapter:txq.
+ * The application should use the rte_event_eth_tx_adapter_txq_set()
+ * and rte_event_eth_tx_adapter_txq_get() functions to access the transmit
+ * queue index, using these macros will help with minimizing application
+ * impact due to a change in how the transmit queue index is specified.
*/
#ifdef __cplusplus
@@ -300,8 +298,7 @@ rte_event_eth_tx_adapter_queue_del(uint8_t id,
static __rte_always_inline void __rte_experimental
rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- p[1] = queue;
+ pkt->hash.txadapter.txq = queue;
}
/**
@@ -320,8 +317,7 @@ rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
static __rte_always_inline uint16_t __rte_experimental
rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- return p[1];
+ return pkt->hash.txadapter.txq;
}
/**
diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
index e2b98a254..8c4c7d790 100644
--- a/lib/librte_mbuf/Makefile
+++ b/lib/librte_mbuf/Makefile
@@ -11,7 +11,7 @@ LDLIBS += -lrte_eal -lrte_mempool
EXPORT_MAP := rte_mbuf_version.map
-LIBABIVER := 4
+LIBABIVER := 5
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
index 94d9c4c96..e37da0250 100644
--- a/lib/librte_mbuf/meson.build
+++ b/lib/librte_mbuf/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 4
+version = 5
sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
deps += ['mempool']
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 3dbc6695e..dd69123a1 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -468,6 +468,17 @@ __extension__
typedef uint64_t MARKER64[0]; /**< marker that allows us to overwrite 8 bytes
* with a single assignment */
+struct rte_mbuf_sched {
+ uint32_t queue_id; /**< Queue ID. */
+ uint8_t traffic_class;
+ /**< Traffic class ID. Traffic class 0
+ * is the highest priority traffic class.
+ */
+ uint8_t color;
+ /**< Color. @see enum rte_color.*/
+ uint16_t reserved; /**< Reserved. */
+};
+
/**
* The generic rte_mbuf, containing a packet mbuf.
*/
@@ -574,14 +585,16 @@ struct rte_mbuf {
* on PKT_RX_FDIR_* flag in ol_flags.
*/
} fdir; /**< Filter identifier if FDIR enabled */
+ struct rte_mbuf_sched sched; /**< Hierarchical scheduler */
struct {
- uint32_t lo;
- uint32_t hi;
+ uint32_t reserved1;
+ uint16_t reserved2;
+ uint16_t txq;
/**< The event eth Tx adapter uses this field
* to store Tx queue id.
* @see rte_event_eth_tx_adapter_txq_set()
*/
- } sched; /**< Hierarchical scheduler */
+ } txadapter; /**< Eventdev ethdev Tx adapter */
/**< User defined tags. See rte_distributor_process() */
uint32_t usr;
} hash; /**< hash information */
@@ -2289,6 +2302,106 @@ rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
*/
void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
+/**
+ * Get the value of mbuf sched queue_id field.
+ */
+static inline uint32_t
+rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.queue_id;
+}
+
+/**
+ * Get the value of mbuf sched traffic_class field.
+ */
+static inline uint8_t
+rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.traffic_class;
+}
+
+/**
+ * Get the value of mbuf sched color field.
+ */
+static inline uint8_t
+rte_mbuf_sched_color_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.color;
+}
+
+/**
+ * Get the values of mbuf sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to read
+ * @param queue_id
+ * Returns the queue id
+ * @param traffic_class
+ * Returns the traffic class id
+ * @param color
+ * Returns the colour id
+ */
+static inline void
+rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
+ uint8_t *traffic_class,
+ uint8_t *color)
+{
+ struct rte_mbuf_sched sched = m->hash.sched;
+
+ *queue_id = sched.queue_id;
+ *traffic_class = sched.traffic_class;
+ *color = sched.color;
+}
+
+/**
+ * Set the mbuf sched queue_id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
+{
+ m->hash.sched.queue_id = queue_id;
+}
+
+/**
+ * Set the mbuf sched traffic_class id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
+{
+ m->hash.sched.traffic_class = traffic_class;
+}
+
+/**
+ * Set the mbuf sched color id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_color_set(struct rte_mbuf *m, uint8_t color)
+{
+ m->hash.sched.color = color;
+}
+
+/**
+ * Set the mbuf sched queue_id, traffic_class and color.
+ * @param m
+ * Mbuf to set
+ * @param queue_id
+ * Queue id value to be set
+ * @param traffic_class
+ * Traffic class id value to be set
+ * @param color
+ * Color id to be set
+ */
+static inline void
+rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t queue_id,
+ uint8_t traffic_class,
+ uint8_t color)
+{
+ m->hash.sched = (struct rte_mbuf_sched){
+ .queue_id = queue_id,
+ .traffic_class = traffic_class,
+ .color = color,
+ };
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 7c7c8dd82..8a2bb13dc 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -107,14 +107,6 @@ mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
return 0;
}
-#define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
- ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
- ((((uint64_t)(tc)) & 0x3) << 2) | \
- ((((uint64_t)(color)) & 0x3) << 4)))
-
-#define MBUF_SCHED_COLOR(sched, color) \
- (((sched) & (~0x30LLU)) | ((color) << 4))
-
struct mtr_trtcm_data {
struct rte_meter_trtcm trtcm;
uint64_t stats[e_RTE_METER_COLORS];
@@ -176,7 +168,7 @@ mtr_data_size(struct rte_table_action_mtr_config *mtr)
struct dscp_table_entry_data {
enum rte_meter_color color;
uint16_t tc;
- uint16_t queue_tc_color;
+ uint16_t tc_queue;
};
struct dscp_table_data {
@@ -319,8 +311,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
uint32_t dscp,
uint16_t total_length)
{
- uint64_t drop_mask, sched;
- uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
+ uint64_t drop_mask;
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
enum rte_meter_color color_in, color_meter, color_policer;
uint32_t tc, mp_id;
@@ -329,7 +320,6 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
color_in = dscp_entry->color;
data += tc;
mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
- sched = *sched_ptr;
/* Meter */
color_meter = rte_meter_trtcm_color_aware_check(
@@ -346,7 +336,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
color_policer =
MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- *sched_ptr = MBUF_SCHED_COLOR(sched, color_policer);
+ rte_mbuf_sched_color_set(mbuf, (uint8_t)color_policer);
return drop_mask;
}
@@ -368,9 +358,8 @@ tm_cfg_check(struct rte_table_action_tm_config *tm)
}
struct tm_data {
- uint16_t queue_tc_color;
- uint16_t subport;
- uint32_t pipe;
+ uint32_t queue_id;
+ uint32_t reserved;
} __attribute__((__packed__));
static int
@@ -397,9 +386,9 @@ tm_apply(struct tm_data *data,
return status;
/* Apply */
- data->queue_tc_color = 0;
- data->subport = (uint16_t) p->subport_id;
- data->pipe = p->pipe_id;
+ data->queue_id = p->subport_id <<
+ (__builtin_ctz(cfg->n_pipes_per_subport) + 4) |
+ p->pipe_id << 4;
return 0;
}
@@ -411,12 +400,11 @@ pkt_work_tm(struct rte_mbuf *mbuf,
uint32_t dscp)
{
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
- struct tm_data sched;
-
- sched = *data;
- sched.queue_tc_color = dscp_entry->queue_tc_color;
- *sched_ptr = sched;
+ uint32_t queue_id = data->queue_id |
+ (dscp_entry->tc << 2) |
+ dscp_entry->tc_queue;
+ rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc,
+ (uint8_t)dscp_entry->color);
}
/**
@@ -2580,17 +2568,13 @@ rte_table_action_dscp_table_update(struct rte_table_action *action,
&action->dscp_table.entry[i];
struct rte_table_action_dscp_table_entry *entry =
&table->entry[i];
- uint16_t queue_tc_color =
- MBUF_SCHED_QUEUE_TC_COLOR(entry->tc_queue_id,
- entry->tc_id,
- entry->color);
if ((dscp_mask & (1LLU << i)) == 0)
continue;
data->color = entry->color;
data->tc = entry->tc_id;
- data->queue_tc_color = queue_tc_color;
+ data->tc_queue = entry->tc_queue_id;
}
return 0;
diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile
index 46c53ed71..644fd9d15 100644
--- a/lib/librte_sched/Makefile
+++ b/lib/librte_sched/Makefile
@@ -18,7 +18,7 @@ LDLIBS += -lrte_timer
EXPORT_MAP := rte_sched_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build
index f85d64df8..8e989e5f6 100644
--- a/lib/librte_sched/meson.build
+++ b/lib/librte_sched/meson.build
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
+version = 2
sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c')
headers = files('rte_sched.h', 'rte_sched_common.h',
'rte_red.h', 'rte_approx.h')
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 587d5e602..dd7739172 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -128,22 +128,6 @@ enum grinder_state {
e_GRINDER_READ_MBUF
};
-/*
- * Path through the scheduler hierarchy used by the scheduler enqueue
- * operation to identify the destination queue for the current
- * packet. Stored in the field pkt.hash.sched of struct rte_mbuf of
- * each packet, typically written by the classification stage and read
- * by scheduler enqueue.
- */
-struct rte_sched_port_hierarchy {
- uint16_t queue:2; /**< Queue ID (0 .. 3) */
- uint16_t traffic_class:2; /**< Traffic class ID (0 .. 3)*/
- uint32_t color:2; /**< Color */
- uint16_t unused:10;
- uint16_t subport; /**< Subport ID */
- uint32_t pipe; /**< Pipe ID */
-};
-
struct rte_sched_grinder {
/* Pipe cache */
uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
@@ -185,6 +169,7 @@ struct rte_sched_port {
/* User parameters */
uint32_t n_subports_per_port;
uint32_t n_pipes_per_subport;
+ uint32_t n_pipes_per_subport_log2;
uint32_t rate;
uint32_t mtu;
uint32_t frame_overhead;
@@ -645,6 +630,8 @@ rte_sched_port_config(struct rte_sched_port_params *params)
/* User parameters */
port->n_subports_per_port = params->n_subports_per_port;
port->n_pipes_per_subport = params->n_pipes_per_subport;
+ port->n_pipes_per_subport_log2 =
+ __builtin_ctz(params->n_pipes_per_subport);
port->rate = params->rate;
port->mtu = params->mtu + params->frame_overhead;
port->frame_overhead = params->frame_overhead;
@@ -1006,44 +993,52 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port,
return 0;
}
+static inline uint32_t
+rte_sched_port_qindex(struct rte_sched_port *port,
+ uint32_t subport,
+ uint32_t pipe,
+ uint32_t traffic_class,
+ uint32_t queue)
+{
+ return ((subport & (port->n_subports_per_port - 1)) <<
+ (port->n_pipes_per_subport_log2 + 4)) |
+ ((pipe & (port->n_pipes_per_subport - 1)) << 4) |
+ ((traffic_class &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << 2) |
+ (queue & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1));
+}
+
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
- uint32_t subport, uint32_t pipe, uint32_t traffic_class,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
+ uint32_t subport, uint32_t pipe,
+ uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color)
{
- struct rte_sched_port_hierarchy *sched
- = (struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- RTE_BUILD_BUG_ON(sizeof(*sched) > sizeof(pkt->hash.sched));
-
- sched->color = (uint32_t) color;
- sched->subport = subport;
- sched->pipe = pipe;
- sched->traffic_class = traffic_class;
- sched->queue = queue;
+ uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe,
+ traffic_class, queue);
+ rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color);
}
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
+ uint32_t queue_id = rte_mbuf_sched_queue_get(pkt);
- *subport = sched->subport;
- *pipe = sched->pipe;
- *traffic_class = sched->traffic_class;
- *queue = sched->queue;
+ *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4);
+ *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1);
+ *traffic_class = (queue_id >> 2) &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1);
+ *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1);
}
enum rte_meter_color
rte_sched_port_pkt_read_color(const struct rte_mbuf *pkt)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- return (enum rte_meter_color) sched->color;
+ return (enum rte_meter_color)rte_mbuf_sched_color_get(pkt);
}
int
@@ -1100,18 +1095,6 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
return 0;
}
-static inline uint32_t
-rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport, uint32_t pipe, uint32_t traffic_class, uint32_t queue)
-{
- uint32_t result;
-
- result = subport * port->n_pipes_per_subport + pipe;
- result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + traffic_class;
- result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
-
- return result;
-}
-
#ifdef RTE_SCHED_DEBUG
static inline int
@@ -1272,11 +1255,8 @@ rte_sched_port_enqueue_qptrs_prefetch0(struct rte_sched_port *port,
#ifdef RTE_SCHED_COLLECT_STATS
struct rte_sched_queue_extra *qe;
#endif
- uint32_t subport, pipe, traffic_class, queue, qindex;
-
- rte_sched_port_pkt_read_tree_path(pkt, &subport, &pipe, &traffic_class, &queue);
+ uint32_t qindex = rte_mbuf_sched_queue_get(pkt);
- qindex = rte_sched_port_qindex(port, subport, pipe, traffic_class, queue);
q = port->queue + qindex;
rte_prefetch0(q);
#ifdef RTE_SCHED_COLLECT_STATS
diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
index 84fa896de..243efa1d4 100644
--- a/lib/librte_sched/rte_sched.h
+++ b/lib/librte_sched/rte_sched.h
@@ -355,6 +355,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Scheduler hierarchy path write to packet descriptor. Typically
* called by the packet classification stage.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -369,7 +371,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Packet color set
*/
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
uint32_t subport, uint32_t pipe, uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color);
@@ -379,6 +382,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
* enqueue operation. The subport, pipe, traffic class and queue
* parameters need to be pre-allocated by the caller.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -392,7 +397,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
*
*/
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue);
diff --git a/test/test/test_sched.c b/test/test/test_sched.c
index 32e500ba9..40e411cab 100644
--- a/test/test/test_sched.c
+++ b/test/test/test_sched.c
@@ -76,7 +76,7 @@ create_mempool(void)
}
static void
-prepare_pkt(struct rte_mbuf *mbuf)
+prepare_pkt(struct rte_sched_port *port, struct rte_mbuf *mbuf)
{
struct ether_hdr *eth_hdr;
struct vlan_hdr *vlan1, *vlan2;
@@ -95,7 +95,8 @@ prepare_pkt(struct rte_mbuf *mbuf)
ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);
- rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW);
+ rte_sched_port_pkt_write(port, mbuf, SUBPORT, PIPE, TC, QUEUE,
+ e_RTE_METER_YELLOW);
/* 64 byte packet */
mbuf->pkt_len = 60;
@@ -138,7 +139,7 @@ test_sched(void)
for (i = 0; i < 10; i++) {
in_mbufs[i] = rte_pktmbuf_alloc(mp);
TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation failed\n");
- prepare_pkt(in_mbufs[i]);
+ prepare_pkt(port, in_mbufs[i]);
}
@@ -155,7 +156,7 @@ test_sched(void)
color = rte_sched_port_pkt_read_color(out_mbufs[i]);
TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong color\n");
- rte_sched_port_pkt_read_tree_path(out_mbufs[i],
+ rte_sched_port_pkt_read_tree_path(port, out_mbufs[i],
&subport, &pipe, &traffic_class, &queue);
TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong subport\n");
--
2.17.1
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH v6 2/2] mbuf: implement generic format for sched field
2018-12-19 15:42 1% ` [dpdk-dev] [PATCH v6 2/2] mbuf: implement generic format for sched field Reshma Pattan
@ 2018-12-19 18:14 0% ` Ananyev, Konstantin
0 siblings, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2018-12-19 18:14 UTC (permalink / raw)
To: Pattan, Reshma, dev, jerin.jacob, Rao, Nikhil, olivier.matz,
thomas, Singh, Jasvinder, Dumitrescu, Cristian
Cc: Pattan, Reshma
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Reshma Pattan
> Sent: Wednesday, December 19, 2018 3:43 PM
> To: dev@dpdk.org; jerin.jacob@caviumnetworks.com; Rao, Nikhil <nikhil.rao@intel.com>; olivier.matz@6wind.com;
> thomas@monjalon.net; Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Cc: Pattan, Reshma <reshma.pattan@intel.com>
> Subject: [dpdk-dev] [PATCH v6 2/2] mbuf: implement generic format for sched field
>
> This patch implements the changes proposed in the deprecation
> notes [1][2].
>
> librte_mbuf changes:
> The mbuf::hash::sched field is updated to support generic
> definition in line with the ethdev TM and MTR APIs. The new generic
> format contains: queue ID, traffic class, color.
>
> Added public APIs to set and get these new fields to and from mbuf.
>
> librte_sched changes:
> In addtion, following API functions of the sched library have
> been modified with an additional parameter of type struct
> rte_sched_port to accommodate the changes made to mbuf sched field.
> (i)rte_sched_port_pkt_write()
> (ii) rte_sched_port_pkt_read_tree_path()
>
> librte_pipeline, qos_sched UT, qos_sched app are updated
> to make use of new changes.
>
> Also mbuf::hash::txadapter has been added for eventdev txq,
> rte_event_eth_tx_adapter_txq_set and rte_event_eth_tx_adapter_txq_get()
> are updated to use uses mbuf::hash::txadapter.txq.
>
> doc:
> Release notes updated.
> Removed deprecation notice for mbuf::hash::sched and sched API.
>
> [1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
> [2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
>
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> ---
> v6: added scheduler comment
>
> v5:
> Removed librte_meter from librte_mbuf dependency list.
> Changed the mbuf set/get functions to use uint8_t for color.
>
> v4: converted mbuf::hash::sched as instantiation of rte_mbuf_sched.
>
> v3: addressed review comments given in the below link.
> http://patches.dpdk.org/patch/48587/
> Updated library ABI versioning in meson build.
> ---
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> 2.17.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-19 9:09 0% ` Hunt, David
@ 2018-12-19 20:31 0% ` Thomas Monjalon
2018-12-20 9:25 0% ` Burakov, Anatoly
2018-12-20 14:52 0% ` Hunt, David
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2018-12-19 20:31 UTC (permalink / raw)
To: Hunt, David, Liang Ma; +Cc: dev, anatoly.burakov
19/12/2018 10:09, Hunt, David:
> On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
> > 14/12/2018 14:11, Liang Ma:
> >> Previously, in order to use the power library, it was necessary
> >> for the user to disable the intel_pstate driver by adding
> >> “intel_pstate=disable” to the kernel command line for the system,
> >> which causes the acpi_cpufreq driver to be loaded in its place.
> >>
> >> This patch adds the ability for the power library use the intel-pstate
> >> driver.
> >>
> >> It adds a new suite of functions behind the current power library API,
> >> and will seamlessly set up the user facing API function pointers to
> >> the relevant functions depending on whether the system is running with
> >> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
> >> using kvm. The library API and ABI is unchanged.
> >>
> >> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> >>
> >> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
> >> ---
> > Please write a changelog when sending a new version.
> >
> > Dave, any comment on this patch?
>
>
> Looks good to me.
>
> Acked-by: David Hunt <david.hunt@intel.com>
>
>
> >> --- /dev/null
> >> +++ b/lib/librte_power/power_pstate_cpufreq.c
> >> @@ -0,0 +1,770 @@
> >> +/* SPDX-License-Identifier: BSD-3-Clause
> >> + * Copyright(c) 2018-2018 Intel Corporation
> > Something wrong here :)
>
> Yes, should simply be "Copyright(c) 2018 Intel Corporation"
There is also a compilation error with meson:
lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
rte_timer.h: No such file or directory
Clearly, some quality checks are missing.
I'm afraid we won't have any patch for power library in 19.02.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] Move common functions in eal_thread.c
@ 2018-12-19 21:09 0% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-12-19 21:09 UTC (permalink / raw)
To: Ravi Kerur; +Cc: dpdk-dev, Thomas Monjalon
On 8/19/2015 9:46 PM, rkerur at gmail.com (Ravi Kerur) wrote:
> v2:
> > Remove un-needed header file eal_private.h from freeBSD
> eal_thread.c after code movement.
>
> v1:
> Changes include
> > Moving common functions in eal_thread.c in
> linuxapp and bsdapp into common/eal_common_thread.c file.
> > Rearrange eal_common_thread.c compilation in Makefile
> for ABI.
>
> Compiled successfully for following targets
> > x86_64-native-linuxapp-clang
> > x86_64-native-linuxapp-gcc
> > x86_x32-native-linuxapp-gcc
> > i686-native-linuxapp-gcc
> > x86_64-native-bsdapp-clang
> > x86_64-native-bsdapp-gcc
>
> Tested on
> > Ubuntu 14.04, testpmd functionality
> > FreeBSD 10.1, testpmd functionality
>
> Signed-off-by: Ravi Kerur <rkerur at gmail.com>
Hi Ravi,
This patch is sitting on patchwork since 2015, I am updating it as rejected, if
it is still relevant please let us know.
Sorry for any inconvenience caused.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC 1/2] doc: clean ABI/API policy guide
2018-12-19 12:52 35% [dpdk-dev] [RFC 1/2] doc: clean ABI/API policy guide Ferruh Yigit
@ 2018-12-20 8:02 4% ` Luca Boccassi
2018-12-20 8:03 8% ` Luca Boccassi
2018-12-21 15:57 35% ` [dpdk-dev] [PATCH v2 " Ferruh Yigit
2 siblings, 0 replies; 200+ results
From: Luca Boccassi @ 2018-12-20 8:02 UTC (permalink / raw)
To: Ferruh Yigit, dev, John McNamara, Marko Kovacevic
Cc: Kevin Traynor, Yongseok Koh, Neil Horman
On Wed, 2018-12-19 at 12:52 +0000, Ferruh Yigit wrote:
> The original document written from the point of ABI versioning but
> later
> additions make document confusing, convert document into a ABI/API
> policy documentation and organize the document in subsections:
> - ABI/API Deprecation
> - Experimental APIs
> - Library versioning
> - ABI versioning
>
> Aim to clarify confusion between deprecation versioned ABI and
> overall
> ABI/API deprecation, also ABI versioning and Library versioning by
> organizing the sections.
>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
> Cc: Luca Boccassi <bluca@debian.org>
> Cc: Kevin Traynor <ktraynor@redhat.com>
> Cc: Yongseok Koh <yskoh@mellanox.com>
> Cc: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Luca Boccassi <bluca@debian.org>
--
Kind regards,
Luca Boccassi
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [RFC 1/2] doc: clean ABI/API policy guide
2018-12-19 12:52 35% [dpdk-dev] [RFC 1/2] doc: clean ABI/API policy guide Ferruh Yigit
2018-12-20 8:02 4% ` Luca Boccassi
@ 2018-12-20 8:03 8% ` Luca Boccassi
2018-12-21 15:57 35% ` [dpdk-dev] [PATCH v2 " Ferruh Yigit
2 siblings, 0 replies; 200+ results
From: Luca Boccassi @ 2018-12-20 8:03 UTC (permalink / raw)
To: Ferruh Yigit, dev, John McNamara, Marko Kovacevic
Cc: Kevin Traynor, Yongseok Koh, Neil Horman
On Wed, 2018-12-19 at 12:52 +0000, Ferruh Yigit wrote:
> + Application
> + \-> LibA.old
> + \-> LibB.new -> LibA.new
> +
> +That is a conflict which can be avoided by setting
> ``CONFIG_RTE_MAJOR_ABI``.
> +If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all -
> otherwise per
> +library - versions defined in the libraries ``LIBABIVER``.
> +An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make
> all libraries
> +``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
This is not related to your reorganisation, but to solve this problem
properly should we start considering ABI bumps as "sticky", so that in
the example above _both_ libA and libB would get an ABI bump?
--
Kind regards,
Luca Boccassi
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-19 20:31 0% ` Thomas Monjalon
@ 2018-12-20 9:25 0% ` Burakov, Anatoly
2018-12-20 9:33 0% ` Burakov, Anatoly
2018-12-20 14:52 0% ` Hunt, David
1 sibling, 1 reply; 200+ results
From: Burakov, Anatoly @ 2018-12-20 9:25 UTC (permalink / raw)
To: Thomas Monjalon, Hunt, David, Liang Ma; +Cc: dev
On 19-Dec-18 8:31 PM, Thomas Monjalon wrote:
> 19/12/2018 10:09, Hunt, David:
>> On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
>>> 14/12/2018 14:11, Liang Ma:
>>>> Previously, in order to use the power library, it was necessary
>>>> for the user to disable the intel_pstate driver by adding
>>>> “intel_pstate=disable” to the kernel command line for the system,
>>>> which causes the acpi_cpufreq driver to be loaded in its place.
>>>>
>>>> This patch adds the ability for the power library use the intel-pstate
>>>> driver.
>>>>
>>>> It adds a new suite of functions behind the current power library API,
>>>> and will seamlessly set up the user facing API function pointers to
>>>> the relevant functions depending on whether the system is running with
>>>> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
>>>> using kvm. The library API and ABI is unchanged.
>>>>
>>>> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
>>>>
>>>> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
>>>> ---
>>> Please write a changelog when sending a new version.
>>>
>>> Dave, any comment on this patch?
>>
>>
>> Looks good to me.
>>
>> Acked-by: David Hunt <david.hunt@intel.com>
>>
>>
>>>> --- /dev/null
>>>> +++ b/lib/librte_power/power_pstate_cpufreq.c
>>>> @@ -0,0 +1,770 @@
>>>> +/* SPDX-License-Identifier: BSD-3-Clause
>>>> + * Copyright(c) 2018-2018 Intel Corporation
>>> Something wrong here :)
>>
>> Yes, should simply be "Copyright(c) 2018 Intel Corporation"
>
>
> There is also a compilation error with meson:
>
> lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
> rte_timer.h: No such file or directory
That's an EAL header, and this file was not modified or referenced in
this commit. This sounds like a pre-existing problem (with meson
build-system?), not related to the patchset.
Is this library not built by default by our patch compilation CI?
>
> Clearly, some quality checks are missing.
>
> I'm afraid we won't have any patch for power library in 19.02.
>
>
>
--
Thanks,
Anatoly
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-20 9:25 0% ` Burakov, Anatoly
@ 2018-12-20 9:33 0% ` Burakov, Anatoly
2018-12-20 10:10 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Burakov, Anatoly @ 2018-12-20 9:33 UTC (permalink / raw)
To: Thomas Monjalon, Hunt, David, Liang Ma; +Cc: dev
On 20-Dec-18 9:25 AM, Burakov, Anatoly wrote:
> On 19-Dec-18 8:31 PM, Thomas Monjalon wrote:
>> 19/12/2018 10:09, Hunt, David:
>>> On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
>>>> 14/12/2018 14:11, Liang Ma:
>>>>> Previously, in order to use the power library, it was necessary
>>>>> for the user to disable the intel_pstate driver by adding
>>>>> “intel_pstate=disable” to the kernel command line for the system,
>>>>> which causes the acpi_cpufreq driver to be loaded in its place.
>>>>>
>>>>> This patch adds the ability for the power library use the intel-pstate
>>>>> driver.
>>>>>
>>>>> It adds a new suite of functions behind the current power library API,
>>>>> and will seamlessly set up the user facing API function pointers to
>>>>> the relevant functions depending on whether the system is running with
>>>>> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
>>>>> using kvm. The library API and ABI is unchanged.
>>>>>
>>>>> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
>>>>>
>>>>> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
>>>>> ---
>>>> Please write a changelog when sending a new version.
>>>>
>>>> Dave, any comment on this patch?
>>>
>>>
>>> Looks good to me.
>>>
>>> Acked-by: David Hunt <david.hunt@intel.com>
>>>
>>>
>>>>> --- /dev/null
>>>>> +++ b/lib/librte_power/power_pstate_cpufreq.c
>>>>> @@ -0,0 +1,770 @@
>>>>> +/* SPDX-License-Identifier: BSD-3-Clause
>>>>> + * Copyright(c) 2018-2018 Intel Corporation
>>>> Something wrong here :)
>>>
>>> Yes, should simply be "Copyright(c) 2018 Intel Corporation"
>>
>>
>> There is also a compilation error with meson:
>>
>> lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
>> rte_timer.h: No such file or directory
>
> That's an EAL header, and this file was not modified or referenced in
> this commit. This sounds like a pre-existing problem (with meson
> build-system?), not related to the patchset.
>
> Is this library not built by default by our patch compilation CI?
>
Disregard that, the patch has a bug in meson build file.
Still, why doesn't our CI build meson?
--
Thanks,
Anatoly
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-20 9:33 0% ` Burakov, Anatoly
@ 2018-12-20 10:10 0% ` Thomas Monjalon
2018-12-20 10:42 0% ` Luca Boccassi
2018-12-20 10:54 0% ` Liang, Ma
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2018-12-20 10:10 UTC (permalink / raw)
To: Burakov, Anatoly, bluca
Cc: Hunt, David, Liang Ma, dev, qian.q.xu, ferruh.yigit
20/12/2018 10:33, Burakov, Anatoly:
> On 20-Dec-18 9:25 AM, Burakov, Anatoly wrote:
> > On 19-Dec-18 8:31 PM, Thomas Monjalon wrote:
> >> 19/12/2018 10:09, Hunt, David:
> >>> On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
> >>>> 14/12/2018 14:11, Liang Ma:
> >>>>> Previously, in order to use the power library, it was necessary
> >>>>> for the user to disable the intel_pstate driver by adding
> >>>>> “intel_pstate=disable” to the kernel command line for the system,
> >>>>> which causes the acpi_cpufreq driver to be loaded in its place.
> >>>>>
> >>>>> This patch adds the ability for the power library use the intel-pstate
> >>>>> driver.
> >>>>>
> >>>>> It adds a new suite of functions behind the current power library API,
> >>>>> and will seamlessly set up the user facing API function pointers to
> >>>>> the relevant functions depending on whether the system is running with
> >>>>> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
> >>>>> using kvm. The library API and ABI is unchanged.
> >>>>>
> >>>>> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> >>>>>
> >>>>> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
> >>>>> ---
> >>>> Please write a changelog when sending a new version.
> >>>>
> >>>> Dave, any comment on this patch?
> >>>
> >>>
> >>> Looks good to me.
> >>>
> >>> Acked-by: David Hunt <david.hunt@intel.com>
> >>>
> >>>
> >>>>> --- /dev/null
> >>>>> +++ b/lib/librte_power/power_pstate_cpufreq.c
> >>>>> @@ -0,0 +1,770 @@
> >>>>> +/* SPDX-License-Identifier: BSD-3-Clause
> >>>>> + * Copyright(c) 2018-2018 Intel Corporation
> >>>> Something wrong here :)
> >>>
> >>> Yes, should simply be "Copyright(c) 2018 Intel Corporation"
> >>
> >>
> >> There is also a compilation error with meson:
> >>
> >> lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
> >> rte_timer.h: No such file or directory
> >
> > That's an EAL header, and this file was not modified or referenced in
> > this commit. This sounds like a pre-existing problem (with meson
> > build-system?), not related to the patchset.
> >
> > Is this library not built by default by our patch compilation CI?
> >
>
> Disregard that, the patch has a bug in meson build file.
>
> Still, why doesn't our CI build meson?
I think we should build a new CI for compilation testing.
Luca proposed to use OBS.
Luca, can we work on it?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-20 10:10 0% ` Thomas Monjalon
@ 2018-12-20 10:42 0% ` Luca Boccassi
2018-12-20 10:44 0% ` Thomas Monjalon
2018-12-20 10:54 0% ` Liang, Ma
1 sibling, 1 reply; 200+ results
From: Luca Boccassi @ 2018-12-20 10:42 UTC (permalink / raw)
To: Thomas Monjalon, Burakov, Anatoly
Cc: Hunt, David, Liang Ma, dev, qian.q.xu, ferruh.yigit
On Thu, 2018-12-20 at 11:10 +0100, Thomas Monjalon wrote:
> 20/12/2018 10:33, Burakov, Anatoly:
> > On 20-Dec-18 9:25 AM, Burakov, Anatoly wrote:
> > > On 19-Dec-18 8:31 PM, Thomas Monjalon wrote:
> > > > 19/12/2018 10:09, Hunt, David:
> > > > > On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
> > > > > > 14/12/2018 14:11, Liang Ma:
> > > > > > > Previously, in order to use the power library, it was
> > > > > > > necessary
> > > > > > > for the user to disable the intel_pstate driver by adding
> > > > > > > “intel_pstate=disable” to the kernel command line for the
> > > > > > > system,
> > > > > > > which causes the acpi_cpufreq driver to be loaded in its
> > > > > > > place.
> > > > > > >
> > > > > > > This patch adds the ability for the power library use the
> > > > > > > intel-pstate
> > > > > > > driver.
> > > > > > >
> > > > > > > It adds a new suite of functions behind the current power
> > > > > > > library API,
> > > > > > > and will seamlessly set up the user facing API function
> > > > > > > pointers to
> > > > > > > the relevant functions depending on whether the system is
> > > > > > > running with
> > > > > > > acpi_cpufreq kernel driver, intel_pstate kernel driver or
> > > > > > > in a guest,
> > > > > > > using kvm. The library API and ABI is unchanged.
> > > > > > >
> > > > > > > Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> > > > > > >
> > > > > > > Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
> > > > > > > ---
> > > > > >
> > > > > > Please write a changelog when sending a new version.
> > > > > >
> > > > > > Dave, any comment on this patch?
> > > > >
> > > > >
> > > > > Looks good to me.
> > > > >
> > > > > Acked-by: David Hunt <david.hunt@intel.com>
> > > > >
> > > > >
> > > > > > > --- /dev/null
> > > > > > > +++ b/lib/librte_power/power_pstate_cpufreq.c
> > > > > > > @@ -0,0 +1,770 @@
> > > > > > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > > > > > + * Copyright(c) 2018-2018 Intel Corporation
> > > > > >
> > > > > > Something wrong here :)
> > > > >
> > > > > Yes, should simply be "Copyright(c) 2018 Intel Corporation"
> > > >
> > > >
> > > > There is also a compilation error with meson:
> > > >
> > > > lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
> > > > rte_timer.h: No such file or directory
> > >
> > > That's an EAL header, and this file was not modified or
> > > referenced in
> > > this commit. This sounds like a pre-existing problem (with meson
> > > build-system?), not related to the patchset.
> > >
> > > Is this library not built by default by our patch compilation CI?
> > >
> >
> > Disregard that, the patch has a bug in meson build file.
> >
> > Still, why doesn't our CI build meson?
>
> I think we should build a new CI for compilation testing.
> Luca proposed to use OBS.
> Luca, can we work on it?
https://build.opensuse.org/package/show/home:bluca:dpdk/dpdk
The Debian/Ubuntu builds use Meson, the Fedora/CentOS/RHEL/SUSE ones
use the makefiles.
More complexity (eg: building with both on all distros) can be added
with a bit of work, if required and if it's worth it.
A postreceive curl call can be added to trigger it on every push to
master. Emails on failure can be sent with the logs.
--
Kind regards,
Luca Boccassi
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-20 10:42 0% ` Luca Boccassi
@ 2018-12-20 10:44 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-12-20 10:44 UTC (permalink / raw)
To: Luca Boccassi
Cc: Burakov, Anatoly, Hunt, David, Liang Ma, dev, qian.q.xu, ferruh.yigit
20/12/2018 11:42, Luca Boccassi:
> On Thu, 2018-12-20 at 11:10 +0100, Thomas Monjalon wrote:
> > 20/12/2018 10:33, Burakov, Anatoly:
> > > On 20-Dec-18 9:25 AM, Burakov, Anatoly wrote:
> > > > On 19-Dec-18 8:31 PM, Thomas Monjalon wrote:
> > > > > 19/12/2018 10:09, Hunt, David:
> > > > > > On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
> > > > > > > 14/12/2018 14:11, Liang Ma:
> > > > > > > > Previously, in order to use the power library, it was
> > > > > > > > necessary
> > > > > > > > for the user to disable the intel_pstate driver by adding
> > > > > > > > “intel_pstate=disable” to the kernel command line for the
> > > > > > > > system,
> > > > > > > > which causes the acpi_cpufreq driver to be loaded in its
> > > > > > > > place.
> > > > > > > >
> > > > > > > > This patch adds the ability for the power library use the
> > > > > > > > intel-pstate
> > > > > > > > driver.
> > > > > > > >
> > > > > > > > It adds a new suite of functions behind the current power
> > > > > > > > library API,
> > > > > > > > and will seamlessly set up the user facing API function
> > > > > > > > pointers to
> > > > > > > > the relevant functions depending on whether the system is
> > > > > > > > running with
> > > > > > > > acpi_cpufreq kernel driver, intel_pstate kernel driver or
> > > > > > > > in a guest,
> > > > > > > > using kvm. The library API and ABI is unchanged.
> > > > > > > >
> > > > > > > > Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> > > > > > > >
> > > > > > > > Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
> > > > > > > > ---
> > > > > > >
> > > > > > > Please write a changelog when sending a new version.
> > > > > > >
> > > > > > > Dave, any comment on this patch?
> > > > > >
> > > > > >
> > > > > > Looks good to me.
> > > > > >
> > > > > > Acked-by: David Hunt <david.hunt@intel.com>
> > > > > >
> > > > > >
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/lib/librte_power/power_pstate_cpufreq.c
> > > > > > > > @@ -0,0 +1,770 @@
> > > > > > > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > > > > > > + * Copyright(c) 2018-2018 Intel Corporation
> > > > > > >
> > > > > > > Something wrong here :)
> > > > > >
> > > > > > Yes, should simply be "Copyright(c) 2018 Intel Corporation"
> > > > >
> > > > >
> > > > > There is also a compilation error with meson:
> > > > >
> > > > > lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
> > > > > rte_timer.h: No such file or directory
> > > >
> > > > That's an EAL header, and this file was not modified or
> > > > referenced in
> > > > this commit. This sounds like a pre-existing problem (with meson
> > > > build-system?), not related to the patchset.
> > > >
> > > > Is this library not built by default by our patch compilation CI?
> > > >
> > >
> > > Disregard that, the patch has a bug in meson build file.
> > >
> > > Still, why doesn't our CI build meson?
> >
> > I think we should build a new CI for compilation testing.
> > Luca proposed to use OBS.
> > Luca, can we work on it?
>
> https://build.opensuse.org/package/show/home:bluca:dpdk/dpdk
>
> The Debian/Ubuntu builds use Meson, the Fedora/CentOS/RHEL/SUSE ones
> use the makefiles.
>
> More complexity (eg: building with both on all distros) can be added
> with a bit of work, if required and if it's worth it.
>
> A postreceive curl call can be added to trigger it on every push to
> master. Emails on failure can be sent with the logs.
We need to integrate it with patchwork, yes.
Let's discuss it offline, thanks.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-20 10:10 0% ` Thomas Monjalon
2018-12-20 10:42 0% ` Luca Boccassi
@ 2018-12-20 10:54 0% ` Liang, Ma
1 sibling, 0 replies; 200+ results
From: Liang, Ma @ 2018-12-20 10:54 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Burakov, Anatoly, bluca, Hunt, David, dev, qian.q.xu, ferruh.yigit
On 20 Dec 11:10, Thomas Monjalon wrote:
> 20/12/2018 10:33, Burakov, Anatoly:
> > On 20-Dec-18 9:25 AM, Burakov, Anatoly wrote:
> > > On 19-Dec-18 8:31 PM, Thomas Monjalon wrote:
> > >> 19/12/2018 10:09, Hunt, David:
> > >>> On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
> > >>>> 14/12/2018 14:11, Liang Ma:
> > >>>>> Previously, in order to use the power library, it was necessary
> > >>>>> for the user to disable the intel_pstate driver by adding
> > >>>>> “intel_pstate=disable” to the kernel command line for the system,
> > >>>>> which causes the acpi_cpufreq driver to be loaded in its place.
> > >>>>>
> > >>>>> This patch adds the ability for the power library use the intel-pstate
> > >>>>> driver.
> > >>>>>
> > >>>>> It adds a new suite of functions behind the current power library API,
> > >>>>> and will seamlessly set up the user facing API function pointers to
> > >>>>> the relevant functions depending on whether the system is running with
> > >>>>> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
> > >>>>> using kvm. The library API and ABI is unchanged.
> > >>>>>
> > >>>>> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> > >>>>>
> > >>>>> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
> > >>>>> ---
> > >>>> Please write a changelog when sending a new version.
> > >>>>
> > >>>> Dave, any comment on this patch?
> > >>>
> > >>>
> > >>> Looks good to me.
> > >>>
> > >>> Acked-by: David Hunt <david.hunt@intel.com>
> > >>>
> > >>>
> > >>>>> --- /dev/null
> > >>>>> +++ b/lib/librte_power/power_pstate_cpufreq.c
> > >>>>> @@ -0,0 +1,770 @@
> > >>>>> +/* SPDX-License-Identifier: BSD-3-Clause
> > >>>>> + * Copyright(c) 2018-2018 Intel Corporation
> > >>>> Something wrong here :)
> > >>>
> > >>> Yes, should simply be "Copyright(c) 2018 Intel Corporation"
> > >>
> > >>
> > >> There is also a compilation error with meson:
> > >>
> > >> lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
> > >> rte_timer.h: No such file or directory
> > >
> > > That's an EAL header, and this file was not modified or referenced in
> > > this commit. This sounds like a pre-existing problem (with meson
> > > build-system?), not related to the patchset.
> > >
> > > Is this library not built by default by our patch compilation CI?
> > >
> >
> > Disregard that, the patch has a bug in meson build file.
> >
Yes, I did a mistake when I edit the meson build file. I will push the fix very soon.
we are testing the fix now.
> > Still, why doesn't our CI build meson?
>
> I think we should build a new CI for compilation testing.
> Luca proposed to use OBS.
> Luca, can we work on it?
>
>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2 1/4] bitmap: remove deprecated bsf64 function
2018-12-11 17:57 4% [dpdk-dev] [PATCH 1/6] bitmap: remove deprecated bsf64 function Anatoly Burakov
2018-12-11 17:57 4% ` [dpdk-dev] [PATCH 2/6] common: add bsf64 function similar to existing bsf32 Anatoly Burakov
@ 2018-12-20 12:09 4% ` Anatoly Burakov
2018-12-20 12:09 4% ` [dpdk-dev] [PATCH v2 2/4] common: add bsf64 and bsf32_safe functions Anatoly Burakov
2 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-12-20 12:09 UTC (permalink / raw)
To: dev
Cc: Neil Horman, John McNamara, Marko Kovacevic, Cristian Dumitrescu,
jerin.jacob, thomas
The function rte_bsf64 was deprecated in a previous release, so
remove the function, and the deprecation notice associated with
it.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 5 -----
doc/guides/rel_notes/release_19_02.rst | 4 ++++
lib/librte_eal/common/include/rte_bitmap.h | 6 ------
3 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index ac7fb29a7..61d94c7de 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -20,11 +20,6 @@ Deprecation Notices
* kvargs: The function ``rte_kvargs_process`` will get a new parameter
for returning key match count. It will ease handling of no-match case.
-* eal: function ``rte_bsf64`` in ``rte_bitmap.h`` has been renamed to
- ``rte_bsf64_safe`` and moved to ``rte_common.h``. A new ``rte_bsf64`` function
- will be added in the next release in ``rte_common.h`` that follows convention
- set by existing ``rte_bsf32`` function.
-
* eal: both declaring and identifying devices will be streamlined in v18.11.
New functions will appear to query a specific port from buses, classes of
device and device drivers. Device declaration will be made coherent with the
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 069f429a7..c4cce4c98 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -99,6 +99,10 @@ API Changes
since 18.05 and are removed in this release.
+* eal: function ``rte_bsf64`` in ``rte_bitmap.h`` has been renamed to
+ ``rte_bsf64_safe`` and moved to ``rte_common.h``.
+
+
ABI Changes
-----------
diff --git a/lib/librte_eal/common/include/rte_bitmap.h b/lib/librte_eal/common/include/rte_bitmap.h
index 77727c828..6b846f251 100644
--- a/lib/librte_eal/common/include/rte_bitmap.h
+++ b/lib/librte_eal/common/include/rte_bitmap.h
@@ -93,12 +93,6 @@ __rte_bitmap_index2_set(struct rte_bitmap *bmp)
bmp->index2 = (((bmp->index1 << RTE_BITMAP_SLAB_BIT_SIZE_LOG2) + bmp->offset1) << RTE_BITMAP_CL_SLAB_SIZE_LOG2);
}
-static inline int __rte_deprecated
-rte_bsf64(uint64_t slab, uint32_t *pos)
-{
- return rte_bsf64_safe(slab, pos);
-}
-
static inline uint32_t
__rte_bitmap_get_memory_footprint(uint32_t n_bits,
uint32_t *array1_byte_offset, uint32_t *array1_slabs,
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 2/4] common: add bsf64 and bsf32_safe functions
2018-12-11 17:57 4% [dpdk-dev] [PATCH 1/6] bitmap: remove deprecated bsf64 function Anatoly Burakov
2018-12-11 17:57 4% ` [dpdk-dev] [PATCH 2/6] common: add bsf64 function similar to existing bsf32 Anatoly Burakov
2018-12-20 12:09 4% ` [dpdk-dev] [PATCH v2 1/4] bitmap: remove deprecated bsf64 function Anatoly Burakov
@ 2018-12-20 12:09 4% ` Anatoly Burakov
2 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-12-20 12:09 UTC (permalink / raw)
To: dev; +Cc: John McNamara, Marko Kovacevic, jerin.jacob, thomas
Add an rte_bsf64 function that follows the convention of existing
rte_bsf32 function. Also, add missing implementation for safe
version of rte_bsf32, and implement unit tests for all recently
added bsf varieties.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
doc/guides/rel_notes/release_19_02.rst | 4 +-
lib/librte_eal/common/include/rte_common.h | 43 +++++++++++++++++++++-
test/test/test_common.c | 41 ++++++++++++++++++++-
3 files changed, 84 insertions(+), 4 deletions(-)
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index c4cce4c98..0f446ed74 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -100,7 +100,9 @@ API Changes
* eal: function ``rte_bsf64`` in ``rte_bitmap.h`` has been renamed to
- ``rte_bsf64_safe`` and moved to ``rte_common.h``.
+ ``rte_bsf64_safe`` and moved to ``rte_common.h``. A new ``rte_bsf64`` function
+ has been added in ``rte_common.h`` that follows convention set by existing
+ ``rte_bsf32`` function.
ABI Changes
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index 66cdf60b2..d102f2cec 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -447,6 +447,30 @@ rte_bsf32(uint32_t v)
return (uint32_t)__builtin_ctz(v);
}
+/**
+ * Searches the input parameter for the least significant set bit
+ * (starting from zero). Safe version (checks for input parameter being zero).
+ *
+ * @warning ``pos`` must be a valid pointer. It is not checked!
+ *
+ * @param v
+ * The input parameter.
+ * @param pos
+ * If ``v`` was not 0, this value will contain position of least significant
+ * bit within the input parameter.
+ * @return
+ * Returns 0 if ``v`` was 0, otherwise returns 1.
+ */
+static inline int
+rte_bsf32_safe(uint64_t v, uint32_t *pos)
+{
+ if (v == 0)
+ return 0;
+
+ *pos = rte_bsf32(v);
+ return 1;
+}
+
/**
* Return the rounded-up log2 of a integer.
*
@@ -482,6 +506,23 @@ rte_fls_u32(uint32_t x)
return (x == 0) ? 0 : 32 - __builtin_clz(x);
}
+/**
+ * Searches the input parameter for the least significant set bit
+ * (starting from zero).
+ * If a least significant 1 bit is found, its bit index is returned.
+ * If the content of the input parameter is zero, then the content of the return
+ * value is undefined.
+ * @param v
+ * input parameter, should not be zero.
+ * @return
+ * least significant set bit in the input parameter.
+ */
+static inline int
+rte_bsf64(uint64_t v)
+{
+ return (uint32_t)__builtin_ctzll(v);
+}
+
/**
* Searches the input parameter for the least significant set bit
* (starting from zero). Safe version (checks for input parameter being zero).
@@ -502,7 +543,7 @@ rte_bsf64_safe(uint64_t v, uint32_t *pos)
if (v == 0)
return 0;
- *pos = __builtin_ctzll(v);
+ *pos = rte_bsf64(v);
return 1;
}
diff --git a/test/test/test_common.c b/test/test/test_common.c
index c6d17baae..4a42aaed8 100644
--- a/test/test/test_common.c
+++ b/test/test/test_common.c
@@ -50,12 +50,48 @@ test_macros(int __rte_unused unused_parm)
return 0;
}
+static int
+test_bsf(void)
+{
+ uint32_t shift, pos;
+
+ /* safe versions should be able to handle 0 */
+ if (rte_bsf32_safe(0, &pos) != 0)
+ FAIL("rte_bsf32_safe");
+ if (rte_bsf64_safe(0, &pos) != 0)
+ FAIL("rte_bsf64_safe");
+
+ for (shift = 0; shift < 63; shift++) {
+ uint32_t val32;
+ uint64_t val64;
+
+ val64 = 1ULL << shift;
+ if ((uint32_t)rte_bsf64(val64) != shift)
+ FAIL("rte_bsf64");
+ if (rte_bsf64_safe(val64, &pos) != 1)
+ FAIL("rte_bsf64_safe");
+ if (pos != shift)
+ FAIL("rte_bsf64_safe");
+
+ if (shift > 31)
+ continue;
+
+ val32 = 1U << shift;
+ if ((uint32_t)rte_bsf32(val32) != shift)
+ FAIL("rte_bsf32");
+ if (rte_bsf32_safe(val32, &pos) != 1)
+ FAIL("rte_bsf32_safe");
+ if (pos != shift)
+ FAIL("rte_bsf32_safe");
+ }
+
+ return 0;
+}
+
static int
test_misc(void)
{
char memdump[] = "memdump_test";
- if (rte_bsf32(129))
- FAIL("rte_bsf32");
rte_memdump(stdout, "test", memdump, sizeof(memdump));
rte_hexdump(stdout, "test", memdump, sizeof(memdump));
@@ -226,6 +262,7 @@ test_common(void)
ret |= test_align();
ret |= test_macros(0);
ret |= test_misc();
+ ret |= test_bsf();
ret |= test_log2();
ret |= test_fls();
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field
@ 2018-12-20 12:16 1% ` Reshma Pattan
2018-12-20 14:55 0% ` Rao, Nikhil
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Reshma Pattan @ 2018-12-20 12:16 UTC (permalink / raw)
To: dev, jerin.jacob, nikhil.rao, olivier.matz, thomas,
jasvinder.singh, cristian.dumitrescu, konstantin.ananyev
Cc: Reshma Pattan
This patch implements the changes proposed in the deprecation
notes [1][2].
librte_mbuf changes:
The mbuf->hash.sched field is updated to support generic
definition in line with the ethdev traffic manager and meter APIs.
The new generic format contains: queue ID, traffic class, color.
Added public APIs to set and get these new fields to and from mbuf.
librte_sched changes:
In addtion, following API functions of the sched library have
been modified with an additional parameter of type struct
rte_sched_port to accommodate the changes made to mbuf sched field.
(i)rte_sched_port_pkt_write()
(ii) rte_sched_port_pkt_read_tree_path()
librte_pipeline, qos_sched UT, qos_sched app are updated
to make use of new changes.
Also mbuf->hash.txadapter has been added for eventdev txq,
rte_event_eth_tx_adapter_txq_set and rte_event_eth_tx_adapter_txq_get()
are updated to use mbuf->hash.txadapter.txq.
doc:
Release notes updated.
Removed deprecation notice for mbuf->hash.sched and sched API.
[1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
[2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
v7:
Edited the commit message.
Moved rte_mbuf_sched inside the rte_mbuf struct.
Added missing empty line in doxygen comments of sched
set and get functions.
v6: added scheduler comment
v5:
Removed librte_meter from librte_mbuf dependency list.
Changed the mbuf set/get functions to use uint8_t for color.
v4: converted mbuf->hash.sched as instantiation of rte_mbuf_sched.
v3: addressed review comments given in the below link.
http://patches.dpdk.org/patch/48587/
Updated library ABI versioning in meson build.
---
---
doc/guides/rel_notes/deprecation.rst | 10 --
doc/guides/rel_notes/release_19_02.rst | 4 +-
examples/qos_sched/app_thread.c | 7 +-
examples/qos_sched/main.c | 1 +
.../rte_event_eth_tx_adapter.h | 18 ++-
lib/librte_mbuf/Makefile | 2 +-
lib/librte_mbuf/meson.build | 2 +-
lib/librte_mbuf/rte_mbuf.h | 119 +++++++++++++++++-
lib/librte_pipeline/rte_table_action.c | 44 +++----
lib/librte_sched/Makefile | 2 +-
lib/librte_sched/meson.build | 1 +
lib/librte_sched/rte_sched.c | 90 ++++++-------
lib/librte_sched/rte_sched.h | 10 +-
test/test/test_sched.c | 9 +-
14 files changed, 197 insertions(+), 122 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index ac7fb29a7..ec80dcc7b 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,16 +49,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* mbuf: The opaque ``mbuf->hash.sched`` field will be updated to support generic
- definition in line with the ethdev TM and MTR APIs. Currently, this field
- is defined in librte_sched in a non-generic way. The new generic format
- will contain: queue ID, traffic class, color. Field size will not change.
-
-* sched: Some API functions will change prototype due to the above
- deprecation note for mbuf->hash.sched, e.g. ``rte_sched_port_pkt_write()``
- and ``rte_sched_port_pkt_read()`` will likely have an additional parameter
- of type ``struct rte_sched_port``.
-
* mbuf: the macro ``RTE_MBUF_INDIRECT()`` will be removed in v18.08 or later and
replaced with ``RTE_MBUF_CLONED()`` which is already added in v18.05. As
``EXT_ATTACHED_MBUF`` is newly introduced in v18.05, ``RTE_MBUF_INDIRECT()``
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 8deb68b9a..1f9ec9fc1 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -156,7 +156,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_kvargs.so.1
librte_latencystats.so.1
librte_lpm.so.2
- librte_mbuf.so.4
+ + librte_mbuf.so.5
librte_member.so.1
librte_mempool.so.5
librte_meter.so.2
@@ -178,7 +178,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_rawdev.so.1
librte_reorder.so.1
librte_ring.so.2
- librte_sched.so.1
+ + librte_sched.so.2
librte_security.so.1
librte_table.so.3
librte_timer.so.1
diff --git a/examples/qos_sched/app_thread.c b/examples/qos_sched/app_thread.c
index a59274236..bec4deee3 100644
--- a/examples/qos_sched/app_thread.c
+++ b/examples/qos_sched/app_thread.c
@@ -73,8 +73,11 @@ app_rx_thread(struct thread_conf **confs)
for(i = 0; i < nb_rx; i++) {
get_pkt_sched(rx_mbufs[i],
&subport, &pipe, &traffic_class, &queue, &color);
- rte_sched_port_pkt_write(rx_mbufs[i], subport, pipe,
- traffic_class, queue, (enum rte_meter_color) color);
+ rte_sched_port_pkt_write(conf->sched_port,
+ rx_mbufs[i],
+ subport, pipe,
+ traffic_class, queue,
+ (enum rte_meter_color) color);
}
if (unlikely(rte_ring_sp_enqueue_bulk(conf->rx_ring,
diff --git a/examples/qos_sched/main.c b/examples/qos_sched/main.c
index e7c97bd64..c0ed16b68 100644
--- a/examples/qos_sched/main.c
+++ b/examples/qos_sched/main.c
@@ -55,6 +55,7 @@ app_main_loop(__attribute__((unused))void *dummy)
flow->rx_thread.rx_port = flow->rx_port;
flow->rx_thread.rx_ring = flow->rx_ring;
flow->rx_thread.rx_queue = flow->rx_queue;
+ flow->rx_thread.sched_port = flow->sched_port;
rx_confs[rx_idx++] = &flow->rx_thread;
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index 81456d4a9..2a50656d9 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -63,13 +63,11 @@
* function can be used to retrieve the adapter's service function ID.
*
* The ethernet port and transmit queue index to transmit the mbuf on are
- * specified using the mbuf port and the higher 16 bits of
- * struct rte_mbuf::hash::sched:hi. The application should use the
- * rte_event_eth_tx_adapter_txq_set() and rte_event_eth_tx_adapter_txq_get()
- * functions to access the transmit queue index since it is expected that the
- * transmit queue will be eventually defined within struct rte_mbuf and using
- * these macros will help with minimizing application impact due to
- * a change in how the transmit queue index is specified.
+ * specified using the mbuf port struct rte_mbuf::hash::txadapter:txq.
+ * The application should use the rte_event_eth_tx_adapter_txq_set()
+ * and rte_event_eth_tx_adapter_txq_get() functions to access the transmit
+ * queue index, using these macros will help with minimizing application
+ * impact due to a change in how the transmit queue index is specified.
*/
#ifdef __cplusplus
@@ -300,8 +298,7 @@ rte_event_eth_tx_adapter_queue_del(uint8_t id,
static __rte_always_inline void __rte_experimental
rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- p[1] = queue;
+ pkt->hash.txadapter.txq = queue;
}
/**
@@ -320,8 +317,7 @@ rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue)
static __rte_always_inline uint16_t __rte_experimental
rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
{
- uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
- return p[1];
+ return pkt->hash.txadapter.txq;
}
/**
diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
index e2b98a254..8c4c7d790 100644
--- a/lib/librte_mbuf/Makefile
+++ b/lib/librte_mbuf/Makefile
@@ -11,7 +11,7 @@ LDLIBS += -lrte_eal -lrte_mempool
EXPORT_MAP := rte_mbuf_version.map
-LIBABIVER := 4
+LIBABIVER := 5
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
index 94d9c4c96..e37da0250 100644
--- a/lib/librte_mbuf/meson.build
+++ b/lib/librte_mbuf/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 4
+version = 5
sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
deps += ['mempool']
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 3dbc6695e..bc562dc8a 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -574,14 +574,25 @@ struct rte_mbuf {
* on PKT_RX_FDIR_* flag in ol_flags.
*/
} fdir; /**< Filter identifier if FDIR enabled */
+ struct rte_mbuf_sched {
+ uint32_t queue_id; /**< Queue ID. */
+ uint8_t traffic_class;
+ /**< Traffic class ID. Traffic class 0
+ * is the highest priority traffic class.
+ */
+ uint8_t color;
+ /**< Color. @see enum rte_color.*/
+ uint16_t reserved; /**< Reserved. */
+ } sched; /**< Hierarchical scheduler */
struct {
- uint32_t lo;
- uint32_t hi;
+ uint32_t reserved1;
+ uint16_t reserved2;
+ uint16_t txq;
/**< The event eth Tx adapter uses this field
* to store Tx queue id.
* @see rte_event_eth_tx_adapter_txq_set()
*/
- } sched; /**< Hierarchical scheduler */
+ } txadapter; /**< Eventdev ethdev Tx adapter */
/**< User defined tags. See rte_distributor_process() */
uint32_t usr;
} hash; /**< hash information */
@@ -2289,6 +2300,108 @@ rte_pktmbuf_linearize(struct rte_mbuf *mbuf)
*/
void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len);
+/**
+ * Get the value of mbuf sched queue_id field.
+ */
+static inline uint32_t
+rte_mbuf_sched_queue_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.queue_id;
+}
+
+/**
+ * Get the value of mbuf sched traffic_class field.
+ */
+static inline uint8_t
+rte_mbuf_sched_traffic_class_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.traffic_class;
+}
+
+/**
+ * Get the value of mbuf sched color field.
+ */
+static inline uint8_t
+rte_mbuf_sched_color_get(const struct rte_mbuf *m)
+{
+ return m->hash.sched.color;
+}
+
+/**
+ * Get the values of mbuf sched queue_id, traffic_class and color.
+ *
+ * @param m
+ * Mbuf to read
+ * @param queue_id
+ * Returns the queue id
+ * @param traffic_class
+ * Returns the traffic class id
+ * @param color
+ * Returns the colour id
+ */
+static inline void
+rte_mbuf_sched_get(const struct rte_mbuf *m, uint32_t *queue_id,
+ uint8_t *traffic_class,
+ uint8_t *color)
+{
+ struct rte_mbuf_sched sched = m->hash.sched;
+
+ *queue_id = sched.queue_id;
+ *traffic_class = sched.traffic_class;
+ *color = sched.color;
+}
+
+/**
+ * Set the mbuf sched queue_id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_queue_set(struct rte_mbuf *m, uint32_t queue_id)
+{
+ m->hash.sched.queue_id = queue_id;
+}
+
+/**
+ * Set the mbuf sched traffic_class id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_traffic_class_set(struct rte_mbuf *m, uint8_t traffic_class)
+{
+ m->hash.sched.traffic_class = traffic_class;
+}
+
+/**
+ * Set the mbuf sched color id to the defined value.
+ */
+static inline void
+rte_mbuf_sched_color_set(struct rte_mbuf *m, uint8_t color)
+{
+ m->hash.sched.color = color;
+}
+
+/**
+ * Set the mbuf sched queue_id, traffic_class and color.
+ *
+ * @param m
+ * Mbuf to set
+ * @param queue_id
+ * Queue id value to be set
+ * @param traffic_class
+ * Traffic class id value to be set
+ * @param color
+ * Color id to be set
+ */
+static inline void
+rte_mbuf_sched_set(struct rte_mbuf *m, uint32_t queue_id,
+ uint8_t traffic_class,
+ uint8_t color)
+{
+ m->hash.sched = (struct rte_mbuf_sched){
+ .queue_id = queue_id,
+ .traffic_class = traffic_class,
+ .color = color,
+ };
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 7c7c8dd82..8a2bb13dc 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -107,14 +107,6 @@ mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
return 0;
}
-#define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
- ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
- ((((uint64_t)(tc)) & 0x3) << 2) | \
- ((((uint64_t)(color)) & 0x3) << 4)))
-
-#define MBUF_SCHED_COLOR(sched, color) \
- (((sched) & (~0x30LLU)) | ((color) << 4))
-
struct mtr_trtcm_data {
struct rte_meter_trtcm trtcm;
uint64_t stats[e_RTE_METER_COLORS];
@@ -176,7 +168,7 @@ mtr_data_size(struct rte_table_action_mtr_config *mtr)
struct dscp_table_entry_data {
enum rte_meter_color color;
uint16_t tc;
- uint16_t queue_tc_color;
+ uint16_t tc_queue;
};
struct dscp_table_data {
@@ -319,8 +311,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
uint32_t dscp,
uint16_t total_length)
{
- uint64_t drop_mask, sched;
- uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
+ uint64_t drop_mask;
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
enum rte_meter_color color_in, color_meter, color_policer;
uint32_t tc, mp_id;
@@ -329,7 +320,6 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
color_in = dscp_entry->color;
data += tc;
mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
- sched = *sched_ptr;
/* Meter */
color_meter = rte_meter_trtcm_color_aware_check(
@@ -346,7 +336,7 @@ pkt_work_mtr(struct rte_mbuf *mbuf,
drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
color_policer =
MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- *sched_ptr = MBUF_SCHED_COLOR(sched, color_policer);
+ rte_mbuf_sched_color_set(mbuf, (uint8_t)color_policer);
return drop_mask;
}
@@ -368,9 +358,8 @@ tm_cfg_check(struct rte_table_action_tm_config *tm)
}
struct tm_data {
- uint16_t queue_tc_color;
- uint16_t subport;
- uint32_t pipe;
+ uint32_t queue_id;
+ uint32_t reserved;
} __attribute__((__packed__));
static int
@@ -397,9 +386,9 @@ tm_apply(struct tm_data *data,
return status;
/* Apply */
- data->queue_tc_color = 0;
- data->subport = (uint16_t) p->subport_id;
- data->pipe = p->pipe_id;
+ data->queue_id = p->subport_id <<
+ (__builtin_ctz(cfg->n_pipes_per_subport) + 4) |
+ p->pipe_id << 4;
return 0;
}
@@ -411,12 +400,11 @@ pkt_work_tm(struct rte_mbuf *mbuf,
uint32_t dscp)
{
struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
- struct tm_data sched;
-
- sched = *data;
- sched.queue_tc_color = dscp_entry->queue_tc_color;
- *sched_ptr = sched;
+ uint32_t queue_id = data->queue_id |
+ (dscp_entry->tc << 2) |
+ dscp_entry->tc_queue;
+ rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc,
+ (uint8_t)dscp_entry->color);
}
/**
@@ -2580,17 +2568,13 @@ rte_table_action_dscp_table_update(struct rte_table_action *action,
&action->dscp_table.entry[i];
struct rte_table_action_dscp_table_entry *entry =
&table->entry[i];
- uint16_t queue_tc_color =
- MBUF_SCHED_QUEUE_TC_COLOR(entry->tc_queue_id,
- entry->tc_id,
- entry->color);
if ((dscp_mask & (1LLU << i)) == 0)
continue;
data->color = entry->color;
data->tc = entry->tc_id;
- data->queue_tc_color = queue_tc_color;
+ data->tc_queue = entry->tc_queue_id;
}
return 0;
diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile
index 46c53ed71..644fd9d15 100644
--- a/lib/librte_sched/Makefile
+++ b/lib/librte_sched/Makefile
@@ -18,7 +18,7 @@ LDLIBS += -lrte_timer
EXPORT_MAP := rte_sched_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build
index f85d64df8..8e989e5f6 100644
--- a/lib/librte_sched/meson.build
+++ b/lib/librte_sched/meson.build
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
+version = 2
sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c')
headers = files('rte_sched.h', 'rte_sched_common.h',
'rte_red.h', 'rte_approx.h')
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 587d5e602..dd7739172 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -128,22 +128,6 @@ enum grinder_state {
e_GRINDER_READ_MBUF
};
-/*
- * Path through the scheduler hierarchy used by the scheduler enqueue
- * operation to identify the destination queue for the current
- * packet. Stored in the field pkt.hash.sched of struct rte_mbuf of
- * each packet, typically written by the classification stage and read
- * by scheduler enqueue.
- */
-struct rte_sched_port_hierarchy {
- uint16_t queue:2; /**< Queue ID (0 .. 3) */
- uint16_t traffic_class:2; /**< Traffic class ID (0 .. 3)*/
- uint32_t color:2; /**< Color */
- uint16_t unused:10;
- uint16_t subport; /**< Subport ID */
- uint32_t pipe; /**< Pipe ID */
-};
-
struct rte_sched_grinder {
/* Pipe cache */
uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
@@ -185,6 +169,7 @@ struct rte_sched_port {
/* User parameters */
uint32_t n_subports_per_port;
uint32_t n_pipes_per_subport;
+ uint32_t n_pipes_per_subport_log2;
uint32_t rate;
uint32_t mtu;
uint32_t frame_overhead;
@@ -645,6 +630,8 @@ rte_sched_port_config(struct rte_sched_port_params *params)
/* User parameters */
port->n_subports_per_port = params->n_subports_per_port;
port->n_pipes_per_subport = params->n_pipes_per_subport;
+ port->n_pipes_per_subport_log2 =
+ __builtin_ctz(params->n_pipes_per_subport);
port->rate = params->rate;
port->mtu = params->mtu + params->frame_overhead;
port->frame_overhead = params->frame_overhead;
@@ -1006,44 +993,52 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port,
return 0;
}
+static inline uint32_t
+rte_sched_port_qindex(struct rte_sched_port *port,
+ uint32_t subport,
+ uint32_t pipe,
+ uint32_t traffic_class,
+ uint32_t queue)
+{
+ return ((subport & (port->n_subports_per_port - 1)) <<
+ (port->n_pipes_per_subport_log2 + 4)) |
+ ((pipe & (port->n_pipes_per_subport - 1)) << 4) |
+ ((traffic_class &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << 2) |
+ (queue & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1));
+}
+
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
- uint32_t subport, uint32_t pipe, uint32_t traffic_class,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
+ uint32_t subport, uint32_t pipe,
+ uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color)
{
- struct rte_sched_port_hierarchy *sched
- = (struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- RTE_BUILD_BUG_ON(sizeof(*sched) > sizeof(pkt->hash.sched));
-
- sched->color = (uint32_t) color;
- sched->subport = subport;
- sched->pipe = pipe;
- sched->traffic_class = traffic_class;
- sched->queue = queue;
+ uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe,
+ traffic_class, queue);
+ rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color);
}
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
+ uint32_t queue_id = rte_mbuf_sched_queue_get(pkt);
- *subport = sched->subport;
- *pipe = sched->pipe;
- *traffic_class = sched->traffic_class;
- *queue = sched->queue;
+ *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4);
+ *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1);
+ *traffic_class = (queue_id >> 2) &
+ (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1);
+ *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1);
}
enum rte_meter_color
rte_sched_port_pkt_read_color(const struct rte_mbuf *pkt)
{
- const struct rte_sched_port_hierarchy *sched
- = (const struct rte_sched_port_hierarchy *) &pkt->hash.sched;
-
- return (enum rte_meter_color) sched->color;
+ return (enum rte_meter_color)rte_mbuf_sched_color_get(pkt);
}
int
@@ -1100,18 +1095,6 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
return 0;
}
-static inline uint32_t
-rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport, uint32_t pipe, uint32_t traffic_class, uint32_t queue)
-{
- uint32_t result;
-
- result = subport * port->n_pipes_per_subport + pipe;
- result = result * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + traffic_class;
- result = result * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
-
- return result;
-}
-
#ifdef RTE_SCHED_DEBUG
static inline int
@@ -1272,11 +1255,8 @@ rte_sched_port_enqueue_qptrs_prefetch0(struct rte_sched_port *port,
#ifdef RTE_SCHED_COLLECT_STATS
struct rte_sched_queue_extra *qe;
#endif
- uint32_t subport, pipe, traffic_class, queue, qindex;
-
- rte_sched_port_pkt_read_tree_path(pkt, &subport, &pipe, &traffic_class, &queue);
+ uint32_t qindex = rte_mbuf_sched_queue_get(pkt);
- qindex = rte_sched_port_qindex(port, subport, pipe, traffic_class, queue);
q = port->queue + qindex;
rte_prefetch0(q);
#ifdef RTE_SCHED_COLLECT_STATS
diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
index 84fa896de..243efa1d4 100644
--- a/lib/librte_sched/rte_sched.h
+++ b/lib/librte_sched/rte_sched.h
@@ -355,6 +355,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Scheduler hierarchy path write to packet descriptor. Typically
* called by the packet classification stage.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -369,7 +371,8 @@ rte_sched_queue_read_stats(struct rte_sched_port *port,
* Packet color set
*/
void
-rte_sched_port_pkt_write(struct rte_mbuf *pkt,
+rte_sched_port_pkt_write(struct rte_sched_port *port,
+ struct rte_mbuf *pkt,
uint32_t subport, uint32_t pipe, uint32_t traffic_class,
uint32_t queue, enum rte_meter_color color);
@@ -379,6 +382,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
* enqueue operation. The subport, pipe, traffic class and queue
* parameters need to be pre-allocated by the caller.
*
+ * @param port
+ * Handle to port scheduler instance
* @param pkt
* Packet descriptor handle
* @param subport
@@ -392,7 +397,8 @@ rte_sched_port_pkt_write(struct rte_mbuf *pkt,
*
*/
void
-rte_sched_port_pkt_read_tree_path(const struct rte_mbuf *pkt,
+rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port,
+ const struct rte_mbuf *pkt,
uint32_t *subport, uint32_t *pipe,
uint32_t *traffic_class, uint32_t *queue);
diff --git a/test/test/test_sched.c b/test/test/test_sched.c
index 32e500ba9..40e411cab 100644
--- a/test/test/test_sched.c
+++ b/test/test/test_sched.c
@@ -76,7 +76,7 @@ create_mempool(void)
}
static void
-prepare_pkt(struct rte_mbuf *mbuf)
+prepare_pkt(struct rte_sched_port *port, struct rte_mbuf *mbuf)
{
struct ether_hdr *eth_hdr;
struct vlan_hdr *vlan1, *vlan2;
@@ -95,7 +95,8 @@ prepare_pkt(struct rte_mbuf *mbuf)
ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);
- rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW);
+ rte_sched_port_pkt_write(port, mbuf, SUBPORT, PIPE, TC, QUEUE,
+ e_RTE_METER_YELLOW);
/* 64 byte packet */
mbuf->pkt_len = 60;
@@ -138,7 +139,7 @@ test_sched(void)
for (i = 0; i < 10; i++) {
in_mbufs[i] = rte_pktmbuf_alloc(mp);
TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation failed\n");
- prepare_pkt(in_mbufs[i]);
+ prepare_pkt(port, in_mbufs[i]);
}
@@ -155,7 +156,7 @@ test_sched(void)
color = rte_sched_port_pkt_read_color(out_mbufs[i]);
TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong color\n");
- rte_sched_port_pkt_read_tree_path(out_mbufs[i],
+ rte_sched_port_pkt_read_tree_path(port, out_mbufs[i],
&subport, &pipe, &traffic_class, &queue);
TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong subport\n");
--
2.17.1
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v4] libs/power: add p-state driver compatibility
2018-12-14 13:11 1% ` [dpdk-dev] [PATCH v3] " Liang Ma
2018-12-19 3:18 0% ` Thomas Monjalon
@ 2018-12-20 14:43 1% ` Liang Ma
2018-12-21 0:34 0% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Liang Ma @ 2018-12-20 14:43 UTC (permalink / raw)
To: david.hunt; +Cc: dev, anatoly.burakov, Liang Ma
Previously, in order to use the power library, it was necessary
for the user to disable the intel_pstate driver by adding
“intel_pstate=disable” to the kernel command line for the system,
which causes the acpi_cpufreq driver to be loaded in its place.
This patch adds the ability for the power library use the intel-pstate
driver.
It adds a new suite of functions behind the current power library API,
and will seamlessly set up the user facing API function pointers to
the relevant functions depending on whether the system is running with
acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
using kvm. The library API and ABI is unchanged.
Signed-off-by: Liang Ma <liang.j.ma@intel.com>
Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: David Hunt <david.hunt@intel.com>
---
Change Log:
v2 Code review rework
v3 Code review rework
v4 Fix the meson build failure
---
lib/librte_power/Makefile | 2 +
lib/librte_power/meson.build | 3 +-
lib/librte_power/power_pstate_cpufreq.c | 771 ++++++++++++++++++++++++++++++++
lib/librte_power/power_pstate_cpufreq.h | 218 +++++++++
lib/librte_power/rte_power.c | 48 +-
lib/librte_power/rte_power.h | 3 +-
6 files changed, 1033 insertions(+), 12 deletions(-)
create mode 100644 lib/librte_power/power_pstate_cpufreq.c
create mode 100644 lib/librte_power/power_pstate_cpufreq.h
diff --git a/lib/librte_power/Makefile b/lib/librte_power/Makefile
index 9bec668..ab77152 100644
--- a/lib/librte_power/Makefile
+++ b/lib/librte_power/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
# library name
LIB = librte_power.a
+CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 -fno-strict-aliasing
LDLIBS += -lrte_eal -lrte_timer
@@ -17,6 +18,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_POWER) := rte_power.c power_acpi_cpufreq.c
SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_kvm_vm.c guest_channel.c
SRCS-$(CONFIG_RTE_LIBRTE_POWER) += rte_power_empty_poll.c
+SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_pstate_cpufreq.c
# install this header file
SYMLINK-$(CONFIG_RTE_LIBRTE_POWER)-include := rte_power.h rte_power_empty_poll.h
diff --git a/lib/librte_power/meson.build b/lib/librte_power/meson.build
index 9ed8b56..02e0337 100644
--- a/lib/librte_power/meson.build
+++ b/lib/librte_power/meson.build
@@ -6,6 +6,7 @@ if host_machine.system() != 'linux'
endif
sources = files('rte_power.c', 'power_acpi_cpufreq.c',
'power_kvm_vm.c', 'guest_channel.c',
- 'rte_power_empty_poll.c')
+ 'rte_power_empty_poll.c',
+ 'power_pstate_cpufreq.c')
headers = files('rte_power.h','rte_power_empty_poll.h')
deps += ['timer']
diff --git a/lib/librte_power/power_pstate_cpufreq.c b/lib/librte_power/power_pstate_cpufreq.c
new file mode 100644
index 0000000..411d0eb
--- /dev/null
+++ b/lib/librte_power/power_pstate_cpufreq.c
@@ -0,0 +1,771 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <limits.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <rte_memcpy.h>
+#include <rte_atomic.h>
+
+#include "power_pstate_cpufreq.h"
+#include "power_common.h"
+
+
+#ifdef RTE_LIBRTE_POWER_DEBUG
+#define POWER_DEBUG_TRACE(fmt, args...) do { \
+ RTE_LOG(ERR, POWER, "%s: " fmt, __func__, ## args); \
+} while (0)
+#else
+#define POWER_DEBUG_TRACE(fmt, args...)
+#endif
+
+#define FOPEN_OR_ERR_RET(f, retval) do { \
+ if ((f) == NULL) { \
+ RTE_LOG(ERR, POWER, "File not openned\n"); \
+ return retval; \
+ } \
+} while (0)
+
+#define FOPS_OR_NULL_GOTO(ret, label) do { \
+ if ((ret) == NULL) { \
+ RTE_LOG(ERR, POWER, "fgets returns nothing\n"); \
+ goto label; \
+ } \
+} while (0)
+
+#define FOPS_OR_ERR_GOTO(ret, label) do { \
+ if ((ret) < 0) { \
+ RTE_LOG(ERR, POWER, "File operations failed\n"); \
+ goto label; \
+ } \
+} while (0)
+
+
+#define POWER_CONVERT_TO_DECIMAL 10
+#define BUS_FREQ 100000
+
+#define POWER_GOVERNOR_PERF "performance"
+#define POWER_SYSFILE_GOVERNOR \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_governor"
+#define POWER_SYSFILE_MAX_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_max_freq"
+#define POWER_SYSFILE_MIN_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_min_freq"
+#define POWER_SYSFILE_CUR_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq"
+#define POWER_SYSFILE_BASE_MAX_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_max_freq"
+#define POWER_SYSFILE_BASE_MIN_FREQ \
+ "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_min_freq"
+#define POWER_MSR_PATH "/dev/cpu/%u/msr"
+
+/*
+ * MSR related
+ */
+#define PLATFORM_INFO 0x0CE
+#define NON_TURBO_MASK 0xFF00
+#define NON_TURBO_OFFSET 0x8
+
+
+enum power_state {
+ POWER_IDLE = 0,
+ POWER_ONGOING,
+ POWER_USED,
+ POWER_UNKNOWN
+};
+
+struct pstate_power_info {
+ unsigned int lcore_id; /**< Logical core id */
+ uint32_t freqs[RTE_MAX_LCORE_FREQS]; /**< Frequency array */
+ uint32_t nb_freqs; /**< number of available freqs */
+ FILE *f_cur_min; /**< FD of scaling_min */
+ FILE *f_cur_max; /**< FD of scaling_max */
+ char governor_ori[32]; /**< Original governor name */
+ uint32_t curr_idx; /**< Freq index in freqs array */
+ uint32_t non_turbo_max_ratio; /**< Non Turbo Max ratio */
+ uint32_t sys_max_freq; /**< system wide max freq */
+ volatile uint32_t state; /**< Power in use state */
+ uint16_t turbo_available; /**< Turbo Boost available */
+ uint16_t turbo_enable; /**< Turbo Boost enable/disable */
+} __rte_cache_aligned;
+
+
+static struct pstate_power_info lcore_power_info[RTE_MAX_LCORE];
+
+/**
+ * It is to read the specific MSR.
+ */
+
+static int32_t
+power_rdmsr(int msr, uint64_t *val, unsigned int lcore_id)
+{
+ int fd, ret;
+ char fullpath[PATH_MAX];
+
+ snprintf(fullpath, sizeof(fullpath), POWER_MSR_PATH, lcore_id);
+
+ fd = open(fullpath, O_RDONLY);
+
+ if (fd < 0) {
+ RTE_LOG(ERR, POWER, "Error opening '%s': %s\n", fullpath,
+ strerror(errno));
+ return fd;
+ }
+
+ ret = pread(fd, val, sizeof(uint64_t), msr);
+
+ if (ret < 0) {
+ RTE_LOG(ERR, POWER, "Error reading '%s': %s\n", fullpath,
+ strerror(errno));
+ goto out;
+ }
+
+ POWER_DEBUG_TRACE("MSR Path %s, offset 0x%X for lcore %u\n",
+ fullpath, msr, lcore_id);
+
+ POWER_DEBUG_TRACE("Ret value %d, content is 0x%"PRIx64"\n", ret, *val);
+
+out: close(fd);
+ return ret;
+}
+
+/**
+ * It is to fopen the sys file for the future setting the lcore frequency.
+ */
+static int
+power_init_for_setting_freq(struct pstate_power_info *pi)
+{
+ FILE *f_min, *f_max;
+ char fullpath_min[PATH_MAX];
+ char fullpath_max[PATH_MAX];
+ uint64_t max_non_turbo = 0;
+
+ snprintf(fullpath_min, sizeof(fullpath_min), POWER_SYSFILE_MIN_FREQ,
+ pi->lcore_id);
+
+ f_min = fopen(fullpath_min, "rw+");
+ FOPEN_OR_ERR_RET(f_min, -1);
+
+ snprintf(fullpath_max, sizeof(fullpath_max), POWER_SYSFILE_MAX_FREQ,
+ pi->lcore_id);
+
+ f_max = fopen(fullpath_max, "rw+");
+ FOPEN_OR_ERR_RET(f_max, -1);
+
+ pi->f_cur_min = f_min;
+ pi->f_cur_max = f_max;
+
+ /* Add MSR read to detect turbo status */
+
+ if (power_rdmsr(PLATFORM_INFO, &max_non_turbo, pi->lcore_id) < 0)
+ return -1;
+
+ max_non_turbo = (max_non_turbo&NON_TURBO_MASK)>>NON_TURBO_OFFSET;
+
+ POWER_DEBUG_TRACE("no turbo perf %"PRIu64"\n", max_non_turbo);
+
+ pi->non_turbo_max_ratio = max_non_turbo;
+
+ return 0;
+}
+
+static int
+set_freq_internal(struct pstate_power_info *pi, uint32_t idx)
+{
+ uint32_t target_freq = 0;
+
+ if (idx >= RTE_MAX_LCORE_FREQS || idx >= pi->nb_freqs) {
+ RTE_LOG(ERR, POWER, "Invalid frequency index %u, which "
+ "should be less than %u\n", idx, pi->nb_freqs);
+ return -1;
+ }
+
+ /* Check if it is the same as current */
+ if (idx == pi->curr_idx)
+ return 0;
+
+ /* Because Intel Pstate Driver only allow user change min/max hint
+ * User need change the min/max as same value.
+ */
+ if (fseek(pi->f_cur_min, 0, SEEK_SET) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to set file position indicator to 0 "
+ "for setting frequency for lcore %u\n",
+ pi->lcore_id);
+ return -1;
+ }
+
+ if (fseek(pi->f_cur_max, 0, SEEK_SET) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to set file position indicator to 0 "
+ "for setting frequency for lcore %u\n",
+ pi->lcore_id);
+ return -1;
+ }
+
+ /* Turbo is available and enabled, first freq bucket is sys max freq */
+ if (pi->turbo_available && pi->turbo_enable && (idx == 0))
+ target_freq = pi->sys_max_freq;
+ else
+ target_freq = pi->freqs[idx];
+
+ /* Decrease freq, the min freq should be updated first */
+ if (idx > pi->curr_idx) {
+
+ if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ POWER_DEBUG_TRACE("Freqency '%u' to be set for lcore %u\n",
+ target_freq, pi->lcore_id);
+
+ fflush(pi->f_cur_min);
+ fflush(pi->f_cur_max);
+
+ }
+
+ /* Increase freq, the max freq should be updated first */
+ if (idx < pi->curr_idx) {
+
+ if (fprintf(pi->f_cur_max, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ if (fprintf(pi->f_cur_min, "%u", target_freq) < 0) {
+ RTE_LOG(ERR, POWER, "Fail to write new frequency for "
+ "lcore %u\n", pi->lcore_id);
+ return -1;
+ }
+
+ POWER_DEBUG_TRACE("Freqency '%u' to be set for lcore %u\n",
+ target_freq, pi->lcore_id);
+
+ fflush(pi->f_cur_max);
+ fflush(pi->f_cur_min);
+ }
+
+ pi->curr_idx = idx;
+
+ return 1;
+}
+
+/**
+ * It is to check the current scaling governor by reading sys file, and then
+ * set it into 'performance' if it is not by writing the sys file. The original
+ * governor will be saved for rolling back.
+ */
+static int
+power_set_governor_performance(struct pstate_power_info *pi)
+{
+ FILE *f;
+ int ret = -1;
+ char buf[BUFSIZ];
+ char fullpath[PATH_MAX];
+ char *s;
+ int val;
+
+ snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_GOVERNOR,
+ pi->lcore_id);
+ f = fopen(fullpath, "rw+");
+ FOPEN_OR_ERR_RET(f, ret);
+
+ s = fgets(buf, sizeof(buf), f);
+ FOPS_OR_NULL_GOTO(s, out);
+
+ /* Check if current governor is performance */
+ if (strncmp(buf, POWER_GOVERNOR_PERF,
+ sizeof(POWER_GOVERNOR_PERF)) == 0) {
+ ret = 0;
+ POWER_DEBUG_TRACE("Power management governor of lcore %u is "
+ "already performance\n", pi->lcore_id);
+ goto out;
+ }
+ /* Save the original governor */
+ snprintf(pi->governor_ori, sizeof(pi->governor_ori), "%s", buf);
+
+ /* Write 'performance' to the governor */
+ val = fseek(f, 0, SEEK_SET);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ val = fputs(POWER_GOVERNOR_PERF, f);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ ret = 0;
+ RTE_LOG(INFO, POWER, "Power management governor of lcore %u has been "
+ "set to performance successfully\n", pi->lcore_id);
+out:
+ fclose(f);
+
+ return ret;
+}
+
+/**
+ * It is to check the governor and then set the original governor back if
+ * needed by writing the sys file.
+ */
+static int
+power_set_governor_original(struct pstate_power_info *pi)
+{
+ FILE *f;
+ int ret = -1;
+ char buf[BUFSIZ];
+ char fullpath[PATH_MAX];
+ char *s;
+ int val;
+
+ snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_GOVERNOR,
+ pi->lcore_id);
+ f = fopen(fullpath, "rw+");
+ FOPEN_OR_ERR_RET(f, ret);
+
+ s = fgets(buf, sizeof(buf), f);
+ FOPS_OR_NULL_GOTO(s, out);
+
+ /* Check if the governor to be set is the same as current */
+ if (strncmp(buf, pi->governor_ori, sizeof(pi->governor_ori)) == 0) {
+ ret = 0;
+ POWER_DEBUG_TRACE("Power management governor of lcore %u "
+ "has already been set to %s\n",
+ pi->lcore_id, pi->governor_ori);
+ goto out;
+ }
+
+ /* Write back the original governor */
+ val = fseek(f, 0, SEEK_SET);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ val = fputs(pi->governor_ori, f);
+ FOPS_OR_ERR_GOTO(val, out);
+
+ ret = 0;
+ RTE_LOG(INFO, POWER, "Power management governor of lcore %u "
+ "has been set back to %s successfully\n",
+ pi->lcore_id, pi->governor_ori);
+out:
+ fclose(f);
+
+ return ret;
+}
+
+/**
+ * It is to get the available frequencies of the specific lcore by reading the
+ * sys file.
+ */
+static int
+power_get_available_freqs(struct pstate_power_info *pi)
+{
+ FILE *f_min, *f_max;
+ int ret = -1;
+ char *p_min, *p_max;
+ char buf_min[BUFSIZ];
+ char buf_max[BUFSIZ];
+ char fullpath_min[PATH_MAX];
+ char fullpath_max[PATH_MAX];
+ char *s_min, *s_max;
+ uint32_t sys_min_freq = 0, sys_max_freq = 0, base_max_freq = 0;
+ uint32_t i, num_freqs = 0;
+
+ snprintf(fullpath_max, sizeof(fullpath_max),
+ POWER_SYSFILE_BASE_MAX_FREQ,
+ pi->lcore_id);
+ snprintf(fullpath_min, sizeof(fullpath_min),
+ POWER_SYSFILE_BASE_MIN_FREQ,
+ pi->lcore_id);
+
+ f_min = fopen(fullpath_min, "r");
+ FOPEN_OR_ERR_RET(f_min, ret);
+
+ f_max = fopen(fullpath_max, "r");
+ FOPEN_OR_ERR_RET(f_max, ret);
+
+ s_min = fgets(buf_min, sizeof(buf_min), f_min);
+ FOPS_OR_NULL_GOTO(s_min, out);
+
+ s_max = fgets(buf_max, sizeof(buf_max), f_max);
+ FOPS_OR_NULL_GOTO(s_max, out);
+
+
+ /* Strip the line break if there is */
+ p_min = strchr(buf_min, '\n');
+ if (p_min != NULL)
+ *p_min = 0;
+
+ p_max = strchr(buf_max, '\n');
+ if (p_max != NULL)
+ *p_max = 0;
+
+ sys_min_freq = strtoul(buf_min, &p_min, POWER_CONVERT_TO_DECIMAL);
+ sys_max_freq = strtoul(buf_max, &p_max, POWER_CONVERT_TO_DECIMAL);
+
+ if (sys_max_freq < sys_min_freq)
+ goto out;
+
+ pi->sys_max_freq = sys_max_freq;
+
+ base_max_freq = pi->non_turbo_max_ratio * BUS_FREQ;
+
+ POWER_DEBUG_TRACE("sys min %u, sys max %u, base_max %u\n",
+ sys_min_freq,
+ sys_max_freq,
+ base_max_freq);
+
+ if (base_max_freq < sys_max_freq)
+ pi->turbo_available = 1;
+ else
+ pi->turbo_available = 0;
+
+ /* If turbo is available then there is one extra freq bucket
+ * to store the sys max freq which value is base_max +1
+ */
+ num_freqs = (base_max_freq - sys_min_freq) / BUS_FREQ + 1 +
+ pi->turbo_available;
+
+ /* Generate the freq bucket array.
+ * If turbo is available the freq bucket[0] value is base_max +1
+ * the bucket[1] is base_max, bucket[2] is base_max - BUS_FREQ
+ * and so on.
+ * If turbo is not available bucket[0] is base_max and so on
+ */
+ for (i = 0, pi->nb_freqs = 0; i < num_freqs; i++) {
+ if ((i == 0) && pi->turbo_available)
+ pi->freqs[pi->nb_freqs++] = base_max_freq + 1;
+ else
+ pi->freqs[pi->nb_freqs++] =
+ base_max_freq - (i - pi->turbo_available) * BUS_FREQ;
+ }
+
+ ret = 0;
+
+ POWER_DEBUG_TRACE("%d frequency(s) of lcore %u are available\n",
+ num_freqs, pi->lcore_id);
+
+out:
+ fclose(f_min);
+ fclose(f_max);
+
+ return ret;
+}
+
+int
+power_pstate_cpufreq_init(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Lcore id %u can not exceed %u\n",
+ lcore_id, RTE_MAX_LCORE - 1U);
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (rte_atomic32_cmpset(&(pi->state), POWER_IDLE, POWER_ONGOING)
+ == 0) {
+ RTE_LOG(INFO, POWER, "Power management of lcore %u is "
+ "in use\n", lcore_id);
+ return -1;
+ }
+
+ pi->lcore_id = lcore_id;
+ /* Check and set the governor */
+ if (power_set_governor_performance(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set governor of lcore %u to "
+ "performance\n", lcore_id);
+ goto fail;
+ }
+ /* Init for setting lcore frequency */
+ if (power_init_for_setting_freq(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot init for setting frequency for "
+ "lcore %u\n", lcore_id);
+ goto fail;
+ }
+
+ /* Get the available frequencies */
+ if (power_get_available_freqs(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot get available frequencies of "
+ "lcore %u\n", lcore_id);
+ goto fail;
+ }
+
+
+ /* Set freq to max by default */
+ if (power_pstate_cpufreq_freq_max(lcore_id) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set frequency of lcore %u "
+ "to max\n", lcore_id);
+ goto fail;
+ }
+
+ RTE_LOG(INFO, POWER, "Initialized successfully for lcore %u "
+ "power management\n", lcore_id);
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_USED);
+
+ return 0;
+
+fail:
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
+
+ return -1;
+}
+
+int
+power_pstate_cpufreq_exit(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Lcore id %u can not exceeds %u\n",
+ lcore_id, RTE_MAX_LCORE - 1U);
+ return -1;
+ }
+ pi = &lcore_power_info[lcore_id];
+
+ if (rte_atomic32_cmpset(&(pi->state), POWER_USED, POWER_ONGOING)
+ == 0) {
+ RTE_LOG(INFO, POWER, "Power management of lcore %u is "
+ "not used\n", lcore_id);
+ return -1;
+ }
+
+ /* Close FD of setting freq */
+ fclose(pi->f_cur_min);
+ fclose(pi->f_cur_max);
+ pi->f_cur_min = NULL;
+ pi->f_cur_max = NULL;
+
+ /* Set the governor back to the original */
+ if (power_set_governor_original(pi) < 0) {
+ RTE_LOG(ERR, POWER, "Cannot set the governor of %u back "
+ "to the original\n", lcore_id);
+ goto fail;
+ }
+
+ RTE_LOG(INFO, POWER, "Power management of lcore %u has exited from "
+ "'performance' mode and been set back to the "
+ "original\n", lcore_id);
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_IDLE);
+
+ return 0;
+
+fail:
+ rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN);
+
+ return -1;
+}
+
+
+uint32_t
+power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (num < pi->nb_freqs) {
+ RTE_LOG(ERR, POWER, "Buffer size is not enough\n");
+ return 0;
+ }
+ rte_memcpy(freqs, pi->freqs, pi->nb_freqs * sizeof(uint32_t));
+
+ return pi->nb_freqs;
+}
+
+uint32_t
+power_pstate_cpufreq_get_freq(unsigned int lcore_id)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return RTE_POWER_INVALID_FREQ_INDEX;
+ }
+
+ return lcore_power_info[lcore_id].curr_idx;
+}
+
+
+int
+power_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ return set_freq_internal(&(lcore_power_info[lcore_id]), index);
+}
+
+int
+power_pstate_cpufreq_freq_up(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (pi->curr_idx == 0)
+ return 0;
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->curr_idx - 1);
+}
+
+int
+power_pstate_cpufreq_freq_down(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ if (pi->curr_idx + 1 == pi->nb_freqs)
+ return 0;
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->curr_idx + 1);
+}
+
+int
+power_pstate_cpufreq_freq_max(unsigned int lcore_id)
+{
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ /* Frequencies in the array are from high to low. */
+ if (lcore_power_info[lcore_id].turbo_available) {
+ if (lcore_power_info[lcore_id].turbo_enable)
+ /* Set to Turbo */
+ return set_freq_internal(
+ &lcore_power_info[lcore_id], 0);
+ else
+ /* Set to max non-turbo */
+ return set_freq_internal(
+ &lcore_power_info[lcore_id], 1);
+ } else
+ return set_freq_internal(&lcore_power_info[lcore_id], 0);
+}
+
+
+int
+power_pstate_cpufreq_freq_min(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ /* Frequencies in the array are from high to low. */
+ return set_freq_internal(pi, pi->nb_freqs - 1);
+}
+
+
+int
+power_pstate_turbo_status(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ return pi->turbo_enable;
+}
+
+int
+power_pstate_enable_turbo(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ if (pi->turbo_available)
+ pi->turbo_enable = 1;
+ else {
+ pi->turbo_enable = 0;
+ RTE_LOG(ERR, POWER,
+ "Failed to enable turbo on lcore %u\n",
+ lcore_id);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+power_pstate_disable_turbo(unsigned int lcore_id)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+
+ pi->turbo_enable = 0;
+
+
+ return 0;
+}
+
+
+int power_pstate_get_capabilities(unsigned int lcore_id,
+ struct rte_power_core_capabilities *caps)
+{
+ struct pstate_power_info *pi;
+
+ if (lcore_id >= RTE_MAX_LCORE) {
+ RTE_LOG(ERR, POWER, "Invalid lcore ID\n");
+ return -1;
+ }
+ if (caps == NULL) {
+ RTE_LOG(ERR, POWER, "Invalid argument\n");
+ return -1;
+ }
+
+ pi = &lcore_power_info[lcore_id];
+ caps->capabilities = 0;
+ caps->turbo = !!(pi->turbo_available);
+
+ return 0;
+}
diff --git a/lib/librte_power/power_pstate_cpufreq.h b/lib/librte_power/power_pstate_cpufreq.h
new file mode 100644
index 0000000..6fd8018
--- /dev/null
+++ b/lib/librte_power/power_pstate_cpufreq.h
@@ -0,0 +1,218 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _POWER_PSTATE_CPUFREQ_H
+#define _POWER_PSTATE_CPUFREQ_H
+
+/**
+ * @file
+ * RTE Power Management via Intel Pstate driver
+ */
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_string_fns.h>
+#include "rte_power.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize power management for a specific lcore. It will check and set the
+ * governor to performance for the lcore, get the available frequencies, and
+ * prepare to set new lcore frequency.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_init(unsigned int lcore_id);
+
+/**
+ * Exit power management on a specific lcore. It will set the governor to which
+ * is before initialized.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_exit(unsigned int lcore_id);
+
+/**
+ * Get the available frequencies of a specific lcore. The return value will be
+ * the minimal one of the total number of available frequencies and the number
+ * of buffer. The index of available frequencies used in other interfaces
+ * should be in the range of 0 to this return value.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param freqs
+ * The buffer array to save the frequencies.
+ * @param num
+ * The number of frequencies to get.
+ *
+ * @return
+ * The number of available frequencies.
+ */
+uint32_t power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs,
+ uint32_t num);
+
+/**
+ * Return the current index of available frequencies of a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * The current index of available frequencies.
+ * If error, it will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)'.
+ */
+uint32_t power_pstate_cpufreq_get_freq(unsigned int lcore_id);
+
+/**
+ * Set the new frequency for a specific lcore by indicating the index of
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param index
+ * The index of available frequencies.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index);
+
+/**
+ * Scale up the frequency of a specific lcore according to the available
+ * frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_up(unsigned int lcore_id);
+
+/**
+ * Scale down the frequency of a specific lcore according to the available
+ * frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_down(unsigned int lcore_id);
+
+/**
+ * Scale up the frequency of a specific lcore to the highest according to the
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_max(unsigned int lcore_id);
+
+/**
+ * Scale down the frequency of a specific lcore to the lowest according to the
+ * available frequencies.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+int power_pstate_cpufreq_freq_min(unsigned int lcore_id);
+
+/**
+ * Get the turbo status of a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 1 Turbo Boost is enabled on this lcore.
+ * - 0 Turbo Boost is disabled on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_turbo_status(unsigned int lcore_id);
+
+/**
+ * Enable Turbo Boost on a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 Turbo Boost is enabled successfully on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_enable_turbo(unsigned int lcore_id);
+
+/**
+ * Disable Turbo Boost on a specific lcore.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * @param lcore_id
+ * lcore id.
+ *
+ * @return
+ * - 0 Turbo Boost disabled successfully on this lcore.
+ * - Negative on error.
+ */
+int power_pstate_disable_turbo(unsigned int lcore_id);
+
+/**
+ * Returns power capabilities for a specific lcore.
+ *
+ * @param lcore_id
+ * lcore id.
+ * @param caps
+ * pointer to rte_power_core_capabilities object.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int power_pstate_get_capabilities(unsigned int lcore_id,
+ struct rte_power_core_capabilities *caps);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_power/rte_power.c b/lib/librte_power/rte_power.c
index 208b791..a05fbef 100644
--- a/lib/librte_power/rte_power.c
+++ b/lib/librte_power/rte_power.c
@@ -7,6 +7,7 @@
#include "rte_power.h"
#include "power_acpi_cpufreq.h"
#include "power_kvm_vm.h"
+#include "power_pstate_cpufreq.h"
#include "power_common.h"
enum power_management_env global_default_env = PM_ENV_NOT_SET;
@@ -56,6 +57,19 @@ rte_power_set_env(enum power_management_env env)
rte_power_freq_enable_turbo = power_kvm_vm_enable_turbo;
rte_power_freq_disable_turbo = power_kvm_vm_disable_turbo;
rte_power_get_capabilities = power_kvm_vm_get_capabilities;
+ } else if (env == PM_ENV_PSTATE_CPUFREQ) {
+ rte_power_freqs = power_pstate_cpufreq_freqs;
+ rte_power_get_freq = power_pstate_cpufreq_get_freq;
+ rte_power_set_freq = power_pstate_cpufreq_set_freq;
+ rte_power_freq_up = power_pstate_cpufreq_freq_up;
+ rte_power_freq_down = power_pstate_cpufreq_freq_down;
+ rte_power_freq_min = power_pstate_cpufreq_freq_min;
+ rte_power_freq_max = power_pstate_cpufreq_freq_max;
+ rte_power_turbo_status = power_pstate_turbo_status;
+ rte_power_freq_enable_turbo = power_pstate_enable_turbo;
+ rte_power_freq_disable_turbo = power_pstate_disable_turbo;
+ rte_power_get_capabilities = power_pstate_get_capabilities;
+
} else {
RTE_LOG(ERR, POWER, "Invalid Power Management Environment(%d) set\n",
env);
@@ -64,7 +78,6 @@ rte_power_set_env(enum power_management_env env)
}
global_default_env = env;
return 0;
-
}
void
@@ -84,21 +97,32 @@ rte_power_init(unsigned int lcore_id)
{
int ret = -1;
- if (global_default_env == PM_ENV_ACPI_CPUFREQ) {
+ switch (global_default_env) {
+ case PM_ENV_ACPI_CPUFREQ:
return power_acpi_cpufreq_init(lcore_id);
- }
- if (global_default_env == PM_ENV_KVM_VM) {
+ case PM_ENV_KVM_VM:
return power_kvm_vm_init(lcore_id);
+ case PM_ENV_PSTATE_CPUFREQ:
+ return power_pstate_cpufreq_init(lcore_id);
+ default:
+ RTE_LOG(INFO, POWER, "Env isn't set yet!\n");
}
+
/* Auto detect Environment */
- RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power "
- "management...\n");
+ RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power management...\n");
ret = power_acpi_cpufreq_init(lcore_id);
if (ret == 0) {
rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
goto out;
}
+ RTE_LOG(INFO, POWER, "Attempting to initialise PSTAT power management...\n");
+ ret = power_pstate_cpufreq_init(lcore_id);
+ if (ret == 0) {
+ rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
+ goto out;
+ }
+
RTE_LOG(INFO, POWER, "Attempting to initialise VM power management...\n");
ret = power_kvm_vm_init(lcore_id);
if (ret == 0) {
@@ -114,13 +138,17 @@ rte_power_init(unsigned int lcore_id)
int
rte_power_exit(unsigned int lcore_id)
{
- if (global_default_env == PM_ENV_ACPI_CPUFREQ)
+ switch (global_default_env) {
+ case PM_ENV_ACPI_CPUFREQ:
return power_acpi_cpufreq_exit(lcore_id);
- if (global_default_env == PM_ENV_KVM_VM)
+ case PM_ENV_KVM_VM:
return power_kvm_vm_exit(lcore_id);
+ case PM_ENV_PSTATE_CPUFREQ:
+ return power_pstate_cpufreq_exit(lcore_id);
+ default:
+ RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit gracefully\n");
- RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit "
- "gracefully\n");
+ }
return -1;
}
diff --git a/lib/librte_power/rte_power.h b/lib/librte_power/rte_power.h
index d70bc0b..c5e8f6b 100644
--- a/lib/librte_power/rte_power.h
+++ b/lib/librte_power/rte_power.h
@@ -20,7 +20,8 @@ extern "C" {
#endif
/* Power Management Environment State */
-enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM};
+enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM,
+ PM_ENV_PSTATE_CPUFREQ};
/**
* Set the default power management implementation. If this is not called prior
--
2.7.5
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-19 20:31 0% ` Thomas Monjalon
2018-12-20 9:25 0% ` Burakov, Anatoly
@ 2018-12-20 14:52 0% ` Hunt, David
2018-12-21 0:30 0% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Hunt, David @ 2018-12-20 14:52 UTC (permalink / raw)
To: Thomas Monjalon, Liang Ma; +Cc: dev, anatoly.burakov
On 19/12/2018 8:31 PM, Thomas Monjalon wrote:
> 19/12/2018 10:09, Hunt, David:
>> On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
>>> 14/12/2018 14:11, Liang Ma:
>>>> Previously, in order to use the power library, it was necessary
>>>> for the user to disable the intel_pstate driver by adding
>>>> “intel_pstate=disable” to the kernel command line for the system,
>>>> which causes the acpi_cpufreq driver to be loaded in its place.
>>>>
>>>> This patch adds the ability for the power library use the intel-pstate
>>>> driver.
>>>>
>>>> It adds a new suite of functions behind the current power library API,
>>>> and will seamlessly set up the user facing API function pointers to
>>>> the relevant functions depending on whether the system is running with
>>>> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
>>>> using kvm. The library API and ABI is unchanged.
>>>>
>>>> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
>>>>
>>>> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
>>>> ---
>>> Please write a changelog when sending a new version.
>>>
>>> Dave, any comment on this patch?
>>
>> Looks good to me.
>>
>> Acked-by: David Hunt <david.hunt@intel.com>
>>
>>
>>>> --- /dev/null
>>>> +++ b/lib/librte_power/power_pstate_cpufreq.c
>>>> @@ -0,0 +1,770 @@
>>>> +/* SPDX-License-Identifier: BSD-3-Clause
>>>> + * Copyright(c) 2018-2018 Intel Corporation
>>> Something wrong here :)
>> Yes, should simply be "Copyright(c) 2018 Intel Corporation"
>
> There is also a compilation error with meson:
>
> lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
> rte_timer.h: No such file or directory
>
> Clearly, some quality checks are missing.
>
> I'm afraid we won't have any patch for power library in 19.02.
Hi Thomas,
We have just pushed a v4, and tested with make, meson/ninja, and several
different build environments. I believe this version should be
acceptable for 19.02.
Regards,
Dave.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field
2018-12-20 12:16 1% ` [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field Reshma Pattan
@ 2018-12-20 14:55 0% ` Rao, Nikhil
2019-01-15 22:37 3% ` Stephen Hemminger
2019-01-15 23:11 4% ` Stephen Hemminger
2 siblings, 0 replies; 200+ results
From: Rao, Nikhil @ 2018-12-20 14:55 UTC (permalink / raw)
To: Pattan, Reshma, dev, jerin.jacob, olivier.matz, thomas, Singh,
Jasvinder, Dumitrescu, Cristian, Ananyev, Konstantin
> -----Original Message-----
> From: Pattan, Reshma
> Sent: Thursday, December 20, 2018 5:46 PM
> To: dev@dpdk.org; jerin.jacob@caviumnetworks.com; Rao, Nikhil
> <nikhil.rao@intel.com>; olivier.matz@6wind.com; thomas@monjalon.net;
> Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
> <cristian.dumitrescu@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>
> Cc: Pattan, Reshma <reshma.pattan@intel.com>
> Subject: [PATCH v7 2/2] mbuf: implement generic format for sched field
>
> This patch implements the changes proposed in the deprecation notes [1][2].
>
> librte_mbuf changes:
> The mbuf->hash.sched field is updated to support generic definition in line
> with the ethdev traffic manager and meter APIs.
> The new generic format contains: queue ID, traffic class, color.
>
> Added public APIs to set and get these new fields to and from mbuf.
>
> librte_sched changes:
> In addtion, following API functions of the sched library have been modified
> with an additional parameter of type struct rte_sched_port to accommodate
> the changes made to mbuf sched field.
> (i)rte_sched_port_pkt_write()
> (ii) rte_sched_port_pkt_read_tree_path()
>
> librte_pipeline, qos_sched UT, qos_sched app are updated to make use of
> new changes.
>
> Also mbuf->hash.txadapter has been added for eventdev txq,
> rte_event_eth_tx_adapter_txq_set and rte_event_eth_tx_adapter_txq_get()
> are updated to use mbuf->hash.txadapter.txq.
>
> doc:
> Release notes updated.
> Removed deprecation notice for mbuf->hash.sched and sched API.
>
> [1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
> [2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
>
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---
> v7:
>
> Edited the commit message.
> Moved rte_mbuf_sched inside the rte_mbuf struct.
> Added missing empty line in doxygen comments of sched set and get
> functions.
>
> v6: added scheduler comment
>
> v5:
> Removed librte_meter from librte_mbuf dependency list.
> Changed the mbuf set/get functions to use uint8_t for color.
>
> v4: converted mbuf->hash.sched as instantiation of rte_mbuf_sched.
>
> v3: addressed review comments given in the below link.
> http://patches.dpdk.org/patch/48587/
> Updated library ABI versioning in meson build.
> ---
> ---
> doc/guides/rel_notes/deprecation.rst | 10 --
> doc/guides/rel_notes/release_19_02.rst | 4 +-
> examples/qos_sched/app_thread.c | 7 +-
> examples/qos_sched/main.c | 1 +
> .../rte_event_eth_tx_adapter.h | 18 ++-
> lib/librte_mbuf/Makefile | 2 +-
> lib/librte_mbuf/meson.build | 2 +-
> lib/librte_mbuf/rte_mbuf.h | 119 +++++++++++++++++-
> lib/librte_pipeline/rte_table_action.c | 44 +++----
> lib/librte_sched/Makefile | 2 +-
> lib/librte_sched/meson.build | 1 +
> lib/librte_sched/rte_sched.c | 90 ++++++-------
> lib/librte_sched/rte_sched.h | 10 +-
> test/test/test_sched.c | 9 +-
> 14 files changed, 197 insertions(+), 122 deletions(-)
>
> diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> index 81456d4a9..2a50656d9 100644
> --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> @@ -63,13 +63,11 @@
> * function can be used to retrieve the adapter's service function ID.
> *
> * The ethernet port and transmit queue index to transmit the mbuf on are
> - * specified using the mbuf port and the higher 16 bits of
> - * struct rte_mbuf::hash::sched:hi. The application should use the
> - * rte_event_eth_tx_adapter_txq_set() and
> rte_event_eth_tx_adapter_txq_get()
> - * functions to access the transmit queue index since it is expected that the
> - * transmit queue will be eventually defined within struct rte_mbuf and using
> - * these macros will help with minimizing application impact due to
> - * a change in how the transmit queue index is specified.
> + * specified using the mbuf port struct rte_mbuf::hash::txadapter:txq.
> + * The application should use the rte_event_eth_tx_adapter_txq_set()
> + * and rte_event_eth_tx_adapter_txq_get() functions to access the
> + transmit
> + * queue index, using these macros will help with minimizing
> + application
> + * impact due to a change in how the transmit queue index is specified.
> */
>
> #ifdef __cplusplus
> @@ -300,8 +298,7 @@ rte_event_eth_tx_adapter_queue_del(uint8_t id,
> static __rte_always_inline void __rte_experimental
> rte_event_eth_tx_adapter_txq_set(struct rte_mbuf *pkt, uint16_t queue) {
> - uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
> - p[1] = queue;
> + pkt->hash.txadapter.txq = queue;
> }
>
> /**
> @@ -320,8 +317,7 @@ rte_event_eth_tx_adapter_txq_set(struct rte_mbuf
> *pkt, uint16_t queue) static __rte_always_inline uint16_t
> __rte_experimental rte_event_eth_tx_adapter_txq_get(struct rte_mbuf
> *pkt) {
> - uint16_t *p = (uint16_t *)&pkt->hash.sched.hi;
> - return p[1];
> + return pkt->hash.txadapter.txq;
> }
>
Event Tx adapter changes
Tested-by: Nikhil Rao <nikhil.rao@intel.com>
Reviewed-by: Nikhil Rao <nikhil.rao@intel.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 0/4] hash: deprecate lock ellision and read/write concurreny flags
@ 2018-12-20 20:10 0% ` Yigit, Ferruh
0 siblings, 0 replies; 200+ results
From: Yigit, Ferruh @ 2018-12-20 20:10 UTC (permalink / raw)
To: Honnappa Nagarahalli, Bruce Richardson
Cc: pablo.de.lara.guarch, dev, Gavin Hu (Arm Technology China),
Dharmik Thakkar, nd, yipeng1.wang, sameh.gobriel
On 11/2/2018 5:38 PM, Honnappa Nagarahalli wrote:
>>
>> On Thu, Nov 01, 2018 at 06:25:18PM -0500, Honnappa Nagarahalli wrote:
>>> Various configuration flags in rte_hash library result in increase of
>>> number of test cases. Configuration flags for enabling transactional
>>> memory use and read/write concurrency are not required. These features
>>> should be supported by default. Please refer to [1] for more context.
>>>
>>> This patch marks these flags for deprecation in 19.02 release and
>>> cleans up the test cases.
>>>
>>> [1] http://mails.dpdk.org/archives/dev/2018-October/117268.html
>>>
>>> Honnappa Nagarahalli (4): hash: prepare for deprecation of flags hash:
>>> deprecate lock ellision and read/write concurreny flags test/hash:
>>> stop using lock ellision and read/write concurreny flags doc/hash:
>>> deprecate lock ellision and read/write concurreny flags
>>>
>> While I'd like to reduce the flags and do cleanup, I'm a little concerned about
>> putting this scope of changes in so late in the release. I wonder if less drastic
>> changes could work as well for this release, and do the cleanup later.
> Thank you Bruce for the review. This patch series is not fixing any user related problems, let us skip this for 18.11. It will give us time as well to think through and get this right.
There was no update in the scope of 19.02, I guess it will skip for 19.02 too.
Patchset updated as "Change requested" in patchwork.
>
>> For example, rather than deprecating the flags now, how about just change
>> the default for when no flags are set? If user has set flags, follow the existing
>> path - if flags is set to zero, then have the defaults be to use RW concurrency
>> or TSX.
> This changes the behavior of the library and what the flags mean, still requires ABI change, but does not need deprecation of flags (I guess this is what you meant). However, it will not solve the problem of losing the capability to disable TSX.
>
>>
>> /Bruce
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC 00/14] prefix network structures
@ 2018-12-20 21:59 3% ` Ferruh Yigit
2018-12-20 23:48 0% ` Stephen Hemminger
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-12-20 21:59 UTC (permalink / raw)
To: Olivier MATZ, dpdk-dev; +Cc: Stephen Hemminger, Keith Wiles, Bruce Richardson
On 10/24/2018 9:18 AM, olivier.matz at 6wind.com (Olivier Matz) wrote:
> This RFC targets 19.02.
>
> The rte_net headers conflict with the libc headers, because
> some definitions are duplicated, sometimes with few differences.
> This was discussed in [1], and more recently at the techboard.
>
> Before sending the deprecation notice (target for this is 18.11),
> here is a draft that can be discussed.
>
> This RFC adds the rte_ (or RTE_) prefix to all structures, functions
> and defines in rte_net library. This is a big changeset, that will
> break the API of many functions, but not the ABI.
>
> One question I'm asking is how can we manage the transition.
> Initially, I hoped it was possible to have a compat layer during
> one release (supporting both prefixed and unprefixed names), but
> now that the patch is done, it seems the impact is too big, and
> impacts too many libraries.
>
> Few examples:
> - rte_eth_macaddr_get/add/remove() use a (struct rte_ether_addr *)
> - many rte_flow structures use the rte_ prefixed net structures
> - the mac field of virtio_net structure is rte_ether_addr
> - the first arg of rte_thash_load_v6_addrs is (struct rte_ipv6_hdr *)
> ...
>
> Therefore, it is clear that doing this would break the compilation
> of many external applications.
>
> Another drawback we need to take in account: it will make the
> backport of patches more difficult, although this is something
> that could be tempered by a script.
>
> While it is obviously better to have a good namespace convention,
> we need to identify the issues we have today before deciding it's
> worth doing the change.
>
> Comments?
Is there an consensus about the patchset? There was a decision on techboard to
go with this change (adding rte_ prefix) [1].
This is something that will affect DPDK consumers. Since many APIs are changing
most probably will break API compatibility for many libraries.
Meanwhile the conflict with the libc headers mentioned a few times in the past,
this is something we need to fix.
There are a few comments reluctant to this big modification, but what I
understand from Olivier's response both using BSD defines or having
compatibility headers in DPDK won't solve the problem completely.
And assuming we will continue with this solution, another question is do we
still want to push in 19.02 scope? (And from process point of view I think a
deprecation notice is not merged for this change in 18.11 scope.)
With the prediction of 19.05 will be big and already break API/ABI for some
libraries, can we push this into 19.05 as an early merge into repo?
And I think this patch will affect LTS releases and will break auto backporting
for many fixes because it touches many places, so pushing this change even to
next LTS (19.11) can be an option.
Olivier, Thomas,
What do you think about postponing this to 19.05 or even 19.11 ?
[1]
https://mails.dpdk.org/archives/dev/2018-October/116695.html
>
>
> Things that are missing in RFC:
> - test with FreeBSD
> - manually fix some indentation issues
>
>
> Olivier Matz (14):
> net: add rte prefix to arp structures
> net: add rte prefix to arp defines
> net: add rte prefix to ether structures
> net: add rte prefix to ether functions
> net: add rte prefix to ether defines
> net: add rte prefix to esp structure
> net: add rte prefix to gre structure
> net: add rte prefix to icmp structure
> net: add rte prefix to icmp defines
> net: add rte prefix to ip structure
> net: add rte prefix to ip defines
> net: add rte prefix to sctp structure
> net: add rte prefix to tcp structure
> net: add rte prefix to udp structure
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC 00/14] prefix network structures
2018-12-20 21:59 3% ` Ferruh Yigit
@ 2018-12-20 23:48 0% ` Stephen Hemminger
2018-12-21 14:38 0% ` Wiles, Keith
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2018-12-20 23:48 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: Olivier MATZ, dpdk-dev, Keith Wiles, Bruce Richardson
On Thu, 20 Dec 2018 21:59:37 +0000
Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> On 10/24/2018 9:18 AM, olivier.matz at 6wind.com (Olivier Matz) wrote:
> > This RFC targets 19.02.
> >
> > The rte_net headers conflict with the libc headers, because
> > some definitions are duplicated, sometimes with few differences.
> > This was discussed in [1], and more recently at the techboard.
> >
> > Before sending the deprecation notice (target for this is 18.11),
> > here is a draft that can be discussed.
> >
> > This RFC adds the rte_ (or RTE_) prefix to all structures, functions
> > and defines in rte_net library. This is a big changeset, that will
> > break the API of many functions, but not the ABI.
> >
> > One question I'm asking is how can we manage the transition.
> > Initially, I hoped it was possible to have a compat layer during
> > one release (supporting both prefixed and unprefixed names), but
> > now that the patch is done, it seems the impact is too big, and
> > impacts too many libraries.
> >
> > Few examples:
> > - rte_eth_macaddr_get/add/remove() use a (struct rte_ether_addr *)
> > - many rte_flow structures use the rte_ prefixed net structures
> > - the mac field of virtio_net structure is rte_ether_addr
> > - the first arg of rte_thash_load_v6_addrs is (struct rte_ipv6_hdr *)
> > ...
> >
> > Therefore, it is clear that doing this would break the compilation
> > of many external applications.
> >
> > Another drawback we need to take in account: it will make the
> > backport of patches more difficult, although this is something
> > that could be tempered by a script.
> >
> > While it is obviously better to have a good namespace convention,
> > we need to identify the issues we have today before deciding it's
> > worth doing the change.
> >
> > Comments?
>
> Is there an consensus about the patchset? There was a decision on techboard to
> go with this change (adding rte_ prefix) [1].
>
>
> This is something that will affect DPDK consumers. Since many APIs are changing
> most probably will break API compatibility for many libraries.
>
> Meanwhile the conflict with the libc headers mentioned a few times in the past,
> this is something we need to fix.
>
> There are a few comments reluctant to this big modification, but what I
> understand from Olivier's response both using BSD defines or having
> compatibility headers in DPDK won't solve the problem completely.
>
> And assuming we will continue with this solution, another question is do we
> still want to push in 19.02 scope? (And from process point of view I think a
> deprecation notice is not merged for this change in 18.11 scope.)
>
> With the prediction of 19.05 will be big and already break API/ABI for some
> libraries, can we push this into 19.05 as an early merge into repo?
>
> And I think this patch will affect LTS releases and will break auto backporting
> for many fixes because it touches many places, so pushing this change even to
> next LTS (19.11) can be an option.
>
>
> Olivier, Thomas,
>
> What do you think about postponing this to 19.05 or even 19.11 ?
>
>
>
> [1]
> https://mails.dpdk.org/archives/dev/2018-October/116695.html
>
> >
> >
> > Things that are missing in RFC:
> > - test with FreeBSD
> > - manually fix some indentation issues
> >
> >
> > Olivier Matz (14):
> > net: add rte prefix to arp structures
> > net: add rte prefix to arp defines
> > net: add rte prefix to ether structures
> > net: add rte prefix to ether functions
> > net: add rte prefix to ether defines
> > net: add rte prefix to esp structure
> > net: add rte prefix to gre structure
> > net: add rte prefix to icmp structure
> > net: add rte prefix to icmp defines
> > net: add rte prefix to ip structure
> > net: add rte prefix to ip defines
> > net: add rte prefix to sctp structure
> > net: add rte prefix to tcp structure
> > net: add rte prefix to udp structure
>
>
Sigh. Another case where DPDK has to reinvent something because
we can't figure out how to do dependent libraries correctly.
I would have rather just using the existing Linux, BSD definitions
and fixing the DPDK code.
It is probably the only viable compromise, but it adds to long
term maintenance, and breaks DPDK applications. Neither of which
is a good thing.
Should this be done by marking the old structure deprecated
first? Ideally, spread over three releases: first, tell the users
in the documentation it is coming; second, mark the old structures
as deprecated causing compiler warnings; third, remove the old
definitions. Doing at once is introducing user pain for no gain.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-20 14:52 0% ` Hunt, David
@ 2018-12-21 0:30 0% ` Thomas Monjalon
2018-12-21 0:33 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-12-21 0:30 UTC (permalink / raw)
To: Hunt, David, Liang Ma; +Cc: dev, anatoly.burakov
20/12/2018 15:52, Hunt, David:
> On 19/12/2018 8:31 PM, Thomas Monjalon wrote:
> > 19/12/2018 10:09, Hunt, David:
> >> On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
> >>> 14/12/2018 14:11, Liang Ma:
> >>>> Previously, in order to use the power library, it was necessary
> >>>> for the user to disable the intel_pstate driver by adding
> >>>> “intel_pstate=disable” to the kernel command line for the system,
> >>>> which causes the acpi_cpufreq driver to be loaded in its place.
> >>>>
> >>>> This patch adds the ability for the power library use the intel-pstate
> >>>> driver.
> >>>>
> >>>> It adds a new suite of functions behind the current power library API,
> >>>> and will seamlessly set up the user facing API function pointers to
> >>>> the relevant functions depending on whether the system is running with
> >>>> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
> >>>> using kvm. The library API and ABI is unchanged.
> >>>>
> >>>> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> >>>>
> >>>> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
> >>>> ---
> >>> Please write a changelog when sending a new version.
> >>>
> >>> Dave, any comment on this patch?
> >>
> >> Looks good to me.
> >>
> >> Acked-by: David Hunt <david.hunt@intel.com>
> >>
> >>
> >>>> --- /dev/null
> >>>> +++ b/lib/librte_power/power_pstate_cpufreq.c
> >>>> @@ -0,0 +1,770 @@
> >>>> +/* SPDX-License-Identifier: BSD-3-Clause
> >>>> + * Copyright(c) 2018-2018 Intel Corporation
> >>> Something wrong here :)
> >> Yes, should simply be "Copyright(c) 2018 Intel Corporation"
> >
> > There is also a compilation error with meson:
> >
> > lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
> > rte_timer.h: No such file or directory
> >
> > Clearly, some quality checks are missing.
> >
> > I'm afraid we won't have any patch for power library in 19.02.
>
>
> Hi Thomas,
>
> We have just pushed a v4, and tested with make, meson/ninja, and several
> different build environments. I believe this version should be
> acceptable for 19.02.
I don't think so.
I will give more comments in v4 and will give up for 19.02.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] libs/power: add p-state driver compatibility
2018-12-21 0:30 0% ` Thomas Monjalon
@ 2018-12-21 0:33 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-12-21 0:33 UTC (permalink / raw)
To: Hunt, David, Liang Ma; +Cc: dev, anatoly.burakov
21/12/2018 01:30, Thomas Monjalon:
> 20/12/2018 15:52, Hunt, David:
> > On 19/12/2018 8:31 PM, Thomas Monjalon wrote:
> > > 19/12/2018 10:09, Hunt, David:
> > >> On 19/12/2018 3:18 AM, Thomas Monjalon wrote:
> > >>> 14/12/2018 14:11, Liang Ma:
> > >>>> Previously, in order to use the power library, it was necessary
> > >>>> for the user to disable the intel_pstate driver by adding
> > >>>> “intel_pstate=disable” to the kernel command line for the system,
> > >>>> which causes the acpi_cpufreq driver to be loaded in its place.
> > >>>>
> > >>>> This patch adds the ability for the power library use the intel-pstate
> > >>>> driver.
> > >>>>
> > >>>> It adds a new suite of functions behind the current power library API,
> > >>>> and will seamlessly set up the user facing API function pointers to
> > >>>> the relevant functions depending on whether the system is running with
> > >>>> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
> > >>>> using kvm. The library API and ABI is unchanged.
> > >>>>
> > >>>> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> > >>>>
> > >>>> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
> > >>>> ---
> > >>> Please write a changelog when sending a new version.
> > >>>
> > >>> Dave, any comment on this patch?
> > >>
> > >> Looks good to me.
> > >>
> > >> Acked-by: David Hunt <david.hunt@intel.com>
> > >>
> > >>
> > >>>> --- /dev/null
> > >>>> +++ b/lib/librte_power/power_pstate_cpufreq.c
> > >>>> @@ -0,0 +1,770 @@
> > >>>> +/* SPDX-License-Identifier: BSD-3-Clause
> > >>>> + * Copyright(c) 2018-2018 Intel Corporation
> > >>> Something wrong here :)
> > >> Yes, should simply be "Copyright(c) 2018 Intel Corporation"
> > >
> > > There is also a compilation error with meson:
> > >
> > > lib/librte_power/rte_power_empty_poll.h:20:10: fatal error:
> > > rte_timer.h: No such file or directory
> > >
> > > Clearly, some quality checks are missing.
> > >
> > > I'm afraid we won't have any patch for power library in 19.02.
> >
> >
> > Hi Thomas,
> >
> > We have just pushed a v4, and tested with make, meson/ninja, and several
> > different build environments. I believe this version should be
> > acceptable for 19.02.
>
> I don't think so.
> I will give more comments in v4 and will give up for 19.02.
Sorry I looked at the wrong things.
The v4 looks OK.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4] libs/power: add p-state driver compatibility
2018-12-20 14:43 1% ` [dpdk-dev] [PATCH v4] " Liang Ma
@ 2018-12-21 0:34 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-12-21 0:34 UTC (permalink / raw)
To: Liang Ma; +Cc: dev, david.hunt, anatoly.burakov
20/12/2018 15:43, Liang Ma:
> Previously, in order to use the power library, it was necessary
> for the user to disable the intel_pstate driver by adding
> “intel_pstate=disable” to the kernel command line for the system,
> which causes the acpi_cpufreq driver to be loaded in its place.
>
> This patch adds the ability for the power library use the intel-pstate
> driver.
>
> It adds a new suite of functions behind the current power library API,
> and will seamlessly set up the user facing API function pointers to
> the relevant functions depending on whether the system is running with
> acpi_cpufreq kernel driver, intel_pstate kernel driver or in a guest,
> using kvm. The library API and ABI is unchanged.
>
> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
> Acked-by: David Hunt <david.hunt@intel.com>
Applied, thanks
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 18.11] malloc: fix deadlock when using malloc stats
2018-12-04 12:22 4% [dpdk-dev] [PATCH 18.11] malloc: fix deadlock when using malloc stats Anatoly Burakov
@ 2018-12-21 12:09 0% ` Thomas Monjalon
2018-12-21 12:12 0% ` Burakov, Anatoly
2018-12-21 12:26 4% ` [dpdk-dev] [PATCH 19.02 v2] " Anatoly Burakov
1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-12-21 12:09 UTC (permalink / raw)
To: Anatoly Burakov
Cc: dev, stable, ferruh.yigit, bruce.richardson, arybchenko, olivier.matz
04/12/2018 13:22, Anatoly Burakov:
> Currently, malloc statistics and external heap creation code
> use memory hotplug lock as a way to synchronize accesses to
> heaps (as in, locking the hotplug lock to prevent list of heaps
> from changing under our feet). At the same time, malloc
> statistics code will also lock the heap because it needs to
> access heap data and does not want any other thread to allocate
> anything from that heap.
>
> In such scheme, it is possible to enter a deadlock with the
> following sequence of events:
>
> thread 1 thread 2
> rte_malloc()
> rte_malloc_dump_stats()
> take heap lock
> take hotplug lock
> failed to allocate,
> attempt to take
> hotplug lock
> attempt to take heap lock
>
> Neither thread will be able to continue, as both of them are
> waiting for the other one to drop the lock. Adding an
> additional lock will require an ABI change, so instead of
> that, make malloc statistics calls thread-unsafe with
> respect to creating/destroying heaps.
>
> Fixes: 72cf92b31855 ("malloc: index heaps using heap ID rather than NUMA node")
> Cc: stable@dpdk.org
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
>
> Notes:
> IMO this is the best we can do for 18.11 without breaking ABI.
> For 19.02, we can introduce a new global heap lock (something
> i should've done in the first place...), so this patch is
> not applicable to 19.02. For 19.02, we can fix this properly
> by introducing another lock and breaking the EAL ABI.
>
> Not sure where to put docs update, feedback welcome.
This patch is also changing the API, because functions become not thread-safe.
I think you should note it in the release notes.
About 19.02, do we want to take this patch (with release notes updated)?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 18.11] malloc: fix deadlock when using malloc stats
2018-12-21 12:09 0% ` Thomas Monjalon
@ 2018-12-21 12:12 0% ` Burakov, Anatoly
0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2018-12-21 12:12 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, stable, ferruh.yigit, bruce.richardson, arybchenko, olivier.matz
On 21-Dec-18 12:09 PM, Thomas Monjalon wrote:
> 04/12/2018 13:22, Anatoly Burakov:
>> Currently, malloc statistics and external heap creation code
>> use memory hotplug lock as a way to synchronize accesses to
>> heaps (as in, locking the hotplug lock to prevent list of heaps
>> from changing under our feet). At the same time, malloc
>> statistics code will also lock the heap because it needs to
>> access heap data and does not want any other thread to allocate
>> anything from that heap.
>>
>> In such scheme, it is possible to enter a deadlock with the
>> following sequence of events:
>>
>> thread 1 thread 2
>> rte_malloc()
>> rte_malloc_dump_stats()
>> take heap lock
>> take hotplug lock
>> failed to allocate,
>> attempt to take
>> hotplug lock
>> attempt to take heap lock
>>
>> Neither thread will be able to continue, as both of them are
>> waiting for the other one to drop the lock. Adding an
>> additional lock will require an ABI change, so instead of
>> that, make malloc statistics calls thread-unsafe with
>> respect to creating/destroying heaps.
>>
>> Fixes: 72cf92b31855 ("malloc: index heaps using heap ID rather than NUMA node")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
>> ---
>>
>> Notes:
>> IMO this is the best we can do for 18.11 without breaking ABI.
>> For 19.02, we can introduce a new global heap lock (something
>> i should've done in the first place...), so this patch is
>> not applicable to 19.02. For 19.02, we can fix this properly
>> by introducing another lock and breaking the EAL ABI.
>>
>> Not sure where to put docs update, feedback welcome.
>
> This patch is also changing the API, because functions become not thread-safe.
> I think you should note it in the release notes.
> About 19.02, do we want to take this patch (with release notes updated)?
>
Yes and yes.
Technically, they still are thread-safe when it comes to individual heap
access - they just aren't thread-safe with regards to
creating/destroying heaps (so, we may enter the dump function, and a
heap may be added/removed while we're iterating over the list of heaps).
I'll send a v2 with release notes update.
--
Thanks,
Anatoly
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH 19.02 v2] malloc: fix deadlock when using malloc stats
2018-12-04 12:22 4% [dpdk-dev] [PATCH 18.11] malloc: fix deadlock when using malloc stats Anatoly Burakov
2018-12-21 12:09 0% ` Thomas Monjalon
@ 2018-12-21 12:26 4% ` Anatoly Burakov
2018-12-21 13:35 0% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Anatoly Burakov @ 2018-12-21 12:26 UTC (permalink / raw)
To: dev; +Cc: John McNamara, Marko Kovacevic, thomas, stable
Currently, malloc statistics and external heap creation code
use memory hotplug lock as a way to synchronize accesses to
heaps (as in, locking the hotplug lock to prevent list of heaps
from changing under our feet). At the same time, malloc
statistics code will also lock the heap because it needs to
access heap data and does not want any other thread to allocate
anything from that heap.
In such scheme, it is possible to enter a deadlock with the
following sequence of events:
thread 1 thread 2
rte_malloc()
rte_malloc_dump_stats()
take heap lock
take hotplug lock
failed to allocate,
attempt to take
hotplug lock
attempt to take heap lock
Neither thread will be able to continue, as both of them are
waiting for the other one to drop the lock. Adding an
additional lock will require an ABI change, so instead of
that, make malloc statistics calls thread-unsafe with
respect to creating/destroying heaps.
Fixes: 72cf92b31855 ("malloc: index heaps using heap ID rather than NUMA node")
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
This is the best we can do for 19.02 without breaking ABI.
doc/guides/rel_notes/release_19_02.rst | 4 ++++
lib/librte_eal/common/include/rte_malloc.h | 9 +++++++++
lib/librte_eal/common/rte_malloc.c | 19 +++----------------
3 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 47768288a..0b248d55d 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -126,6 +126,10 @@ API Changes
- In cases where memfd support would have been required to provide segment
fd's (such as in-memory or no-huge mode)
+* eal: Functions ``rte_malloc_dump_stats()``, ``rte_malloc_dump_heaps()`` and
+ ``rte_malloc_get_socket_stats()`` are no longer safe to call concurrently with
+ ``rte_malloc_heap_create()`` or ``rte_malloc_heap_destroy()`` function calls.
+
* pdump: The ``rte_pdump_set_socket_dir()``, the parameter ``path`` of
``rte_pdump_init()`` and enum ``rte_pdump_socktype`` were deprecated
since 18.05 and are removed in this release.
diff --git a/lib/librte_eal/common/include/rte_malloc.h b/lib/librte_eal/common/include/rte_malloc.h
index a5290b074..54a12467a 100644
--- a/lib/librte_eal/common/include/rte_malloc.h
+++ b/lib/librte_eal/common/include/rte_malloc.h
@@ -251,6 +251,9 @@ rte_malloc_validate(const void *ptr, size_t *size);
/**
* Get heap statistics for the specified heap.
*
+ * @note This function is not thread-safe with respect to
+ * ``rte_malloc_heap_create()``/``rte_malloc_heap_destroy()`` functions.
+ *
* @param socket
* An unsigned integer specifying the socket to get heap statistics for
* @param socket_stats
@@ -461,6 +464,9 @@ rte_malloc_heap_socket_is_external(int socket_id);
* Dump for the specified type to a file. If the type argument is
* NULL, all memory types will be dumped.
*
+ * @note This function is not thread-safe with respect to
+ * ``rte_malloc_heap_create()``/``rte_malloc_heap_destroy()`` functions.
+ *
* @param f
* A pointer to a file for output
* @param type
@@ -473,6 +479,9 @@ rte_malloc_dump_stats(FILE *f, const char *type);
/**
* Dump contents of all malloc heaps to a file.
*
+ * @note This function is not thread-safe with respect to
+ * ``rte_malloc_heap_create()``/``rte_malloc_heap_destroy()`` functions.
+ *
* @param f
* A pointer to a file for output
*/
diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c
index 09051c236..b39de3c99 100644
--- a/lib/librte_eal/common/rte_malloc.c
+++ b/lib/librte_eal/common/rte_malloc.c
@@ -156,20 +156,14 @@ rte_malloc_get_socket_stats(int socket,
struct rte_malloc_socket_stats *socket_stats)
{
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
- int heap_idx, ret = -1;
-
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
+ int heap_idx;
heap_idx = malloc_socket_to_heap_id(socket);
if (heap_idx < 0)
- goto unlock;
+ return -1;
- ret = malloc_heap_get_stats(&mcfg->malloc_heaps[heap_idx],
+ return malloc_heap_get_stats(&mcfg->malloc_heaps[heap_idx],
socket_stats);
-unlock:
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
-
- return ret;
}
/*
@@ -181,14 +175,10 @@ rte_malloc_dump_heaps(FILE *f)
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
unsigned int idx;
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
-
for (idx = 0; idx < RTE_MAX_HEAPS; idx++) {
fprintf(f, "Heap id: %u\n", idx);
malloc_heap_dump(&mcfg->malloc_heaps[idx], f);
}
-
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
}
int
@@ -262,8 +252,6 @@ rte_malloc_dump_stats(FILE *f, __rte_unused const char *type)
unsigned int heap_id;
struct rte_malloc_socket_stats sock_stats;
- rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
-
/* Iterate through all initialised heaps */
for (heap_id = 0; heap_id < RTE_MAX_HEAPS; heap_id++) {
struct malloc_heap *heap = &mcfg->malloc_heaps[heap_id];
@@ -280,7 +268,6 @@ rte_malloc_dump_stats(FILE *f, __rte_unused const char *type)
fprintf(f, "\tAlloc_count:%u,\n",sock_stats.alloc_count);
fprintf(f, "\tFree_count:%u,\n", sock_stats.free_count);
}
- rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
return;
}
--
2.17.1
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v4 00/10] ipsec: new library for IPsec data-path processing
2018-12-14 16:29 2% ` [dpdk-dev] [PATCH v4 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
@ 2018-12-21 13:32 0% ` Akhil Goyal
0 siblings, 0 replies; 200+ results
From: Akhil Goyal @ 2018-12-21 13:32 UTC (permalink / raw)
To: Konstantin Ananyev, dev; +Cc: Thomas Monjalon
Hi Konstantin,
I am done with the review, will be running the code in early next week
after I finish the review of changes in ipsec application.
key points for review were
- some code may be generic and can be moved in appropriate files
- documentation update
- spell checks spacing etc.
- some cases like cipher only need to be looked appropriately
- test cases for lookaside and inline proto
- checksum/ttl update
With these comments we cannot make this to RC1, but RC2 can be looked upon.
Thanks,
Akhil
On 12/14/2018 9:59 PM, Konstantin Ananyev wrote:
> This patch series depends on the patch:
> http://patches.dpdk.org/patch/48044/
> to be applied first.
>
> v3 -> v4
> - Changes to adress Declan comments
> - Update docs
>
> v2 -> v3
> - Several fixes for IPv6 support
> - Extra checks for input parameters in public APi functions
>
> v1 -> v2
> - Changes to get into account l2_len for outbound transport packets
> (Qi comments)
> - Several bug fixes
> - Some code restructured
> - Update MAINTAINERS file
>
> RFCv2 -> v1
> - Changes per Jerin comments
> - Implement transport mode
> - Several bug fixes
> - UT largely reworked and extended
>
> This patch introduces a new library within DPDK: librte_ipsec.
> The aim is to provide DPDK native high performance library for IPsec
> data-path processing.
> The library is supposed to utilize existing DPDK crypto-dev and
> security API to provide application with transparent IPsec
> processing API.
> The library is concentrated on data-path protocols processing
> (ESP and AH), IKE protocol(s) implementation is out of scope
> for that library.
> Current patch introduces SA-level API.
>
> SA (low) level API
> ==================
>
> API described below operates on SA level.
> It provides functionality that allows user for given SA to process
> inbound and outbound IPsec packets.
> To be more specific:
> - for inbound ESP/AH packets perform decryption, authentication,
> integrity checking, remove ESP/AH related headers
> - for outbound packets perform payload encryption, attach ICV,
> update/add IP headers, add ESP/AH headers/trailers,
> setup related mbuf felids (ol_flags, tx_offloads, etc.).
> - initialize/un-initialize given SA based on user provided parameters.
>
> The following functionality:
> - match inbound/outbound packets to particular SA
> - manage crypto/security devices
> - provide SAD/SPD related functionality
> - determine what crypto/security device has to be used
> for given packet(s)
> is out of scope for SA-level API.
>
> SA-level API is based on top of crypto-dev/security API and relies on
> them
> to perform actual cipher and integrity checking.
> To have an ability to easily map crypto/security sessions into related
> IPSec SA opaque userdata field was added into
> rte_cryptodev_sym_session and rte_security_session structures.
> That implies ABI change for both librte_crytpodev and librte_security.
>
> Due to the nature of crypto-dev API (enqueue/deque model) we use
> asynchronous API for IPsec packets destined to be processed
> by crypto-device.
> Expected API call sequence would be:
> /* enqueue for processing by crypto-device */
> rte_ipsec_pkt_crypto_prepare(...);
> rte_cryptodev_enqueue_burst(...);
> /* dequeue from crypto-device and do final processing (if any) */
> rte_cryptodev_dequeue_burst(...);
> rte_ipsec_pkt_crypto_group(...); /* optional */
> rte_ipsec_pkt_process(...);
>
> Though for packets destined for inline processing no extra overhead
> is required and synchronous API call: rte_ipsec_pkt_process()
> is sufficient for that case.
>
> Current implementation supports all four currently defined
> rte_security types.
> Though to accommodate future custom implementations function pointers
> model is used for both for *crypto_prepare* and *process*
> impelementations.
>
> Konstantin Ananyev (10):
> cryptodev: add opaque userdata pointer into crypto sym session
> security: add opaque userdata pointer into security session
> net: add ESP trailer structure definition
> lib: introduce ipsec library
> ipsec: add SA data-path API
> ipsec: implement SA data-path API
> ipsec: rework SA replay window/SQN for MT environment
> ipsec: helper functions to group completed crypto-ops
> test/ipsec: introduce functional test
> doc: add IPsec library guide
>
> MAINTAINERS | 5 +
> config/common_base | 5 +
> doc/guides/prog_guide/index.rst | 1 +
> doc/guides/prog_guide/ipsec_lib.rst | 74 +
> doc/guides/rel_notes/release_19_02.rst | 10 +
> lib/Makefile | 2 +
> lib/librte_cryptodev/rte_cryptodev.h | 2 +
> lib/librte_ipsec/Makefile | 27 +
> lib/librte_ipsec/crypto.h | 123 ++
> lib/librte_ipsec/iph.h | 84 +
> lib/librte_ipsec/ipsec_sqn.h | 343 ++++
> lib/librte_ipsec/meson.build | 10 +
> lib/librte_ipsec/pad.h | 45 +
> lib/librte_ipsec/rte_ipsec.h | 153 ++
> lib/librte_ipsec/rte_ipsec_group.h | 151 ++
> lib/librte_ipsec/rte_ipsec_sa.h | 172 ++
> lib/librte_ipsec/rte_ipsec_version.map | 15 +
> lib/librte_ipsec/sa.c | 1407 +++++++++++++++
> lib/librte_ipsec/sa.h | 98 ++
> lib/librte_ipsec/ses.c | 45 +
> lib/librte_net/rte_esp.h | 10 +-
> lib/librte_security/rte_security.h | 2 +
> lib/meson.build | 2 +
> mk/rte.app.mk | 2 +
> test/test/Makefile | 3 +
> test/test/meson.build | 3 +
> test/test/test_ipsec.c | 2209 ++++++++++++++++++++++++
> 27 files changed, 5002 insertions(+), 1 deletion(-)
> create mode 100644 doc/guides/prog_guide/ipsec_lib.rst
> create mode 100644 lib/librte_ipsec/Makefile
> create mode 100644 lib/librte_ipsec/crypto.h
> create mode 100644 lib/librte_ipsec/iph.h
> create mode 100644 lib/librte_ipsec/ipsec_sqn.h
> create mode 100644 lib/librte_ipsec/meson.build
> create mode 100644 lib/librte_ipsec/pad.h
> create mode 100644 lib/librte_ipsec/rte_ipsec.h
> create mode 100644 lib/librte_ipsec/rte_ipsec_group.h
> create mode 100644 lib/librte_ipsec/rte_ipsec_sa.h
> create mode 100644 lib/librte_ipsec/rte_ipsec_version.map
> create mode 100644 lib/librte_ipsec/sa.c
> create mode 100644 lib/librte_ipsec/sa.h
> create mode 100644 lib/librte_ipsec/ses.c
> create mode 100644 test/test/test_ipsec.c
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 19.02 v2] malloc: fix deadlock when using malloc stats
2018-12-21 12:26 4% ` [dpdk-dev] [PATCH 19.02 v2] " Anatoly Burakov
@ 2018-12-21 13:35 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-12-21 13:35 UTC (permalink / raw)
To: Anatoly Burakov; +Cc: dev, John McNamara, Marko Kovacevic, stable
21/12/2018 13:26, Anatoly Burakov:
> Currently, malloc statistics and external heap creation code
> use memory hotplug lock as a way to synchronize accesses to
> heaps (as in, locking the hotplug lock to prevent list of heaps
> from changing under our feet). At the same time, malloc
> statistics code will also lock the heap because it needs to
> access heap data and does not want any other thread to allocate
> anything from that heap.
>
> In such scheme, it is possible to enter a deadlock with the
> following sequence of events:
>
> thread 1 thread 2
> rte_malloc()
> rte_malloc_dump_stats()
> take heap lock
> take hotplug lock
> failed to allocate,
> attempt to take
> hotplug lock
> attempt to take heap lock
>
> Neither thread will be able to continue, as both of them are
> waiting for the other one to drop the lock. Adding an
> additional lock will require an ABI change, so instead of
> that, make malloc statistics calls thread-unsafe with
> respect to creating/destroying heaps.
>
> Fixes: 72cf92b31855 ("malloc: index heaps using heap ID rather than NUMA node")
> Cc: stable@dpdk.org
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
>
> Notes:
> This is the best we can do for 19.02 without breaking ABI.
Applied, thanks
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3 1/2] cryptodev: change queue pair configure structure
@ 2018-12-21 13:55 1% ` Fan Zhang
2019-01-08 23:20 3% ` De Lara Guarch, Pablo
2018-12-21 13:55 1% ` [dpdk-dev] [PATCH v3 2/2] cryptodev: change symmetric session structure Fan Zhang
2 siblings, 1 reply; 200+ results
From: Fan Zhang @ 2018-12-21 13:55 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, fiona.trahe
This patch changes the cryptodev queue pair configure structure
to enable two mempool passed into cryptodev PMD simutaneously.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@@intel.com>
---
app/test-crypto-perf/main.c | 6 ++--
doc/guides/rel_notes/release_19_02.rst | 5 +++
drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 7 ++--
drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c | 5 +--
drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h | 2 ++
drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 7 ++--
drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c | 5 +--
drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h | 2 ++
drivers/crypto/armv8/rte_armv8_pmd.c | 7 ++--
drivers/crypto/armv8/rte_armv8_pmd_ops.c | 5 +--
drivers/crypto/armv8/rte_armv8_pmd_private.h | 2 ++
drivers/crypto/caam_jr/caam_jr.c | 3 +-
drivers/crypto/ccp/ccp_pmd_ops.c | 5 +--
drivers/crypto/ccp/ccp_pmd_private.h | 2 ++
drivers/crypto/ccp/rte_ccp_pmd.c | 9 +++++-
drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c | 3 +-
drivers/crypto/dpaa_sec/dpaa_sec.c | 3 +-
drivers/crypto/kasumi/rte_kasumi_pmd.c | 7 ++--
drivers/crypto/kasumi/rte_kasumi_pmd_ops.c | 5 +--
drivers/crypto/kasumi/rte_kasumi_pmd_private.h | 2 ++
drivers/crypto/mvsam/rte_mrvl_pmd_ops.c | 5 +--
drivers/crypto/mvsam/rte_mrvl_pmd_private.h | 3 ++
drivers/crypto/null/null_crypto_pmd.c | 5 +--
drivers/crypto/null/null_crypto_pmd_ops.c | 5 +--
drivers/crypto/null/null_crypto_pmd_private.h | 2 ++
drivers/crypto/octeontx/otx_cryptodev_ops.c | 3 +-
drivers/crypto/openssl/rte_openssl_pmd.c | 7 ++--
drivers/crypto/openssl/rte_openssl_pmd_ops.c | 5 +--
drivers/crypto/openssl/rte_openssl_pmd_private.h | 2 ++
drivers/crypto/qat/qat_sym_pmd.c | 2 +-
drivers/crypto/scheduler/scheduler_pmd_ops.c | 5 ++-
drivers/crypto/snow3g/rte_snow3g_pmd.c | 7 ++--
drivers/crypto/snow3g/rte_snow3g_pmd_ops.c | 5 +--
drivers/crypto/snow3g/rte_snow3g_pmd_private.h | 2 ++
drivers/crypto/virtio/virtio_cryptodev.c | 6 ++--
drivers/crypto/zuc/rte_zuc_pmd.c | 7 ++--
drivers/crypto/zuc/rte_zuc_pmd_ops.c | 5 +--
drivers/crypto/zuc/rte_zuc_pmd_private.h | 2 ++
drivers/net/softnic/rte_eth_softnic_cryptodev.c | 2 +-
examples/fips_validation/main.c | 4 +--
examples/ip_pipeline/cryptodev.c | 2 +-
examples/ipsec-secgw/ipsec-secgw.c | 7 ++--
examples/l2fwd-crypto/main.c | 4 ++-
examples/vhost_crypto/main.c | 9 ++++--
lib/librte_cryptodev/rte_cryptodev.c | 5 ++-
lib/librte_cryptodev/rte_cryptodev.h | 7 ++--
lib/librte_cryptodev/rte_cryptodev_pmd.h | 3 +-
test/test/test_cryptodev.c | 37 +++++++++-------------
test/test/test_cryptodev_asym.c | 8 ++---
test/test/test_event_crypto_adapter.c | 5 +--
50 files changed, 156 insertions(+), 107 deletions(-)
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 953e058c9..38a2e429f 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -218,6 +218,9 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
session_pool_socket[socket_id] = sess_mp;
}
+ qp_conf.mp_session = session_pool_socket[socket_id];
+ qp_conf.mp_session_private = session_pool_socket[socket_id];
+
ret = rte_cryptodev_configure(cdev_id, &conf);
if (ret < 0) {
printf("Failed to configure cryptodev %u", cdev_id);
@@ -226,8 +229,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
for (j = 0; j < opts->nb_qps; j++) {
ret = rte_cryptodev_queue_pair_setup(cdev_id, j,
- &qp_conf, socket_id,
- session_pool_socket[socket_id]);
+ &qp_conf, socket_id);
if (ret < 0) {
printf("Failed to setup queue pair %u on "
"cryptodev %u", j, cdev_id);
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 47768288a..4420c2441 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -130,6 +130,11 @@ API Changes
``rte_pdump_init()`` and enum ``rte_pdump_socktype`` were deprecated
since 18.05 and are removed in this release.
+* cryptodev: as shown in the the 18.08 deprecation notice, the structure
+ ``rte_cryptodev_qp_conf`` has been added two parameters of symmetric session
+ mempool and symmetric session private data mempool, and the last parameter of
+ ``rte_cryptodev_queue_pair_setup()`` is removed.
+
ABI Changes
-----------
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index ebdf7c35a..abc7a6d5f 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -151,7 +151,8 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct aesni_gcm_session *)_sess_private_data;
@@ -159,7 +160,7 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_op *op)
if (unlikely(aesni_gcm_set_session_parameters(qp->ops,
sess, sym_op->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
sym_op->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -419,7 +420,7 @@ handle_completed_gcm_crypto_op(struct aesni_gcm_qp *qp,
memset(sess, 0, sizeof(struct aesni_gcm_session));
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sess);
+ rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
index c343a393f..2f70f2a1a 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
@@ -201,7 +201,7 @@ aesni_gcm_pmd_qp_create_processed_pkts_ring(struct aesni_gcm_qp *qp,
static int
aesni_gcm_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct aesni_gcm_qp *qp = NULL;
struct aesni_gcm_private *internals = dev->data->dev_private;
@@ -229,7 +229,8 @@ aesni_gcm_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_pkts == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
index 92b041354..903e7503d 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
@@ -48,6 +48,8 @@ struct aesni_gcm_qp {
/**< Queue pair statistics */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
uint16_t id;
/**< Queue Pair Identifier */
char name[RTE_CRYPTODEV_NAME_MAX_LEN];
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index 83250e32c..b0f5c4d67 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -668,7 +668,8 @@ get_session(struct aesni_mb_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct aesni_mb_session *)_sess_private_data;
@@ -676,7 +677,7 @@ get_session(struct aesni_mb_qp *qp, struct rte_crypto_op *op)
if (unlikely(aesni_mb_set_session_parameters(qp->op_fns,
sess, op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -951,7 +952,7 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job)
memset(sess, 0, sizeof(struct aesni_mb_session));
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sess);
+ rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
index f3eff2685..af3021616 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
@@ -566,7 +566,7 @@ aesni_mb_pmd_qp_create_processed_ops_ring(struct aesni_mb_qp *qp,
static int
aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct aesni_mb_qp *qp = NULL;
struct aesni_mb_private *internals = dev->data->dev_private;
@@ -604,7 +604,8 @@ aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
goto qp_setup_cleanup;
}
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
index d8021cdaa..923403336 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
@@ -131,6 +131,8 @@ struct aesni_mb_qp {
/**< Ring for placing operations ready for processing */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats stats;
/**< Queue pair statistics */
uint8_t digest_idx;
diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
index 9d15fee53..3b2d7fb2f 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd.c
@@ -514,7 +514,8 @@ get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct armv8_crypto_session *)_sess_private_data;
@@ -522,7 +523,7 @@ get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op)
if (unlikely(armv8_crypto_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -656,7 +657,7 @@ process_op(struct armv8_crypto_qp *qp, struct rte_crypto_op *op,
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
rte_mempool_put(qp->sess_mp, sess);
- rte_mempool_put(qp->sess_mp, op->sym->session);
+ rte_mempool_put(qp->sess_mp_priv, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
index ae03117ea..a4fee83a8 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
@@ -220,7 +220,7 @@ armv8_crypto_pmd_qp_create_processed_ops_ring(struct armv8_crypto_qp *qp,
static int
armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct armv8_crypto_qp *qp = NULL;
@@ -245,7 +245,8 @@ armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_private.h b/drivers/crypto/armv8/rte_armv8_pmd_private.h
index 7feb021db..0afd9c7c5 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_private.h
+++ b/drivers/crypto/armv8/rte_armv8_pmd_private.h
@@ -116,6 +116,8 @@ struct armv8_crypto_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats stats;
/**< Queue pair statistics */
char name[RTE_CRYPTODEV_NAME_MAX_LEN];
diff --git a/drivers/crypto/caam_jr/caam_jr.c b/drivers/crypto/caam_jr/caam_jr.c
index f505adf6b..45b281331 100644
--- a/drivers/crypto/caam_jr/caam_jr.c
+++ b/drivers/crypto/caam_jr/caam_jr.c
@@ -1540,8 +1540,7 @@ static int
caam_jr_queue_pair_setup(
struct rte_cryptodev *dev, uint16_t qp_id,
__rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
- __rte_unused int socket_id,
- __rte_unused struct rte_mempool *session_pool)
+ __rte_unused int socket_id)
{
struct sec_job_ring_t *internals;
struct caam_jr_qp *qp = NULL;
diff --git a/drivers/crypto/ccp/ccp_pmd_ops.c b/drivers/crypto/ccp/ccp_pmd_ops.c
index 6984913f1..d5041f0ec 100644
--- a/drivers/crypto/ccp/ccp_pmd_ops.c
+++ b/drivers/crypto/ccp/ccp_pmd_ops.c
@@ -685,7 +685,7 @@ ccp_pmd_qp_create_batch_info_ring(struct ccp_qp *qp,
static int
ccp_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct ccp_private *internals = dev->data->dev_private;
struct ccp_qp *qp;
@@ -726,7 +726,8 @@ ccp_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
goto qp_setup_cleanup;
}
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
/* mempool for batch info */
qp->batch_mp = rte_mempool_create(
diff --git a/drivers/crypto/ccp/ccp_pmd_private.h b/drivers/crypto/ccp/ccp_pmd_private.h
index 79752f687..7f2979e89 100644
--- a/drivers/crypto/ccp/ccp_pmd_private.h
+++ b/drivers/crypto/ccp/ccp_pmd_private.h
@@ -76,6 +76,8 @@ struct ccp_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_mempool *batch_mp;
/**< Session Mempool for batch info */
struct rte_cryptodev_stats qp_stats;
diff --git a/drivers/crypto/ccp/rte_ccp_pmd.c b/drivers/crypto/ccp/rte_ccp_pmd.c
index 92d8a9559..b4bb5528f 100644
--- a/drivers/crypto/ccp/rte_ccp_pmd.c
+++ b/drivers/crypto/ccp/rte_ccp_pmd.c
@@ -179,7 +179,7 @@ get_ccp_session(struct ccp_qp *qp, struct rte_crypto_op *op)
if (unlikely(ccp_set_session_parameters(sess, op->sym->xform,
internals) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -241,6 +241,13 @@ ccp_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
for (i = 0; i < nb_dequeued; i++)
if (unlikely(ops[i]->sess_type ==
RTE_CRYPTO_OP_SESSIONLESS)) {
+ struct ccp_session *sess = (struct ccp_session *)
+ get_sym_session_private_data(
+ ops[i]->sym->session,
+ ccp_cryptodev_driver_id);
+
+ rte_mempool_put(qp->sess_mp_priv,
+ sess);
rte_mempool_put(qp->sess_mp,
ops[i]->sym->session);
ops[i]->sym->session = NULL;
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 6095c6021..82220ac4f 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -1518,8 +1518,7 @@ dpaa2_sec_queue_pair_release(struct rte_cryptodev *dev, uint16_t queue_pair_id)
static int
dpaa2_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
__rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
- __rte_unused int socket_id,
- __rte_unused struct rte_mempool *session_pool)
+ __rte_unused int socket_id)
{
struct dpaa2_sec_dev_private *priv = dev->data->dev_private;
struct dpaa2_sec_qp *qp;
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index d83e74541..c95e43b7f 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -1661,8 +1661,7 @@ dpaa_sec_queue_pair_release(struct rte_cryptodev *dev,
static int
dpaa_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
__rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
- __rte_unused int socket_id,
- __rte_unused struct rte_mempool *session_pool)
+ __rte_unused int socket_id)
{
struct dpaa_sec_dev_private *internals;
struct dpaa_sec_qp *qp = NULL;
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index 239a1cf44..6df645a23 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -145,7 +145,8 @@ kasumi_get_session(struct kasumi_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct kasumi_session *)_sess_private_data;
@@ -153,7 +154,7 @@ kasumi_get_session(struct kasumi_qp *qp, struct rte_crypto_op *op)
if (unlikely(kasumi_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -325,7 +326,7 @@ process_ops(struct rte_crypto_op **ops, struct kasumi_session *session,
memset(session, 0, sizeof(struct kasumi_session));
memset(ops[i]->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, session);
+ rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
}
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
index 9e4bf1b52..a4982f091 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
@@ -192,7 +192,7 @@ kasumi_pmd_qp_create_processed_ops_ring(struct kasumi_qp *qp,
static int
kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct kasumi_qp *qp = NULL;
@@ -217,7 +217,8 @@ kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
index 488777ca8..76f746c03 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
@@ -36,6 +36,8 @@ struct kasumi_qp {
/**< Ring for placing processed ops */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
uint8_t temp_digest[KASUMI_DIGEST_LENGTH];
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
index 9956f051f..ef520356f 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
@@ -633,7 +633,7 @@ mrvl_crypto_pmd_close(struct rte_cryptodev *dev)
static int
mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct mrvl_crypto_qp *qp = NULL;
char match[RTE_CRYPTODEV_NAME_MAX_LEN];
@@ -690,7 +690,8 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (sam_cio_init(&qp->cio_params, &qp->cio) < 0)
break;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
dev->data->queue_pairs[qp_id] = qp;
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
index 6f8cf5624..deb80c55d 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
@@ -51,6 +51,9 @@ struct mrvl_crypto_qp {
/** Session Mempool. */
struct rte_mempool *sess_mp;
+ /** Session Private Data Mempool. */
+ struct rte_mempool *sess_mp_priv;
+
/** Queue pair statistics. */
struct rte_cryptodev_stats stats;
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index 6e29a21a6..d5e3064f2 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -87,7 +87,8 @@ get_session(struct null_crypto_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct null_crypto_session *)_sess_private_data;
@@ -95,7 +96,7 @@ get_session(struct null_crypto_qp *qp, struct rte_crypto_op *op)
if (unlikely(null_crypto_set_session_parameters(sess,
sym_op->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
sym_op->session = (struct rte_cryptodev_sym_session *)_sess;
diff --git a/drivers/crypto/null/null_crypto_pmd_ops.c b/drivers/crypto/null/null_crypto_pmd_ops.c
index 2bdcd019e..941d62bed 100644
--- a/drivers/crypto/null/null_crypto_pmd_ops.c
+++ b/drivers/crypto/null/null_crypto_pmd_ops.c
@@ -184,7 +184,7 @@ null_crypto_pmd_qp_create_processed_pkts_ring(struct null_crypto_qp *qp,
static int
null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct null_crypto_private *internals = dev->data->dev_private;
struct null_crypto_qp *qp;
@@ -228,7 +228,8 @@ null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
goto qp_setup_cleanup;
}
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/null/null_crypto_pmd_private.h b/drivers/crypto/null/null_crypto_pmd_private.h
index d5905afd8..d7bfd9cc8 100644
--- a/drivers/crypto/null/null_crypto_pmd_private.h
+++ b/drivers/crypto/null/null_crypto_pmd_private.h
@@ -31,6 +31,8 @@ struct null_crypto_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
} __rte_cache_aligned;
diff --git a/drivers/crypto/octeontx/otx_cryptodev_ops.c b/drivers/crypto/octeontx/otx_cryptodev_ops.c
index 90d0c14b8..6a0cf83f4 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_ops.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_ops.c
@@ -186,8 +186,7 @@ static int
otx_cpt_que_pair_setup(struct rte_cryptodev *dev,
uint16_t que_pair_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id __rte_unused,
- struct rte_mempool *session_pool __rte_unused)
+ int socket_id __rte_unused)
{
void *cptvf = dev->data->dev_private;
struct cpt_instance *instance = NULL;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index a0ccacb1e..a193af642 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -768,7 +768,8 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct openssl_session *)_sess_private_data;
@@ -776,7 +777,7 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
if (unlikely(openssl_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -2020,7 +2021,7 @@ process_op(struct openssl_qp *qp, struct rte_crypto_op *op,
memset(sess, 0, sizeof(struct openssl_session));
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sess);
+ rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index bdaf937a3..5644f593a 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -710,7 +710,7 @@ openssl_pmd_qp_create_processed_ops_ring(struct openssl_qp *qp,
static int
openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct openssl_qp *qp = NULL;
@@ -735,7 +735,8 @@ openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_private.h b/drivers/crypto/openssl/rte_openssl_pmd_private.h
index a8f2c8482..43ac3813d 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_private.h
+++ b/drivers/crypto/openssl/rte_openssl_pmd_private.h
@@ -64,6 +64,8 @@ struct openssl_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats stats;
/**< Queue pair statistics */
uint8_t temp_digest[DIGEST_LENGTH_MAX];
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index c3f700406..31ccab32e 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -127,7 +127,7 @@ static int qat_sym_qp_release(struct rte_cryptodev *dev, uint16_t queue_pair_id)
static int qat_sym_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool __rte_unused)
+ int socket_id)
{
struct qat_qp *qp;
int ret = 0;
diff --git a/drivers/crypto/scheduler/scheduler_pmd_ops.c b/drivers/crypto/scheduler/scheduler_pmd_ops.c
index 939105aa8..cf70218b7 100644
--- a/drivers/crypto/scheduler/scheduler_pmd_ops.c
+++ b/drivers/crypto/scheduler/scheduler_pmd_ops.c
@@ -390,8 +390,7 @@ scheduler_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
/** Setup a queue pair */
static int
scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
- const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
- struct rte_mempool *session_pool)
+ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
{
struct scheduler_ctx *sched_ctx = dev->data->dev_private;
struct scheduler_qp_ctx *qp_ctx;
@@ -419,7 +418,7 @@ scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
* must be big enough for all the drivers used.
*/
ret = rte_cryptodev_queue_pair_setup(slave_id, qp_id,
- qp_conf, socket_id, session_pool);
+ qp_conf, socket_id);
if (ret < 0)
return ret;
}
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index a17536b77..7d131f780 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -147,7 +147,8 @@ snow3g_get_session(struct snow3g_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct snow3g_session *)_sess_private_data;
@@ -155,7 +156,7 @@ snow3g_get_session(struct snow3g_qp *qp, struct rte_crypto_op *op)
if (unlikely(snow3g_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -340,7 +341,7 @@ process_ops(struct rte_crypto_op **ops, struct snow3g_session *session,
memset(session, 0, sizeof(struct snow3g_session));
memset(ops[i]->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, session);
+ rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
}
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
index cfbc9522a..fad483c75 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
@@ -193,7 +193,7 @@ snow3g_pmd_qp_create_processed_ops_ring(struct snow3g_qp *qp,
static int
snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct snow3g_qp *qp = NULL;
@@ -218,7 +218,8 @@ snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
index b7807b621..df5c6092b 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
@@ -36,6 +36,8 @@ struct snow3g_qp {
/**< Ring for placing processed ops */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
uint8_t temp_digest[SNOW3G_DIGEST_LENGTH];
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 568b5a406..4bae3b865 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -36,8 +36,7 @@ static void virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev);
static int virtio_crypto_qp_setup(struct rte_cryptodev *dev,
uint16_t queue_pair_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id,
- struct rte_mempool *session_pool);
+ int socket_id);
static int virtio_crypto_qp_release(struct rte_cryptodev *dev,
uint16_t queue_pair_id);
static void virtio_crypto_dev_free_mbufs(struct rte_cryptodev *dev);
@@ -585,8 +584,7 @@ virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev)
static int
virtio_crypto_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id,
- struct rte_mempool *session_pool __rte_unused)
+ int socket_id)
{
int ret;
struct virtqueue *vq;
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index 313f4590b..997c2092f 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -144,7 +144,8 @@ zuc_get_session(struct zuc_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct zuc_session *)_sess_private_data;
@@ -152,7 +153,7 @@ zuc_get_session(struct zuc_qp *qp, struct rte_crypto_op *op)
if (unlikely(zuc_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -327,7 +328,7 @@ process_ops(struct rte_crypto_op **ops, enum zuc_operation op_type,
memset(sessions[i], 0, sizeof(struct zuc_session));
memset(ops[i]->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sessions[i]);
+ rte_mempool_put(qp->sess_mp_priv, sessions[i]);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
}
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_ops.c b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
index 6da396542..7bd985fc1 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_ops.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
@@ -193,7 +193,7 @@ zuc_pmd_qp_create_processed_ops_ring(struct zuc_qp *qp,
static int
zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct zuc_qp *qp = NULL;
@@ -218,7 +218,8 @@ zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_private.h b/drivers/crypto/zuc/rte_zuc_pmd_private.h
index 5e5906ddb..aa73c0016 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_private.h
+++ b/drivers/crypto/zuc/rte_zuc_pmd_private.h
@@ -36,6 +36,8 @@ struct zuc_qp {
/**< Ring for placing processed ops */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
uint8_t temp_digest[ZUC_DIGEST_LENGTH];
diff --git a/drivers/net/softnic/rte_eth_softnic_cryptodev.c b/drivers/net/softnic/rte_eth_softnic_cryptodev.c
index 1480f6dd5..f031d8803 100644
--- a/drivers/net/softnic/rte_eth_softnic_cryptodev.c
+++ b/drivers/net/softnic/rte_eth_softnic_cryptodev.c
@@ -101,7 +101,7 @@ softnic_cryptodev_create(struct pmd_internals *p,
queue_conf.nb_descriptors = params->queue_size;
for (i = 0; i < params->n_queues; i++) {
status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id, NULL);
+ &queue_conf, socket_id);
if (status < 0)
return NULL;
}
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index e7559c633..384b7a240 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -39,7 +39,7 @@ static int
cryptodev_fips_validate_app_int(void)
{
struct rte_cryptodev_config conf = {rte_socket_id(), 1};
- struct rte_cryptodev_qp_conf qp_conf = {128};
+ struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL};
int ret;
ret = rte_cryptodev_configure(env.dev_id, &conf);
@@ -52,7 +52,7 @@ cryptodev_fips_validate_app_int(void)
return ret;
ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
- rte_socket_id(), env.mpool);
+ rte_socket_id());
if (ret < 0)
return ret;
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
index c4ba72bec..b365810de 100644
--- a/examples/ip_pipeline/cryptodev.c
+++ b/examples/ip_pipeline/cryptodev.c
@@ -93,7 +93,7 @@ cryptodev_create(const char *name, struct cryptodev_params *params)
queue_conf.nb_descriptors = params->queue_size;
for (i = 0; i < params->n_queues; i++) {
status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id, NULL);
+ &queue_conf, socket_id);
if (status < 0)
return NULL;
}
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 1bc0b5b50..a0ff8f7f7 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -1493,10 +1493,13 @@ cryptodevs_init(void)
cdev_id);
qp_conf.nb_descriptors = CDEV_QUEUE_DESC;
+ qp_conf.mp_session =
+ socket_ctx[dev_conf.socket_id].session_pool;
+ qp_conf.mp_session_private =
+ socket_ctx[dev_conf.socket_id].session_pool;
for (qp = 0; qp < dev_conf.nb_queue_pairs; qp++)
if (rte_cryptodev_queue_pair_setup(cdev_id, qp,
- &qp_conf, dev_conf.socket_id,
- socket_ctx[dev_conf.socket_id].session_pool))
+ &qp_conf, dev_conf.socket_id))
rte_panic("Failed to setup queue %u for "
"cdev_id %u\n", 0, cdev_id);
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index f12fd266e..1df7ba743 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -2443,9 +2443,11 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
}
qp_conf.nb_descriptors = 2048;
+ qp_conf.mp_session = session_pool_socket[socket_id];
+ qp_conf.mp_session_private = session_pool_socket[socket_id];
retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
- socket_id, session_pool_socket[socket_id]);
+ socket_id);
if (retval < 0) {
printf("Failed to setup queue pair %u on cryptodev %u",
0, cdev_id);
diff --git a/examples/vhost_crypto/main.c b/examples/vhost_crypto/main.c
index 3deb5263f..cb30f84c0 100644
--- a/examples/vhost_crypto/main.c
+++ b/examples/vhost_crypto/main.c
@@ -463,7 +463,7 @@ free_resource(void)
int
main(int argc, char *argv[])
{
- struct rte_cryptodev_qp_conf qp_conf = {NB_CRYPTO_DESCRIPTORS};
+ struct rte_cryptodev_qp_conf qp_conf;
struct rte_cryptodev_config config;
struct rte_cryptodev_info dev_info;
char name[128];
@@ -551,11 +551,14 @@ main(int argc, char *argv[])
options.infos[i] = info;
+ qp_conf.nb_descriptors = NB_CRYPTO_DESCRIPTORS;
+ qp_conf.mp_session = info->sess_pool;
+ qp_conf.mp_session_private = info->sess_pool;
+
for (j = 0; j < dev_info.max_nb_queue_pairs; j++) {
ret = rte_cryptodev_queue_pair_setup(info->cid, j,
&qp_conf, rte_lcore_to_socket_id(
- lo->lcore_id),
- info->sess_pool);
+ lo->lcore_id));
if (ret < 0) {
RTE_LOG(ERR, USER1, "Failed to configure qp\n");
goto error_exit;
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index a52eaaa45..11776b6ac 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -941,8 +941,7 @@ rte_cryptodev_close(uint8_t dev_id)
int
rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
- const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
- struct rte_mempool *session_pool)
+ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
{
struct rte_cryptodev *dev;
@@ -967,7 +966,7 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_setup, -ENOTSUP);
return (*dev->dev_ops->queue_pair_setup)(dev, queue_pair_id, qp_conf,
- socket_id, session_pool);
+ socket_id);
}
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 4099823f1..f9e7507da 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -495,6 +495,10 @@ enum rte_cryptodev_event_type {
/** Crypto device queue pair configuration structure. */
struct rte_cryptodev_qp_conf {
uint32_t nb_descriptors; /**< Number of descriptors per queue pair */
+ struct rte_mempool *mp_session;
+ /**< The mempool for creating session in sessionless mode */
+ struct rte_mempool *mp_session_private;
+ /**< The mempool for creating sess private data in sessionless mode */
};
/**
@@ -689,8 +693,7 @@ rte_cryptodev_close(uint8_t dev_id);
*/
extern int
rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
- const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
- struct rte_mempool *session_pool);
+ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id);
/**
* Get the number of queue pairs on a specific crypto device
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index 1b6cafd17..f15c9af30 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -188,13 +188,12 @@ typedef void (*cryptodev_info_get_t)(struct rte_cryptodev *dev,
* @param qp_id Queue Pair Index
* @param qp_conf Queue configuration structure
* @param socket_id Socket Index
- * @param session_pool Pointer to device session mempool
*
* @return Returns 0 on success.
*/
typedef int (*cryptodev_queue_pair_setup_t)(struct rte_cryptodev *dev,
uint16_t qp_id, const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool);
+ int socket_id);
/**
* Release memory resources allocated by given queue pair.
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 84065eb49..aac0b1f0b 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -461,12 +461,13 @@ testsuite_setup(void)
dev_id, ts_params->conf.nb_queue_pairs);
ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+ ts_params->qp_conf.mp_session = ts_params->session_mpool;
+ ts_params->qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
dev_id, qp_id, &ts_params->qp_conf,
- rte_cryptodev_socket_id(dev_id),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(dev_id)),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, dev_id);
}
@@ -519,8 +520,7 @@ ut_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id,
&ts_params->qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
}
@@ -709,13 +709,14 @@ test_queue_pair_descriptor_setup(void)
* freed so are re-used if ring is released and re-created.
*/
qp_conf.nb_descriptors = MIN_NUM_OPS_INFLIGHT; /* min size*/
+ qp_conf.mp_session = ts_params->session_mpool;
+ qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for "
"rte_cryptodev_queue_pair_setup: num_inflights "
"%u on qp %u on cryptodev %u",
@@ -729,8 +730,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for"
" rte_cryptodev_queue_pair_setup: num_inflights"
" %u on qp %u on cryptodev %u",
@@ -744,8 +744,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for "
"rte_cryptodev_queue_pair_setup: num_inflights"
" %u on qp %u on cryptodev %u",
@@ -760,8 +759,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Unexpectedly passed test for "
"rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -776,8 +774,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Unexpectedly passed test for "
"rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -791,8 +788,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for"
" rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -807,8 +803,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Unexpectedly passed test for "
"rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -824,8 +819,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0],
qp_id, &qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed test for rte_cryptodev_queue_pair_setup:"
"invalid qp %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
@@ -835,8 +829,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0],
qp_id, &qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed test for rte_cryptodev_queue_pair_setup:"
"invalid qp %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
diff --git a/test/test/test_cryptodev_asym.c b/test/test/test_cryptodev_asym.c
index a899f9973..0f6fc5767 100644
--- a/test/test/test_cryptodev_asym.c
+++ b/test/test/test_cryptodev_asym.c
@@ -383,11 +383,12 @@ testsuite_setup(void)
/* configure qp */
ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+ ts_params->qp_conf.mp_session = ts_params->session_mpool;
+ ts_params->qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
dev_id, qp_id, &ts_params->qp_conf,
- rte_cryptodev_socket_id(dev_id),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(dev_id)),
"Failed to setup queue pair %u on cryptodev %u ASYM",
qp_id, dev_id);
}
@@ -449,8 +450,7 @@ ut_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id,
&ts_params->qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
}
diff --git a/test/test/test_event_crypto_adapter.c b/test/test/test_event_crypto_adapter.c
index de258c346..54717870e 100644
--- a/test/test/test_event_crypto_adapter.c
+++ b/test/test/test_event_crypto_adapter.c
@@ -546,11 +546,12 @@ configure_cryptodev(void)
TEST_CDEV_ID, conf.nb_queue_pairs);
qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+ qp_conf.mp_session = params.session_mpool;
+ qp_conf.mp_session_private = params.session_mpool;
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
TEST_CDEV_ID, TEST_CDEV_QP_ID, &qp_conf,
- rte_cryptodev_socket_id(TEST_CDEV_ID),
- params.session_mpool),
+ rte_cryptodev_socket_id(TEST_CDEV_ID)),
"Failed to setup queue pair %u on cryptodev %u\n",
TEST_CDEV_QP_ID, TEST_CDEV_ID);
--
2.13.6
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v3 2/2] cryptodev: change symmetric session structure
2018-12-21 13:55 1% ` [dpdk-dev] [PATCH v3 1/2] cryptodev: change queue pair configure structure Fan Zhang
@ 2018-12-21 13:55 1% ` Fan Zhang
2 siblings, 0 replies; 200+ results
From: Fan Zhang @ 2018-12-21 13:55 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, fiona.trahe
This patch changes the symmetric session structure of cryptodev.
The symmetric session now contains extra information for secure
access purposes. The patch also includes the updates to the
PMDs, test applications, and examples to fit the change.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
app/test-crypto-perf/cperf.h | 1 +
app/test-crypto-perf/cperf_ops.c | 11 +-
app/test-crypto-perf/cperf_ops.h | 2 +-
app/test-crypto-perf/cperf_test_latency.c | 5 +-
app/test-crypto-perf/cperf_test_latency.h | 1 +
app/test-crypto-perf/cperf_test_pmd_cyclecount.c | 5 +-
app/test-crypto-perf/cperf_test_pmd_cyclecount.h | 1 +
app/test-crypto-perf/cperf_test_throughput.c | 5 +-
app/test-crypto-perf/cperf_test_throughput.h | 1 +
app/test-crypto-perf/cperf_test_verify.c | 5 +-
app/test-crypto-perf/cperf_test_verify.h | 1 +
app/test-crypto-perf/main.c | 103 ++++++----
doc/guides/rel_notes/release_19_02.rst | 14 ++
drivers/crypto/aesni_gcm/Makefile | 1 +
drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 3 +-
drivers/crypto/aesni_gcm/meson.build | 1 +
drivers/crypto/aesni_mb/Makefile | 1 +
drivers/crypto/aesni_mb/meson.build | 2 +
drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 3 +-
drivers/crypto/armv8/Makefile | 1 +
drivers/crypto/armv8/rte_armv8_pmd.c | 3 +-
drivers/crypto/kasumi/Makefile | 1 +
drivers/crypto/kasumi/meson.build | 1 +
drivers/crypto/kasumi/rte_kasumi_pmd.c | 3 +-
drivers/crypto/openssl/Makefile | 1 +
drivers/crypto/openssl/meson.build | 1 +
drivers/crypto/openssl/rte_openssl_pmd.c | 3 +-
drivers/crypto/snow3g/Makefile | 1 +
drivers/crypto/snow3g/rte_snow3g_pmd.c | 3 +-
drivers/crypto/zuc/Makefile | 1 +
drivers/crypto/zuc/meson.build | 1 +
drivers/crypto/zuc/rte_zuc_pmd.c | 3 +-
drivers/net/softnic/rte_eth_softnic_cli.c | 52 ++++-
drivers/net/softnic/rte_eth_softnic_cryptodev.c | 50 ++++-
drivers/net/softnic/rte_eth_softnic_internals.h | 3 +
examples/fips_validation/main.c | 34 +++-
examples/ip_pipeline/cli.c | 49 +++--
examples/ip_pipeline/cryptodev.c | 49 ++++-
examples/ip_pipeline/cryptodev.h | 3 +
examples/ip_pipeline/examples/flow_crypto.cli | 9 +-
examples/ipsec-secgw/ipsec-secgw.c | 48 +++--
examples/ipsec-secgw/ipsec.c | 2 +-
examples/ipsec-secgw/ipsec.h | 2 +
examples/l2fwd-crypto/main.c | 66 ++++---
examples/vhost_crypto/main.c | 13 +-
lib/librte_cryptodev/Makefile | 1 +
lib/librte_cryptodev/meson.build | 1 +
lib/librte_cryptodev/rte_cryptodev.c | 190 +++++++++++++++----
lib/librte_cryptodev/rte_cryptodev.h | 65 ++++++-
lib/librte_cryptodev/rte_cryptodev_pmd.h | 13 +-
lib/librte_cryptodev/rte_cryptodev_version.map | 2 +
lib/librte_vhost/rte_vhost_crypto.h | 9 +-
lib/librte_vhost/vhost_crypto.c | 8 +-
test/test/test_cryptodev.c | 229 ++++++++++++++---------
test/test/test_cryptodev_blockcipher.c | 7 +-
test/test/test_cryptodev_blockcipher.h | 1 +
test/test/test_event_crypto_adapter.c | 32 +++-
57 files changed, 845 insertions(+), 282 deletions(-)
diff --git a/app/test-crypto-perf/cperf.h b/app/test-crypto-perf/cperf.h
index db58228dc..2b0aad095 100644
--- a/app/test-crypto-perf/cperf.h
+++ b/app/test-crypto-perf/cperf.h
@@ -15,6 +15,7 @@ struct cperf_op_fns;
typedef void *(*cperf_constructor_t)(
struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_priv_mp,
uint8_t dev_id,
uint16_t qp_id,
const struct cperf_options *options,
diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
index 44808f50a..f59568b80 100644
--- a/app/test-crypto-perf/cperf_ops.c
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -469,6 +469,7 @@ cperf_set_ops_aead(struct rte_crypto_op **ops,
static struct rte_cryptodev_sym_session *
cperf_create_session(struct rte_mempool *sess_mp,
+ struct rte_mempool *priv_mp,
uint8_t dev_id,
const struct cperf_options *options,
const struct cperf_test_vector *test_vector,
@@ -505,7 +506,7 @@ cperf_create_session(struct rte_mempool *sess_mp,
}
/* create crypto session */
rte_cryptodev_sym_session_init(dev_id, sess, &cipher_xform,
- sess_mp);
+ priv_mp);
/*
* auth only
*/
@@ -533,7 +534,7 @@ cperf_create_session(struct rte_mempool *sess_mp,
}
/* create crypto session */
rte_cryptodev_sym_session_init(dev_id, sess, &auth_xform,
- sess_mp);
+ priv_mp);
/*
* cipher and auth
*/
@@ -592,12 +593,12 @@ cperf_create_session(struct rte_mempool *sess_mp,
cipher_xform.next = &auth_xform;
/* create crypto session */
rte_cryptodev_sym_session_init(dev_id,
- sess, &cipher_xform, sess_mp);
+ sess, &cipher_xform, priv_mp);
} else { /* auth then cipher */
auth_xform.next = &cipher_xform;
/* create crypto session */
rte_cryptodev_sym_session_init(dev_id,
- sess, &auth_xform, sess_mp);
+ sess, &auth_xform, priv_mp);
}
} else { /* options->op_type == CPERF_AEAD */
aead_xform.type = RTE_CRYPTO_SYM_XFORM_AEAD;
@@ -618,7 +619,7 @@ cperf_create_session(struct rte_mempool *sess_mp,
/* Create crypto session */
rte_cryptodev_sym_session_init(dev_id,
- sess, &aead_xform, sess_mp);
+ sess, &aead_xform, priv_mp);
}
return sess;
diff --git a/app/test-crypto-perf/cperf_ops.h b/app/test-crypto-perf/cperf_ops.h
index 29e109f2a..ff125d12c 100644
--- a/app/test-crypto-perf/cperf_ops.h
+++ b/app/test-crypto-perf/cperf_ops.h
@@ -13,7 +13,7 @@
typedef struct rte_cryptodev_sym_session *(*cperf_sessions_create_t)(
- struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_mp, struct rte_mempool *sess_priv_mp,
uint8_t dev_id, const struct cperf_options *options,
const struct cperf_test_vector *test_vector,
uint16_t iv_offset);
diff --git a/app/test-crypto-perf/cperf_test_latency.c b/app/test-crypto-perf/cperf_test_latency.c
index c9c98dc50..0fc3a6680 100644
--- a/app/test-crypto-perf/cperf_test_latency.c
+++ b/app/test-crypto-perf/cperf_test_latency.c
@@ -62,6 +62,7 @@ cperf_latency_test_free(struct cperf_latency_ctx *ctx)
void *
cperf_latency_test_constructor(struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_priv_mp,
uint8_t dev_id, uint16_t qp_id,
const struct cperf_options *options,
const struct cperf_test_vector *test_vector,
@@ -86,8 +87,8 @@ cperf_latency_test_constructor(struct rte_mempool *sess_mp,
sizeof(struct rte_crypto_sym_op) +
sizeof(struct cperf_op_result *);
- ctx->sess = op_fns->sess_create(sess_mp, dev_id, options, test_vector,
- iv_offset);
+ ctx->sess = op_fns->sess_create(sess_mp, sess_priv_mp, dev_id, options,
+ test_vector, iv_offset);
if (ctx->sess == NULL)
goto err;
diff --git a/app/test-crypto-perf/cperf_test_latency.h b/app/test-crypto-perf/cperf_test_latency.h
index d3fc3218d..ed5b0a07b 100644
--- a/app/test-crypto-perf/cperf_test_latency.h
+++ b/app/test-crypto-perf/cperf_test_latency.h
@@ -17,6 +17,7 @@
void *
cperf_latency_test_constructor(
struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_priv_mp,
uint8_t dev_id,
uint16_t qp_id,
const struct cperf_options *options,
diff --git a/app/test-crypto-perf/cperf_test_pmd_cyclecount.c b/app/test-crypto-perf/cperf_test_pmd_cyclecount.c
index c8d16db6d..92af5ec90 100644
--- a/app/test-crypto-perf/cperf_test_pmd_cyclecount.c
+++ b/app/test-crypto-perf/cperf_test_pmd_cyclecount.c
@@ -80,6 +80,7 @@ cperf_pmd_cyclecount_test_free(struct cperf_pmd_cyclecount_ctx *ctx)
void *
cperf_pmd_cyclecount_test_constructor(struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_priv_mp,
uint8_t dev_id, uint16_t qp_id,
const struct cperf_options *options,
const struct cperf_test_vector *test_vector,
@@ -106,8 +107,8 @@ cperf_pmd_cyclecount_test_constructor(struct rte_mempool *sess_mp,
uint16_t iv_offset = sizeof(struct rte_crypto_op) +
sizeof(struct rte_crypto_sym_op);
- ctx->sess = op_fns->sess_create(
- sess_mp, dev_id, options, test_vector, iv_offset);
+ ctx->sess = op_fns->sess_create(sess_mp, sess_priv_mp, dev_id, options,
+ test_vector, iv_offset);
if (ctx->sess == NULL)
goto err;
diff --git a/app/test-crypto-perf/cperf_test_pmd_cyclecount.h b/app/test-crypto-perf/cperf_test_pmd_cyclecount.h
index beb441991..3084038a1 100644
--- a/app/test-crypto-perf/cperf_test_pmd_cyclecount.h
+++ b/app/test-crypto-perf/cperf_test_pmd_cyclecount.h
@@ -18,6 +18,7 @@
void *
cperf_pmd_cyclecount_test_constructor(
struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_priv_mp,
uint8_t dev_id,
uint16_t qp_id,
const struct cperf_options *options,
diff --git a/app/test-crypto-perf/cperf_test_throughput.c b/app/test-crypto-perf/cperf_test_throughput.c
index 8766d6e9b..2767f4ea8 100644
--- a/app/test-crypto-perf/cperf_test_throughput.c
+++ b/app/test-crypto-perf/cperf_test_throughput.c
@@ -47,6 +47,7 @@ cperf_throughput_test_free(struct cperf_throughput_ctx *ctx)
void *
cperf_throughput_test_constructor(struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_priv_mp,
uint8_t dev_id, uint16_t qp_id,
const struct cperf_options *options,
const struct cperf_test_vector *test_vector,
@@ -69,8 +70,8 @@ cperf_throughput_test_constructor(struct rte_mempool *sess_mp,
uint16_t iv_offset = sizeof(struct rte_crypto_op) +
sizeof(struct rte_crypto_sym_op);
- ctx->sess = op_fns->sess_create(sess_mp, dev_id, options, test_vector,
- iv_offset);
+ ctx->sess = op_fns->sess_create(sess_mp, sess_priv_mp, dev_id, options,
+ test_vector, iv_offset);
if (ctx->sess == NULL)
goto err;
diff --git a/app/test-crypto-perf/cperf_test_throughput.h b/app/test-crypto-perf/cperf_test_throughput.h
index 439ec8e55..91e1a4b70 100644
--- a/app/test-crypto-perf/cperf_test_throughput.h
+++ b/app/test-crypto-perf/cperf_test_throughput.h
@@ -18,6 +18,7 @@
void *
cperf_throughput_test_constructor(
struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_priv_mp,
uint8_t dev_id,
uint16_t qp_id,
const struct cperf_options *options,
diff --git a/app/test-crypto-perf/cperf_test_verify.c b/app/test-crypto-perf/cperf_test_verify.c
index 9134b921e..0497cf9a1 100644
--- a/app/test-crypto-perf/cperf_test_verify.c
+++ b/app/test-crypto-perf/cperf_test_verify.c
@@ -51,6 +51,7 @@ cperf_verify_test_free(struct cperf_verify_ctx *ctx)
void *
cperf_verify_test_constructor(struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_priv_mp,
uint8_t dev_id, uint16_t qp_id,
const struct cperf_options *options,
const struct cperf_test_vector *test_vector,
@@ -73,8 +74,8 @@ cperf_verify_test_constructor(struct rte_mempool *sess_mp,
uint16_t iv_offset = sizeof(struct rte_crypto_op) +
sizeof(struct rte_crypto_sym_op);
- ctx->sess = op_fns->sess_create(sess_mp, dev_id, options, test_vector,
- iv_offset);
+ ctx->sess = op_fns->sess_create(sess_mp, sess_priv_mp, dev_id, options,
+ test_vector, iv_offset);
if (ctx->sess == NULL)
goto err;
diff --git a/app/test-crypto-perf/cperf_test_verify.h b/app/test-crypto-perf/cperf_test_verify.h
index 9f70ad87b..ac2192ba9 100644
--- a/app/test-crypto-perf/cperf_test_verify.h
+++ b/app/test-crypto-perf/cperf_test_verify.h
@@ -18,6 +18,7 @@
void *
cperf_verify_test_constructor(
struct rte_mempool *sess_mp,
+ struct rte_mempool *sess_priv_mp,
uint8_t dev_id,
uint16_t qp_id,
const struct cperf_options *options,
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 38a2e429f..175c639fb 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -21,6 +21,10 @@
#include "cperf_test_verify.h"
#include "cperf_test_pmd_cyclecount.h"
+static struct {
+ struct rte_mempool *sess_mp;
+ struct rte_mempool *priv_mp;
+} session_pool_socket[RTE_MAX_NUMA_NODES];
const char *cperf_test_type_strs[] = {
[CPERF_TEST_TYPE_THROUGHPUT] = "throughput",
@@ -61,8 +65,58 @@ const struct cperf_test cperf_testmap[] = {
};
static int
-cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
- struct rte_mempool *session_pool_socket[])
+fill_session_pool_socket(int32_t socket_id, uint32_t session_priv_size,
+ uint32_t nb_sessions)
+{
+ char mp_name[RTE_MEMPOOL_NAMESIZE];
+ struct rte_mempool *sess_mp;
+
+ if (session_pool_socket[socket_id].priv_mp == NULL) {
+ snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
+ "priv_sess_mp_%u", socket_id);
+
+ sess_mp = rte_mempool_create(mp_name,
+ nb_sessions,
+ session_priv_size,
+ 0, 0, NULL, NULL, NULL,
+ NULL, socket_id,
+ 0);
+
+ if (sess_mp == NULL) {
+ printf("Cannot create pool \"%s\" on socket %d\n",
+ mp_name, socket_id);
+ return -ENOMEM;
+ }
+
+ printf("Allocated pool \"%s\" on socket %d\n",
+ mp_name, socket_id);
+ session_pool_socket[socket_id].priv_mp = sess_mp;
+ }
+
+ if (session_pool_socket[socket_id].sess_mp == NULL) {
+
+ snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
+ "sess_mp_%u", socket_id);
+
+ sess_mp = rte_cryptodev_sym_session_pool_create(mp_name,
+ nb_sessions, 0, 0, 0, socket_id);
+
+ if (sess_mp == NULL) {
+ printf("Cannot create pool \"%s\" on socket %d\n",
+ mp_name, socket_id);
+ return -ENOMEM;
+ }
+
+ printf("Allocated pool \"%s\" on socket %d\n",
+ mp_name, socket_id);
+ session_pool_socket[socket_id].sess_mp = sess_mp;
+ }
+
+ return 0;
+}
+
+static int
+cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
{
uint8_t enabled_cdev_count = 0, nb_lcores, cdev_id;
uint32_t sessions_needed = 0;
@@ -177,11 +231,11 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
rte_cryptodev_scheduler_slaves_get(cdev_id,
NULL);
- sessions_needed = 2 * enabled_cdev_count *
+ sessions_needed = enabled_cdev_count *
opts->nb_qps * nb_slaves;
#endif
} else
- sessions_needed = 2 * enabled_cdev_count *
+ sessions_needed = enabled_cdev_count *
opts->nb_qps;
/*
@@ -194,32 +248,15 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
"%u sessions\n", opts->nb_qps);
return -ENOTSUP;
}
- if (session_pool_socket[socket_id] == NULL) {
- char mp_name[RTE_MEMPOOL_NAMESIZE];
- struct rte_mempool *sess_mp;
-
- snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
- "sess_mp_%u", socket_id);
- sess_mp = rte_mempool_create(mp_name,
- sessions_needed,
- max_sess_size,
- 0,
- 0, NULL, NULL, NULL,
- NULL, socket_id,
- 0);
-
- if (sess_mp == NULL) {
- printf("Cannot create session pool on socket %d\n",
- socket_id);
- return -ENOMEM;
- }
- printf("Allocated session pool on socket %d\n", socket_id);
- session_pool_socket[socket_id] = sess_mp;
- }
+ ret = fill_session_pool_socket(socket_id, max_sess_size,
+ sessions_needed);
+ if (ret < 0)
+ return ret;
- qp_conf.mp_session = session_pool_socket[socket_id];
- qp_conf.mp_session_private = session_pool_socket[socket_id];
+ qp_conf.mp_session = session_pool_socket[socket_id].sess_mp;
+ qp_conf.mp_session_private =
+ session_pool_socket[socket_id].priv_mp;
ret = rte_cryptodev_configure(cdev_id, &conf);
if (ret < 0) {
@@ -453,10 +490,7 @@ main(int argc, char **argv)
struct cperf_options opts = {0};
struct cperf_test_vector *t_vec = NULL;
struct cperf_op_fns op_fns;
-
void *ctx[RTE_MAX_LCORE] = { };
- struct rte_mempool *session_pool_socket[RTE_MAX_NUMA_NODES] = { 0 };
-
int nb_cryptodevs = 0;
uint16_t total_nb_qps = 0;
uint8_t cdev_id, i;
@@ -489,8 +523,7 @@ main(int argc, char **argv)
goto err;
}
- nb_cryptodevs = cperf_initialize_cryptodev(&opts, enabled_cdevs,
- session_pool_socket);
+ nb_cryptodevs = cperf_initialize_cryptodev(&opts, enabled_cdevs);
if (!opts.silent)
cperf_options_dump(&opts);
@@ -558,7 +591,9 @@ main(int argc, char **argv)
uint8_t socket_id = rte_cryptodev_socket_id(cdev_id);
ctx[i] = cperf_testmap[opts.test].constructor(
- session_pool_socket[socket_id], cdev_id, qp_id,
+ session_pool_socket[socket_id].sess_mp,
+ session_pool_socket[socket_id].priv_mp,
+ cdev_id, qp_id,
&opts, t_vec, &op_fns);
if (ctx[i] == NULL) {
RTE_LOG(ERR, USER1, "Test run constructor failed\n");
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 4420c2441..7dbba15fe 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -135,6 +135,20 @@ API Changes
mempool and symmetric session private data mempool, and the last parameter of
``rte_cryptodev_queue_pair_setup()`` is removed.
+* cryptodev: as shown in the the 18.08 deprecation notice, the structure
+ ``rte_cryptodev_sym_session`` has been updated to contain more information
+ to ensure safely accessing driver private data and user data area. The
+ creation of mempool for ``rte_cryptodev_sym_session`` objects is now enforced
+ to use new function ``rte_cryptodev_sym_session_pool_create()`` so that
+ the correct session information is set. Failed to do so will cause
+ ``rte_cryptodev_sym_session_create()`` function call failed. With the change
+ cryptodev does no longer enforce using the same mempool for symmetric session
+ header and the driver specific private data, and prevent the segmentation
+ faults caused by the incorrect access to both the session's private data and
+ user data. All cryptodev related applications (test applications and sample
+ applications) have been updated to demonstrate how to use this new
+ method.
+
ABI Changes
-----------
diff --git a/drivers/crypto/aesni_gcm/Makefile b/drivers/crypto/aesni_gcm/Makefile
index 0a5c1a872..9241ad762 100644
--- a/drivers/crypto/aesni_gcm/Makefile
+++ b/drivers/crypto/aesni_gcm/Makefile
@@ -8,6 +8,7 @@ LIB = librte_pmd_aesni_gcm.a
# build flags
CFLAGS += -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
CFLAGS += $(WERROR_FLAGS)
# library version
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index abc7a6d5f..948ff0763 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -419,7 +419,8 @@ handle_completed_gcm_crypto_op(struct aesni_gcm_qp *qp,
if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(sess, 0, sizeof(struct aesni_gcm_session));
memset(op->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ op->sym->session));
rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
diff --git a/drivers/crypto/aesni_gcm/meson.build b/drivers/crypto/aesni_gcm/meson.build
index a02da1ef5..70f57ad73 100644
--- a/drivers/crypto/aesni_gcm/meson.build
+++ b/drivers/crypto/aesni_gcm/meson.build
@@ -8,5 +8,6 @@ else
ext_deps += lib
endif
+allow_experimental_apis = true
sources = files('aesni_gcm_pmd.c', 'aesni_gcm_pmd_ops.c')
deps += ['bus_vdev']
diff --git a/drivers/crypto/aesni_mb/Makefile b/drivers/crypto/aesni_mb/Makefile
index 806a95eb8..a6fa071ec 100644
--- a/drivers/crypto/aesni_mb/Makefile
+++ b/drivers/crypto/aesni_mb/Makefile
@@ -9,6 +9,7 @@ LIB = librte_pmd_aesni_mb.a
# build flags
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
# library version
LIBABIVER := 1
diff --git a/drivers/crypto/aesni_mb/meson.build b/drivers/crypto/aesni_mb/meson.build
index aae0995e5..145c3d984 100644
--- a/drivers/crypto/aesni_mb/meson.build
+++ b/drivers/crypto/aesni_mb/meson.build
@@ -9,4 +9,6 @@ else
endif
sources = files('rte_aesni_mb_pmd.c', 'rte_aesni_mb_pmd_ops.c')
+allow_experimental_apis = true
+
deps += ['bus_vdev']
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index b0f5c4d67..f3b270d09 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -951,7 +951,8 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job)
if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(sess, 0, sizeof(struct aesni_mb_session));
memset(op->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ op->sym->session));
rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
diff --git a/drivers/crypto/armv8/Makefile b/drivers/crypto/armv8/Makefile
index e862af72e..f71f6b14a 100644
--- a/drivers/crypto/armv8/Makefile
+++ b/drivers/crypto/armv8/Makefile
@@ -28,6 +28,7 @@ EXPORT_MAP := rte_pmd_armv8_version.map
# external library dependencies
CFLAGS += -I$(ARMV8_CRYPTO_LIB_PATH)
CFLAGS += -I$(ARMV8_CRYPTO_LIB_PATH)/asm/include
+CFLAGS += -DALLOW_EXPERIMENTAL_API
LDLIBS += -L$(ARMV8_CRYPTO_LIB_PATH) -larmv8_crypto
LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
LDLIBS += -lrte_cryptodev
diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
index 3b2d7fb2f..0d4649adc 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd.c
@@ -655,7 +655,8 @@ process_op(struct armv8_crypto_qp *qp, struct rte_crypto_op *op,
if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(sess, 0, sizeof(struct armv8_crypto_session));
memset(op->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ op->sym->session));
rte_mempool_put(qp->sess_mp, sess);
rte_mempool_put(qp->sess_mp_priv, op->sym->session);
op->sym->session = NULL;
diff --git a/drivers/crypto/kasumi/Makefile b/drivers/crypto/kasumi/Makefile
index cafe94986..3de2f97ed 100644
--- a/drivers/crypto/kasumi/Makefile
+++ b/drivers/crypto/kasumi/Makefile
@@ -15,6 +15,7 @@ LIB = librte_pmd_kasumi.a
# build flags
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
# library version
LIBABIVER := 1
diff --git a/drivers/crypto/kasumi/meson.build b/drivers/crypto/kasumi/meson.build
index a09b0e251..80f13cd24 100644
--- a/drivers/crypto/kasumi/meson.build
+++ b/drivers/crypto/kasumi/meson.build
@@ -8,5 +8,6 @@ else
ext_deps += lib
endif
+allow_experimental_apis = true
sources = files('rte_kasumi_pmd.c', 'rte_kasumi_pmd_ops.c')
deps += ['bus_vdev']
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index 6df645a23..3abdb01a9 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -325,7 +325,8 @@ process_ops(struct rte_crypto_op **ops, struct kasumi_session *session,
if (ops[i]->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(session, 0, sizeof(struct kasumi_session));
memset(ops[i]->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ ops[i]->sym->session));
rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
diff --git a/drivers/crypto/openssl/Makefile b/drivers/crypto/openssl/Makefile
index 8fe086b90..ae6c3bcac 100644
--- a/drivers/crypto/openssl/Makefile
+++ b/drivers/crypto/openssl/Makefile
@@ -9,6 +9,7 @@ LIB = librte_pmd_openssl.a
# build flags
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
# library version
LIBABIVER := 1
diff --git a/drivers/crypto/openssl/meson.build b/drivers/crypto/openssl/meson.build
index c2a0dd8ba..77a6596d7 100644
--- a/drivers/crypto/openssl/meson.build
+++ b/drivers/crypto/openssl/meson.build
@@ -5,6 +5,7 @@ dep = dependency('libcrypto', required: false)
if not dep.found()
build = false
endif
+allow_experimental_apis = true
deps += 'bus_vdev'
sources = files('rte_openssl_pmd.c', 'rte_openssl_pmd_ops.c')
ext_deps += dep
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index a193af642..ea5aac69e 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -2020,7 +2020,8 @@ process_op(struct openssl_qp *qp, struct rte_crypto_op *op,
openssl_reset_session(sess);
memset(sess, 0, sizeof(struct openssl_session));
memset(op->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ op->sym->session));
rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
diff --git a/drivers/crypto/snow3g/Makefile b/drivers/crypto/snow3g/Makefile
index ee5027d0c..37f77dbf8 100644
--- a/drivers/crypto/snow3g/Makefile
+++ b/drivers/crypto/snow3g/Makefile
@@ -15,6 +15,7 @@ LIB = librte_pmd_snow3g.a
# build flags
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
# library version
LIBABIVER := 1
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index 7d131f780..5fd94b686 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -340,7 +340,8 @@ process_ops(struct rte_crypto_op **ops, struct snow3g_session *session,
if (ops[i]->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(session, 0, sizeof(struct snow3g_session));
memset(ops[i]->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ ops[i]->sym->session));
rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
diff --git a/drivers/crypto/zuc/Makefile b/drivers/crypto/zuc/Makefile
index 68d84eebc..8d625aa01 100644
--- a/drivers/crypto/zuc/Makefile
+++ b/drivers/crypto/zuc/Makefile
@@ -15,6 +15,7 @@ LIB = librte_pmd_zuc.a
# build flags
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
# library version
LIBABIVER := 1
diff --git a/drivers/crypto/zuc/meson.build b/drivers/crypto/zuc/meson.build
index b8ca7107e..63f2a5298 100644
--- a/drivers/crypto/zuc/meson.build
+++ b/drivers/crypto/zuc/meson.build
@@ -8,5 +8,6 @@ else
ext_deps += lib
endif
+allow_experimental_apis = true
sources = files('rte_zuc_pmd.c', 'rte_zuc_pmd_ops.c')
deps += ['bus_vdev']
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index 997c2092f..637994dfd 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -327,7 +327,8 @@ process_ops(struct rte_crypto_op **ops, enum zuc_operation op_type,
if (ops[i]->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(sessions[i], 0, sizeof(struct zuc_session));
memset(ops[i]->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ ops[i]->sym->session));
rte_mempool_put(qp->sess_mp_priv, sessions[i]);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c
index 57b623377..76136c2e2 100644
--- a/drivers/net/softnic/rte_eth_softnic_cli.c
+++ b/drivers/net/softnic/rte_eth_softnic_cli.c
@@ -1092,7 +1092,7 @@ cmd_tap(struct pmd_internals *softnic,
/**
* cryptodev <tap_name> dev <device_name> | dev_id <device_id>
- * queue <n_queues> <queue_size>
+ * queue <n_queues> <queue_size> max_sessions <n_sessions>
**/
static void
@@ -1106,7 +1106,7 @@ cmd_cryptodev(struct pmd_internals *softnic,
char *name;
memset(¶ms, 0, sizeof(params));
- if (n_tokens != 7) {
+ if (n_tokens != 9) {
snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
return;
}
@@ -1145,6 +1145,19 @@ cmd_cryptodev(struct pmd_internals *softnic,
return;
}
+ if (strcmp(tokens[7], "max_sessions")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND,
+ "4");
+ return;
+ }
+
+ if (softnic_parser_read_uint32(¶ms.session_pool_size, tokens[8])
+ < 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID,
+ "q");
+ return;
+ }
+
if (softnic_cryptodev_create(softnic, name, ¶ms) == NULL) {
snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
return;
@@ -1739,6 +1752,41 @@ cmd_table_action_profile(struct pmd_internals *softnic,
t0 += 1;
} /* decap */
+ if (t0 < n_tokens && (strcmp(tokens[t0], "sym_crypto") == 0)) {
+ struct softnic_cryptodev *cryptodev;
+
+ if (n_tokens < t0 + 5 ||
+ strcmp(tokens[t0 + 1], "dev") ||
+ strcmp(tokens[t0 + 3], "offset")) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH,
+ "table action profile sym_crypto");
+ return;
+ }
+
+ cryptodev = softnic_cryptodev_find(softnic, tokens[t0 + 2]);
+ if (cryptodev == NULL) {
+ snprintf(out, out_size, MSG_ARG_INVALID,
+ "table action profile sym_crypto");
+ return;
+ }
+
+ p.sym_crypto.cryptodev_id = cryptodev->dev_id;
+
+ if (softnic_parser_read_uint32(&p.sym_crypto.op_offset,
+ tokens[t0 + 4]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID,
+ "table action profile sym_crypto");
+ return;
+ }
+
+ p.sym_crypto.mp_create = cryptodev->mp_create;
+ p.sym_crypto.mp_init = cryptodev->mp_init;
+
+ p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
+
+ t0 += 5;
+ } /* sym_crypto */
+
if (t0 < n_tokens) {
snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
return;
diff --git a/drivers/net/softnic/rte_eth_softnic_cryptodev.c b/drivers/net/softnic/rte_eth_softnic_cryptodev.c
index f031d8803..18a52ed05 100644
--- a/drivers/net/softnic/rte_eth_softnic_cryptodev.c
+++ b/drivers/net/softnic/rte_eth_softnic_cryptodev.c
@@ -11,6 +11,8 @@
#include "rte_eth_softnic_internals.h"
+#define SOFTNIC_CRYPTO_SESSION_CACHE_SIZE 128
+
int
softnic_cryptodev_init(struct pmd_internals *p)
{
@@ -61,13 +63,16 @@ softnic_cryptodev_create(struct pmd_internals *p,
struct softnic_cryptodev *cryptodev;
uint32_t dev_id, i;
uint32_t socket_id;
+ uint32_t cache_size;
+ char mp_name[NAME_SIZE];
int status;
/* Check input params */
if ((name == NULL) ||
softnic_cryptodev_find(p, name) ||
(params->n_queues == 0) ||
- (params->queue_size == 0))
+ (params->queue_size == 0) ||
+ (params->session_pool_size == 0))
return NULL;
if (params->dev_name) {
@@ -83,6 +88,12 @@ softnic_cryptodev_create(struct pmd_internals *p,
dev_id = params->dev_id;
}
+ cache_size = (params->session_pool_size / 2 <
+ SOFTNIC_CRYPTO_SESSION_CACHE_SIZE) ?
+ (params->session_pool_size / 2) :
+ SOFTNIC_CRYPTO_SESSION_CACHE_SIZE;
+
+
socket_id = rte_cryptodev_socket_id(dev_id);
rte_cryptodev_info_get(dev_id, &dev_info);
@@ -119,7 +130,44 @@ softnic_cryptodev_create(struct pmd_internals *p,
cryptodev->dev_id = dev_id;
cryptodev->n_queues = params->n_queues;
+ snprintf(mp_name, NAME_SIZE, "%s_mp%u", name, dev_id);
+ cryptodev->mp_create = rte_cryptodev_sym_session_pool_create(
+ mp_name,
+ params->session_pool_size,
+ 0,
+ cache_size,
+ 0,
+ socket_id);
+ if (!cryptodev->mp_create)
+ goto error_exit;
+
+ snprintf(mp_name, NAME_SIZE, "%s_priv_mp%u", name, dev_id);
+ cryptodev->mp_init = rte_mempool_create(
+ mp_name,
+ params->session_pool_size,
+ rte_cryptodev_sym_get_private_session_size(dev_id),
+ cache_size,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ socket_id,
+ 0);
+ if (!cryptodev->mp_init)
+ goto error_exit;
+
TAILQ_INSERT_TAIL(&p->cryptodev_list, cryptodev, node);
return cryptodev;
+
+error_exit:
+ if (cryptodev->mp_create)
+ rte_mempool_free(cryptodev->mp_create);
+ if (cryptodev->mp_init)
+ rte_mempool_free(cryptodev->mp_init);
+
+ free(cryptodev);
+
+ return NULL;
}
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 31698b9f0..685058be6 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -286,6 +286,7 @@ struct softnic_cryptodev_params {
uint32_t dev_id; /**< Valid only when *dev_name* is NULL. */
uint32_t n_queues;
uint32_t queue_size;
+ uint32_t session_pool_size;
};
struct softnic_cryptodev {
@@ -293,6 +294,8 @@ struct softnic_cryptodev {
char name[NAME_SIZE];
uint16_t dev_id;
uint32_t n_queues;
+ struct rte_mempool *mp_create;
+ struct rte_mempool *mp_init;
};
TAILQ_HEAD(softnic_cryptodev_list, softnic_cryptodev);
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index 384b7a240..bd9aa9018 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -29,6 +29,8 @@ struct cryptodev_fips_validate_env {
uint32_t is_path_folder;
uint32_t dev_id;
struct rte_mempool *mpool;
+ struct rte_mempool *sess_mpool;
+ struct rte_mempool *sess_priv_mpool;
struct rte_mempool *op_pool;
struct rte_mbuf *mbuf;
struct rte_crypto_op *op;
@@ -40,6 +42,8 @@ cryptodev_fips_validate_app_int(void)
{
struct rte_cryptodev_config conf = {rte_socket_id(), 1};
struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL};
+ uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size(
+ env.dev_id);
int ret;
ret = rte_cryptodev_configure(env.dev_id, &conf);
@@ -58,6 +62,17 @@ cryptodev_fips_validate_app_int(void)
ret = -ENOMEM;
+ env.sess_mpool = rte_cryptodev_sym_session_pool_create(
+ "FIPS_SESS_MEMPOOL", 16, 0, 0, 0, rte_socket_id());
+ if (!env.sess_mpool)
+ goto error_exit;
+
+ env.sess_priv_mpool = rte_mempool_create("FIPS_SESS_PRIV_MEMPOOL",
+ 16, sess_sz, 0, 0, NULL, NULL, NULL,
+ NULL, rte_socket_id(), 0);
+ if (!env.sess_priv_mpool)
+ goto error_exit;
+
env.op_pool = rte_crypto_op_pool_create(
"FIPS_OP_POOL",
RTE_CRYPTO_OP_TYPE_SYMMETRIC,
@@ -75,10 +90,23 @@ cryptodev_fips_validate_app_int(void)
if (!env.op)
goto error_exit;
+ qp_conf.mp_session = env.sess_mpool;
+ qp_conf.mp_session_private = env.sess_priv_mpool;
+
+ ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
+ rte_socket_id());
+ if (ret < 0)
+ goto error_exit;
+
return 0;
error_exit:
+
rte_mempool_free(env.mpool);
+ if (env.sess_mpool)
+ rte_mempool_free(env.sess_mpool);
+ if (env.sess_priv_mpool)
+ rte_mempool_free(env.sess_priv_mpool);
if (env.op_pool)
rte_mempool_free(env.op_pool);
@@ -93,6 +121,8 @@ cryptodev_fips_validate_app_uninit(void)
rte_cryptodev_sym_session_clear(env.dev_id, env.sess);
rte_cryptodev_sym_session_free(env.sess);
rte_mempool_free(env.mpool);
+ rte_mempool_free(env.sess_mpool);
+ rte_mempool_free(env.sess_priv_mpool);
rte_mempool_free(env.op_pool);
}
@@ -797,12 +827,12 @@ fips_run_test(void)
if (ret < 0)
return ret;
- env.sess = rte_cryptodev_sym_session_create(env.mpool);
+ env.sess = rte_cryptodev_sym_session_create(env.sess_mpool);
if (!env.sess)
return -ENOMEM;
ret = rte_cryptodev_sym_session_init(env.dev_id,
- env.sess, &xform, env.mpool);
+ env.sess, &xform, env.sess_priv_mpool);
if (ret < 0) {
RTE_LOG(ERR, USER1, "Error %i: Init session\n",
ret);
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index 910386282..a92467e63 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -790,7 +790,8 @@ cmd_kni(char **tokens,
static const char cmd_cryptodev_help[] =
"cryptodev <cryptodev_name>\n"
" dev <device_name> | dev_id <device_id>\n"
-" queue <n_queues> <queue_size>\n";
+" queue <n_queues> <queue_size>\n"
+" max_sessions <n_sessions>";
static void
cmd_cryptodev(char **tokens,
@@ -802,7 +803,7 @@ cmd_cryptodev(char **tokens,
char *name;
memset(¶ms, 0, sizeof(params));
- if (n_tokens != 7) {
+ if (n_tokens != 9) {
snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
return;
}
@@ -825,7 +826,7 @@ cmd_cryptodev(char **tokens,
if (strcmp(tokens[4], "queue")) {
snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "4");
+ "queue");
return;
}
@@ -841,6 +842,18 @@ cmd_cryptodev(char **tokens,
return;
}
+ if (strcmp(tokens[7], "max_sessions")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND,
+ "max_sessions");
+ return;
+ }
+
+ if (parser_read_uint32(¶ms.session_pool_size, tokens[8]) < 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID,
+ "queue_size");
+ return;
+ }
+
if (cryptodev_create(name, ¶ms) == NULL) {
snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
return;
@@ -1030,9 +1043,7 @@ static const char cmd_table_action_profile_help[] =
" stats none | pkts]\n"
" [stats pkts | bytes | both]\n"
" [time]\n"
-" [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset> "
-" mempool_create <mempool_name>\n"
-" mempool_init <mempool_name>]\n"
+" [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
" [tag]\n"
" [decap]\n";
@@ -1404,13 +1415,10 @@ cmd_table_action_profile(char **tokens,
if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
struct cryptodev *cryptodev;
- struct mempool *mempool;
- if (n_tokens < t0 + 9 ||
+ if (n_tokens < t0 + 5 ||
strcmp(tokens[t0 + 1], "dev") ||
- strcmp(tokens[t0 + 3], "offset") ||
- strcmp(tokens[t0 + 5], "mempool_create") ||
- strcmp(tokens[t0 + 7], "mempool_init")) {
+ strcmp(tokens[t0 + 3], "offset")) {
snprintf(out, out_size, MSG_ARG_MISMATCH,
"table action profile sym_crypto");
return;
@@ -1432,25 +1440,12 @@ cmd_table_action_profile(char **tokens,
return;
}
- mempool = mempool_find(tokens[t0 + 6]);
- if (mempool == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
- p.sym_crypto.mp_create = mempool->m;
-
- mempool = mempool_find(tokens[t0 + 8]);
- if (mempool == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
- p.sym_crypto.mp_init = mempool->m;
+ p.sym_crypto.mp_create = cryptodev->mp_create;
+ p.sym_crypto.mp_init = cryptodev->mp_init;
p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
- t0 += 9;
+ t0 += 5;
} /* sym_crypto */
if ((t0 < n_tokens) && (strcmp(tokens[t0], "tag") == 0)) {
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
index b365810de..ac1e38d6a 100644
--- a/examples/ip_pipeline/cryptodev.c
+++ b/examples/ip_pipeline/cryptodev.c
@@ -11,6 +11,8 @@
#include "cryptodev.h"
+#define PIPELINE_CRYPTO_SESSION_CACHE_SIZE 128
+
static struct cryptodev_list cryptodev_list;
int
@@ -53,13 +55,16 @@ cryptodev_create(const char *name, struct cryptodev_params *params)
struct cryptodev *cryptodev;
uint32_t dev_id, i;
uint32_t socket_id;
+ uint32_t cache_size;
+ char mp_name[NAME_SIZE];
int status;
/* Check input params */
if ((name == NULL) ||
cryptodev_find(name) ||
(params->n_queues == 0) ||
- (params->queue_size == 0))
+ (params->queue_size == 0) ||
+ (params->session_pool_size == 0))
return NULL;
if (params->dev_name) {
@@ -75,6 +80,11 @@ cryptodev_create(const char *name, struct cryptodev_params *params)
dev_id = params->dev_id;
}
+ cache_size = (params->session_pool_size / 2 <
+ PIPELINE_CRYPTO_SESSION_CACHE_SIZE) ?
+ (params->session_pool_size / 2) :
+ PIPELINE_CRYPTO_SESSION_CACHE_SIZE;
+
socket_id = rte_cryptodev_socket_id(dev_id);
rte_cryptodev_info_get(dev_id, &dev_info);
@@ -111,7 +121,44 @@ cryptodev_create(const char *name, struct cryptodev_params *params)
cryptodev->dev_id = dev_id;
cryptodev->n_queues = params->n_queues;
+ snprintf(mp_name, NAME_SIZE, "%s_mp%u", name, dev_id);
+ cryptodev->mp_create = rte_cryptodev_sym_session_pool_create(
+ mp_name,
+ params->session_pool_size,
+ 0,
+ cache_size,
+ 0,
+ socket_id);
+ if (!cryptodev->mp_create)
+ goto error_exit;
+
+ snprintf(mp_name, NAME_SIZE, "%s_mp_priv%u", name, dev_id);
+ cryptodev->mp_init = rte_mempool_create(
+ NULL,
+ params->session_pool_size,
+ rte_cryptodev_sym_get_private_session_size(dev_id),
+ cache_size,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ socket_id,
+ 0);
+ if (!cryptodev->mp_init)
+ goto error_exit;
+
TAILQ_INSERT_TAIL(&cryptodev_list, cryptodev, node);
return cryptodev;
+
+error_exit:
+ if (cryptodev->mp_create)
+ rte_mempool_free(cryptodev->mp_create);
+ if (cryptodev->mp_init)
+ rte_mempool_free(cryptodev->mp_init);
+
+ free(cryptodev);
+
+ return NULL;
}
diff --git a/examples/ip_pipeline/cryptodev.h b/examples/ip_pipeline/cryptodev.h
index d06b3f2f1..d00434379 100644
--- a/examples/ip_pipeline/cryptodev.h
+++ b/examples/ip_pipeline/cryptodev.h
@@ -17,6 +17,8 @@ struct cryptodev {
char name[NAME_SIZE];
uint16_t dev_id;
uint32_t n_queues;
+ struct rte_mempool *mp_create;
+ struct rte_mempool *mp_init;
};
TAILQ_HEAD(cryptodev_list, cryptodev);
@@ -35,6 +37,7 @@ struct cryptodev_params {
uint32_t dev_id; /**< Valid only when *dev_name* is NULL. */
uint32_t n_queues;
uint32_t queue_size;
+ uint32_t session_pool_size;
};
struct cryptodev *
diff --git a/examples/ip_pipeline/examples/flow_crypto.cli b/examples/ip_pipeline/examples/flow_crypto.cli
index 9b639deb7..849f9d5fe 100644
--- a/examples/ip_pipeline/examples/flow_crypto.cli
+++ b/examples/ip_pipeline/examples/flow_crypto.cli
@@ -21,14 +21,13 @@
; 5 Crypto Operation 1792 160
mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 1
-mempool MEMPOOL_SESSION0 buffer 1024 pool 1024 cache 128 cpu 1
-link LINK0 dev 0000:81:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
+link LINK0 dev 81:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
#Cryptodev
-cryptodev CRYPTO0 dev crypto_aesni_gcm0 queue 1 1024
+cryptodev CRYPTO0 dev crypto_aesni_gcm0 queue 1 1024 max_sessions 512
-table action profile AP0 ipv4 offset 270 fwd sym_crypto dev CRYPTO0 offset 1792 mempool_create MEMPOOL_SESSION0 mempool_init MEMPOOL_SESSION0
+table action profile AP0 ipv4 offset 270 fwd sym_crypto dev CRYPTO0 offset 1792
table action profile AP1 ipv4 offset 270 fwd
pipeline PIPELINE0 period 10 offset_port_id 0 cpu 1
@@ -46,7 +45,7 @@ pipeline PIPELINE0 table match stub action AP1
pipeline PIPELINE0 port in 0 table 0
pipeline PIPELINE0 port in 1 table 1
-thread 24 pipeline PIPELINE0 enable
+thread 2 pipeline PIPELINE0 enable
pipeline PIPELINE0 table 0 rule add match default action fwd port 2
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index a0ff8f7f7..fc102a396 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -55,7 +55,7 @@
#define CDEV_QUEUE_DESC 2048
#define CDEV_MAP_ENTRIES 16384
-#define CDEV_MP_NB_OBJS 2048
+#define CDEV_MP_NB_OBJS 1024
#define CDEV_MP_CACHE_SZ 64
#define MAX_QUEUE_PAIRS 1
@@ -820,11 +820,15 @@ main_loop(__attribute__((unused)) void *dummy)
qconf->inbound.sa_ctx = socket_ctx[socket_id].sa_in;
qconf->inbound.cdev_map = cdev_map_in;
qconf->inbound.session_pool = socket_ctx[socket_id].session_pool;
+ qconf->inbound.session_priv_pool =
+ socket_ctx[socket_id].session_priv_pool;
qconf->outbound.sp4_ctx = socket_ctx[socket_id].sp_ip4_out;
qconf->outbound.sp6_ctx = socket_ctx[socket_id].sp_ip6_out;
qconf->outbound.sa_ctx = socket_ctx[socket_id].sa_out;
qconf->outbound.cdev_map = cdev_map_out;
qconf->outbound.session_pool = socket_ctx[socket_id].session_pool;
+ qconf->outbound.session_priv_pool =
+ socket_ctx[socket_id].session_priv_pool;
if (qconf->nb_rx_queue == 0) {
RTE_LOG(INFO, IPSEC, "lcore %u has nothing to do\n", lcore_id);
@@ -1460,10 +1464,10 @@ cryptodevs_init(void)
dev_conf.nb_queue_pairs = qp;
uint32_t dev_max_sess = cdev_info.sym.max_nb_sessions;
- if (dev_max_sess != 0 && dev_max_sess < (CDEV_MP_NB_OBJS / 2))
+ if (dev_max_sess != 0 && dev_max_sess < CDEV_MP_NB_OBJS)
rte_exit(EXIT_FAILURE,
"Device does not support at least %u "
- "sessions", CDEV_MP_NB_OBJS / 2);
+ "sessions", CDEV_MP_NB_OBJS);
if (!socket_ctx[dev_conf.socket_id].session_pool) {
char mp_name[RTE_MEMPOOL_NAMESIZE];
@@ -1471,6 +1475,19 @@ cryptodevs_init(void)
snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
"sess_mp_%u", dev_conf.socket_id);
+ sess_mp = rte_cryptodev_sym_session_pool_create(
+ mp_name, CDEV_MP_NB_OBJS,
+ 0, CDEV_MP_CACHE_SZ, 0,
+ dev_conf.socket_id);
+ socket_ctx[dev_conf.socket_id].session_pool = sess_mp;
+ }
+
+ if (!socket_ctx[dev_conf.socket_id].session_priv_pool) {
+ char mp_name[RTE_MEMPOOL_NAMESIZE];
+ struct rte_mempool *sess_mp;
+
+ snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
+ "sess_mp_priv_%u", dev_conf.socket_id);
sess_mp = rte_mempool_create(mp_name,
CDEV_MP_NB_OBJS,
max_sess_sz,
@@ -1478,25 +1495,28 @@ cryptodevs_init(void)
0, NULL, NULL, NULL,
NULL, dev_conf.socket_id,
0);
- if (sess_mp == NULL)
- rte_exit(EXIT_FAILURE,
- "Cannot create session pool on socket %d\n",
- dev_conf.socket_id);
- else
- printf("Allocated session pool on socket %d\n",
- dev_conf.socket_id);
- socket_ctx[dev_conf.socket_id].session_pool = sess_mp;
+ socket_ctx[dev_conf.socket_id].session_priv_pool =
+ sess_mp;
}
+ if (!socket_ctx[dev_conf.socket_id].session_priv_pool ||
+ !socket_ctx[dev_conf.socket_id].session_pool)
+ rte_exit(EXIT_FAILURE,
+ "Cannot create session pool on socket %d\n",
+ dev_conf.socket_id);
+ else
+ printf("Allocated session pool on socket %d\n",
+ dev_conf.socket_id);
+
if (rte_cryptodev_configure(cdev_id, &dev_conf))
rte_panic("Failed to initialize cryptodev %u\n",
cdev_id);
qp_conf.nb_descriptors = CDEV_QUEUE_DESC;
qp_conf.mp_session =
- socket_ctx[dev_conf.socket_id].session_pool;
+ socket_ctx[dev_conf.socket_id].session_pool;
qp_conf.mp_session_private =
- socket_ctx[dev_conf.socket_id].session_pool;
+ socket_ctx[dev_conf.socket_id].session_priv_pool;
for (qp = 0; qp < dev_conf.nb_queue_pairs; qp++)
if (rte_cryptodev_queue_pair_setup(cdev_id, qp,
&qp_conf, dev_conf.socket_id))
@@ -1521,7 +1541,7 @@ cryptodevs_init(void)
snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
"sess_mp_%u", socket_id);
sess_mp = rte_mempool_create(mp_name,
- CDEV_MP_NB_OBJS,
+ (CDEV_MP_NB_OBJS * 2),
max_sess_sz,
CDEV_MP_CACHE_SZ,
0, NULL, NULL, NULL,
diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c
index 3d415f1af..9dc6e173c 100644
--- a/examples/ipsec-secgw/ipsec.c
+++ b/examples/ipsec-secgw/ipsec.c
@@ -323,7 +323,7 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
ipsec_ctx->session_pool);
rte_cryptodev_sym_session_init(ipsec_ctx->tbl[cdev_id_qp].id,
sa->crypto_session, sa->xforms,
- ipsec_ctx->session_pool);
+ ipsec_ctx->session_priv_pool);
rte_cryptodev_info_get(ipsec_ctx->tbl[cdev_id_qp].id,
&cdev_info);
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index c998c8076..f35552857 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -144,6 +144,7 @@ struct ipsec_ctx {
uint16_t last_qp;
struct cdev_qp tbl[MAX_QP_PER_LCORE];
struct rte_mempool *session_pool;
+ struct rte_mempool *session_priv_pool;
struct rte_mbuf *ol_pkts[MAX_PKT_BURST] __rte_aligned(sizeof(void *));
uint16_t ol_pkts_cnt;
};
@@ -166,6 +167,7 @@ struct socket_ctx {
struct rt_ctx *rt_ip6;
struct rte_mempool *mbuf_pool;
struct rte_mempool *session_pool;
+ struct rte_mempool *session_priv_pool;
};
struct cnt_blk {
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 1df7ba743..9982f07e9 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -221,7 +221,10 @@ static struct rte_eth_conf port_conf = {
struct rte_mempool *l2fwd_pktmbuf_pool;
struct rte_mempool *l2fwd_crypto_op_pool;
-struct rte_mempool *session_pool_socket[RTE_MAX_NUMA_NODES] = { 0 };
+static struct {
+ struct rte_mempool *sess_mp;
+ struct rte_mempool *priv_mp;
+} session_pool_socket[RTE_MAX_NUMA_NODES];
/* Per-port statistics struct */
struct l2fwd_port_statistics {
@@ -645,7 +648,6 @@ initialize_crypto_session(struct l2fwd_crypto_options *options, uint8_t cdev_id)
return NULL;
uint8_t socket_id = (uint8_t) retval;
- struct rte_mempool *sess_mp = session_pool_socket[socket_id];
if (options->xform_chain == L2FWD_CRYPTO_AEAD) {
first_xform = &options->aead_xform;
@@ -661,13 +663,14 @@ initialize_crypto_session(struct l2fwd_crypto_options *options, uint8_t cdev_id)
first_xform = &options->auth_xform;
}
- session = rte_cryptodev_sym_session_create(sess_mp);
-
+ session = rte_cryptodev_sym_session_create(
+ session_pool_socket[socket_id].sess_mp);
if (session == NULL)
return NULL;
if (rte_cryptodev_sym_session_init(cdev_id, session,
- first_xform, sess_mp) < 0)
+ first_xform,
+ session_pool_socket[socket_id].priv_mp) < 0)
return NULL;
return session;
@@ -2267,38 +2270,54 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
rte_cryptodev_scheduler_slaves_get(cdev_id,
NULL);
- sessions_needed = 2 * enabled_cdev_count * nb_slaves;
+ sessions_needed = enabled_cdev_count * nb_slaves;
#endif
} else
- sessions_needed = 2 * enabled_cdev_count;
+ sessions_needed = enabled_cdev_count;
- if (session_pool_socket[socket_id] == NULL) {
+ if (session_pool_socket[socket_id].priv_mp == NULL) {
char mp_name[RTE_MEMPOOL_NAMESIZE];
- struct rte_mempool *sess_mp;
snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
- "sess_mp_%u", socket_id);
+ "priv_sess_mp_%u", socket_id);
- /*
- * Create enough objects for session headers and
- * device private data
- */
- sess_mp = rte_mempool_create(mp_name,
+ session_pool_socket[socket_id].priv_mp =
+ rte_mempool_create(mp_name,
sessions_needed,
max_sess_sz,
- SESSION_POOL_CACHE_SIZE,
- 0, NULL, NULL, NULL,
+ 0, 0, NULL, NULL, NULL,
NULL, socket_id,
0);
- if (sess_mp == NULL) {
- printf("Cannot create session pool on socket %d\n",
+ if (session_pool_socket[socket_id].priv_mp == NULL) {
+ printf("Cannot create pool on socket %d\n",
+ socket_id);
+ return -ENOMEM;
+ }
+
+ printf("Allocated pool \"%s\" on socket %d\n",
+ mp_name, socket_id);
+ }
+
+ if (session_pool_socket[socket_id].sess_mp == NULL) {
+ char mp_name[RTE_MEMPOOL_NAMESIZE];
+ snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
+ "sess_mp_%u", socket_id);
+
+ session_pool_socket[socket_id].sess_mp =
+ rte_cryptodev_sym_session_pool_create(
+ mp_name,
+ sessions_needed,
+ 0, 0, 0, socket_id);
+
+ if (session_pool_socket[socket_id].sess_mp == NULL) {
+ printf("Cannot create pool on socket %d\n",
socket_id);
return -ENOMEM;
}
- printf("Allocated session pool on socket %d\n", socket_id);
- session_pool_socket[socket_id] = sess_mp;
+ printf("Allocated pool \"%s\" on socket %d\n",
+ mp_name, socket_id);
}
/* Set AEAD parameters */
@@ -2443,8 +2462,9 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
}
qp_conf.nb_descriptors = 2048;
- qp_conf.mp_session = session_pool_socket[socket_id];
- qp_conf.mp_session_private = session_pool_socket[socket_id];
+ qp_conf.mp_session = session_pool_socket[socket_id].sess_mp;
+ qp_conf.mp_session_private =
+ session_pool_socket[socket_id].priv_mp;
retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
socket_id);
diff --git a/examples/vhost_crypto/main.c b/examples/vhost_crypto/main.c
index cb30f84c0..8bdcb3a9c 100644
--- a/examples/vhost_crypto/main.c
+++ b/examples/vhost_crypto/main.c
@@ -46,6 +46,7 @@ struct vhost_crypto_info {
int vids[MAX_NB_SOCKETS];
uint32_t nb_vids;
struct rte_mempool *sess_pool;
+ struct rte_mempool *sess_priv_pool;
struct rte_mempool *cop_pool;
uint8_t cid;
uint32_t qid;
@@ -289,6 +290,7 @@ new_device(int vid)
}
ret = rte_vhost_crypto_create(vid, info->cid, info->sess_pool,
+ info->sess_priv_pool,
rte_lcore_to_socket_id(options.los[i].lcore_id));
if (ret) {
RTE_LOG(ERR, USER1, "Cannot create vhost crypto\n");
@@ -448,6 +450,7 @@ free_resource(void)
rte_mempool_free(info->cop_pool);
rte_mempool_free(info->sess_pool);
+ rte_mempool_free(info->sess_priv_pool);
for (j = 0; j < lo->nb_sockets; j++) {
rte_vhost_driver_unregister(lo->socket_files[i]);
@@ -528,11 +531,17 @@ main(int argc, char *argv[])
}
snprintf(name, 127, "SESS_POOL_%u", lo->lcore_id);
- info->sess_pool = rte_mempool_create(name, SESSION_MAP_ENTRIES,
+ info->sess_pool = rte_cryptodev_sym_session_pool_create(name,
+ SESSION_MAP_ENTRIES, 0, 0, 0,
+ rte_lcore_to_socket_id(lo->lcore_id));
+
+ snprintf(name, 127, "SESS_POOL_PRIV_%u", lo->lcore_id);
+ info->sess_priv_pool = rte_mempool_create(name,
+ SESSION_MAP_ENTRIES,
rte_cryptodev_sym_get_private_session_size(
info->cid), 64, 0, NULL, NULL, NULL, NULL,
rte_lcore_to_socket_id(lo->lcore_id), 0);
- if (!info->sess_pool) {
+ if (!info->sess_priv_pool || info->sess_pool) {
RTE_LOG(ERR, USER1, "Failed to create mempool");
goto error_exit;
}
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index a8f94c097..ade108b90 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -12,6 +12,7 @@ LIBABIVER := 5
# build flags
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
LDLIBS += -lrte_eal -lrte_mempool -lrte_ring -lrte_mbuf
LDLIBS += -lrte_kvargs
diff --git a/lib/librte_cryptodev/meson.build b/lib/librte_cryptodev/meson.build
index 990dd3d44..40ccce37a 100644
--- a/lib/librte_cryptodev/meson.build
+++ b/lib/librte_cryptodev/meson.build
@@ -2,6 +2,7 @@
# Copyright(c) 2017 Intel Corporation
version = 5
+allow_experimental_apis = true
sources = files('rte_cryptodev.c', 'rte_cryptodev_pmd.c')
headers = files('rte_cryptodev.h',
'rte_cryptodev_pmd.h',
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 11776b6ac..e5e60f7e2 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -189,6 +189,16 @@ const char *rte_crypto_asym_op_strings[] = {
[RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE] = "sharedsecret_compute",
};
+/**
+ * The private data structure stored in the session mempool private data.
+ */
+struct rte_cryptodev_sym_session_pool_private_data {
+ uint16_t nb_drivers;
+ /**< number of elements in sess_data array */
+ uint16_t user_data_sz;
+ /**< session user data will be placed after sess_data */
+};
+
int
rte_cryptodev_get_cipher_algo_enum(enum rte_crypto_cipher_algorithm *algo_enum,
const char *algo_string)
@@ -951,7 +961,45 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
return -EINVAL;
}
+ if (!qp_conf) {
+ CDEV_LOG_ERR("qp_conf cannot be NULL\n");
+ return -EINVAL;
+ }
+
+ if ((qp_conf->mp_session && !qp_conf->mp_session_private) ||
+ (!qp_conf->mp_session && qp_conf->mp_session_private)) {
+ CDEV_LOG_ERR("Invalid mempools\n");
+ return -EINVAL;
+ }
+
dev = &rte_crypto_devices[dev_id];
+
+ if (qp_conf->mp_session) {
+ struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
+ uint32_t obj_size = qp_conf->mp_session->elt_size;
+ uint32_t obj_priv_size = qp_conf->mp_session_private->elt_size;
+ struct rte_cryptodev_sym_session s = {0};
+
+ pool_priv = rte_mempool_get_priv(qp_conf->mp_session);
+ if (!pool_priv || qp_conf->mp_session->private_data_size <
+ sizeof(*pool_priv)) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return -EINVAL;
+ }
+
+ s.nb_drivers = pool_priv->nb_drivers;
+ s.user_data_sz = pool_priv->user_data_sz;
+
+ if ((rte_cryptodev_sym_get_existing_header_session_size(&s) >
+ obj_size) || (s.nb_drivers <= dev->driver_id) ||
+ rte_cryptodev_sym_get_private_session_size(dev_id) >
+ obj_priv_size) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return -EINVAL;
+ }
+
+ }
+
if (queue_pair_id >= dev->data->nb_queue_pairs) {
CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
return -EINVAL;
@@ -969,7 +1017,6 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
socket_id);
}
-
int
rte_cryptodev_stats_get(uint8_t dev_id, struct rte_cryptodev_stats *stats)
{
@@ -1143,7 +1190,6 @@ rte_cryptodev_pmd_callback_process(struct rte_cryptodev *dev,
rte_spinlock_unlock(&rte_cryptodev_cb_lock);
}
-
int
rte_cryptodev_sym_session_init(uint8_t dev_id,
struct rte_cryptodev_sym_session *sess,
@@ -1160,12 +1206,15 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
return -EINVAL;
index = dev->driver_id;
+ if (index >= sess->nb_drivers)
+ return -EINVAL;
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->sym_session_configure, -ENOTSUP);
- if (sess->sess_private_data[index] == NULL) {
+ if (sess->sess_data[index].refcnt == 0) {
ret = dev->dev_ops->sym_session_configure(dev, xforms,
- sess, mp);
+ sess, mp);
+
if (ret < 0) {
CDEV_LOG_ERR(
"dev_id %d failed to configure session details",
@@ -1174,6 +1223,7 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
}
}
+ sess->sess_data[index].refcnt++;
return 0;
}
@@ -1212,10 +1262,70 @@ rte_cryptodev_asym_session_init(uint8_t dev_id,
return 0;
}
+struct rte_mempool *__rte_experimental
+rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
+ uint32_t elt_size, uint32_t cache_size, uint16_t user_data_size,
+ int socket_id)
+{
+ struct rte_mempool *mp;
+ struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
+ uint32_t obj_sz;
+
+ obj_sz = rte_cryptodev_sym_get_header_session_size() + user_data_size;
+ if (obj_sz > elt_size)
+ CDEV_LOG_INFO("elt_size %u is expanded to %u\n", elt_size,
+ obj_sz);
+ else
+ obj_sz = elt_size;
+
+ mp = rte_mempool_create(name, nb_elts, obj_sz, cache_size,
+ (uint32_t)(sizeof(*pool_priv)),
+ NULL, NULL, NULL, NULL,
+ socket_id, 0);
+ if (mp == NULL) {
+ CDEV_LOG_ERR("%s(name=%s) failed, rte_errno=%d\n",
+ __func__, name, rte_errno);
+ return NULL;
+ }
+
+ pool_priv = rte_mempool_get_priv(mp);
+ if (!pool_priv) {
+ CDEV_LOG_ERR("%s(name=%s) failed to get private data\n",
+ __func__, name);
+ rte_mempool_free(mp);
+ return NULL;
+ }
+
+ pool_priv->nb_drivers = nb_drivers;
+ pool_priv->user_data_sz = user_data_size;
+
+ return mp;
+}
+
+static unsigned int
+rte_cryptodev_sym_session_data_size(struct rte_cryptodev_sym_session *sess)
+{
+ return (sizeof(sess->sess_data[0]) * sess->nb_drivers) +
+ sess->user_data_sz;
+}
+
struct rte_cryptodev_sym_session *
rte_cryptodev_sym_session_create(struct rte_mempool *mp)
{
struct rte_cryptodev_sym_session *sess;
+ struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
+
+ if (!mp) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return NULL;
+ }
+
+ pool_priv = rte_mempool_get_priv(mp);
+
+ if (!pool_priv || mp->private_data_size < sizeof(*pool_priv)) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return NULL;
+ }
/* Allocate a session structure from the session pool */
if (rte_mempool_get(mp, (void **)&sess)) {
@@ -1226,7 +1336,12 @@ rte_cryptodev_sym_session_create(struct rte_mempool *mp)
/* Clear device session pointer.
* Include the flag indicating presence of user data
*/
- memset(sess, 0, (sizeof(void *) * nb_drivers) + sizeof(uint8_t));
+ sess->nb_drivers = pool_priv->nb_drivers;
+ sess->user_data_sz = pool_priv->user_data_sz;
+ sess->opaque_data = 0;
+
+ memset(sess->sess_data, 0,
+ rte_cryptodev_sym_session_data_size(sess));
return sess;
}
@@ -1255,12 +1370,17 @@ rte_cryptodev_sym_session_clear(uint8_t dev_id,
struct rte_cryptodev_sym_session *sess)
{
struct rte_cryptodev *dev;
+ uint8_t driver_id;
dev = rte_cryptodev_pmd_get_dev(dev_id);
if (dev == NULL || sess == NULL)
return -EINVAL;
+ driver_id = dev->driver_id;
+ if (--sess->sess_data[driver_id].refcnt != 0)
+ return -EBUSY;
+
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->sym_session_clear, -ENOTSUP);
dev->dev_ops->sym_session_clear(dev, sess);
@@ -1290,16 +1410,15 @@ int
rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
{
uint8_t i;
- void *sess_priv;
struct rte_mempool *sess_mp;
if (sess == NULL)
return -EINVAL;
/* Check that all device private data has been freed */
- for (i = 0; i < nb_drivers; i++) {
- sess_priv = get_sym_session_private_data(sess, i);
- if (sess_priv != NULL)
+ /* Check that all device private data has been freed */
+ for (i = 0; i < sess->nb_drivers; i++) {
+ if (sess->sess_data[i].refcnt != 0)
return -EBUSY;
}
@@ -1334,16 +1453,32 @@ rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session *sess)
return 0;
}
-
unsigned int
rte_cryptodev_sym_get_header_session_size(void)
{
/*
- * Header contains pointers to the private data
- * of all registered drivers, and a flag which
- * indicates presence of user data
+ * Header contains all pointers to the private data
+ * of all registered drivers with a reference count, and the
+ * information of maximum number of drivers in the system and the user
+ * data size.
*/
- return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
+ struct rte_cryptodev_sym_session s = {0};
+ s.nb_drivers = nb_drivers;
+ s.user_data_sz = 0;
+
+ return (unsigned int)(sizeof(s) +
+ rte_cryptodev_sym_session_data_size(&s));
+}
+
+unsigned int __rte_experimental
+rte_cryptodev_sym_get_existing_header_session_size(
+ struct rte_cryptodev_sym_session *sess)
+{
+ if (!sess)
+ return 0;
+ else
+ return (unsigned int)(sizeof(*sess) +
+ rte_cryptodev_sym_session_data_size(sess));
}
unsigned int __rte_experimental
@@ -1361,7 +1496,6 @@ unsigned int
rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
{
struct rte_cryptodev *dev;
- unsigned int header_size = sizeof(void *) * nb_drivers;
unsigned int priv_sess_size;
if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
@@ -1374,14 +1508,6 @@ rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
priv_sess_size = (*dev->dev_ops->sym_session_get_size)(dev);
- /*
- * If size is less than session header size,
- * return the latter, as this guarantees that
- * sessionless operations will work
- */
- if (priv_sess_size < header_size)
- return header_size;
-
return priv_sess_size;
}
@@ -1415,15 +1541,13 @@ rte_cryptodev_sym_session_set_user_data(
void *data,
uint16_t size)
{
- uint16_t off_set = sizeof(void *) * nb_drivers;
- uint8_t *user_data_present = (uint8_t *)sess + off_set;
-
if (sess == NULL)
return -EINVAL;
- *user_data_present = 1;
- off_set += sizeof(uint8_t);
- rte_memcpy((uint8_t *)sess + off_set, data, size);
+ if (sess->user_data_sz < size)
+ return -ENOMEM;
+
+ rte_memcpy(sess->sess_data + sess->nb_drivers, data, size);
return 0;
}
@@ -1431,14 +1555,10 @@ void * __rte_experimental
rte_cryptodev_sym_session_get_user_data(
struct rte_cryptodev_sym_session *sess)
{
- uint16_t off_set = sizeof(void *) * nb_drivers;
- uint8_t *user_data_present = (uint8_t *)sess + off_set;
-
- if (sess == NULL || !*user_data_present)
+ if (sess == NULL || sess->user_data_sz == 0)
return NULL;
- off_set += sizeof(uint8_t);
- return (uint8_t *)sess + off_set;
+ return (void *)(sess->sess_data + sess->nb_drivers);
}
/** Initialise rte_crypto_op mempool element */
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index f9e7507da..698a859f3 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -951,14 +951,22 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
dev->data->queue_pairs[qp_id], ops, nb_ops);
}
-
/** Cryptodev symmetric crypto session
* Each session is derived from a fixed xform chain. Therefore each session
* has a fixed algo, key, op-type, digest_len etc.
*/
struct rte_cryptodev_sym_session {
- __extension__ void *sess_private_data[0];
- /**< Private symmetric session material */
+ uint64_t opaque_data;
+ /**< Can be used for external metadata */
+ uint16_t nb_drivers;
+ /**< number of elements in sess_data array */
+ uint16_t user_data_sz;
+ /**< session user data will be placed after sess_data */
+ __extension__ struct {
+ void *data;
+ uint16_t refcnt;
+ } sess_data[0];
+ /**< Driver specific session material, variable size */
};
/** Cryptodev asymmetric crypto session */
@@ -968,6 +976,37 @@ struct rte_cryptodev_asym_session {
};
/**
+ * Create a symmetric session mempool.
+ *
+ * @param name
+ * The unique mempool name.
+ * @param nb_elts
+ * The number of elements in the mempool.
+ * @param elt_size
+ * The size of the element. This value will be ignored if it is smaller than
+ * the minimum session header size required for the system. For the user who
+ * want to use the same mempool for sym session and session private data it
+ * can be the maximum value of all existing devices' private data and session
+ * header sizes.
+ * @param cache_size
+ * The number of per-lcore cache elements
+ * @param priv_size
+ * The private data size of each session.
+ * @param socket_id
+ * The *socket_id* argument is the socket identifier in the case of
+ * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
+ * constraint for the reserved zone.
+ *
+ * @return
+ * - On success return size of the session
+ * - On failure returns 0
+ */
+struct rte_mempool * __rte_experimental
+rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
+ uint32_t elt_size, uint32_t cache_size, uint16_t priv_size,
+ int socket_id);
+
+/**
* Create symmetric crypto session header (generic with no private data)
*
* @param mempool Symmetric session mempool to allocate session
@@ -1097,15 +1136,31 @@ rte_cryptodev_asym_session_clear(uint8_t dev_id,
struct rte_cryptodev_asym_session *sess);
/**
- * Get the size of the header session, for all registered drivers.
+ * Get the size of the header session, for all registered drivers excluding
+ * the user data size.
*
* @return
- * Size of the symmetric eader session.
+ * Size of the symmetric header session.
*/
unsigned int
rte_cryptodev_sym_get_header_session_size(void);
/**
+ * Get the size of the header session from created session.
+ *
+ * @param sess
+ * The sym cryptodev session pointer
+ *
+ * @return
+ * - If sess is not NULL, return the size of the header session including
+ * the private data size defined within sess.
+ * - If sess is NULL, return 0.
+ */
+unsigned int __rte_experimental
+rte_cryptodev_sym_get_existing_header_session_size(
+ struct rte_cryptodev_sym_session *sess);
+
+/**
* Get the size of the asymmetric session header, for all registered drivers.
*
* @return
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index f15c9af30..defe05ea0 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -475,14 +475,23 @@ RTE_INIT(init_ ##driver_id)\
static inline void *
get_sym_session_private_data(const struct rte_cryptodev_sym_session *sess,
uint8_t driver_id) {
- return sess->sess_private_data[driver_id];
+ if (unlikely(sess->nb_drivers <= driver_id))
+ return NULL;
+
+ return sess->sess_data[driver_id].data;
}
static inline void
set_sym_session_private_data(struct rte_cryptodev_sym_session *sess,
uint8_t driver_id, void *private_data)
{
- sess->sess_private_data[driver_id] = private_data;
+ if (unlikely(sess->nb_drivers <= driver_id)) {
+ CDEV_LOG_ERR("Set private data for driver %u not allowed\n",
+ driver_id);
+ return;
+ }
+
+ sess->sess_data[driver_id].data = private_data;
}
static inline void *
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index a695b61dc..0d0f3bc28 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -105,4 +105,6 @@ EXPERIMENTAL {
rte_cryptodev_sym_session_set_user_data;
rte_crypto_asym_op_strings;
rte_crypto_asym_xform_strings;
+ rte_cryptodev_sym_session_pool_create;
+ rte_cryptodev_sym_get_existing_header_session_size;
};
diff --git a/lib/librte_vhost/rte_vhost_crypto.h b/lib/librte_vhost/rte_vhost_crypto.h
index f9fbc0548..d08e0ffab 100644
--- a/lib/librte_vhost/rte_vhost_crypto.h
+++ b/lib/librte_vhost/rte_vhost_crypto.h
@@ -26,8 +26,9 @@ enum rte_vhost_crypto_zero_copy {
* The identifier of DPDK Cryptodev, the same cryptodev_id can be assigned to
* multiple Vhost-crypto devices.
* @param sess_pool
- * The pointer to the created cryptodev session pool with the private data size
- * matches the target DPDK Cryptodev.
+ * The pointer to the created cryptodev session pool.
+ * @param sess_priv_pool
+ * The pointer to the created cryptodev session private data mempool.
* @param socket_id
* NUMA Socket ID to allocate resources on. *
* @return
@@ -36,7 +37,9 @@ enum rte_vhost_crypto_zero_copy {
*/
int __rte_experimental
rte_vhost_crypto_create(int vid, uint8_t cryptodev_id,
- struct rte_mempool *sess_pool, int socket_id);
+ struct rte_mempool *sess_pool,
+ struct rte_mempool *sess_priv_pool,
+ int socket_id);
/**
* Free the Vhost-crypto instance
diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c
index dd01afc08..598196fb7 100644
--- a/lib/librte_vhost/vhost_crypto.c
+++ b/lib/librte_vhost/vhost_crypto.c
@@ -198,6 +198,7 @@ struct vhost_crypto {
struct rte_hash *session_map;
struct rte_mempool *mbuf_pool;
struct rte_mempool *sess_pool;
+ struct rte_mempool *sess_priv_pool;
struct rte_mempool *wb_pool;
/** DPDK cryptodev ID */
@@ -369,7 +370,7 @@ vhost_crypto_create_sess(struct vhost_crypto *vcrypto,
}
if (rte_cryptodev_sym_session_init(vcrypto->cid, session, &xform1,
- vcrypto->sess_pool) < 0) {
+ vcrypto->sess_priv_pool) < 0) {
VC_LOG_ERR("Failed to initialize session");
sess_param->session_id = -VIRTIO_CRYPTO_ERR;
return;
@@ -1293,7 +1294,9 @@ vhost_crypto_complete_one_vm_requests(struct rte_crypto_op **ops,
int __rte_experimental
rte_vhost_crypto_create(int vid, uint8_t cryptodev_id,
- struct rte_mempool *sess_pool, int socket_id)
+ struct rte_mempool *sess_pool,
+ struct rte_mempool *sess_priv_pool,
+ int socket_id)
{
struct virtio_net *dev = get_device(vid);
struct rte_hash_parameters params = {0};
@@ -1321,6 +1324,7 @@ rte_vhost_crypto_create(int vid, uint8_t cryptodev_id,
}
vcrypto->sess_pool = sess_pool;
+ vcrypto->sess_priv_pool = sess_priv_pool;
vcrypto->cid = cryptodev_id;
vcrypto->cache_session_id = UINT64_MAX;
vcrypto->last_session_id = 1;
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index aac0b1f0b..238b7dd34 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -48,6 +48,7 @@ struct crypto_testsuite_params {
struct rte_mempool *large_mbuf_pool;
struct rte_mempool *op_mpool;
struct rte_mempool *session_mpool;
+ struct rte_mempool *session_priv_mpool;
struct rte_cryptodev_config conf;
struct rte_cryptodev_qp_conf qp_conf;
@@ -444,17 +445,24 @@ testsuite_setup(void)
return TEST_FAILED;
}
- ts_params->session_mpool = rte_mempool_create(
- "test_sess_mp",
- MAX_NB_SESSIONS * 2,
- session_size,
- 0, 0, NULL, NULL, NULL,
- NULL, SOCKET_ID_ANY,
- 0);
-
+ ts_params->session_mpool = rte_cryptodev_sym_session_pool_create(
+ "test_sess_mp", MAX_NB_SESSIONS, 0, 0, 0,
+ SOCKET_ID_ANY);
TEST_ASSERT_NOT_NULL(ts_params->session_mpool,
"session mempool allocation failed");
+ ts_params->session_priv_mpool = rte_mempool_create(
+ "test_sess_mp_priv",
+ MAX_NB_SESSIONS,
+ session_size,
+ 0, 0, NULL, NULL, NULL,
+ NULL, SOCKET_ID_ANY,
+ 0);
+ TEST_ASSERT_NOT_NULL(ts_params->session_priv_mpool,
+ "session mempool allocation failed");
+
+
+
TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id,
&ts_params->conf),
"Failed to configure cryptodev %u with %u qps",
@@ -462,7 +470,7 @@ testsuite_setup(void)
ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
ts_params->qp_conf.mp_session = ts_params->session_mpool;
- ts_params->qp_conf.mp_session_private = ts_params->session_mpool;
+ ts_params->qp_conf.mp_session_private = ts_params->session_priv_mpool;
for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
@@ -491,6 +499,11 @@ testsuite_teardown(void)
}
/* Free session mempools */
+ if (ts_params->session_priv_mpool != NULL) {
+ rte_mempool_free(ts_params->session_priv_mpool);
+ ts_params->session_priv_mpool = NULL;
+ }
+
if (ts_params->session_mpool != NULL) {
rte_mempool_free(ts_params->session_mpool);
ts_params->session_mpool = NULL;
@@ -510,6 +523,9 @@ ut_setup(void)
/* Reconfigure device to default parameters */
ts_params->conf.socket_id = SOCKET_ID_ANY;
+ ts_params->qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT;
+ ts_params->qp_conf.mp_session = ts_params->session_mpool;
+ ts_params->qp_conf.mp_session_private = ts_params->session_priv_mpool;
TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0],
&ts_params->conf),
@@ -710,7 +726,7 @@ test_queue_pair_descriptor_setup(void)
*/
qp_conf.nb_descriptors = MIN_NUM_OPS_INFLIGHT; /* min size*/
qp_conf.mp_session = ts_params->session_mpool;
- qp_conf.mp_session_private = ts_params->session_mpool;
+ qp_conf.mp_session_private = ts_params->session_priv_mpool;
for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
@@ -1337,7 +1353,7 @@ test_AES_CBC_HMAC_SHA1_encrypt_digest(void)
/* Create crypto session*/
rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
ut_params->sess, &ut_params->cipher_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
/* Generate crypto op data structure */
@@ -1551,7 +1567,7 @@ test_AES_cipheronly_mb_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)),
@@ -1570,7 +1586,7 @@ test_AES_docsis_mb_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)),
@@ -1589,7 +1605,7 @@ test_AES_docsis_qat_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)),
@@ -1608,7 +1624,7 @@ test_DES_docsis_qat_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)),
@@ -1627,7 +1643,7 @@ test_authonly_mb_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)),
@@ -1646,7 +1662,7 @@ test_authonly_qat_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)),
@@ -1664,7 +1680,7 @@ test_AES_chain_mb_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)),
@@ -1685,7 +1701,7 @@ test_AES_cipheronly_scheduler_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)),
@@ -1704,7 +1720,7 @@ test_AES_chain_scheduler_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)),
@@ -1723,7 +1739,7 @@ test_authonly_scheduler_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD)),
@@ -1744,7 +1760,7 @@ test_AES_chain_openssl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)),
@@ -1763,7 +1779,7 @@ test_AES_cipheronly_openssl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)),
@@ -1782,7 +1798,7 @@ test_AES_chain_ccp_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CCP_PMD)),
@@ -1801,7 +1817,7 @@ test_AES_cipheronly_ccp_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CCP_PMD)),
@@ -1820,7 +1836,7 @@ test_AES_chain_qat_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)),
@@ -1839,7 +1855,7 @@ test_AES_cipheronly_qat_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)),
@@ -1858,7 +1874,7 @@ test_AES_cipheronly_virtio_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD)),
@@ -1877,7 +1893,7 @@ test_AES_chain_caam_jr_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)),
@@ -1896,7 +1912,7 @@ test_AES_cipheronly_caam_jr_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)),
@@ -1915,7 +1931,7 @@ test_authonly_caam_jr_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)),
@@ -1935,7 +1951,7 @@ test_AES_chain_dpaa_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)),
@@ -1954,7 +1970,7 @@ test_AES_cipheronly_dpaa_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)),
@@ -1973,7 +1989,7 @@ test_authonly_dpaa_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)),
@@ -1992,7 +2008,7 @@ test_AES_chain_dpaa2_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)),
@@ -2011,7 +2027,7 @@ test_AES_cipheronly_dpaa2_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)),
@@ -2030,7 +2046,7 @@ test_authonly_dpaa2_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)),
@@ -2049,7 +2065,7 @@ test_authonly_openssl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)),
@@ -2068,7 +2084,7 @@ test_authonly_ccp_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CCP_PMD)),
@@ -2087,7 +2103,7 @@ test_AES_chain_armv8_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_ARMV8_PMD)),
@@ -2106,7 +2122,7 @@ test_AES_chain_mrvl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)),
@@ -2125,7 +2141,7 @@ test_AES_cipheronly_mrvl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)),
@@ -2144,7 +2160,7 @@ test_authonly_mrvl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)),
@@ -2163,7 +2179,7 @@ test_3DES_chain_mrvl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)),
@@ -2182,7 +2198,7 @@ test_3DES_cipheronly_mrvl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_MVSAM_PMD)),
@@ -2201,6 +2217,7 @@ test_AES_chain_octeontx_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool, ts_params->session_mpool,
+ ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)),
@@ -2219,6 +2236,7 @@ test_AES_cipheronly_octeontx_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool, ts_params->session_mpool,
+ ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)),
@@ -2237,6 +2255,7 @@ test_3DES_chain_octeontx_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool, ts_params->session_mpool,
+ ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)),
@@ -2255,6 +2274,7 @@ test_3DES_cipheronly_octeontx_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool, ts_params->session_mpool,
+ ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)),
@@ -2273,6 +2293,7 @@ test_authonly_octeontx_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool, ts_params->session_mpool,
+ ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD)),
@@ -2315,7 +2336,8 @@ create_wireless_algo_hash_session(uint8_t dev_id,
ts_params->session_mpool);
rte_cryptodev_sym_session_init(dev_id, ut_params->sess,
- &ut_params->auth_xform, ts_params->session_mpool);
+ &ut_params->auth_xform,
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
return 0;
}
@@ -2352,7 +2374,8 @@ create_wireless_algo_cipher_session(uint8_t dev_id,
ts_params->session_mpool);
rte_cryptodev_sym_session_init(dev_id, ut_params->sess,
- &ut_params->cipher_xform, ts_params->session_mpool);
+ &ut_params->cipher_xform,
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
return 0;
}
@@ -2468,7 +2491,8 @@ create_wireless_algo_cipher_auth_session(uint8_t dev_id,
ts_params->session_mpool);
rte_cryptodev_sym_session_init(dev_id, ut_params->sess,
- &ut_params->cipher_xform, ts_params->session_mpool);
+ &ut_params->cipher_xform,
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
return 0;
@@ -2527,7 +2551,8 @@ create_wireless_cipher_auth_session(uint8_t dev_id,
ts_params->session_mpool);
rte_cryptodev_sym_session_init(dev_id, ut_params->sess,
- &ut_params->cipher_xform, ts_params->session_mpool);
+ &ut_params->cipher_xform,
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
return 0;
@@ -2589,7 +2614,8 @@ create_wireless_algo_auth_cipher_session(uint8_t dev_id,
ts_params->session_mpool);
rte_cryptodev_sym_session_init(dev_id, ut_params->sess,
- &ut_params->auth_xform, ts_params->session_mpool);
+ &ut_params->auth_xform,
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
@@ -5075,7 +5101,7 @@ test_3DES_chain_qat_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)),
@@ -5094,7 +5120,7 @@ test_DES_cipheronly_qat_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)),
@@ -5113,7 +5139,7 @@ test_DES_cipheronly_openssl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)),
@@ -5132,7 +5158,7 @@ test_DES_docsis_openssl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)),
@@ -5151,7 +5177,7 @@ test_DES_cipheronly_mb_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)),
@@ -5169,7 +5195,7 @@ test_3DES_cipheronly_mb_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)),
@@ -5188,7 +5214,7 @@ test_DES_docsis_mb_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)),
@@ -5207,7 +5233,7 @@ test_3DES_chain_caam_jr_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)),
@@ -5226,7 +5252,7 @@ test_3DES_cipheronly_caam_jr_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD)),
@@ -5245,7 +5271,7 @@ test_3DES_chain_dpaa_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)),
@@ -5264,7 +5290,7 @@ test_3DES_cipheronly_dpaa_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD)),
@@ -5283,7 +5309,7 @@ test_3DES_chain_dpaa2_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)),
@@ -5302,7 +5328,7 @@ test_3DES_cipheronly_dpaa2_sec_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD)),
@@ -5321,7 +5347,7 @@ test_3DES_chain_ccp_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CCP_PMD)),
@@ -5340,7 +5366,7 @@ test_3DES_cipheronly_ccp_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_CCP_PMD)),
@@ -5359,7 +5385,7 @@ test_3DES_cipheronly_qat_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD)),
@@ -5378,7 +5404,7 @@ test_3DES_chain_openssl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)),
@@ -5397,7 +5423,7 @@ test_3DES_cipheronly_openssl_all(void)
status = test_blockcipher_all_tests(ts_params->mbuf_pool,
ts_params->op_mpool,
- ts_params->session_mpool,
+ ts_params->session_mpool, ts_params->session_priv_mpool,
ts_params->valid_devs[0],
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)),
@@ -5443,7 +5469,8 @@ create_aead_session(uint8_t dev_id, enum rte_crypto_aead_algorithm algo,
ts_params->session_mpool);
rte_cryptodev_sym_session_init(dev_id, ut_params->sess,
- &ut_params->aead_xform, ts_params->session_mpool);
+ &ut_params->aead_xform,
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
@@ -6547,7 +6574,7 @@ static int MD5_HMAC_create_session(struct crypto_testsuite_params *ts_params,
rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
ut_params->sess, &ut_params->auth_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
if (ut_params->sess == NULL)
return TEST_FAILED;
@@ -6728,7 +6755,7 @@ test_multi_session(void)
rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
sessions[i], &ut_params->auth_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(sessions[i],
"Session creation failed at session number %u",
i);
@@ -6766,7 +6793,7 @@ test_multi_session(void)
/* Next session create should fail */
rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
sessions[i], &ut_params->auth_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NULL(sessions[i],
"Session creation succeeded unexpectedly!");
@@ -6847,7 +6874,7 @@ test_multi_session_random_usage(void)
ts_params->valid_devs[0],
sessions[i],
&ut_paramz[i].ut_params.auth_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(sessions[i],
"Session creation failed at session number %u",
@@ -6925,7 +6952,7 @@ test_null_cipher_only_operation(void)
rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
ut_params->sess,
&ut_params->cipher_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
/* Generate Crypto op data structure */
@@ -6998,7 +7025,7 @@ test_null_auth_only_operation(void)
/* Create Crypto session*/
rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
ut_params->sess, &ut_params->auth_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
/* Generate Crypto op data structure */
@@ -7077,7 +7104,7 @@ test_null_cipher_auth_operation(void)
/* Create Crypto session*/
rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
ut_params->sess, &ut_params->cipher_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
/* Generate Crypto op data structure */
@@ -7165,7 +7192,7 @@ test_null_auth_cipher_operation(void)
/* Create Crypto session*/
rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
ut_params->sess, &ut_params->cipher_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
/* Generate Crypto op data structure */
@@ -7235,7 +7262,7 @@ test_null_invalid_operation(void)
/* Create Crypto session*/
ret = rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
ut_params->sess, &ut_params->cipher_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT(ret < 0,
"Session creation succeeded unexpectedly");
@@ -7253,7 +7280,7 @@ test_null_invalid_operation(void)
/* Create Crypto session*/
ret = rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
ut_params->sess, &ut_params->auth_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT(ret < 0,
"Session creation succeeded unexpectedly");
@@ -7294,7 +7321,7 @@ test_null_burst_operation(void)
/* Create Crypto session*/
rte_cryptodev_sym_session_init(ts_params->valid_devs[0],
ut_params->sess, &ut_params->cipher_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
TEST_ASSERT_EQUAL(rte_crypto_op_bulk_alloc(ts_params->op_mpool,
@@ -7429,7 +7456,7 @@ static int create_gmac_session(uint8_t dev_id,
rte_cryptodev_sym_session_init(dev_id, ut_params->sess,
&ut_params->auth_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
@@ -7809,7 +7836,7 @@ create_auth_session(struct crypto_unittest_params *ut_params,
rte_cryptodev_sym_session_init(dev_id, ut_params->sess,
&ut_params->auth_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
@@ -7862,7 +7889,7 @@ create_auth_cipher_session(struct crypto_unittest_params *ut_params,
rte_cryptodev_sym_session_init(dev_id, ut_params->sess,
&ut_params->auth_xform,
- ts_params->session_mpool);
+ ts_params->session_priv_mpool);
TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
@@ -8740,12 +8767,14 @@ test_scheduler_attach_slave_op(void)
for (i = 0; i < rte_cryptodev_count() && nb_devs_attached < 2;
i++) {
struct rte_cryptodev_info info;
+ unsigned int session_size;
rte_cryptodev_info_get(i, &info);
if (info.driver_id != rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD)))
continue;
+ session_size = rte_cryptodev_sym_get_private_session_size(i);
/*
* Create the session mempool again, since now there are new devices
* to use the mempool.
@@ -8754,8 +8783,10 @@ test_scheduler_attach_slave_op(void)
rte_mempool_free(ts_params->session_mpool);
ts_params->session_mpool = NULL;
}
- unsigned int session_size =
- rte_cryptodev_sym_get_private_session_size(i);
+ if (ts_params->session_priv_mpool) {
+ rte_mempool_free(ts_params->session_priv_mpool);
+ ts_params->session_priv_mpool = NULL;
+ }
if (info.sym.max_nb_sessions != 0 &&
info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
@@ -8766,22 +8797,40 @@ test_scheduler_attach_slave_op(void)
return TEST_FAILED;
}
/*
- * Create mempool with maximum number of sessions * 2,
+ * Create mempool with maximum number of sessions,
* to include the session headers
*/
if (ts_params->session_mpool == NULL) {
- ts_params->session_mpool = rte_mempool_create(
- "test_sess_mp",
- MAX_NB_SESSIONS * 2,
+ ts_params->session_mpool =
+ rte_cryptodev_sym_session_pool_create(
+ "test_sess_mp",
+ MAX_NB_SESSIONS, 0, 0, 0,
+ SOCKET_ID_ANY);
+ TEST_ASSERT_NOT_NULL(ts_params->session_mpool,
+ "session mempool allocation failed");
+ }
+
+ /*
+ * Create mempool with maximum number of sessions,
+ * to include device specific session private data
+ */
+ if (ts_params->session_priv_mpool == NULL) {
+ ts_params->session_priv_mpool = rte_mempool_create(
+ "test_sess_mp_priv",
+ MAX_NB_SESSIONS,
session_size,
0, 0, NULL, NULL, NULL,
NULL, SOCKET_ID_ANY,
0);
- TEST_ASSERT_NOT_NULL(ts_params->session_mpool,
+ TEST_ASSERT_NOT_NULL(ts_params->session_priv_mpool,
"session mempool allocation failed");
}
+ ts_params->qp_conf.mp_session = ts_params->session_mpool;
+ ts_params->qp_conf.mp_session_private =
+ ts_params->session_priv_mpool;
+
ret = rte_cryptodev_scheduler_slave_attach(sched_id,
(uint8_t)i);
diff --git a/test/test/test_cryptodev_blockcipher.c b/test/test/test_cryptodev_blockcipher.c
index 1c3f29f6b..4d6f46a6e 100644
--- a/test/test/test_cryptodev_blockcipher.c
+++ b/test/test/test_cryptodev_blockcipher.c
@@ -25,6 +25,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
struct rte_mempool *mbuf_pool,
struct rte_mempool *op_mpool,
struct rte_mempool *sess_mpool,
+ struct rte_mempool *sess_priv_mpool,
uint8_t dev_id,
int driver_id,
char *test_msg)
@@ -347,7 +348,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
sess = rte_cryptodev_sym_session_create(sess_mpool);
rte_cryptodev_sym_session_init(dev_id, sess, init_xform,
- sess_mpool);
+ sess_priv_mpool);
if (!sess) {
snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
"FAILED: %s", __LINE__,
@@ -615,6 +616,7 @@ int
test_blockcipher_all_tests(struct rte_mempool *mbuf_pool,
struct rte_mempool *op_mpool,
struct rte_mempool *sess_mpool,
+ struct rte_mempool *sess_priv_mpool,
uint8_t dev_id,
int driver_id,
enum blockcipher_test_type test_type)
@@ -730,7 +732,8 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool,
continue;
status = test_blockcipher_one_case(tc, mbuf_pool, op_mpool,
- sess_mpool, dev_id, driver_id, test_msg);
+ sess_mpool, sess_priv_mpool, dev_id, driver_id,
+ test_msg);
printf(" %u) TestCase %s %s\n", test_index ++,
tc->test_descr, test_msg);
diff --git a/test/test/test_cryptodev_blockcipher.h b/test/test/test_cryptodev_blockcipher.h
index f8bd85838..5c22d5da6 100644
--- a/test/test/test_cryptodev_blockcipher.h
+++ b/test/test/test_cryptodev_blockcipher.h
@@ -104,6 +104,7 @@ int
test_blockcipher_all_tests(struct rte_mempool *mbuf_pool,
struct rte_mempool *op_mpool,
struct rte_mempool *sess_mpool,
+ struct rte_mempool *sess_priv_mpool,
uint8_t dev_id,
int driver_id,
enum blockcipher_test_type test_type);
diff --git a/test/test/test_event_crypto_adapter.c b/test/test/test_event_crypto_adapter.c
index 54717870e..f750ce3d8 100644
--- a/test/test/test_event_crypto_adapter.c
+++ b/test/test/test_event_crypto_adapter.c
@@ -61,6 +61,7 @@ struct event_crypto_adapter_test_params {
struct rte_mempool *mbuf_pool;
struct rte_mempool *op_mpool;
struct rte_mempool *session_mpool;
+ struct rte_mempool *session_priv_mpool;
struct rte_cryptodev_config *config;
uint8_t crypto_event_port_id;
};
@@ -193,12 +194,13 @@ test_op_forward_mode(uint8_t session_less)
sym_op = op->sym;
if (!session_less) {
- sess = rte_cryptodev_sym_session_create(params.session_mpool);
+ sess = rte_cryptodev_sym_session_create(
+ params.session_mpool);
TEST_ASSERT_NOT_NULL(sess, "Session creation failed\n");
/* Create Crypto session*/
rte_cryptodev_sym_session_init(TEST_CDEV_ID, sess,
- &cipher_xform, params.session_mpool);
+ &cipher_xform, params.session_priv_mpool);
ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID,
evdev, &cap);
@@ -381,7 +383,8 @@ test_op_new_mode(uint8_t session_less)
sym_op = op->sym;
if (!session_less) {
- sess = rte_cryptodev_sym_session_create(params.session_mpool);
+ sess = rte_cryptodev_sym_session_create(
+ params.session_mpool);
TEST_ASSERT_NOT_NULL(sess, "Session creation failed\n");
ret = rte_event_crypto_adapter_caps_get(TEST_ADAPTER_ID,
@@ -396,7 +399,7 @@ test_op_new_mode(uint8_t session_less)
&m_data, sizeof(m_data));
}
rte_cryptodev_sym_session_init(TEST_CDEV_ID, sess,
- &cipher_xform, params.session_mpool);
+ &cipher_xform, params.session_priv_mpool);
rte_crypto_op_attach_sym_session(op, sess);
} else {
struct rte_crypto_sym_xform *first_xform;
@@ -526,15 +529,20 @@ configure_cryptodev(void)
session_size = rte_cryptodev_sym_get_private_session_size(TEST_CDEV_ID);
session_size += sizeof(union rte_event_crypto_metadata);
- params.session_mpool = rte_mempool_create(
- "CRYPTO_ADAPTER_SESSION_MP",
- MAX_NB_SESSIONS * 2,
+ params.session_mpool = rte_cryptodev_sym_session_pool_create(
+ "CRYPTO_ADAPTER_SESSION_MP",
+ MAX_NB_SESSIONS, 0, 0, 0, SOCKET_ID_ANY);
+ TEST_ASSERT_NOT_NULL(params.session_mpool,
+ "session mempool allocation failed\n");
+
+ params.session_priv_mpool = rte_mempool_create(
+ "CRYPTO_ADAPTER_SESSION_MP_PRIV",
+ MAX_NB_SESSIONS,
session_size,
0, 0, NULL, NULL, NULL,
NULL, SOCKET_ID_ANY,
0);
-
- TEST_ASSERT_NOT_NULL(params.session_mpool,
+ TEST_ASSERT_NOT_NULL(params.session_priv_mpool,
"session mempool allocation failed\n");
rte_cryptodev_info_get(TEST_CDEV_ID, &info);
@@ -547,7 +555,7 @@ configure_cryptodev(void)
qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
qp_conf.mp_session = params.session_mpool;
- qp_conf.mp_session_private = params.session_mpool;
+ qp_conf.mp_session_private = params.session_priv_mpool;
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
TEST_CDEV_ID, TEST_CDEV_QP_ID, &qp_conf,
@@ -859,6 +867,10 @@ crypto_teardown(void)
rte_mempool_free(params.session_mpool);
params.session_mpool = NULL;
}
+ if (params.session_priv_mpool != NULL) {
+ rte_mempool_free(params.session_priv_mpool);
+ params.session_priv_mpool = NULL;
+ }
/* Free ops mempool */
if (params.op_mpool != NULL) {
--
2.13.6
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [RFC 00/14] prefix network structures
2018-12-20 23:48 0% ` Stephen Hemminger
@ 2018-12-21 14:38 0% ` Wiles, Keith
2018-12-21 15:14 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Wiles, Keith @ 2018-12-21 14:38 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Yigit, Ferruh, Olivier MATZ, dpdk-dev, Richardson, Bruce
> On Dec 20, 2018, at 5:48 PM, Stephen Hemminger <stephen@networkplumber.org> wrote:
>
> On Thu, 20 Dec 2018 21:59:37 +0000
> Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>
>> On 10/24/2018 9:18 AM, olivier.matz at 6wind.com (Olivier Matz) wrote:
>>> This RFC targets 19.02.
>>>
>>> The rte_net headers conflict with the libc headers, because
>>> some definitions are duplicated, sometimes with few differences.
>>> This was discussed in [1], and more recently at the techboard.
>>>
>>> Before sending the deprecation notice (target for this is 18.11),
>>> here is a draft that can be discussed.
>>>
>>> This RFC adds the rte_ (or RTE_) prefix to all structures, functions
>>> and defines in rte_net library. This is a big changeset, that will
>>> break the API of many functions, but not the ABI.
>>>
>>> One question I'm asking is how can we manage the transition.
>>> Initially, I hoped it was possible to have a compat layer during
>>> one release (supporting both prefixed and unprefixed names), but
>>> now that the patch is done, it seems the impact is too big, and
>>> impacts too many libraries.
>>>
>>> Few examples:
>>> - rte_eth_macaddr_get/add/remove() use a (struct rte_ether_addr *)
>>> - many rte_flow structures use the rte_ prefixed net structures
>>> - the mac field of virtio_net structure is rte_ether_addr
>>> - the first arg of rte_thash_load_v6_addrs is (struct rte_ipv6_hdr *)
>>> ...
>>>
>>> Therefore, it is clear that doing this would break the compilation
>>> of many external applications.
>>>
>>> Another drawback we need to take in account: it will make the
>>> backport of patches more difficult, although this is something
>>> that could be tempered by a script.
>>>
>>> While it is obviously better to have a good namespace convention,
>>> we need to identify the issues we have today before deciding it's
>>> worth doing the change.
>>>
>>> Comments?
>>
>> Is there an consensus about the patchset? There was a decision on techboard to
>> go with this change (adding rte_ prefix) [1].
>>
>>
>> This is something that will affect DPDK consumers. Since many APIs are changing
>> most probably will break API compatibility for many libraries.
>>
>> Meanwhile the conflict with the libc headers mentioned a few times in the past,
>> this is something we need to fix.
>>
>> There are a few comments reluctant to this big modification, but what I
>> understand from Olivier's response both using BSD defines or having
>> compatibility headers in DPDK won't solve the problem completely.
>>
>> And assuming we will continue with this solution, another question is do we
>> still want to push in 19.02 scope? (And from process point of view I think a
>> deprecation notice is not merged for this change in 18.11 scope.)
>>
>> With the prediction of 19.05 will be big and already break API/ABI for some
>> libraries, can we push this into 19.05 as an early merge into repo?
>>
>> And I think this patch will affect LTS releases and will break auto backporting
>> for many fixes because it touches many places, so pushing this change even to
>> next LTS (19.11) can be an option.
>>
>>
>> Olivier, Thomas,
>>
>> What do you think about postponing this to 19.05 or even 19.11 ?
>>
>>
>>
>> [1]
>> https://mails.dpdk.org/archives/dev/2018-October/116695.html
>>
>>>
>>>
>>> Things that are missing in RFC:
>>> - test with FreeBSD
>>> - manually fix some indentation issues
>>>
>>>
>>> Olivier Matz (14):
>>> net: add rte prefix to arp structures
>>> net: add rte prefix to arp defines
>>> net: add rte prefix to ether structures
>>> net: add rte prefix to ether functions
>>> net: add rte prefix to ether defines
>>> net: add rte prefix to esp structure
>>> net: add rte prefix to gre structure
>>> net: add rte prefix to icmp structure
>>> net: add rte prefix to icmp defines
>>> net: add rte prefix to ip structure
>>> net: add rte prefix to ip defines
>>> net: add rte prefix to sctp structure
>>> net: add rte prefix to tcp structure
>>> net: add rte prefix to udp structure
>>
>>
>
> Sigh. Another case where DPDK has to reinvent something because
> we can't figure out how to do dependent libraries correctly.
> I would have rather just using the existing Linux, BSD definitions
> and fixing the DPDK code.
>
> It is probably the only viable compromise, but it adds to long
> term maintenance, and breaks DPDK applications. Neither of which
> is a good thing.
>
> Should this be done by marking the old structure deprecated
> first? Ideally, spread over three releases: first, tell the users
> in the documentation it is coming; second, mark the old structures
> as deprecated causing compiler warnings; third, remove the old
> definitions. Doing at once is introducing user pain for no gain.
+1
Regards,
Keith
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC 00/14] prefix network structures
2018-12-21 14:38 0% ` Wiles, Keith
@ 2018-12-21 15:14 0% ` Ferruh Yigit
2018-12-27 9:35 0% ` Olivier Matz
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-12-21 15:14 UTC (permalink / raw)
To: Wiles, Keith, Stephen Hemminger; +Cc: Olivier MATZ, dpdk-dev, Richardson, Bruce
On 12/21/2018 2:38 PM, Wiles, Keith wrote:
>
>
>> On Dec 20, 2018, at 5:48 PM, Stephen Hemminger <stephen@networkplumber.org> wrote:
>>
>> On Thu, 20 Dec 2018 21:59:37 +0000
>> Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>
>>> On 10/24/2018 9:18 AM, olivier.matz at 6wind.com (Olivier Matz) wrote:
>>>> This RFC targets 19.02.
>>>>
>>>> The rte_net headers conflict with the libc headers, because
>>>> some definitions are duplicated, sometimes with few differences.
>>>> This was discussed in [1], and more recently at the techboard.
>>>>
>>>> Before sending the deprecation notice (target for this is 18.11),
>>>> here is a draft that can be discussed.
>>>>
>>>> This RFC adds the rte_ (or RTE_) prefix to all structures, functions
>>>> and defines in rte_net library. This is a big changeset, that will
>>>> break the API of many functions, but not the ABI.
>>>>
>>>> One question I'm asking is how can we manage the transition.
>>>> Initially, I hoped it was possible to have a compat layer during
>>>> one release (supporting both prefixed and unprefixed names), but
>>>> now that the patch is done, it seems the impact is too big, and
>>>> impacts too many libraries.
>>>>
>>>> Few examples:
>>>> - rte_eth_macaddr_get/add/remove() use a (struct rte_ether_addr *)
>>>> - many rte_flow structures use the rte_ prefixed net structures
>>>> - the mac field of virtio_net structure is rte_ether_addr
>>>> - the first arg of rte_thash_load_v6_addrs is (struct rte_ipv6_hdr *)
>>>> ...
>>>>
>>>> Therefore, it is clear that doing this would break the compilation
>>>> of many external applications.
>>>>
>>>> Another drawback we need to take in account: it will make the
>>>> backport of patches more difficult, although this is something
>>>> that could be tempered by a script.
>>>>
>>>> While it is obviously better to have a good namespace convention,
>>>> we need to identify the issues we have today before deciding it's
>>>> worth doing the change.
>>>>
>>>> Comments?
>>>
>>> Is there an consensus about the patchset? There was a decision on techboard to
>>> go with this change (adding rte_ prefix) [1].
>>>
>>>
>>> This is something that will affect DPDK consumers. Since many APIs are changing
>>> most probably will break API compatibility for many libraries.
>>>
>>> Meanwhile the conflict with the libc headers mentioned a few times in the past,
>>> this is something we need to fix.
>>>
>>> There are a few comments reluctant to this big modification, but what I
>>> understand from Olivier's response both using BSD defines or having
>>> compatibility headers in DPDK won't solve the problem completely.
>>>
>>> And assuming we will continue with this solution, another question is do we
>>> still want to push in 19.02 scope? (And from process point of view I think a
>>> deprecation notice is not merged for this change in 18.11 scope.)
>>>
>>> With the prediction of 19.05 will be big and already break API/ABI for some
>>> libraries, can we push this into 19.05 as an early merge into repo?
>>>
>>> And I think this patch will affect LTS releases and will break auto backporting
>>> for many fixes because it touches many places, so pushing this change even to
>>> next LTS (19.11) can be an option.
>>>
>>>
>>> Olivier, Thomas,
>>>
>>> What do you think about postponing this to 19.05 or even 19.11 ?
>>>
>>>
>>>
>>> [1]
>>> https://mails.dpdk.org/archives/dev/2018-October/116695.html
>>>
>>>>
>>>>
>>>> Things that are missing in RFC:
>>>> - test with FreeBSD
>>>> - manually fix some indentation issues
>>>>
>>>>
>>>> Olivier Matz (14):
>>>> net: add rte prefix to arp structures
>>>> net: add rte prefix to arp defines
>>>> net: add rte prefix to ether structures
>>>> net: add rte prefix to ether functions
>>>> net: add rte prefix to ether defines
>>>> net: add rte prefix to esp structure
>>>> net: add rte prefix to gre structure
>>>> net: add rte prefix to icmp structure
>>>> net: add rte prefix to icmp defines
>>>> net: add rte prefix to ip structure
>>>> net: add rte prefix to ip defines
>>>> net: add rte prefix to sctp structure
>>>> net: add rte prefix to tcp structure
>>>> net: add rte prefix to udp structure
>>>
>>>
>>
>> Sigh. Another case where DPDK has to reinvent something because
>> we can't figure out how to do dependent libraries correctly.
>> I would have rather just using the existing Linux, BSD definitions
>> and fixing the DPDK code.
>>
>> It is probably the only viable compromise, but it adds to long
>> term maintenance, and breaks DPDK applications. Neither of which
>> is a good thing.
>>
>> Should this be done by marking the old structure deprecated
>> first? Ideally, spread over three releases: first, tell the users
>> in the documentation it is coming; second, mark the old structures
>> as deprecated causing compiler warnings; third, remove the old
>> definitions. Doing at once is introducing user pain for no gain.
>
> +1
With the current timeline, readiness of the patch and comments, at least it
won't able to make this release, I will update the patchset status as 'Deferred'
Should we discuss this again in techboard?
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2 1/2] doc: clean ABI/API policy guide
2018-12-19 12:52 35% [dpdk-dev] [RFC 1/2] doc: clean ABI/API policy guide Ferruh Yigit
2018-12-20 8:02 4% ` Luca Boccassi
2018-12-20 8:03 8% ` Luca Boccassi
@ 2018-12-21 15:57 35% ` Ferruh Yigit
2019-01-22 16:23 35% ` [dpdk-dev] [PATCH v3 1/3] " Ferruh Yigit
2 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-12-21 15:57 UTC (permalink / raw)
To: Ferruh Yigit, John McNamara, Marko Kovacevic
Cc: dev, Luca Boccassi, Kevin Traynor, Yongseok Koh, Neil Horman
The original document written from the point of ABI versioning but later
additions make document confusing, convert document into a ABI/API
policy documentation and organize the document in subsections:
- ABI/API Deprecation
- Experimental APIs
- Library versioning
- ABI versioning
Aim to clarify confusion between deprecation versioned ABI and overall
ABI/API deprecation, also ABI versioning and Library versioning by
organizing the sections.
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
Cc: Luca Boccassi <bluca@debian.org>
Cc: Kevin Traynor <ktraynor@redhat.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
---
doc/guides/contributing/versioning.rst | 132 +++++++++++++------------
1 file changed, 71 insertions(+), 61 deletions(-)
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 01b36247e..19af56cd2 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -1,33 +1,31 @@
.. SPDX-License-Identifier: BSD-3-Clause
Copyright 2018 The DPDK contributors
-Managing ABI updates
-====================
+DPDK ABI/API policy
+===================
Description
-----------
This document details some methods for handling ABI management in the DPDK.
-Note this document is not exhaustive, in that C library versioning is flexible
-allowing multiple methods to achieve various goals, but it will provide the user
-with some introductory methods
General Guidelines
------------------
#. Whenever possible, ABI should be preserved
-#. Libraries or APIs marked in ``experimental`` state may change without constraint.
+#. ABI/API may be changed with a deprecation process
+#. The modification of symbols can generally be managed with versioning
+#. Libraries or APIs marked in ``experimental`` state may change without constraint
#. New APIs will be marked as ``experimental`` for at least one release to allow
any issues found by users of the new API to be fixed quickly
#. The addition of symbols is generally not problematic
-#. The modification of symbols can generally be managed with versioning
#. The removal of symbols generally is an ABI break and requires bumping of the
LIBABIVER macro
#. Updates to the minimum hardware requirements, which drop support for hardware which
was previously supported, should be treated as an ABI change.
What is an ABI
---------------
+~~~~~~~~~~~~~~
An ABI (Application Binary Interface) is the set of runtime interfaces exposed
by a library. It is similar to an API (Application Programming Interface) but
@@ -39,9 +37,13 @@ Therefore, in the case of dynamic linking, it is critical that an ABI is
preserved, or (when modified), done in such a way that the application is unable
to behave improperly or in an unexpected fashion.
-The DPDK ABI policy
+
+ABI/API Deprecation
-------------------
+The DPDK ABI policy
+~~~~~~~~~~~~~~~~~~~
+
ABI versions are set at the time of major release labeling, and the ABI may
change multiple times, without warning, between the last release label and the
HEAD label of the git tree.
@@ -99,8 +101,36 @@ readability purposes should be avoided.
follow the relevant deprecation policy procedures as above: 3 acks and
announcement at least one release in advance.
+Examples of Deprecation Notices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+ to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+ in version 2.0. Backwards compatibility will be maintained for this function
+ until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+ performance reasons. Existing binary applications will have backwards
+ compatibility in release 2.0, while newly built binaries will need to
+ reference the new structure variant ``struct rte_foo2``. Compatibility will
+ be removed in release 2.2, and all applications will require updating and
+ rebuilding to the new structure at that time, which will be renamed to the
+ original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+ upcoming release 2.0 will not contain these changes, but release 2.1 will,
+ and no backwards compatibility is planned due to the extensive nature of
+ these changes. Binaries using this library built prior to version 2.1 will
+ require updating and recompilation.
+
+
Experimental APIs
-~~~~~~~~~~~~~~~~~
+-----------------
APIs marked as ``experimental`` are not considered part of the ABI and may
change without warning at any time. Since changes to APIs are most likely
@@ -130,35 +160,38 @@ is not required. Though, an API should remain in experimental state for at least
one release. Thereafter, normal process of posting patch for review to mailing
list can be followed.
-Examples of Deprecation Notices
--------------------------------
-The following are some examples of ABI deprecation notices which would be
-added to the Release Notes:
+Library versioning
+------------------
-* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
- to be replaced with the inline function ``rte_foo()``.
+Downstreams might want to provide different DPDK releases at the same time to
+support multiple consumers of DPDK linked against older and newer sonames.
-* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
- in version 2.0. Backwards compatibility will be maintained for this function
- until the release of version 2.1
+Also due to the interdependencies that DPDK libraries can have applications
+might end up with an executable space in which multiple versions of a library
+are mapped by ld.so.
-* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
- performance reasons. Existing binary applications will have backwards
- compatibility in release 2.0, while newly built binaries will need to
- reference the new structure variant ``struct rte_foo2``. Compatibility will
- be removed in release 2.2, and all applications will require updating and
- rebuilding to the new structure at that time, which will be renamed to the
- original ``struct rte_foo``.
+Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
+depending on LibA.
-* Significant ABI changes are planned for the ``librte_dostuff`` library. The
- upcoming release 2.0 will not contain these changes, but release 2.1 will,
- and no backwards compatibility is planned due to the extensive nature of
- these changes. Binaries using this library built prior to version 2.1 will
- require updating and recompilation.
+.. note::
+
+ Application
+ \-> LibA.old
+ \-> LibB.new -> LibA.new
+
+That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
+If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
+library - versions defined in the libraries ``LIBABIVER``.
+An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
+``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
+
+
+ABI versioning
+--------------
Versioning Macros
------------------
+~~~~~~~~~~~~~~~~~
When a symbol is exported from a library to provide an API, it also provides a
calling convention (ABI) that is embodied in its name, return type and
@@ -186,36 +219,11 @@ The macros exported are:
fully qualified function ``p``, so that if a symbol becomes versioned, it
can still be mapped back to the public symbol name.
-Setting a Major ABI version
----------------------------
-
-Downstreams might want to provide different DPDK releases at the same time to
-support multiple consumers of DPDK linked against older and newer sonames.
-
-Also due to the interdependencies that DPDK libraries can have applications
-might end up with an executable space in which multiple versions of a library
-are mapped by ld.so.
-
-Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
-depending on LibA.
-
-.. note::
-
- Application
- \-> LibA.old
- \-> LibB.new -> LibA.new
-
-That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
-If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
-library - versions defined in the libraries ``LIBABIVER``.
-An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
-``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
-
Examples of ABI Macro use
--------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^
Updating a public API
-~~~~~~~~~~~~~~~~~~~~~
+_____________________
Assume we have a function as follows
@@ -425,7 +433,7 @@ and a new DPDK_2.1 version, used by future built applications.
Deprecating part of a public API
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+________________________________
Lets assume that you've done the above update, and after a few releases have
passed you decide you would like to retire the old version of the function.
@@ -483,7 +491,7 @@ possibly incompatible library version:
+LIBABIVER := 2
Deprecating an entire ABI version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+_________________________________
While removing a symbol from and ABI may be useful, it is often more practical
to remove an entire version node at once. If a version node completely
@@ -532,6 +540,7 @@ Lastly, any VERSION_SYMBOL macros that point to the old version node should be
removed, taking care to keep, where need old code in place to support newer
versions of the symbol.
+
Running the ABI Validator
-------------------------
@@ -571,3 +580,4 @@ compile both tags) it will create compatibility reports in the
follows::
grep -lr Incompatible compat_reports/
+
--
2.17.2
^ permalink raw reply [relevance 35%]
* Re: [dpdk-dev] [PATCH] net/mlx5: modify-header support using Direct Verbs
@ 2018-12-25 11:38 3% ` Shahaf Shuler
2018-12-25 16:00 0% ` Dekel Peled
0 siblings, 1 reply; 200+ results
From: Shahaf Shuler @ 2018-12-25 11:38 UTC (permalink / raw)
To: Dekel Peled, Yongseok Koh; +Cc: dev, Ori Kam, Dekel Peled
Hi Dekel,
See some comments below,
Sunday, December 23, 2018 11:58 AM, Dekel Peled:
> Subject: [PATCH] net/mlx5: modify-header support using Direct Verbs
Maybe title can be: "support modify header using Direct Verbs"
>
> This patch implements the set of actions to support offload of packet header
> modifications to MLX5 NIC.
>
> Implamantation is based on RFC [1].
>
> [1] http://mails.dpdk.org/archives/dev/2018-November/119971.html
>
> Signed-off-by: Dekel Peled <dekelp@mellanox.com>
> ---
> drivers/net/mlx5/mlx5.h | 1 +
> drivers/net/mlx5/mlx5_flow.h | 56 ++-
> drivers/net/mlx5/mlx5_flow_dv.c | 998
> +++++++++++++++++++++++++++++++++++++++-
> drivers/net/mlx5/mlx5_glue.c | 22 +
> drivers/net/mlx5/mlx5_glue.h | 5 +
> drivers/net/mlx5/mlx5_prm.h | 11 +-
> 6 files changed, 1084 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> 75aeeb2..b2fe5cb 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -227,6 +227,7 @@ struct priv {
> LIST_HEAD(ind_tables, mlx5_ind_table_ibv) ind_tbls;
> LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
> LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource)
> encaps_decaps;
> + LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource)
> modify_cmds;
> uint32_t link_speed_capa; /* Link speed capabilities. */
> struct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */
> struct mlx5_stats_ctrl stats_ctrl; /* Stats control. */ diff --git
> a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index
> 4a7c052..cb1e6fd 100644
> --- a/drivers/net/mlx5/mlx5_flow.h
> +++ b/drivers/net/mlx5/mlx5_flow.h
> @@ -69,6 +69,18 @@
> (MLX5_FLOW_LAYER_INNER_L2 | MLX5_FLOW_LAYER_INNER_L3 | \
> MLX5_FLOW_LAYER_INNER_L4)
>
> +/* Layer Masks. */
> +#define MLX5_FLOW_LAYER_L2 \
> + (MLX5_FLOW_LAYER_OUTER_L2 | MLX5_FLOW_LAYER_INNER_L2)
> #define
> +MLX5_FLOW_LAYER_L3_IPV4 \
> + (MLX5_FLOW_LAYER_OUTER_L3_IPV4 |
> MLX5_FLOW_LAYER_INNER_L3_IPV4)
> +#define MLX5_FLOW_LAYER_L3_IPV6 \
> + (MLX5_FLOW_LAYER_OUTER_L3_IPV6 |
> MLX5_FLOW_LAYER_INNER_L3_IPV6)
> +#define MLX5_FLOW_LAYER_L3 \
> + (MLX5_FLOW_LAYER_L3_IPV4 | MLX5_FLOW_LAYER_L3_IPV6) #define
> +MLX5_FLOW_LAYER_L4 \
> + (MLX5_FLOW_LAYER_OUTER_L4 | MLX5_FLOW_LAYER_INNER_L4)
> +
> /* Actions */
> #define MLX5_FLOW_ACTION_DROP (1u << 0) #define
> MLX5_FLOW_ACTION_QUEUE (1u << 1) @@ -110,6 +122,17 @@
> MLX5_FLOW_ACTION_NVGRE_DECAP | \
> MLX5_FLOW_ACTION_RAW_DECAP)
>
> +#define MLX5_FLOW_MODIFY_HDR_ACTIONS
> (MLX5_FLOW_ACTION_SET_IPV4_SRC | \
> + MLX5_FLOW_ACTION_SET_IPV4_DST | \
> + MLX5_FLOW_ACTION_SET_IPV6_SRC | \
> + MLX5_FLOW_ACTION_SET_IPV6_DST | \
> + MLX5_FLOW_ACTION_SET_TP_SRC | \
> + MLX5_FLOW_ACTION_SET_TP_DST | \
> + MLX5_FLOW_ACTION_SET_TTL | \
> + MLX5_FLOW_ACTION_DEC_TTL | \
> + MLX5_FLOW_ACTION_SET_MAC_SRC | \
> + MLX5_FLOW_ACTION_SET_MAC_DST)
> +
> #ifndef IPPROTO_MPLS
> #define IPPROTO_MPLS 137
> #endif
> @@ -153,9 +176,6 @@
> /* IBV hash source bits for IPV6. */
> #define MLX5_IPV6_IBV_RX_HASH (IBV_RX_HASH_SRC_IPV6 |
> IBV_RX_HASH_DST_IPV6)
>
> -/* Max number of actions per DV flow. */ -#define
> MLX5_DV_MAX_NUMBER_OF_ACTIONS 8
> -
> enum mlx5_flow_drv_type {
> MLX5_FLOW_TYPE_MIN,
> MLX5_FLOW_TYPE_DV,
> @@ -172,9 +192,6 @@ struct mlx5_flow_dv_match_params {
> /**< Matcher value. This value is used as the mask or as a key. */ };
>
> -#define MLX5_DV_MAX_NUMBER_OF_ACTIONS 8 -#define
> MLX5_ENCAP_MAX_LEN 132
> -
> /* Matcher structure. */
> struct mlx5_flow_dv_matcher {
> LIST_ENTRY(mlx5_flow_dv_matcher) next; @@ -187,6 +204,8 @@
> struct mlx5_flow_dv_matcher {
> struct mlx5_flow_dv_match_params mask; /**< Matcher mask. */ };
>
> +#define MLX5_ENCAP_MAX_LEN 132
> +
> /* Encap/decap resource structure. */
> struct mlx5_flow_dv_encap_decap_resource {
> LIST_ENTRY(mlx5_flow_dv_encap_decap_resource) next; @@ -200,6
> +219,29 @@ struct mlx5_flow_dv_encap_decap_resource {
> uint8_t ft_type;
> };
>
> +/* Number of modification commands. */
> +#define MLX5_MODIFY_NUM 8
> +
> +/* Modify resource structure */
> +struct mlx5_flow_dv_modify_hdr_resource {
> + LIST_ENTRY(mlx5_flow_dv_modify_hdr_resource) next;
> + /* Pointer to next element. */
> + rte_atomic32_t refcnt; /**< Reference counter. */
> + struct ibv_flow_action *verbs_action;
> + /**< Verbs modify header action object. */
> + uint8_t ft_type; /**< Flow table type, Rx or Tx. */
> + uint32_t actions_num; /**< Number of modification actions. */
> + struct mlx5_modification_cmd actions[MLX5_MODIFY_NUM];
> + /**< Modification actions. */
> +};
> +
> +/*
> + * Max number of actions per DV flow.
> + * See CREATE_FLOW_MAX_FLOW_ACTIONS_SUPPORTED
> + * In rdma-core file providers/mlx5/verbs.c */ #define
> +MLX5_DV_MAX_NUMBER_OF_ACTIONS 8
> +
> /* DV flows structure. */
> struct mlx5_flow_dv {
> uint64_t hash_fields; /**< Fields that participate in the hash. */ @@ -
> 210,6 +252,8 @@ struct mlx5_flow_dv {
> /**< Holds the value that the packet is compared to. */
> struct mlx5_flow_dv_encap_decap_resource *encap_decap;
> /**< Pointer to encap/decap resource in cache. */
> + struct mlx5_flow_dv_modify_hdr_resource *modify_hdr;
> + /**< Pointer to modify header resource in cache. */
> struct ibv_flow *flow; /**< Installed flow. */ #ifdef
> HAVE_IBV_FLOW_DV_SUPPORT
> struct mlx5dv_flow_action_attr
> actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS];
> diff --git a/drivers/net/mlx5/mlx5_flow_dv.c
> b/drivers/net/mlx5/mlx5_flow_dv.c index 1f31874..ad4e501 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -35,6 +35,504 @@
>
> #ifdef HAVE_IBV_FLOW_DV_SUPPORT
>
> +union flow_dv_attr {
> + struct {
> + uint32_t valid:1;
> + uint32_t ipv4:1;
> + uint32_t ipv6:1;
> + uint32_t tcp:1;
> + uint32_t udp:1;
> + uint32_t reserved:27;
> + };
> + uint32_t attr;
> +};
> +
> +static void
> +flow_dv_attr_init(const struct rte_flow_item *item, union flow_dv_attr
> +*attr) {
Can we avoid this duplicated parsing and use the parsing done on translate when traversing the items list (using item_flags)?
it will require to do the item translate before the actions translate.
Koh, Ori what do you think?
If yes, then the swap between the item and action translate should be on a separate patch to ease the patch review.
> + for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
> + switch (item->type) {
> + case RTE_FLOW_ITEM_TYPE_IPV4:
> + attr->ipv4 = 1;
> + break;
> + case RTE_FLOW_ITEM_TYPE_IPV6:
> + attr->ipv6 = 1;
> + break;
> + case RTE_FLOW_ITEM_TYPE_UDP:
> + attr->udp = 1;
> + break;
> + case RTE_FLOW_ITEM_TYPE_TCP:
> + attr->tcp = 1;
> + break;
> + default:
> + break;
> + }
> + }
> + attr->valid = 1;
> +}
> +
> +struct field_modify_info {
> + int bits; /* Offset of field in protocol header, in bits. */
> + enum mlx5_modification_field outer_type;
> + enum mlx5_modification_field inner_type; };
> +
> +struct field_modify_info modify_eth[] = {
> + {4 * 8, MLX5_MODI_OUT_DMAC_47_16,
> MLX5_MODI_IN_DMAC_47_16},
> + {2 * 8, MLX5_MODI_OUT_DMAC_15_0,
> MLX5_MODI_IN_DMAC_15_0},
> + {4 * 8, MLX5_MODI_OUT_SMAC_47_16,
> MLX5_MODI_IN_SMAC_47_16},
> + {2 * 8, MLX5_MODI_OUT_SMAC_15_0, MLX5_MODI_IN_SMAC_15_0},
> + {2 * 8, MLX5_MODI_OUT_ETHERTYPE, MLX5_MODI_IN_ETHERTYPE},
> + {0, 0, 0},
> +};
> +
> +struct field_modify_info modify_ipv4[] = {
> + {1 * 8, 0, 0}, /* Ver,len. */
> + {1 * 8, MLX5_MODI_OUT_IP_DSCP, MLX5_MODI_IN_IP_DSCP},
> + {2 * 8, 0, 0}, /* Data length. */
> + {4 * 8, 0, 0}, /* Fragment info. */
> + {1 * 8, MLX5_MODI_OUT_IPV4_TTL, MLX5_MODI_IN_IPV4_TTL},
> + {3 * 8, 0, 0}, /* Protocol and checksum. */
> + {4 * 8, MLX5_MODI_OUT_SIPV4, MLX5_MODI_IN_SIPV4},
> + {4 * 8, MLX5_MODI_OUT_DIPV4, MLX5_MODI_IN_DIPV4},
> + {0, 0, 0},
> +};
> +
> +struct field_modify_info modify_ipv6[] = {
> + {6 * 8, 0, 0}, /* Ver... */
> + {2 * 8, MLX5_MODI_OUT_IPV6_HOPLIMIT,
> MLX5_MODI_IN_IPV6_HOPLIMIT},
> + {4 * 8, MLX5_MODI_OUT_SIPV6_127_96,
> MLX5_MODI_IN_SIPV6_127_96},
> + {4 * 8, MLX5_MODI_OUT_SIPV6_95_64,
> MLX5_MODI_IN_SIPV6_95_64},
> + {4 * 8, MLX5_MODI_OUT_SIPV6_63_32,
> MLX5_MODI_IN_SIPV6_63_32},
> + {4 * 8, MLX5_MODI_OUT_SIPV6_31_0, MLX5_MODI_IN_SIPV6_31_0},
> + {4 * 8, MLX5_MODI_OUT_DIPV6_127_96,
> MLX5_MODI_IN_DIPV6_127_96},
> + {4 * 8, MLX5_MODI_OUT_DIPV6_95_64,
> MLX5_MODI_IN_DIPV6_95_64},
> + {4 * 8, MLX5_MODI_OUT_DIPV6_63_32,
> MLX5_MODI_IN_DIPV6_63_32},
> + {4 * 8, MLX5_MODI_OUT_DIPV6_31_0, MLX5_MODI_IN_DIPV6_31_0},
> + {0, 0, 0},
> +};
> +
> +struct field_modify_info modify_udp[] = {
> + {2 * 8, MLX5_MODI_OUT_UDP_SPORT, MLX5_MODI_IN_UDP_SPORT},
> + {2 * 8, MLX5_MODI_OUT_UDP_DPORT,
> MLX5_MODI_IN_UDP_DPORT},
> + {4 * 8, 0, 0}, /* Length and checksum. */
> + {0, 0, 0},
> +};
> +
> +struct field_modify_info modify_tcp[] = {
> + {2 * 8, MLX5_MODI_OUT_TCP_SPORT, MLX5_MODI_IN_TCP_SPORT},
> + {2 * 8, MLX5_MODI_OUT_TCP_DPORT, MLX5_MODI_IN_TCP_DPORT},
> + {9 * 8, 0, 0}, /* Seq, ack and data offset. */
> + {1 * 8, MLX5_MODI_OUT_TCP_FLAGS, MLX5_MODI_IN_TCP_FLAGS},
> + {6 * 8, 0, 0}, /* Window, checksum and urgent pointer. */
> + {0, 0, 0},
> +};
> +
> +/**
> + * Convert modify-header action to DV specification.
> + *
> + * @param[in] item
> + * Pointer to item specification.
> + * @param[in] field
> + * Pointer to field modification information.
> + * @param[in,out] resource
> + * Pointer to the modify-header resource.
> + * @param[in] type
> + * Type of modification.
> + * @param[out] error
> + * Pointer to the error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_convert_modify_action(struct rte_flow_item *item,
> + struct field_modify_info *field,
> + struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> + uint32_t type,
> + struct rte_flow_error *error)
> +{
> + uint32_t bits_offset;
> + int bits;
> + uint32_t i = resource->actions_num;
> + struct mlx5_modification_cmd *actions = resource->actions;
> + int found = 0;
> + int j;
> + int set;
> + const uint8_t *spec = item->spec;
> + const uint8_t *mask = item->mask;
> +
> + for (bits_offset = 0; field->bits > 0; field++) {
> + bits = field->bits;
> + /* Scan and generate modify commands for each mask
> segment. */
> + for (j = 0; j < bits; ++j) {
> + set = mask[(bits_offset + j) / 8] & (1 << (j % 8));
I don't understand this logic. Let's say I would like to set the TCP source port. The mask item will have 0xff on the tcp.sport, the rest will be 0.
The first field will be the TCP source port which located in 2B offset of the TCP header. meaning bits = 16, j = 0, base_offset = 0.
So it looks like the mask will be checked for offset 0, while in fact the source port located in offset of 16bits.
I also don't understand why the whole logic is in bits granularity and not bytes.
> + if (set && found && j != bits - 1)
> + continue;
> + if (set && !found) {
> + if (!field->outer_type)
> + DRV_LOG(DEBUG,
> + "unsupported modification"
> + " field");
> + actions[i].type = type;
> + actions[i].src_offset = j;
> + actions[i].src_field = field->outer_type;
> + found = 1;
> + continue;
> + }
> + if ((set && (j == bits - 1)) || (found && !set)) {
> + /* Reach end of mask or end of mask segment.
> */
> + actions[i].bits = j - actions[i].src_offset;
> + if (j == bits - 1)
> + actions[i].bits++;
> + rte_memcpy(&actions[i].data[4 - bits / 8],
> + &spec[bits_offset / 8], bits / 8);
> + actions[i].data0 =
> + rte_cpu_to_be_32(actions[i].data0);
> + found = 0;
> + ++i;
> + if (i > MLX5_MODIFY_NUM)
> + return rte_flow_error_set(error,
> EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "too many items to modify");
> + }
> + if (resource->actions_num != i)
> + resource->actions_num = i;
> + }
> + bits_offset += field->bits;
> + }
> + if (!resource->actions_num)
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "invalid modification flow item");
> + return 0;
> +}
> +
> +/**
> + * Convert modify-header set IPv4 address action to DV specification.
> + *
> + * @param[in,out] resource
> + * Pointer to the modify-header resource.
> + * @param[in] action
> + * Pointer to action specification.
> + * @param[out] error
> + * Pointer to the error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_convert_action_modify_ipv4
> + (struct mlx5_flow_dv_modify_hdr_resource *resource,
> + const struct rte_flow_action *action,
> + struct rte_flow_error *error)
> +{
> + const struct rte_flow_action_set_ipv4 *conf =
> + (const struct rte_flow_action_set_ipv4 *)(action->conf);
> + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV4 };
> + struct rte_flow_item_ipv4 ipv4;
> + struct rte_flow_item_ipv4 ipv4_mask;
> +
> + memset(&ipv4, 0, sizeof(ipv4));
> + memset(&ipv4_mask, 0, sizeof(ipv4_mask));
> + if (action->type == RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC) {
> + ipv4.hdr.src_addr = conf->ipv4_addr;
> + ipv4_mask.hdr.src_addr =
> rte_flow_item_ipv4_mask.hdr.src_addr;
> + } else {
> + ipv4.hdr.dst_addr = conf->ipv4_addr;
> + ipv4_mask.hdr.dst_addr =
> rte_flow_item_ipv4_mask.hdr.dst_addr;
> + }
> + item.spec = &ipv4;
> + item.mask = &ipv4_mask;
> + return flow_dv_convert_modify_action(&item, modify_ipv4, resource,
> + MLX5_MODIFICATION_TYPE_SET,
> error); }
> +
> +/**
> + * Convert modify-header set IPv6 address action to DV specification.
> + *
> + * @param[in,out] resource
> + * Pointer to the modify-header resource.
> + * @param[in] action
> + * Pointer to action specification.
> + * @param[out] error
> + * Pointer to the error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_convert_action_modify_ipv6
> + (struct mlx5_flow_dv_modify_hdr_resource *resource,
> + const struct rte_flow_action *action,
> + struct rte_flow_error *error)
> +{
> + const struct rte_flow_action_set_ipv6 *conf =
> + (const struct rte_flow_action_set_ipv6 *)(action->conf);
> + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV6 };
> + struct rte_flow_item_ipv6 ipv6;
> + struct rte_flow_item_ipv6 ipv6_mask;
> +
> + memset(&ipv6, 0, sizeof(ipv6));
> + memset(&ipv6_mask, 0, sizeof(ipv6_mask));
> + if (action->type == RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC) {
> + memcpy(&ipv6.hdr.src_addr, &conf->ipv6_addr,
> + sizeof(ipv6.hdr.src_addr));
> + memcpy(&ipv6_mask.hdr.src_addr,
> + &rte_flow_item_ipv6_mask.hdr.src_addr,
> + sizeof(ipv6.hdr.src_addr));
> + } else {
> + memcpy(&ipv6.hdr.dst_addr, &conf->ipv6_addr,
> + sizeof(ipv6.hdr.dst_addr));
> + memcpy(&ipv6_mask.hdr.dst_addr,
> + &rte_flow_item_ipv6_mask.hdr.dst_addr,
> + sizeof(ipv6.hdr.dst_addr));
> + }
> + item.spec = &ipv6;
> + item.mask = &ipv6_mask;
> + return flow_dv_convert_modify_action(&item, modify_ipv6, resource,
> + MLX5_MODIFICATION_TYPE_SET,
> error); }
> +
> +/**
> + * Convert modify-header set MAC address action to DV specification.
> + *
> + * @param[in,out] resource
> + * Pointer to the modify-header resource.
> + * @param[in] action
> + * Pointer to action specification.
> + * @param[out] error
> + * Pointer to the error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_convert_action_modify_mac
> + (struct mlx5_flow_dv_modify_hdr_resource *resource,
> + const struct rte_flow_action *action,
> + struct rte_flow_error *error)
> +{
> + const struct rte_flow_action_set_mac *conf =
> + (const struct rte_flow_action_set_mac *)(action->conf);
> + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_ETH };
> + struct rte_flow_item_eth eth;
> + struct rte_flow_item_eth eth_mask;
> +
> + memset(ð, 0, sizeof(eth));
> + memset(ð_mask, 0, sizeof(eth_mask));
> + if (action->type == RTE_FLOW_ACTION_TYPE_SET_MAC_SRC) {
> + memcpy(ð.src.addr_bytes, &conf->mac_addr,
> + sizeof(eth.src.addr_bytes));
> + memcpy(ð_mask.src.addr_bytes,
> + &rte_flow_item_eth_mask.src.addr_bytes,
> + sizeof(eth_mask.src.addr_bytes));
> + } else {
> + memcpy(ð.dst.addr_bytes, &conf->mac_addr,
> + sizeof(eth.dst.addr_bytes));
> + memcpy(ð_mask.dst.addr_bytes,
> + &rte_flow_item_eth_mask.dst.addr_bytes,
> + sizeof(eth_mask.dst.addr_bytes));
> + }
> + item.spec = ð
> + item.mask = ð_mask;
> + return flow_dv_convert_modify_action(&item, modify_eth, resource,
> + MLX5_MODIFICATION_TYPE_SET,
> error); }
> +
> +/**
> + * Convert modify-header set TP action to DV specification.
> + *
> + * @param[in,out] resource
> + * Pointer to the modify-header resource.
> + * @param[in] action
> + * Pointer to action specification.
> + * @param[in] items
> + * Pointer to rte_flow_item objects list.
> + * @param[in] attr
> + * Pointer to flow attributes structure.
> + * @param[out] error
> + * Pointer to the error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_convert_action_modify_tp
> + (struct mlx5_flow_dv_modify_hdr_resource *resource,
> + const struct rte_flow_action *action,
> + const struct rte_flow_item *items,
> + union flow_dv_attr *attr,
> + struct rte_flow_error *error)
> +{
> + const struct rte_flow_action_set_tp *conf =
> + (const struct rte_flow_action_set_tp *)(action->conf);
> + struct rte_flow_item item;
> + struct rte_flow_item_udp udp;
> + struct rte_flow_item_udp udp_mask;
> + struct rte_flow_item_tcp tcp;
> + struct rte_flow_item_tcp tcp_mask;
> + struct field_modify_info *field;
> +
> + if (!attr->valid)
> + flow_dv_attr_init(items, attr);
> + if (attr->udp) {
> + memset(&udp, 0, sizeof(udp));
> + memset(&udp_mask, 0, sizeof(udp_mask));
> + if (action->type == RTE_FLOW_ACTION_TYPE_SET_TP_SRC) {
> + udp.hdr.src_port = conf->port;
> + udp_mask.hdr.src_port =
> +
> rte_flow_item_udp_mask.hdr.src_port;
> + } else {
> + udp.hdr.dst_port = conf->port;
> + udp_mask.hdr.dst_port =
> +
> rte_flow_item_udp_mask.hdr.dst_port;
> + }
> + item.type = RTE_FLOW_ITEM_TYPE_UDP;
> + item.spec = &udp;
> + item.mask = &udp_mask;
> + field = modify_udp;
> + }
> + if (attr->tcp) {
> + memset(&tcp, 0, sizeof(tcp));
> + memset(&tcp_mask, 0, sizeof(tcp_mask));
> + if (action->type == RTE_FLOW_ACTION_TYPE_SET_TP_SRC) {
> + tcp.hdr.src_port = conf->port;
> + tcp_mask.hdr.src_port =
> + rte_flow_item_tcp_mask.hdr.src_port;
> + } else {
> + tcp.hdr.dst_port = conf->port;
> + tcp_mask.hdr.dst_port =
> + rte_flow_item_tcp_mask.hdr.dst_port;
> + }
> + item.type = RTE_FLOW_ITEM_TYPE_TCP;
> + item.spec = &tcp;
> + item.mask = &tcp_mask;
> + field = modify_tcp;
> + }
> + return flow_dv_convert_modify_action(&item, field, resource,
> + MLX5_MODIFICATION_TYPE_SET,
> error); }
> +
> +/**
> + * Convert modify-header set TTL action to DV specification.
> + *
> + * @param[in,out] resource
> + * Pointer to the modify-header resource.
> + * @param[in] action
> + * Pointer to action specification.
> + * @param[in] items
> + * Pointer to rte_flow_item objects list.
> + * @param[in] attr
> + * Pointer to flow attributes structure.
> + * @param[out] error
> + * Pointer to the error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_convert_action_modify_ttl
> + (struct mlx5_flow_dv_modify_hdr_resource *resource,
> + const struct rte_flow_action *action,
> + const struct rte_flow_item *items,
> + union flow_dv_attr *attr,
> + struct rte_flow_error *error)
> +{
> + const struct rte_flow_action_set_ttl *conf =
> + (const struct rte_flow_action_set_ttl *)(action->conf);
> + struct rte_flow_item item;
> + struct rte_flow_item_ipv4 ipv4;
> + struct rte_flow_item_ipv4 ipv4_mask;
> + struct rte_flow_item_ipv6 ipv6;
> + struct rte_flow_item_ipv6 ipv6_mask;
> + struct field_modify_info *field;
> +
> + if (!attr->valid)
> + flow_dv_attr_init(items, attr);
> + if (attr->ipv4) {
> + memset(&ipv4, 0, sizeof(ipv4));
> + memset(&ipv4_mask, 0, sizeof(ipv4_mask));
> + ipv4.hdr.time_to_live = conf->ttl_value;
> + ipv4_mask.hdr.time_to_live = 0xFF;
> + item.type = RTE_FLOW_ITEM_TYPE_IPV4;
> + item.spec = &ipv4;
> + item.mask = &ipv4_mask;
> + field = modify_ipv4;
> + }
> + if (attr->ipv6) {
> + memset(&ipv6, 0, sizeof(ipv6));
> + memset(&ipv6_mask, 0, sizeof(ipv6_mask));
> + ipv6.hdr.hop_limits = conf->ttl_value;
> + ipv6_mask.hdr.hop_limits = 0xFF;
> + item.type = RTE_FLOW_ITEM_TYPE_IPV6;
> + item.spec = &ipv6;
> + item.mask = &ipv6_mask;
> + field = modify_ipv6;
> + }
> + return flow_dv_convert_modify_action(&item, field, resource,
> + MLX5_MODIFICATION_TYPE_SET,
> error); }
> +
> +/**
> + * Convert modify-header decrement TTL action to DV specification.
> + *
> + * @param[in,out] resource
> + * Pointer to the modify-header resource.
> + * @param[in] action
> + * Pointer to action specification.
> + * @param[in] items
> + * Pointer to rte_flow_item objects list.
> + * @param[in] attr
> + * Pointer to flow attributes structure.
> + * @param[out] error
> + * Pointer to the error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_convert_action_modify_dec_ttl
> + (struct mlx5_flow_dv_modify_hdr_resource *resource,
> + const struct rte_flow_item *items,
> + union flow_dv_attr *attr,
> + struct rte_flow_error *error)
> +{
> + struct rte_flow_item item;
> + struct rte_flow_item_ipv4 ipv4;
> + struct rte_flow_item_ipv4 ipv4_mask;
> + struct rte_flow_item_ipv6 ipv6;
> + struct rte_flow_item_ipv6 ipv6_mask;
> + struct field_modify_info *field;
> +
> + if (!attr->valid)
> + flow_dv_attr_init(items, attr);
> + if (attr->ipv4) {
> + memset(&ipv4, 0, sizeof(ipv4));
> + memset(&ipv4_mask, 0, sizeof(ipv4_mask));
> + ipv4.hdr.time_to_live = 0xFF;
> + ipv4_mask.hdr.time_to_live = 0xFF;
> + item.type = RTE_FLOW_ITEM_TYPE_IPV4;
> + item.spec = &ipv4;
> + item.mask = &ipv4_mask;
> + field = modify_ipv4;
> + }
> + if (attr->ipv6) {
> + memset(&ipv6, 0, sizeof(ipv6));
> + memset(&ipv6_mask, 0, sizeof(ipv6_mask));
> + ipv6.hdr.hop_limits = 0xFF;
> + ipv6_mask.hdr.hop_limits = 0xFF;
> + item.type = RTE_FLOW_ITEM_TYPE_IPV6;
> + item.spec = &ipv6;
> + item.mask = &ipv6_mask;
> + field = modify_ipv6;
> + }
> + return flow_dv_convert_modify_action(&item, field, resource,
> + MLX5_MODIFICATION_TYPE_ADD,
> error); }
> +
> /**
> * Validate META item.
> *
> @@ -166,6 +664,11 @@
> RTE_FLOW_ERROR_TYPE_ACTION,
> NULL,
> "can only have a single encap or"
> " decap action in a flow");
> + if (action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS)
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION,
> NULL,
> + "can't have decap action after"
> + " modify action");
> if (attr->egress)
> return rte_flow_error_set(error, ENOTSUP,
>
> RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, @@ -254,6 +757,11 @@
> RTE_FLOW_ERROR_TYPE_ACTION,
> NULL,
> "can only have a single decap"
> " action in a flow");
> + if (action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS)
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION,
> NULL,
> + "can't have decap action after"
> + " modify action");
> /* decap action is valid on egress only if it is followed by encap */
> if (attr->egress) {
> for (; action->type != RTE_FLOW_ACTION_TYPE_END && @@ -
> 270,7 +778,6 @@
> return 0;
> }
>
> -
> /**
> * Find existing encap/decap resource or create and register a new one.
> *
> @@ -704,6 +1211,302 @@
> }
>
> /**
> + * Validate the modify-header actions.
> + *
> + * @param[in] action_flags
> + * Holds the actions detected until now.
> + * @param[in] action
> + * Pointer to the modify action.
> + * @param[out] error
> + * Pointer to error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_validate_action_modify_hdr(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + struct rte_flow_error *error)
> +{
> + if (action->type != RTE_FLOW_ACTION_TYPE_DEC_TTL && !action-
> >conf)
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION_CONF,
> + NULL, "action configuration not set");
> + if (action_flags & MLX5_FLOW_ENCAP_ACTIONS)
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION,
> NULL,
> + "can't have encap action before"
> + " modify action");
> + return 0;
> +}
> +
> +/**
> + * Validate the modify-header MAC address actions.
> + *
> + * @param[in] action_flags
> + * Holds the actions detected until now.
> + * @param[in] action
> + * Pointer to the modify action.
> + * @param[in] item_flags
> + * Holds the items detected.
> + * @param[out] error
> + * Pointer to error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_validate_action_modify_mac(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + const uint64_t item_flags,
> + struct rte_flow_error *error)
> +{
> + int ret = 0;
> +
> + ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
> + if (!ret) {
> + if (!(item_flags & MLX5_FLOW_LAYER_L2))
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "no L2 item in pattern");
> + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL, "after decap no L2 "
> + "item in pattern");
> + }
I didn't get this part, why there is no L2?
Same question for the other verifications present here.
> + return ret;
> +}
> +
> +/**
> + * Validate the modify-header IPv4 address actions.
> + *
> + * @param[in] action_flags
> + * Holds the actions detected until now.
> + * @param[in] action
> + * Pointer to the modify action.
> + * @param[in] item_flags
> + * Holds the items detected.
> + * @param[out] error
> + * Pointer to error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_validate_action_modify_ipv4(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + const uint64_t item_flags,
> + struct rte_flow_error *error)
> +{
> + int ret = 0;
> +
> + ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
> + if (!ret) {
> + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV4))
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "no ipv4 item in pattern");
> + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL, "after decap "
> + "no ipv4 item in pattern");
> + }
> + return ret;
> +}
> +
> +/**
> + * Validate the modify-header IPv6 address actions.
> + *
> + * @param[in] action_flags
> + * Holds the actions detected until now.
> + * @param[in] action
> + * Pointer to the modify action.
> + * @param[in] item_flags
> + * Holds the items detected.
> + * @param[out] error
> + * Pointer to error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_validate_action_modify_ipv6(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + const uint64_t item_flags,
> + struct rte_flow_error *error)
> +{
> + int ret = 0;
> +
> + ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
> + if (!ret) {
> + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV6))
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "no ipv6 item in pattern");
> + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL, "after decap "
> + "no ipv6 item in pattern");
> + }
> + return ret;
> +}
> +
> +/**
> + * Validate the modify-header TP actions.
> + *
> + * @param[in] action_flags
> + * Holds the actions detected until now.
> + * @param[in] action
> + * Pointer to the modify action.
> + * @param[in] item_flags
> + * Holds the items detected.
> + * @param[out] error
> + * Pointer to error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_validate_action_modify_tp(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + const uint64_t item_flags,
> + struct rte_flow_error *error)
> +{
> + int ret = 0;
> +
> + ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
> + if (!ret) {
> + if (!(item_flags & MLX5_FLOW_LAYER_L4))
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL, "no transport layer "
> + "in pattern");
> + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL, "after decap no "
> + "transport layer in pattern");
> + }
> + return ret;
> +}
> +
> +/**
> + * Validate the modify-header TTL actions.
> + *
> + * @param[in] action_flags
> + * Holds the actions detected until now.
> + * @param[in] action
> + * Pointer to the modify action.
> + * @param[in] item_flags
> + * Holds the items detected.
> + * @param[out] error
> + * Pointer to error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_validate_action_modify_ttl(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + const uint64_t item_flags,
> + struct rte_flow_error *error)
> +{
> + int ret = 0;
> +
> + ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
> + if (!ret) {
> + if (!(item_flags & MLX5_FLOW_LAYER_L3))
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "no IP protocol in pattern");
> + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL, "after decap "
> + "no IP protocol in pattern");
> + }
> + return ret;
> +}
> +
> +/**
> + * Find existing modify-header resource or create and register a new one.
> + *
> + * @param dev[in, out]
> + * Pointer to rte_eth_dev structure.
> + * @param[in, out] resource
> + * Pointer to modify-header resource.
> + * @parm[in, out] dev_flow
> + * Pointer to the dev_flow.
> + * @param[out] error
> + * pointer to error structure.
> + *
> + * @return
> + * 0 on success otherwise -errno and errno is set.
> + */
> +static int
> +flow_dv_modify_hdr_resource_register
> + (struct rte_eth_dev *dev,
> + struct mlx5_flow_dv_modify_hdr_resource *resource,
> + struct mlx5_flow *dev_flow,
> + struct rte_flow_error *error)
> +{
> + struct priv *priv = dev->data->dev_private;
> + struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
> +
> + /* Lookup a matching resource from cache. */
> + LIST_FOREACH(cache_resource, &priv->modify_cmds, next) {
> + if (resource->ft_type == cache_resource->ft_type &&
> + resource->actions_num == cache_resource->actions_num
> &&
> + !memcmp((const void *)resource->actions,
> + (const void *)cache_resource->actions,
> + (resource->actions_num *
> + sizeof(resource->actions[0])))) {
> + DRV_LOG(DEBUG, "modify-header resource %p: refcnt
> %d++",
> + (void *)cache_resource,
> + rte_atomic32_read(&cache_resource-
> >refcnt));
> + rte_atomic32_inc(&cache_resource->refcnt);
> + dev_flow->dv.modify_hdr = cache_resource;
> + return 0;
> + }
> + }
> + /* Register new modify-header resource. */
> + cache_resource = rte_calloc(__func__, 1, sizeof(*cache_resource), 0);
> + if (!cache_resource)
> + return rte_flow_error_set(error, ENOMEM,
> +
> RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
> + "cannot allocate resource memory");
> + *cache_resource = *resource;
> + cache_resource->verbs_action =
> + mlx5_glue->dv_create_flow_action_modify_header
> + (priv->ctx,
> + cache_resource->actions_num *
> + sizeof(cache_resource->actions[0]),
> + (uint64_t *)cache_resource->actions,
> + cache_resource->ft_type);
> + if (!cache_resource->verbs_action) {
> + rte_free(cache_resource);
> + return rte_flow_error_set(error, ENOMEM,
> +
> RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> + NULL, "cannot create action");
> + }
> + rte_atomic32_init(&cache_resource->refcnt);
> + rte_atomic32_inc(&cache_resource->refcnt);
> + LIST_INSERT_HEAD(&priv->modify_cmds, cache_resource, next);
> + dev_flow->dv.modify_hdr = cache_resource;
> + DRV_LOG(DEBUG, "new modify-header resource %p: refcnt %d++",
> + (void *)cache_resource,
> + rte_atomic32_read(&cache_resource->refcnt));
> + return 0;
> +}
> +
> +/**
> * Verify the @p attributes will be correctly understood by the NIC and store
> * them in the @p flow if everything is correct.
> *
> @@ -1014,6 +1817,87 @@
> action_flags |= MLX5_FLOW_ACTION_RAW_DECAP;
> ++actions_n;
> break;
> + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
> + ret =
> flow_dv_validate_action_modify_mac(action_flags,
> + actions,
> + item_flags,
> + error);
> + if (ret < 0)
> + return ret;
> + /* Count all modify-header actions as one action. */
> + if (!(action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS))
> + ++actions_n;
> + action_flags |= actions->type ==
> +
> RTE_FLOW_ACTION_TYPE_SET_MAC_SRC ?
> +
> MLX5_FLOW_ACTION_SET_MAC_SRC :
> +
> MLX5_FLOW_ACTION_SET_MAC_DST;
> + break;
> +
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
> + ret =
> flow_dv_validate_action_modify_ipv4(action_flags,
> + actions,
> + item_flags,
> + error);
> + if (ret < 0)
> + return ret;
> + /* Count all modify-header actions as one action. */
> + if (!(action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS))
> + ++actions_n;
> + action_flags |= actions->type ==
> +
> RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC ?
> +
> MLX5_FLOW_ACTION_SET_IPV4_SRC :
> +
> MLX5_FLOW_ACTION_SET_IPV4_DST;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
> + ret =
> flow_dv_validate_action_modify_ipv6(action_flags,
> + actions,
> + item_flags,
> + error);
> + if (ret < 0)
> + return ret;
> + /* Count all modify-header actions as one action. */
> + if (!(action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS))
> + ++actions_n;
> + action_flags |= actions->type ==
> +
> RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC ?
> +
> MLX5_FLOW_ACTION_SET_IPV6_SRC :
> +
> MLX5_FLOW_ACTION_SET_IPV6_DST;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
> + ret = flow_dv_validate_action_modify_tp(action_flags,
> + actions,
> + item_flags,
> + error);
> + if (ret < 0)
> + return ret;
> + /* Count all modify-header actions as one action. */
> + if (!(action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS))
> + ++actions_n;
> + action_flags |= actions->type ==
> +
> RTE_FLOW_ACTION_TYPE_SET_TP_SRC ?
> +
> MLX5_FLOW_ACTION_SET_TP_SRC :
> +
> MLX5_FLOW_ACTION_SET_TP_DST;
> + break;
> + case RTE_FLOW_ACTION_TYPE_DEC_TTL:
> + case RTE_FLOW_ACTION_TYPE_SET_TTL:
> + ret = flow_dv_validate_action_modify_ttl(action_flags,
> + actions,
> + item_flags,
> + error);
> + if (ret < 0)
> + return ret;
> + /* Count all modify-header actions as one action. */
> + if (!(action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS))
> + ++actions_n;
> + action_flags |= actions->type ==
> + RTE_FLOW_ACTION_TYPE_SET_TTL ?
> +
> MLX5_FLOW_ACTION_SET_TTL :
> +
> MLX5_FLOW_ACTION_DEC_TTL;
> + break;
> default:
> return rte_flow_error_set(error, ENOTSUP,
>
> RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -1895,10 +2779,16 @@
> },
> };
> int actions_n = 0;
> + bool actions_end = false;
> + struct mlx5_flow_dv_modify_hdr_resource res = {
> + .ft_type = attr->egress ? MLX5DV_FLOW_TABLE_TYPE_NIC_TX
> :
> +
> MLX5DV_FLOW_TABLE_TYPE_NIC_RX
> + };
> + union flow_dv_attr flow_attr = { .attr = 0 };
>
> if (priority == MLX5_FLOW_PRIO_RSVD)
> priority = priv->config.flow_prio - 1;
> - for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
> + for (; !actions_end ; actions++) {
> const struct rte_flow_action_queue *queue;
> const struct rte_flow_action_rss *rss;
> const struct rte_flow_action *action = actions; @@ -2025,6
> +2915,77 @@
> /* If decap is followed by encap, handle it at encap. */
> action_flags |= MLX5_FLOW_ACTION_RAW_DECAP;
> break;
> + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
> + if (flow_dv_convert_action_modify_mac(&res, actions,
> + error))
> + return -rte_errno;
> + action_flags |= actions->type ==
> +
> RTE_FLOW_ACTION_TYPE_SET_MAC_SRC ?
> + MLX5_FLOW_ACTION_SET_MAC_SRC
> :
> + MLX5_FLOW_ACTION_SET_MAC_DST;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
> + if (flow_dv_convert_action_modify_ipv4(&res, actions,
> + error))
> + return -rte_errno;
> + action_flags |= actions->type ==
> +
> RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC ?
> + MLX5_FLOW_ACTION_SET_IPV4_SRC :
> + MLX5_FLOW_ACTION_SET_IPV4_DST;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
> + if (flow_dv_convert_action_modify_ipv6(&res, actions,
> + error))
> + return -rte_errno;
> + action_flags |= actions->type ==
> +
> RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC ?
> + MLX5_FLOW_ACTION_SET_IPV6_SRC :
> + MLX5_FLOW_ACTION_SET_IPV6_DST;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
> + if (flow_dv_convert_action_modify_tp(&res, actions,
> + items, &flow_attr,
> + error))
> + return -rte_errno;
> + action_flags |= actions->type ==
> +
> RTE_FLOW_ACTION_TYPE_SET_TP_SRC ?
> + MLX5_FLOW_ACTION_SET_TP_SRC :
> + MLX5_FLOW_ACTION_SET_TP_DST;
> + break;
> + case RTE_FLOW_ACTION_TYPE_DEC_TTL:
> + if (flow_dv_convert_action_modify_dec_ttl(&res,
> items,
> + &flow_attr,
> + error))
> + return -rte_errno;
> + action_flags |= MLX5_FLOW_ACTION_DEC_TTL;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_TTL:
> + if (flow_dv_convert_action_modify_ttl(&res, actions,
> + items, &flow_attr,
> + error))
> + return -rte_errno;
> + action_flags |= MLX5_FLOW_ACTION_SET_TTL;
> + break;
> + case RTE_FLOW_ACTION_TYPE_END:
> + actions_end = true;
> + if (action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS) {
> + /* create modify action if needed. */
> + if (flow_dv_modify_hdr_resource_register
> + (dev, &res,
> + dev_flow,
> + error))
> + return -rte_errno;
> + dev_flow->dv.actions[actions_n].type =
> +
> MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;
> + dev_flow->dv.actions[actions_n].action =
> + dev_flow->dv.modify_hdr-
> >verbs_action;
> + actions_n++;
> + }
> + break;
> default:
> break;
> }
> @@ -2309,6 +3270,37 @@
> }
>
> /**
> + * Release a modify-header resource.
> + *
> + * @param flow
> + * Pointer to mlx5_flow.
> + *
> + * @return
> + * 1 while a reference on it exists, 0 when freed.
> + */
> +static int
> +flow_dv_modify_hdr_resource_release(struct mlx5_flow *flow) {
> + struct mlx5_flow_dv_modify_hdr_resource *cache_resource =
> + flow->dv.modify_hdr;
> +
> + assert(cache_resource->verbs_action);
> + DRV_LOG(DEBUG, "modify-header resource %p: refcnt %d--",
> + (void *)cache_resource,
> + rte_atomic32_read(&cache_resource->refcnt));
> + if (rte_atomic32_dec_and_test(&cache_resource->refcnt)) {
> + claim_zero(mlx5_glue->destroy_flow_action
> + (cache_resource->verbs_action));
> + LIST_REMOVE(cache_resource, next);
> + rte_free(cache_resource);
> + DRV_LOG(DEBUG, "modify-header resource %p: removed",
> + (void *)cache_resource);
> + return 0;
> + }
> + return 1;
> +}
> +
> +/**
> * Remove the flow from the NIC but keeps it in memory.
> *
> * @param[in] dev
> @@ -2365,6 +3357,8 @@
> flow_dv_matcher_release(dev, dev_flow);
> if (dev_flow->dv.encap_decap)
> flow_dv_encap_decap_resource_release(dev_flow);
> + if (dev_flow->dv.modify_hdr)
> + flow_dv_modify_hdr_resource_release(dev_flow);
> rte_free(dev_flow);
> }
> }
> diff --git a/drivers/net/mlx5/mlx5_glue.c b/drivers/net/mlx5/mlx5_glue.c index
> dd10ad6..a806d92 100644
> --- a/drivers/net/mlx5/mlx5_glue.c
> +++ b/drivers/net/mlx5/mlx5_glue.c
> @@ -479,6 +479,26 @@
> #endif
> }
>
> +static struct ibv_flow_action *
> +mlx5_glue_dv_create_flow_action_modify_header
> + (struct ibv_context *ctx,
> + size_t actions_sz,
> + uint64_t actions[],
> + enum mlx5dv_flow_table_type
> ft_type) { #ifdef
> +HAVE_IBV_FLOW_DV_SUPPORT
> + return mlx5dv_create_flow_action_modify_header(ctx, actions_sz,
> + actions, ft_type);
> +#else
> + (void)ctx;
> + (void)actions_sz;
> + (void)actions;
> + (void)ft_type;
> + return NULL;
> +#endif
> +}
> +
> +
> alignas(RTE_CACHE_LINE_SIZE)
> const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){
> .version = MLX5_GLUE_VERSION,
> @@ -535,4 +555,6 @@
> .dv_create_flow = mlx5_glue_dv_create_flow,
> .dv_create_flow_action_packet_reformat =
> mlx5_glue_dv_create_flow_action_packet_reformat,
> + .dv_create_flow_action_modify_header =
> + mlx5_glue_dv_create_flow_action_modify_header,
> };
> diff --git a/drivers/net/mlx5/mlx5_glue.h b/drivers/net/mlx5/mlx5_glue.h
> index 2d92ba8..9cfe836 100644
> --- a/drivers/net/mlx5/mlx5_glue.h
> +++ b/drivers/net/mlx5/mlx5_glue.h
> @@ -164,6 +164,11 @@ struct mlx5_glue {
> void *data,
> enum mlx5dv_flow_action_packet_reformat_type
> reformat_type,
> enum mlx5dv_flow_table_type ft_type);
> + struct ibv_flow_action *(*dv_create_flow_action_modify_header)
> + (struct ibv_context *ctx,
> + size_t actions_sz,
> + uint64_t actions[],
> + enum mlx5dv_flow_table_type
> ft_type);
Need to bump up the LIB_GLUE_VERSION due to this ABI change.
> };
>
> const struct mlx5_glue *mlx5_glue;
> diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h index
> 29742b1..545f84a 100644
> --- a/drivers/net/mlx5/mlx5_prm.h
> +++ b/drivers/net/mlx5/mlx5_prm.h
> @@ -280,8 +280,17 @@ struct mlx5_cqe {
> /* CQE format value. */
> #define MLX5_COMPRESSED 0x3
>
> +/* Write a specific data value to a field. */ #define
> +MLX5_MODIFICATION_TYPE_SET 1
> +
> +/* Add a specific data value to a field. */ #define
> +MLX5_MODIFICATION_TYPE_ADD 2
> +
> +/* Copy a specific data value to another one in a packet. */ #define
> +MLX5_MODIFICATION_TYPE_COPY 3
> +
> /* The field of packet to be modified. */ -enum mlx5_modificaiton_field {
> +enum mlx5_modification_field {
> MLX5_MODI_OUT_SMAC_47_16 = 1,
> MLX5_MODI_OUT_SMAC_15_0,
> MLX5_MODI_OUT_ETHERTYPE,
> --
> 1.8.3.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] net/mlx5: modify-header support using Direct Verbs
2018-12-25 11:38 3% ` Shahaf Shuler
@ 2018-12-25 16:00 0% ` Dekel Peled
0 siblings, 0 replies; 200+ results
From: Dekel Peled @ 2018-12-25 16:00 UTC (permalink / raw)
To: Shahaf Shuler, Yongseok Koh; +Cc: dev, Ori Kam
Thanks, PSB.
> -----Original Message-----
> From: Shahaf Shuler
> Sent: Tuesday, December 25, 2018 1:38 PM
> To: Dekel Peled <dekelp@mellanox.com>; Yongseok Koh
> <yskoh@mellanox.com>
> Cc: dev@dpdk.org; Ori Kam <orika@mellanox.com>; Dekel Peled
> <dekelp@mellanox.com>
> Subject: RE: [PATCH] net/mlx5: modify-header support using Direct Verbs
>
> Hi Dekel,
>
> See some comments below,
>
> Sunday, December 23, 2018 11:58 AM, Dekel Peled:
> > Subject: [PATCH] net/mlx5: modify-header support using Direct Verbs
>
> Maybe title can be: "support modify header using Direct Verbs"
OK, I'll change it.
>
> >
> > This patch implements the set of actions to support offload of packet
> > header modifications to MLX5 NIC.
> >
> > Implamantation is based on RFC [1].
> >
> > [1] http://mails.dpdk.org/archives/dev/2018-November/119971.html
> >
> > Signed-off-by: Dekel Peled <dekelp@mellanox.com>
> > ---
> > drivers/net/mlx5/mlx5.h | 1 +
> > drivers/net/mlx5/mlx5_flow.h | 56 ++-
> > drivers/net/mlx5/mlx5_flow_dv.c | 998
> > +++++++++++++++++++++++++++++++++++++++-
> > drivers/net/mlx5/mlx5_glue.c | 22 +
> > drivers/net/mlx5/mlx5_glue.h | 5 +
> > drivers/net/mlx5/mlx5_prm.h | 11 +-
> > 6 files changed, 1084 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> > 75aeeb2..b2fe5cb 100644
> > --- a/drivers/net/mlx5/mlx5.h
> > +++ b/drivers/net/mlx5/mlx5.h
> > @@ -227,6 +227,7 @@ struct priv {
> > LIST_HEAD(ind_tables, mlx5_ind_table_ibv) ind_tbls;
> > LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
> > LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource)
> > encaps_decaps;
> > + LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource)
> > modify_cmds;
> > uint32_t link_speed_capa; /* Link speed capabilities. */
> > struct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */
> > struct mlx5_stats_ctrl stats_ctrl; /* Stats control. */ diff --git
> > a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index
> > 4a7c052..cb1e6fd 100644
> > --- a/drivers/net/mlx5/mlx5_flow.h
> > +++ b/drivers/net/mlx5/mlx5_flow.h
> > @@ -69,6 +69,18 @@
> > (MLX5_FLOW_LAYER_INNER_L2 | MLX5_FLOW_LAYER_INNER_L3 | \
> > MLX5_FLOW_LAYER_INNER_L4)
> >
> > +/* Layer Masks. */
> > +#define MLX5_FLOW_LAYER_L2 \
> > + (MLX5_FLOW_LAYER_OUTER_L2 | MLX5_FLOW_LAYER_INNER_L2)
> > #define
> > +MLX5_FLOW_LAYER_L3_IPV4 \
> > + (MLX5_FLOW_LAYER_OUTER_L3_IPV4 |
> > MLX5_FLOW_LAYER_INNER_L3_IPV4)
> > +#define MLX5_FLOW_LAYER_L3_IPV6 \
> > + (MLX5_FLOW_LAYER_OUTER_L3_IPV6 |
> > MLX5_FLOW_LAYER_INNER_L3_IPV6)
> > +#define MLX5_FLOW_LAYER_L3 \
> > + (MLX5_FLOW_LAYER_L3_IPV4 | MLX5_FLOW_LAYER_L3_IPV6)
> #define
> > +MLX5_FLOW_LAYER_L4 \
> > + (MLX5_FLOW_LAYER_OUTER_L4 | MLX5_FLOW_LAYER_INNER_L4)
> > +
> > /* Actions */
> > #define MLX5_FLOW_ACTION_DROP (1u << 0) #define
> > MLX5_FLOW_ACTION_QUEUE (1u << 1) @@ -110,6 +122,17 @@
> > MLX5_FLOW_ACTION_NVGRE_DECAP | \
> > MLX5_FLOW_ACTION_RAW_DECAP)
> >
> > +#define MLX5_FLOW_MODIFY_HDR_ACTIONS
> > (MLX5_FLOW_ACTION_SET_IPV4_SRC | \
> > + MLX5_FLOW_ACTION_SET_IPV4_DST | \
> > + MLX5_FLOW_ACTION_SET_IPV6_SRC | \
> > + MLX5_FLOW_ACTION_SET_IPV6_DST | \
> > + MLX5_FLOW_ACTION_SET_TP_SRC | \
> > + MLX5_FLOW_ACTION_SET_TP_DST | \
> > + MLX5_FLOW_ACTION_SET_TTL | \
> > + MLX5_FLOW_ACTION_DEC_TTL | \
> > + MLX5_FLOW_ACTION_SET_MAC_SRC | \
> > + MLX5_FLOW_ACTION_SET_MAC_DST)
> > +
> > #ifndef IPPROTO_MPLS
> > #define IPPROTO_MPLS 137
> > #endif
> > @@ -153,9 +176,6 @@
> > /* IBV hash source bits for IPV6. */ #define MLX5_IPV6_IBV_RX_HASH
> > (IBV_RX_HASH_SRC_IPV6 |
> > IBV_RX_HASH_DST_IPV6)
> >
> > -/* Max number of actions per DV flow. */ -#define
> > MLX5_DV_MAX_NUMBER_OF_ACTIONS 8
> > -
> > enum mlx5_flow_drv_type {
> > MLX5_FLOW_TYPE_MIN,
> > MLX5_FLOW_TYPE_DV,
> > @@ -172,9 +192,6 @@ struct mlx5_flow_dv_match_params {
> > /**< Matcher value. This value is used as the mask or as a key. */
> > };
> >
> > -#define MLX5_DV_MAX_NUMBER_OF_ACTIONS 8 -#define
> MLX5_ENCAP_MAX_LEN
> > 132
> > -
> > /* Matcher structure. */
> > struct mlx5_flow_dv_matcher {
> > LIST_ENTRY(mlx5_flow_dv_matcher) next; @@ -187,6 +204,8 @@
> struct
> > mlx5_flow_dv_matcher {
> > struct mlx5_flow_dv_match_params mask; /**< Matcher mask. */ };
> >
> > +#define MLX5_ENCAP_MAX_LEN 132
> > +
> > /* Encap/decap resource structure. */ struct
> > mlx5_flow_dv_encap_decap_resource {
> > LIST_ENTRY(mlx5_flow_dv_encap_decap_resource) next; @@ -
> 200,6
> > +219,29 @@ struct mlx5_flow_dv_encap_decap_resource {
> > uint8_t ft_type;
> > };
> >
> > +/* Number of modification commands. */ #define MLX5_MODIFY_NUM 8
> > +
> > +/* Modify resource structure */
> > +struct mlx5_flow_dv_modify_hdr_resource {
> > + LIST_ENTRY(mlx5_flow_dv_modify_hdr_resource) next;
> > + /* Pointer to next element. */
> > + rte_atomic32_t refcnt; /**< Reference counter. */
> > + struct ibv_flow_action *verbs_action;
> > + /**< Verbs modify header action object. */
> > + uint8_t ft_type; /**< Flow table type, Rx or Tx. */
> > + uint32_t actions_num; /**< Number of modification actions. */
> > + struct mlx5_modification_cmd actions[MLX5_MODIFY_NUM];
> > + /**< Modification actions. */
> > +};
> > +
> > +/*
> > + * Max number of actions per DV flow.
> > + * See CREATE_FLOW_MAX_FLOW_ACTIONS_SUPPORTED
> > + * In rdma-core file providers/mlx5/verbs.c */ #define
> > +MLX5_DV_MAX_NUMBER_OF_ACTIONS 8
> > +
> > /* DV flows structure. */
> > struct mlx5_flow_dv {
> > uint64_t hash_fields; /**< Fields that participate in the hash. */
> > @@ -
> > 210,6 +252,8 @@ struct mlx5_flow_dv {
> > /**< Holds the value that the packet is compared to. */
> > struct mlx5_flow_dv_encap_decap_resource *encap_decap;
> > /**< Pointer to encap/decap resource in cache. */
> > + struct mlx5_flow_dv_modify_hdr_resource *modify_hdr;
> > + /**< Pointer to modify header resource in cache. */
> > struct ibv_flow *flow; /**< Installed flow. */ #ifdef
> > HAVE_IBV_FLOW_DV_SUPPORT
> > struct mlx5dv_flow_action_attr
> > actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS];
> > diff --git a/drivers/net/mlx5/mlx5_flow_dv.c
> > b/drivers/net/mlx5/mlx5_flow_dv.c index 1f31874..ad4e501 100644
> > --- a/drivers/net/mlx5/mlx5_flow_dv.c
> > +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> > @@ -35,6 +35,504 @@
> >
> > #ifdef HAVE_IBV_FLOW_DV_SUPPORT
> >
> > +union flow_dv_attr {
> > + struct {
> > + uint32_t valid:1;
> > + uint32_t ipv4:1;
> > + uint32_t ipv6:1;
> > + uint32_t tcp:1;
> > + uint32_t udp:1;
> > + uint32_t reserved:27;
> > + };
> > + uint32_t attr;
> > +};
> > +
> > +static void
> > +flow_dv_attr_init(const struct rte_flow_item *item, union
> > +flow_dv_attr
> > +*attr) {
>
> Can we avoid this duplicated parsing and use the parsing done on translate
> when traversing the items list (using item_flags)?
> it will require to do the item translate before the actions translate.
I tried to avoid it but couldn't.
It used to be items before actions, changed in http://git.dpdk.org/dpdk/commit/?id=e31b6a4151bc8ef97b0fb1ac951b33d811d52969.
The duplicate parsing will occur at most once per flow rule, and only if specific items are present.
> Koh, Ori what do you think?
>
> If yes, then the swap between the item and action translate should be on a
> separate patch to ease the patch review.
>
> > + for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
> > + switch (item->type) {
> > + case RTE_FLOW_ITEM_TYPE_IPV4:
> > + attr->ipv4 = 1;
> > + break;
> > + case RTE_FLOW_ITEM_TYPE_IPV6:
> > + attr->ipv6 = 1;
> > + break;
> > + case RTE_FLOW_ITEM_TYPE_UDP:
> > + attr->udp = 1;
> > + break;
> > + case RTE_FLOW_ITEM_TYPE_TCP:
> > + attr->tcp = 1;
> > + break;
> > + default:
> > + break;
> > + }
> > + }
> > + attr->valid = 1;
> > +}
> > +
> > +struct field_modify_info {
> > + int bits; /* Offset of field in protocol header, in bits. */
> > + enum mlx5_modification_field outer_type;
> > + enum mlx5_modification_field inner_type; };
> > +
> > +struct field_modify_info modify_eth[] = {
> > + {4 * 8, MLX5_MODI_OUT_DMAC_47_16,
> > MLX5_MODI_IN_DMAC_47_16},
> > + {2 * 8, MLX5_MODI_OUT_DMAC_15_0,
> > MLX5_MODI_IN_DMAC_15_0},
> > + {4 * 8, MLX5_MODI_OUT_SMAC_47_16,
> > MLX5_MODI_IN_SMAC_47_16},
> > + {2 * 8, MLX5_MODI_OUT_SMAC_15_0,
> MLX5_MODI_IN_SMAC_15_0},
> > + {2 * 8, MLX5_MODI_OUT_ETHERTYPE, MLX5_MODI_IN_ETHERTYPE},
> > + {0, 0, 0},
> > +};
> > +
> > +struct field_modify_info modify_ipv4[] = {
> > + {1 * 8, 0, 0}, /* Ver,len. */
> > + {1 * 8, MLX5_MODI_OUT_IP_DSCP, MLX5_MODI_IN_IP_DSCP},
> > + {2 * 8, 0, 0}, /* Data length. */
> > + {4 * 8, 0, 0}, /* Fragment info. */
> > + {1 * 8, MLX5_MODI_OUT_IPV4_TTL, MLX5_MODI_IN_IPV4_TTL},
> > + {3 * 8, 0, 0}, /* Protocol and checksum. */
> > + {4 * 8, MLX5_MODI_OUT_SIPV4, MLX5_MODI_IN_SIPV4},
> > + {4 * 8, MLX5_MODI_OUT_DIPV4, MLX5_MODI_IN_DIPV4},
> > + {0, 0, 0},
> > +};
> > +
> > +struct field_modify_info modify_ipv6[] = {
> > + {6 * 8, 0, 0}, /* Ver... */
> > + {2 * 8, MLX5_MODI_OUT_IPV6_HOPLIMIT,
> > MLX5_MODI_IN_IPV6_HOPLIMIT},
> > + {4 * 8, MLX5_MODI_OUT_SIPV6_127_96,
> > MLX5_MODI_IN_SIPV6_127_96},
> > + {4 * 8, MLX5_MODI_OUT_SIPV6_95_64,
> > MLX5_MODI_IN_SIPV6_95_64},
> > + {4 * 8, MLX5_MODI_OUT_SIPV6_63_32,
> > MLX5_MODI_IN_SIPV6_63_32},
> > + {4 * 8, MLX5_MODI_OUT_SIPV6_31_0,
> MLX5_MODI_IN_SIPV6_31_0},
> > + {4 * 8, MLX5_MODI_OUT_DIPV6_127_96,
> > MLX5_MODI_IN_DIPV6_127_96},
> > + {4 * 8, MLX5_MODI_OUT_DIPV6_95_64,
> > MLX5_MODI_IN_DIPV6_95_64},
> > + {4 * 8, MLX5_MODI_OUT_DIPV6_63_32,
> > MLX5_MODI_IN_DIPV6_63_32},
> > + {4 * 8, MLX5_MODI_OUT_DIPV6_31_0,
> MLX5_MODI_IN_DIPV6_31_0},
> > + {0, 0, 0},
> > +};
> > +
> > +struct field_modify_info modify_udp[] = {
> > + {2 * 8, MLX5_MODI_OUT_UDP_SPORT,
> MLX5_MODI_IN_UDP_SPORT},
> > + {2 * 8, MLX5_MODI_OUT_UDP_DPORT,
> > MLX5_MODI_IN_UDP_DPORT},
> > + {4 * 8, 0, 0}, /* Length and checksum. */
> > + {0, 0, 0},
> > +};
> > +
> > +struct field_modify_info modify_tcp[] = {
> > + {2 * 8, MLX5_MODI_OUT_TCP_SPORT,
> MLX5_MODI_IN_TCP_SPORT},
> > + {2 * 8, MLX5_MODI_OUT_TCP_DPORT,
> MLX5_MODI_IN_TCP_DPORT},
> > + {9 * 8, 0, 0}, /* Seq, ack and data offset. */
> > + {1 * 8, MLX5_MODI_OUT_TCP_FLAGS,
> MLX5_MODI_IN_TCP_FLAGS},
> > + {6 * 8, 0, 0}, /* Window, checksum and urgent pointer. */
> > + {0, 0, 0},
> > +};
> > +
> > +/**
> > + * Convert modify-header action to DV specification.
> > + *
> > + * @param[in] item
> > + * Pointer to item specification.
> > + * @param[in] field
> > + * Pointer to field modification information.
> > + * @param[in,out] resource
> > + * Pointer to the modify-header resource.
> > + * @param[in] type
> > + * Type of modification.
> > + * @param[out] error
> > + * Pointer to the error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_convert_modify_action(struct rte_flow_item *item,
> > + struct field_modify_info *field,
> > + struct mlx5_flow_dv_modify_hdr_resource
> > *resource,
> > + uint32_t type,
> > + struct rte_flow_error *error) {
> > + uint32_t bits_offset;
> > + int bits;
> > + uint32_t i = resource->actions_num;
> > + struct mlx5_modification_cmd *actions = resource->actions;
> > + int found = 0;
> > + int j;
> > + int set;
> > + const uint8_t *spec = item->spec;
> > + const uint8_t *mask = item->mask;
> > +
> > + for (bits_offset = 0; field->bits > 0; field++) {
> > + bits = field->bits;
> > + /* Scan and generate modify commands for each mask
> > segment. */
> > + for (j = 0; j < bits; ++j) {
> > + set = mask[(bits_offset + j) / 8] & (1 << (j % 8));
>
> I don't understand this logic. Let's say I would like to set the TCP source port.
> The mask item will have 0xff on the tcp.sport, the rest will be 0.
> The first field will be the TCP source port which located in 2B offset of the TCP
> header. meaning bits = 16, j = 0, base_offset = 0.
> So it looks like the mask will be checked for offset 0, while in fact the source
> port located in offset of 16bits.
>
> I also don't understand why the whole logic is in bits granularity and not
> bytes.
I will change it to bytes and simplify the logic.
>
>
> > + if (set && found && j != bits - 1)
> > + continue;
> > + if (set && !found) {
> > + if (!field->outer_type)
> > + DRV_LOG(DEBUG,
> > + "unsupported modification"
> > + " field");
> > + actions[i].type = type;
> > + actions[i].src_offset = j;
> > + actions[i].src_field = field->outer_type;
> > + found = 1;
> > + continue;
> > + }
> > + if ((set && (j == bits - 1)) || (found && !set)) {
> > + /* Reach end of mask or end of mask
> segment.
> > */
> > + actions[i].bits = j - actions[i].src_offset;
> > + if (j == bits - 1)
> > + actions[i].bits++;
> > + rte_memcpy(&actions[i].data[4 - bits / 8],
> > + &spec[bits_offset / 8], bits / 8);
> > + actions[i].data0 =
> > + rte_cpu_to_be_32(actions[i].data0);
> > + found = 0;
> > + ++i;
> > + if (i > MLX5_MODIFY_NUM)
> > + return rte_flow_error_set(error,
> > EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL,
> > + "too many items to modify");
> > + }
> > + if (resource->actions_num != i)
> > + resource->actions_num = i;
> > + }
> > + bits_offset += field->bits;
> > + }
> > + if (!resource->actions_num)
> > + return rte_flow_error_set(error, EINVAL,
> > + RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL,
> > + "invalid modification flow item");
> > + return 0;
> > +}
> > +
> > +/**
> > + * Convert modify-header set IPv4 address action to DV specification.
> > + *
> > + * @param[in,out] resource
> > + * Pointer to the modify-header resource.
> > + * @param[in] action
> > + * Pointer to action specification.
> > + * @param[out] error
> > + * Pointer to the error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_convert_action_modify_ipv4
> > + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> > + const struct rte_flow_action *action,
> > + struct rte_flow_error *error)
> > +{
> > + const struct rte_flow_action_set_ipv4 *conf =
> > + (const struct rte_flow_action_set_ipv4 *)(action->conf);
> > + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV4 };
> > + struct rte_flow_item_ipv4 ipv4;
> > + struct rte_flow_item_ipv4 ipv4_mask;
> > +
> > + memset(&ipv4, 0, sizeof(ipv4));
> > + memset(&ipv4_mask, 0, sizeof(ipv4_mask));
> > + if (action->type == RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC) {
> > + ipv4.hdr.src_addr = conf->ipv4_addr;
> > + ipv4_mask.hdr.src_addr =
> > rte_flow_item_ipv4_mask.hdr.src_addr;
> > + } else {
> > + ipv4.hdr.dst_addr = conf->ipv4_addr;
> > + ipv4_mask.hdr.dst_addr =
> > rte_flow_item_ipv4_mask.hdr.dst_addr;
> > + }
> > + item.spec = &ipv4;
> > + item.mask = &ipv4_mask;
> > + return flow_dv_convert_modify_action(&item, modify_ipv4,
> resource,
> > + MLX5_MODIFICATION_TYPE_SET,
> > error); }
> > +
> > +/**
> > + * Convert modify-header set IPv6 address action to DV specification.
> > + *
> > + * @param[in,out] resource
> > + * Pointer to the modify-header resource.
> > + * @param[in] action
> > + * Pointer to action specification.
> > + * @param[out] error
> > + * Pointer to the error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_convert_action_modify_ipv6
> > + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> > + const struct rte_flow_action *action,
> > + struct rte_flow_error *error)
> > +{
> > + const struct rte_flow_action_set_ipv6 *conf =
> > + (const struct rte_flow_action_set_ipv6 *)(action->conf);
> > + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV6 };
> > + struct rte_flow_item_ipv6 ipv6;
> > + struct rte_flow_item_ipv6 ipv6_mask;
> > +
> > + memset(&ipv6, 0, sizeof(ipv6));
> > + memset(&ipv6_mask, 0, sizeof(ipv6_mask));
> > + if (action->type == RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC) {
> > + memcpy(&ipv6.hdr.src_addr, &conf->ipv6_addr,
> > + sizeof(ipv6.hdr.src_addr));
> > + memcpy(&ipv6_mask.hdr.src_addr,
> > + &rte_flow_item_ipv6_mask.hdr.src_addr,
> > + sizeof(ipv6.hdr.src_addr));
> > + } else {
> > + memcpy(&ipv6.hdr.dst_addr, &conf->ipv6_addr,
> > + sizeof(ipv6.hdr.dst_addr));
> > + memcpy(&ipv6_mask.hdr.dst_addr,
> > + &rte_flow_item_ipv6_mask.hdr.dst_addr,
> > + sizeof(ipv6.hdr.dst_addr));
> > + }
> > + item.spec = &ipv6;
> > + item.mask = &ipv6_mask;
> > + return flow_dv_convert_modify_action(&item, modify_ipv6,
> resource,
> > + MLX5_MODIFICATION_TYPE_SET,
> > error); }
> > +
> > +/**
> > + * Convert modify-header set MAC address action to DV specification.
> > + *
> > + * @param[in,out] resource
> > + * Pointer to the modify-header resource.
> > + * @param[in] action
> > + * Pointer to action specification.
> > + * @param[out] error
> > + * Pointer to the error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_convert_action_modify_mac
> > + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> > + const struct rte_flow_action *action,
> > + struct rte_flow_error *error)
> > +{
> > + const struct rte_flow_action_set_mac *conf =
> > + (const struct rte_flow_action_set_mac *)(action->conf);
> > + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_ETH };
> > + struct rte_flow_item_eth eth;
> > + struct rte_flow_item_eth eth_mask;
> > +
> > + memset(ð, 0, sizeof(eth));
> > + memset(ð_mask, 0, sizeof(eth_mask));
> > + if (action->type == RTE_FLOW_ACTION_TYPE_SET_MAC_SRC) {
> > + memcpy(ð.src.addr_bytes, &conf->mac_addr,
> > + sizeof(eth.src.addr_bytes));
> > + memcpy(ð_mask.src.addr_bytes,
> > + &rte_flow_item_eth_mask.src.addr_bytes,
> > + sizeof(eth_mask.src.addr_bytes));
> > + } else {
> > + memcpy(ð.dst.addr_bytes, &conf->mac_addr,
> > + sizeof(eth.dst.addr_bytes));
> > + memcpy(ð_mask.dst.addr_bytes,
> > + &rte_flow_item_eth_mask.dst.addr_bytes,
> > + sizeof(eth_mask.dst.addr_bytes));
> > + }
> > + item.spec = ð
> > + item.mask = ð_mask;
> > + return flow_dv_convert_modify_action(&item, modify_eth,
> resource,
> > + MLX5_MODIFICATION_TYPE_SET,
> > error); }
> > +
> > +/**
> > + * Convert modify-header set TP action to DV specification.
> > + *
> > + * @param[in,out] resource
> > + * Pointer to the modify-header resource.
> > + * @param[in] action
> > + * Pointer to action specification.
> > + * @param[in] items
> > + * Pointer to rte_flow_item objects list.
> > + * @param[in] attr
> > + * Pointer to flow attributes structure.
> > + * @param[out] error
> > + * Pointer to the error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_convert_action_modify_tp
> > + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> > + const struct rte_flow_action *action,
> > + const struct rte_flow_item *items,
> > + union flow_dv_attr *attr,
> > + struct rte_flow_error *error)
> > +{
> > + const struct rte_flow_action_set_tp *conf =
> > + (const struct rte_flow_action_set_tp *)(action->conf);
> > + struct rte_flow_item item;
> > + struct rte_flow_item_udp udp;
> > + struct rte_flow_item_udp udp_mask;
> > + struct rte_flow_item_tcp tcp;
> > + struct rte_flow_item_tcp tcp_mask;
> > + struct field_modify_info *field;
> > +
> > + if (!attr->valid)
> > + flow_dv_attr_init(items, attr);
> > + if (attr->udp) {
> > + memset(&udp, 0, sizeof(udp));
> > + memset(&udp_mask, 0, sizeof(udp_mask));
> > + if (action->type == RTE_FLOW_ACTION_TYPE_SET_TP_SRC) {
> > + udp.hdr.src_port = conf->port;
> > + udp_mask.hdr.src_port =
> > +
> > rte_flow_item_udp_mask.hdr.src_port;
> > + } else {
> > + udp.hdr.dst_port = conf->port;
> > + udp_mask.hdr.dst_port =
> > +
> > rte_flow_item_udp_mask.hdr.dst_port;
> > + }
> > + item.type = RTE_FLOW_ITEM_TYPE_UDP;
> > + item.spec = &udp;
> > + item.mask = &udp_mask;
> > + field = modify_udp;
> > + }
> > + if (attr->tcp) {
> > + memset(&tcp, 0, sizeof(tcp));
> > + memset(&tcp_mask, 0, sizeof(tcp_mask));
> > + if (action->type == RTE_FLOW_ACTION_TYPE_SET_TP_SRC) {
> > + tcp.hdr.src_port = conf->port;
> > + tcp_mask.hdr.src_port =
> > +
> rte_flow_item_tcp_mask.hdr.src_port;
> > + } else {
> > + tcp.hdr.dst_port = conf->port;
> > + tcp_mask.hdr.dst_port =
> > +
> rte_flow_item_tcp_mask.hdr.dst_port;
> > + }
> > + item.type = RTE_FLOW_ITEM_TYPE_TCP;
> > + item.spec = &tcp;
> > + item.mask = &tcp_mask;
> > + field = modify_tcp;
> > + }
> > + return flow_dv_convert_modify_action(&item, field, resource,
> > + MLX5_MODIFICATION_TYPE_SET,
> > error); }
> > +
> > +/**
> > + * Convert modify-header set TTL action to DV specification.
> > + *
> > + * @param[in,out] resource
> > + * Pointer to the modify-header resource.
> > + * @param[in] action
> > + * Pointer to action specification.
> > + * @param[in] items
> > + * Pointer to rte_flow_item objects list.
> > + * @param[in] attr
> > + * Pointer to flow attributes structure.
> > + * @param[out] error
> > + * Pointer to the error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_convert_action_modify_ttl
> > + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> > + const struct rte_flow_action *action,
> > + const struct rte_flow_item *items,
> > + union flow_dv_attr *attr,
> > + struct rte_flow_error *error)
> > +{
> > + const struct rte_flow_action_set_ttl *conf =
> > + (const struct rte_flow_action_set_ttl *)(action->conf);
> > + struct rte_flow_item item;
> > + struct rte_flow_item_ipv4 ipv4;
> > + struct rte_flow_item_ipv4 ipv4_mask;
> > + struct rte_flow_item_ipv6 ipv6;
> > + struct rte_flow_item_ipv6 ipv6_mask;
> > + struct field_modify_info *field;
> > +
> > + if (!attr->valid)
> > + flow_dv_attr_init(items, attr);
> > + if (attr->ipv4) {
> > + memset(&ipv4, 0, sizeof(ipv4));
> > + memset(&ipv4_mask, 0, sizeof(ipv4_mask));
> > + ipv4.hdr.time_to_live = conf->ttl_value;
> > + ipv4_mask.hdr.time_to_live = 0xFF;
> > + item.type = RTE_FLOW_ITEM_TYPE_IPV4;
> > + item.spec = &ipv4;
> > + item.mask = &ipv4_mask;
> > + field = modify_ipv4;
> > + }
> > + if (attr->ipv6) {
> > + memset(&ipv6, 0, sizeof(ipv6));
> > + memset(&ipv6_mask, 0, sizeof(ipv6_mask));
> > + ipv6.hdr.hop_limits = conf->ttl_value;
> > + ipv6_mask.hdr.hop_limits = 0xFF;
> > + item.type = RTE_FLOW_ITEM_TYPE_IPV6;
> > + item.spec = &ipv6;
> > + item.mask = &ipv6_mask;
> > + field = modify_ipv6;
> > + }
> > + return flow_dv_convert_modify_action(&item, field, resource,
> > + MLX5_MODIFICATION_TYPE_SET,
> > error); }
> > +
> > +/**
> > + * Convert modify-header decrement TTL action to DV specification.
> > + *
> > + * @param[in,out] resource
> > + * Pointer to the modify-header resource.
> > + * @param[in] action
> > + * Pointer to action specification.
> > + * @param[in] items
> > + * Pointer to rte_flow_item objects list.
> > + * @param[in] attr
> > + * Pointer to flow attributes structure.
> > + * @param[out] error
> > + * Pointer to the error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_convert_action_modify_dec_ttl
> > + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> > + const struct rte_flow_item *items,
> > + union flow_dv_attr *attr,
> > + struct rte_flow_error *error)
> > +{
> > + struct rte_flow_item item;
> > + struct rte_flow_item_ipv4 ipv4;
> > + struct rte_flow_item_ipv4 ipv4_mask;
> > + struct rte_flow_item_ipv6 ipv6;
> > + struct rte_flow_item_ipv6 ipv6_mask;
> > + struct field_modify_info *field;
> > +
> > + if (!attr->valid)
> > + flow_dv_attr_init(items, attr);
> > + if (attr->ipv4) {
> > + memset(&ipv4, 0, sizeof(ipv4));
> > + memset(&ipv4_mask, 0, sizeof(ipv4_mask));
> > + ipv4.hdr.time_to_live = 0xFF;
> > + ipv4_mask.hdr.time_to_live = 0xFF;
> > + item.type = RTE_FLOW_ITEM_TYPE_IPV4;
> > + item.spec = &ipv4;
> > + item.mask = &ipv4_mask;
> > + field = modify_ipv4;
> > + }
> > + if (attr->ipv6) {
> > + memset(&ipv6, 0, sizeof(ipv6));
> > + memset(&ipv6_mask, 0, sizeof(ipv6_mask));
> > + ipv6.hdr.hop_limits = 0xFF;
> > + ipv6_mask.hdr.hop_limits = 0xFF;
> > + item.type = RTE_FLOW_ITEM_TYPE_IPV6;
> > + item.spec = &ipv6;
> > + item.mask = &ipv6_mask;
> > + field = modify_ipv6;
> > + }
> > + return flow_dv_convert_modify_action(&item, field, resource,
> > + MLX5_MODIFICATION_TYPE_ADD,
> > error); }
> > +
> > /**
> > * Validate META item.
> > *
> > @@ -166,6 +664,11 @@
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > NULL,
> > "can only have a single encap or"
> > " decap action in a flow");
> > + if (action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS)
> > + return rte_flow_error_set(error, EINVAL,
> > + RTE_FLOW_ERROR_TYPE_ACTION,
> > NULL,
> > + "can't have decap action after"
> > + " modify action");
> > if (attr->egress)
> > return rte_flow_error_set(error, ENOTSUP,
> >
> > RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, @@ -254,6 +757,11 @@
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > NULL,
> > "can only have a single decap"
> > " action in a flow");
> > + if (action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS)
> > + return rte_flow_error_set(error, EINVAL,
> > + RTE_FLOW_ERROR_TYPE_ACTION,
> > NULL,
> > + "can't have decap action after"
> > + " modify action");
> > /* decap action is valid on egress only if it is followed by encap */
> > if (attr->egress) {
> > for (; action->type != RTE_FLOW_ACTION_TYPE_END &&
> @@ -
> > 270,7 +778,6 @@
> > return 0;
> > }
> >
> > -
> > /**
> > * Find existing encap/decap resource or create and register a new one.
> > *
> > @@ -704,6 +1211,302 @@
> > }
> >
> > /**
> > + * Validate the modify-header actions.
> > + *
> > + * @param[in] action_flags
> > + * Holds the actions detected until now.
> > + * @param[in] action
> > + * Pointer to the modify action.
> > + * @param[out] error
> > + * Pointer to error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_validate_action_modify_hdr(const uint64_t action_flags,
> > + const struct rte_flow_action *action,
> > + struct rte_flow_error *error)
> > +{
> > + if (action->type != RTE_FLOW_ACTION_TYPE_DEC_TTL && !action-
> > >conf)
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION_CONF,
> > + NULL, "action configuration not
> set");
> > + if (action_flags & MLX5_FLOW_ENCAP_ACTIONS)
> > + return rte_flow_error_set(error, EINVAL,
> > + RTE_FLOW_ERROR_TYPE_ACTION,
> > NULL,
> > + "can't have encap action before"
> > + " modify action");
> > + return 0;
> > +}
> > +
> > +/**
> > + * Validate the modify-header MAC address actions.
> > + *
> > + * @param[in] action_flags
> > + * Holds the actions detected until now.
> > + * @param[in] action
> > + * Pointer to the modify action.
> > + * @param[in] item_flags
> > + * Holds the items detected.
> > + * @param[out] error
> > + * Pointer to error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_validate_action_modify_mac(const uint64_t action_flags,
> > + const struct rte_flow_action *action,
> > + const uint64_t item_flags,
> > + struct rte_flow_error *error)
> > +{
> > + int ret = 0;
> > +
> > + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> error);
> > + if (!ret) {
> > + if (!(item_flags & MLX5_FLOW_LAYER_L2))
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL,
> > + "no L2 item in pattern");
> > + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL, "after decap no L2 "
> > + "item in pattern");
> > + }
>
> I didn't get this part, why there is no L2?
> Same question for the other verifications present here.
My mistake, will remove this validation here and elsewhere.
>
> > + return ret;
> > +}
> > +
> > +/**
> > + * Validate the modify-header IPv4 address actions.
> > + *
> > + * @param[in] action_flags
> > + * Holds the actions detected until now.
> > + * @param[in] action
> > + * Pointer to the modify action.
> > + * @param[in] item_flags
> > + * Holds the items detected.
> > + * @param[out] error
> > + * Pointer to error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_validate_action_modify_ipv4(const uint64_t action_flags,
> > + const struct rte_flow_action *action,
> > + const uint64_t item_flags,
> > + struct rte_flow_error *error) {
> > + int ret = 0;
> > +
> > + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> error);
> > + if (!ret) {
> > + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV4))
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL,
> > + "no ipv4 item in pattern");
> > + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL, "after decap "
> > + "no ipv4 item in pattern");
> > + }
> > + return ret;
> > +}
> > +
> > +/**
> > + * Validate the modify-header IPv6 address actions.
> > + *
> > + * @param[in] action_flags
> > + * Holds the actions detected until now.
> > + * @param[in] action
> > + * Pointer to the modify action.
> > + * @param[in] item_flags
> > + * Holds the items detected.
> > + * @param[out] error
> > + * Pointer to error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_validate_action_modify_ipv6(const uint64_t action_flags,
> > + const struct rte_flow_action *action,
> > + const uint64_t item_flags,
> > + struct rte_flow_error *error) {
> > + int ret = 0;
> > +
> > + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> error);
> > + if (!ret) {
> > + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV6))
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL,
> > + "no ipv6 item in pattern");
> > + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL, "after decap "
> > + "no ipv6 item in pattern");
> > + }
> > + return ret;
> > +}
> > +
> > +/**
> > + * Validate the modify-header TP actions.
> > + *
> > + * @param[in] action_flags
> > + * Holds the actions detected until now.
> > + * @param[in] action
> > + * Pointer to the modify action.
> > + * @param[in] item_flags
> > + * Holds the items detected.
> > + * @param[out] error
> > + * Pointer to error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_validate_action_modify_tp(const uint64_t action_flags,
> > + const struct rte_flow_action *action,
> > + const uint64_t item_flags,
> > + struct rte_flow_error *error)
> > +{
> > + int ret = 0;
> > +
> > + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> error);
> > + if (!ret) {
> > + if (!(item_flags & MLX5_FLOW_LAYER_L4))
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL, "no transport layer "
> > + "in pattern");
> > + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL, "after decap no "
> > + "transport layer in pattern");
> > + }
> > + return ret;
> > +}
> > +
> > +/**
> > + * Validate the modify-header TTL actions.
> > + *
> > + * @param[in] action_flags
> > + * Holds the actions detected until now.
> > + * @param[in] action
> > + * Pointer to the modify action.
> > + * @param[in] item_flags
> > + * Holds the items detected.
> > + * @param[out] error
> > + * Pointer to error structure.
> > + *
> > + * @return
> > + * 0 on success, a negative errno value otherwise and rte_errno is set.
> > + */
> > +static int
> > +flow_dv_validate_action_modify_ttl(const uint64_t action_flags,
> > + const struct rte_flow_action *action,
> > + const uint64_t item_flags,
> > + struct rte_flow_error *error)
> > +{
> > + int ret = 0;
> > +
> > + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> error);
> > + if (!ret) {
> > + if (!(item_flags & MLX5_FLOW_LAYER_L3))
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL,
> > + "no IP protocol in pattern");
> > + if (action_flags & MLX5_FLOW_DECAP_ACTIONS)
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL, "after decap "
> > + "no IP protocol in pattern");
> > + }
> > + return ret;
> > +}
> > +
> > +/**
> > + * Find existing modify-header resource or create and register a new one.
> > + *
> > + * @param dev[in, out]
> > + * Pointer to rte_eth_dev structure.
> > + * @param[in, out] resource
> > + * Pointer to modify-header resource.
> > + * @parm[in, out] dev_flow
> > + * Pointer to the dev_flow.
> > + * @param[out] error
> > + * pointer to error structure.
> > + *
> > + * @return
> > + * 0 on success otherwise -errno and errno is set.
> > + */
> > +static int
> > +flow_dv_modify_hdr_resource_register
> > + (struct rte_eth_dev *dev,
> > + struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> > + struct mlx5_flow *dev_flow,
> > + struct rte_flow_error *error)
> > +{
> > + struct priv *priv = dev->data->dev_private;
> > + struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
> > +
> > + /* Lookup a matching resource from cache. */
> > + LIST_FOREACH(cache_resource, &priv->modify_cmds, next) {
> > + if (resource->ft_type == cache_resource->ft_type &&
> > + resource->actions_num == cache_resource->actions_num
> > &&
> > + !memcmp((const void *)resource->actions,
> > + (const void *)cache_resource->actions,
> > + (resource->actions_num *
> > + sizeof(resource->actions[0])))) {
> > + DRV_LOG(DEBUG, "modify-header resource %p:
> refcnt
> > %d++",
> > + (void *)cache_resource,
> > + rte_atomic32_read(&cache_resource-
> > >refcnt));
> > + rte_atomic32_inc(&cache_resource->refcnt);
> > + dev_flow->dv.modify_hdr = cache_resource;
> > + return 0;
> > + }
> > + }
> > + /* Register new modify-header resource. */
> > + cache_resource = rte_calloc(__func__, 1, sizeof(*cache_resource),
> 0);
> > + if (!cache_resource)
> > + return rte_flow_error_set(error, ENOMEM,
> > +
> > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
> > + "cannot allocate resource
> memory");
> > + *cache_resource = *resource;
> > + cache_resource->verbs_action =
> > + mlx5_glue->dv_create_flow_action_modify_header
> > + (priv->ctx,
> > + cache_resource->actions_num *
> > + sizeof(cache_resource->actions[0]),
> > + (uint64_t *)cache_resource-
> >actions,
> > + cache_resource->ft_type);
> > + if (!cache_resource->verbs_action) {
> > + rte_free(cache_resource);
> > + return rte_flow_error_set(error, ENOMEM,
> > +
> > RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> > + NULL, "cannot create action");
> > + }
> > + rte_atomic32_init(&cache_resource->refcnt);
> > + rte_atomic32_inc(&cache_resource->refcnt);
> > + LIST_INSERT_HEAD(&priv->modify_cmds, cache_resource, next);
> > + dev_flow->dv.modify_hdr = cache_resource;
> > + DRV_LOG(DEBUG, "new modify-header resource %p: refcnt %d++",
> > + (void *)cache_resource,
> > + rte_atomic32_read(&cache_resource->refcnt));
> > + return 0;
> > +}
> > +
> > +/**
> > * Verify the @p attributes will be correctly understood by the NIC and
> store
> > * them in the @p flow if everything is correct.
> > *
> > @@ -1014,6 +1817,87 @@
> > action_flags |= MLX5_FLOW_ACTION_RAW_DECAP;
> > ++actions_n;
> > break;
> > + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
> > + ret =
> > flow_dv_validate_action_modify_mac(action_flags,
> > + actions,
> > + item_flags,
> > + error);
> > + if (ret < 0)
> > + return ret;
> > + /* Count all modify-header actions as one action. */
> > + if (!(action_flags &
> > MLX5_FLOW_MODIFY_HDR_ACTIONS))
> > + ++actions_n;
> > + action_flags |= actions->type ==
> > +
> > RTE_FLOW_ACTION_TYPE_SET_MAC_SRC ?
> > +
> > MLX5_FLOW_ACTION_SET_MAC_SRC :
> > +
> > MLX5_FLOW_ACTION_SET_MAC_DST;
> > + break;
> > +
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
> > + ret =
> > flow_dv_validate_action_modify_ipv4(action_flags,
> > + actions,
> > + item_flags,
> > + error);
> > + if (ret < 0)
> > + return ret;
> > + /* Count all modify-header actions as one action. */
> > + if (!(action_flags &
> > MLX5_FLOW_MODIFY_HDR_ACTIONS))
> > + ++actions_n;
> > + action_flags |= actions->type ==
> > +
> > RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC ?
> > +
> > MLX5_FLOW_ACTION_SET_IPV4_SRC :
> > +
> > MLX5_FLOW_ACTION_SET_IPV4_DST;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
> > + ret =
> > flow_dv_validate_action_modify_ipv6(action_flags,
> > + actions,
> > + item_flags,
> > + error);
> > + if (ret < 0)
> > + return ret;
> > + /* Count all modify-header actions as one action. */
> > + if (!(action_flags &
> > MLX5_FLOW_MODIFY_HDR_ACTIONS))
> > + ++actions_n;
> > + action_flags |= actions->type ==
> > +
> > RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC ?
> > +
> > MLX5_FLOW_ACTION_SET_IPV6_SRC :
> > +
> > MLX5_FLOW_ACTION_SET_IPV6_DST;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
> > + ret =
> flow_dv_validate_action_modify_tp(action_flags,
> > + actions,
> > + item_flags,
> > + error);
> > + if (ret < 0)
> > + return ret;
> > + /* Count all modify-header actions as one action. */
> > + if (!(action_flags &
> > MLX5_FLOW_MODIFY_HDR_ACTIONS))
> > + ++actions_n;
> > + action_flags |= actions->type ==
> > +
> > RTE_FLOW_ACTION_TYPE_SET_TP_SRC ?
> > +
> > MLX5_FLOW_ACTION_SET_TP_SRC :
> > +
> > MLX5_FLOW_ACTION_SET_TP_DST;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_DEC_TTL:
> > + case RTE_FLOW_ACTION_TYPE_SET_TTL:
> > + ret =
> flow_dv_validate_action_modify_ttl(action_flags,
> > + actions,
> > + item_flags,
> > + error);
> > + if (ret < 0)
> > + return ret;
> > + /* Count all modify-header actions as one action. */
> > + if (!(action_flags &
> > MLX5_FLOW_MODIFY_HDR_ACTIONS))
> > + ++actions_n;
> > + action_flags |= actions->type ==
> > + RTE_FLOW_ACTION_TYPE_SET_TTL ?
> > +
> > MLX5_FLOW_ACTION_SET_TTL :
> > +
> > MLX5_FLOW_ACTION_DEC_TTL;
> > + break;
> > default:
> > return rte_flow_error_set(error, ENOTSUP,
> >
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > @@ -1895,10 +2779,16 @@
> > },
> > };
> > int actions_n = 0;
> > + bool actions_end = false;
> > + struct mlx5_flow_dv_modify_hdr_resource res = {
> > + .ft_type = attr->egress ?
> MLX5DV_FLOW_TABLE_TYPE_NIC_TX
> > :
> > +
> > MLX5DV_FLOW_TABLE_TYPE_NIC_RX
> > + };
> > + union flow_dv_attr flow_attr = { .attr = 0 };
> >
> > if (priority == MLX5_FLOW_PRIO_RSVD)
> > priority = priv->config.flow_prio - 1;
> > - for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
> > + for (; !actions_end ; actions++) {
> > const struct rte_flow_action_queue *queue;
> > const struct rte_flow_action_rss *rss;
> > const struct rte_flow_action *action = actions; @@ -2025,6
> > +2915,77 @@
> > /* If decap is followed by encap, handle it at encap.
> */
> > action_flags |= MLX5_FLOW_ACTION_RAW_DECAP;
> > break;
> > + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
> > + if (flow_dv_convert_action_modify_mac(&res,
> actions,
> > + error))
> > + return -rte_errno;
> > + action_flags |= actions->type ==
> > +
> > RTE_FLOW_ACTION_TYPE_SET_MAC_SRC ?
> > +
> MLX5_FLOW_ACTION_SET_MAC_SRC
> > :
> > +
> MLX5_FLOW_ACTION_SET_MAC_DST;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
> > + if (flow_dv_convert_action_modify_ipv4(&res,
> actions,
> > + error))
> > + return -rte_errno;
> > + action_flags |= actions->type ==
> > +
> > RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC ?
> > + MLX5_FLOW_ACTION_SET_IPV4_SRC
> :
> > +
> MLX5_FLOW_ACTION_SET_IPV4_DST;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
> > + if (flow_dv_convert_action_modify_ipv6(&res,
> actions,
> > + error))
> > + return -rte_errno;
> > + action_flags |= actions->type ==
> > +
> > RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC ?
> > + MLX5_FLOW_ACTION_SET_IPV6_SRC
> :
> > +
> MLX5_FLOW_ACTION_SET_IPV6_DST;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
> > + if (flow_dv_convert_action_modify_tp(&res, actions,
> > + items, &flow_attr,
> > + error))
> > + return -rte_errno;
> > + action_flags |= actions->type ==
> > +
> > RTE_FLOW_ACTION_TYPE_SET_TP_SRC ?
> > + MLX5_FLOW_ACTION_SET_TP_SRC :
> > + MLX5_FLOW_ACTION_SET_TP_DST;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_DEC_TTL:
> > + if (flow_dv_convert_action_modify_dec_ttl(&res,
> > items,
> > + &flow_attr,
> > + error))
> > + return -rte_errno;
> > + action_flags |= MLX5_FLOW_ACTION_DEC_TTL;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_SET_TTL:
> > + if (flow_dv_convert_action_modify_ttl(&res, actions,
> > + items, &flow_attr,
> > + error))
> > + return -rte_errno;
> > + action_flags |= MLX5_FLOW_ACTION_SET_TTL;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_END:
> > + actions_end = true;
> > + if (action_flags &
> > MLX5_FLOW_MODIFY_HDR_ACTIONS) {
> > + /* create modify action if needed. */
> > + if (flow_dv_modify_hdr_resource_register
> > + (dev, &res,
> > + dev_flow,
> > + error))
> > + return -rte_errno;
> > + dev_flow->dv.actions[actions_n].type =
> > +
> > MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;
> > + dev_flow->dv.actions[actions_n].action =
> > + dev_flow->dv.modify_hdr-
> > >verbs_action;
> > + actions_n++;
> > + }
> > + break;
> > default:
> > break;
> > }
> > @@ -2309,6 +3270,37 @@
> > }
> >
> > /**
> > + * Release a modify-header resource.
> > + *
> > + * @param flow
> > + * Pointer to mlx5_flow.
> > + *
> > + * @return
> > + * 1 while a reference on it exists, 0 when freed.
> > + */
> > +static int
> > +flow_dv_modify_hdr_resource_release(struct mlx5_flow *flow) {
> > + struct mlx5_flow_dv_modify_hdr_resource *cache_resource =
> > + flow->dv.modify_hdr;
> > +
> > + assert(cache_resource->verbs_action);
> > + DRV_LOG(DEBUG, "modify-header resource %p: refcnt %d--",
> > + (void *)cache_resource,
> > + rte_atomic32_read(&cache_resource->refcnt));
> > + if (rte_atomic32_dec_and_test(&cache_resource->refcnt)) {
> > + claim_zero(mlx5_glue->destroy_flow_action
> > + (cache_resource->verbs_action));
> > + LIST_REMOVE(cache_resource, next);
> > + rte_free(cache_resource);
> > + DRV_LOG(DEBUG, "modify-header resource %p: removed",
> > + (void *)cache_resource);
> > + return 0;
> > + }
> > + return 1;
> > +}
> > +
> > +/**
> > * Remove the flow from the NIC but keeps it in memory.
> > *
> > * @param[in] dev
> > @@ -2365,6 +3357,8 @@
> > flow_dv_matcher_release(dev, dev_flow);
> > if (dev_flow->dv.encap_decap)
> >
> flow_dv_encap_decap_resource_release(dev_flow);
> > + if (dev_flow->dv.modify_hdr)
> > + flow_dv_modify_hdr_resource_release(dev_flow);
> > rte_free(dev_flow);
> > }
> > }
> > diff --git a/drivers/net/mlx5/mlx5_glue.c
> > b/drivers/net/mlx5/mlx5_glue.c index
> > dd10ad6..a806d92 100644
> > --- a/drivers/net/mlx5/mlx5_glue.c
> > +++ b/drivers/net/mlx5/mlx5_glue.c
> > @@ -479,6 +479,26 @@
> > #endif
> > }
> >
> > +static struct ibv_flow_action *
> > +mlx5_glue_dv_create_flow_action_modify_header
> > + (struct ibv_context *ctx,
> > + size_t actions_sz,
> > + uint64_t actions[],
> > + enum mlx5dv_flow_table_type
> > ft_type) { #ifdef
> > +HAVE_IBV_FLOW_DV_SUPPORT
> > + return mlx5dv_create_flow_action_modify_header(ctx, actions_sz,
> > + actions, ft_type);
> > +#else
> > + (void)ctx;
> > + (void)actions_sz;
> > + (void)actions;
> > + (void)ft_type;
> > + return NULL;
> > +#endif
> > +}
> > +
> > +
> > alignas(RTE_CACHE_LINE_SIZE)
> > const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){
> > .version = MLX5_GLUE_VERSION,
> > @@ -535,4 +555,6 @@
> > .dv_create_flow = mlx5_glue_dv_create_flow,
> > .dv_create_flow_action_packet_reformat =
> >
> mlx5_glue_dv_create_flow_action_packet_reformat,
> > + .dv_create_flow_action_modify_header =
> > + mlx5_glue_dv_create_flow_action_modify_header,
> > };
> > diff --git a/drivers/net/mlx5/mlx5_glue.h
> > b/drivers/net/mlx5/mlx5_glue.h index 2d92ba8..9cfe836 100644
> > --- a/drivers/net/mlx5/mlx5_glue.h
> > +++ b/drivers/net/mlx5/mlx5_glue.h
> > @@ -164,6 +164,11 @@ struct mlx5_glue {
> > void *data,
> > enum mlx5dv_flow_action_packet_reformat_type
> > reformat_type,
> > enum mlx5dv_flow_table_type ft_type);
> > + struct ibv_flow_action *(*dv_create_flow_action_modify_header)
> > + (struct ibv_context *ctx,
> > + size_t actions_sz,
> > + uint64_t actions[],
> > + enum mlx5dv_flow_table_type
> > ft_type);
>
> Need to bump up the LIB_GLUE_VERSION due to this ABI change.
I will change it.
>
> > };
> >
> > const struct mlx5_glue *mlx5_glue;
> > diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h
> > index 29742b1..545f84a 100644
> > --- a/drivers/net/mlx5/mlx5_prm.h
> > +++ b/drivers/net/mlx5/mlx5_prm.h
> > @@ -280,8 +280,17 @@ struct mlx5_cqe {
> > /* CQE format value. */
> > #define MLX5_COMPRESSED 0x3
> >
> > +/* Write a specific data value to a field. */ #define
> > +MLX5_MODIFICATION_TYPE_SET 1
> > +
> > +/* Add a specific data value to a field. */ #define
> > +MLX5_MODIFICATION_TYPE_ADD 2
> > +
> > +/* Copy a specific data value to another one in a packet. */ #define
> > +MLX5_MODIFICATION_TYPE_COPY 3
> > +
> > /* The field of packet to be modified. */ -enum
> > mlx5_modificaiton_field {
> > +enum mlx5_modification_field {
> > MLX5_MODI_OUT_SMAC_47_16 = 1,
> > MLX5_MODI_OUT_SMAC_15_0,
> > MLX5_MODI_OUT_ETHERTYPE,
> > --
> > 1.8.3.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC 00/14] prefix network structures
2018-12-21 15:14 0% ` Ferruh Yigit
@ 2018-12-27 9:35 0% ` Olivier Matz
0 siblings, 0 replies; 200+ results
From: Olivier Matz @ 2018-12-27 9:35 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: Wiles, Keith, Stephen Hemminger, dpdk-dev, Richardson, Bruce
Hi,
On Fri, Dec 21, 2018 at 03:14:29PM +0000, Ferruh Yigit wrote:
> On 12/21/2018 2:38 PM, Wiles, Keith wrote:
> >
> >
> >> On Dec 20, 2018, at 5:48 PM, Stephen Hemminger <stephen@networkplumber.org> wrote:
> >>
> >> On Thu, 20 Dec 2018 21:59:37 +0000
> >> Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> >>
> >>> On 10/24/2018 9:18 AM, olivier.matz at 6wind.com (Olivier Matz) wrote:
> >>>> This RFC targets 19.02.
> >>>>
> >>>> The rte_net headers conflict with the libc headers, because
> >>>> some definitions are duplicated, sometimes with few differences.
> >>>> This was discussed in [1], and more recently at the techboard.
> >>>>
> >>>> Before sending the deprecation notice (target for this is 18.11),
> >>>> here is a draft that can be discussed.
> >>>>
> >>>> This RFC adds the rte_ (or RTE_) prefix to all structures, functions
> >>>> and defines in rte_net library. This is a big changeset, that will
> >>>> break the API of many functions, but not the ABI.
> >>>>
> >>>> One question I'm asking is how can we manage the transition.
> >>>> Initially, I hoped it was possible to have a compat layer during
> >>>> one release (supporting both prefixed and unprefixed names), but
> >>>> now that the patch is done, it seems the impact is too big, and
> >>>> impacts too many libraries.
> >>>>
> >>>> Few examples:
> >>>> - rte_eth_macaddr_get/add/remove() use a (struct rte_ether_addr *)
> >>>> - many rte_flow structures use the rte_ prefixed net structures
> >>>> - the mac field of virtio_net structure is rte_ether_addr
> >>>> - the first arg of rte_thash_load_v6_addrs is (struct rte_ipv6_hdr *)
> >>>> ...
> >>>>
> >>>> Therefore, it is clear that doing this would break the compilation
> >>>> of many external applications.
> >>>>
> >>>> Another drawback we need to take in account: it will make the
> >>>> backport of patches more difficult, although this is something
> >>>> that could be tempered by a script.
> >>>>
> >>>> While it is obviously better to have a good namespace convention,
> >>>> we need to identify the issues we have today before deciding it's
> >>>> worth doing the change.
> >>>>
> >>>> Comments?
> >>>
> >>> Is there an consensus about the patchset? There was a decision on techboard to
> >>> go with this change (adding rte_ prefix) [1].
> >>>
> >>>
> >>> This is something that will affect DPDK consumers. Since many APIs are changing
> >>> most probably will break API compatibility for many libraries.
> >>>
> >>> Meanwhile the conflict with the libc headers mentioned a few times in the past,
> >>> this is something we need to fix.
> >>>
> >>> There are a few comments reluctant to this big modification, but what I
> >>> understand from Olivier's response both using BSD defines or having
> >>> compatibility headers in DPDK won't solve the problem completely.
> >>>
> >>> And assuming we will continue with this solution, another question is do we
> >>> still want to push in 19.02 scope? (And from process point of view I think a
> >>> deprecation notice is not merged for this change in 18.11 scope.)
> >>>
> >>> With the prediction of 19.05 will be big and already break API/ABI for some
> >>> libraries, can we push this into 19.05 as an early merge into repo?
> >>>
> >>> And I think this patch will affect LTS releases and will break auto backporting
> >>> for many fixes because it touches many places, so pushing this change even to
> >>> next LTS (19.11) can be an option.
> >>>
> >>>
> >>> Olivier, Thomas,
> >>>
> >>> What do you think about postponing this to 19.05 or even 19.11 ?
> >>>
> >>>
> >>>
> >>> [1]
> >>> https://mails.dpdk.org/archives/dev/2018-October/116695.html
> >>>
> >>>>
> >>>>
> >>>> Things that are missing in RFC:
> >>>> - test with FreeBSD
> >>>> - manually fix some indentation issues
> >>>>
> >>>>
> >>>> Olivier Matz (14):
> >>>> net: add rte prefix to arp structures
> >>>> net: add rte prefix to arp defines
> >>>> net: add rte prefix to ether structures
> >>>> net: add rte prefix to ether functions
> >>>> net: add rte prefix to ether defines
> >>>> net: add rte prefix to esp structure
> >>>> net: add rte prefix to gre structure
> >>>> net: add rte prefix to icmp structure
> >>>> net: add rte prefix to icmp defines
> >>>> net: add rte prefix to ip structure
> >>>> net: add rte prefix to ip defines
> >>>> net: add rte prefix to sctp structure
> >>>> net: add rte prefix to tcp structure
> >>>> net: add rte prefix to udp structure
> >>>
> >>>
> >>
> >> Sigh. Another case where DPDK has to reinvent something because
> >> we can't figure out how to do dependent libraries correctly.
> >> I would have rather just using the existing Linux, BSD definitions
> >> and fixing the DPDK code.
It is not that simple. As I said in [1], there are still some
differences between gnu libc and freebsd libc. Unfortunatly, the struct
ether_addr is one of the most important in dpdk, because it is widely
used in APIs (drivers).
We can find others differences, for instance in constant definitions in
if_arp.h. I also see that some structures are packed in freebsd but not
in glibc (ex: icmp6), this could have performance impact.
Many protocols that are currently defined in dpdk are missing in glibc:
esp, sctp, gre, mpls, ... so we will at least need rte_ structures for
these protocols.
Supporting other OSes or libc in the future could also increase the gaps.
For these reasons think it is reasonable to have a consistent set of
network structures in dpdk.
[1] https://mails.dpdk.org/archives/dev/2018-October/117258.html
> >> It is probably the only viable compromise, but it adds to long
> >> term maintenance, and breaks DPDK applications. Neither of which
> >> is a good thing.
> >>
> >> Should this be done by marking the old structure deprecated
> >> first? Ideally, spread over three releases: first, tell the users
> >> in the documentation it is coming; second, mark the old structures
> >> as deprecated causing compiler warnings; third, remove the old
> >> definitions. Doing at once is introducing user pain for no gain.
> >
> > +1
Annoucing the change before doing it is obvious. Marking the old
structures as deprecated before removing them is maybe doable (to be
checked that it does not cause conflicts with new structures), but it
means the conflict with libc headers that we are trying to solve will
remain for one more version, for a limited gain.
> With the current timeline, readiness of the patch and comments, at least it
> won't able to make this release, I will update the patchset status as 'Deferred'
>
> Should we discuss this again in techboard?
We should surely weigh the pros and cons. Especially the additional
backport troubles it can bring.
Are many people bothered by the current conflict with the libc headers?
Olivier
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v5 00/10] ipsec: new library for IPsec data-path processing
@ 2018-12-28 15:17 2% ` Konstantin Ananyev
0 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2018-12-28 15:17 UTC (permalink / raw)
To: dev, dev; +Cc: akhil.goyal, Konstantin Ananyev
v4 -> v5
- Fix issue with SQN overflows
- Address Akhil comments:
documentation update
spell checks spacing etc.
fix input crypto_xform check/prepcess
test cases for lookaside and inline proto
v3 -> v4
- Changes to adress Declan comments
- Update docs
v2 -> v3
- Several fixes for IPv6 support
- Extra checks for input parameters in public APi functions
v1 -> v2
- Changes to get into account l2_len for outbound transport packets
(Qi comments)
- Several bug fixes
- Some code restructured
- Update MAINTAINERS file
RFCv2 -> v1
- Changes per Jerin comments
- Implement transport mode
- Several bug fixes
- UT largely reworked and extended
This patch introduces a new library within DPDK: librte_ipsec.
The aim is to provide DPDK native high performance library for IPsec
data-path processing.
The library is supposed to utilize existing DPDK crypto-dev and
security API to provide application with transparent IPsec
processing API.
The library is concentrated on data-path protocols processing
(ESP and AH), IKE protocol(s) implementation is out of scope
for that library.
Current patch introduces SA-level API.
SA (low) level API
==================
API described below operates on SA level.
It provides functionality that allows user for given SA to process
inbound and outbound IPsec packets.
To be more specific:
- for inbound ESP/AH packets perform decryption, authentication,
integrity checking, remove ESP/AH related headers
- for outbound packets perform payload encryption, attach ICV,
update/add IP headers, add ESP/AH headers/trailers,
setup related mbuf felids (ol_flags, tx_offloads, etc.).
- initialize/un-initialize given SA based on user provided parameters.
The following functionality:
- match inbound/outbound packets to particular SA
- manage crypto/security devices
- provide SAD/SPD related functionality
- determine what crypto/security device has to be used
for given packet(s)
is out of scope for SA-level API.
SA-level API is based on top of crypto-dev/security API and relies on them
to perform actual cipher and integrity checking.
To have an ability to easily map crypto/security sessions into related
IPSec SA opaque userdata field was added into
rte_cryptodev_sym_session and rte_security_session structures.
That implies ABI change for both librte_crytpodev and librte_security.
Due to the nature of crypto-dev API (enqueue/deque model) we use
asynchronous API for IPsec packets destined to be processed by crypto-device.
Expected API call sequence would be:
/* enqueue for processing by crypto-device */
rte_ipsec_pkt_crypto_prepare(...);
rte_cryptodev_enqueue_burst(...);
/* dequeue from crypto-device and do final processing (if any) */
rte_cryptodev_dequeue_burst(...);
rte_ipsec_pkt_crypto_group(...); /* optional */
rte_ipsec_pkt_process(...);
Though for packets destined for inline processing no extra overhead
is required and synchronous API call: rte_ipsec_pkt_process()
is sufficient for that case.
Current implementation supports all four currently defined
rte_security types.
Though to accommodate future custom implementations function pointers
model is used for both for *crypto_prepare* and *process* impelementations.
Konstantin Ananyev (10):
cryptodev: add opaque userdata pointer into crypto sym session
security: add opaque userdata pointer into security session
net: add ESP trailer structure definition
lib: introduce ipsec library
ipsec: add SA data-path API
ipsec: implement SA data-path API
ipsec: rework SA replay window/SQN for MT environment
ipsec: helper functions to group completed crypto-ops
test/ipsec: introduce functional test
doc: add IPsec library guide
MAINTAINERS | 8 +-
config/common_base | 5 +
doc/guides/prog_guide/index.rst | 1 +
doc/guides/prog_guide/ipsec_lib.rst | 168 ++
doc/guides/rel_notes/release_19_02.rst | 11 +
lib/Makefile | 2 +
lib/librte_cryptodev/rte_cryptodev.h | 2 +
lib/librte_ipsec/Makefile | 27 +
lib/librte_ipsec/crypto.h | 123 ++
lib/librte_ipsec/iph.h | 84 +
lib/librte_ipsec/ipsec_sqn.h | 343 ++++
lib/librte_ipsec/meson.build | 10 +
lib/librte_ipsec/pad.h | 45 +
lib/librte_ipsec/rte_ipsec.h | 154 ++
lib/librte_ipsec/rte_ipsec_group.h | 151 ++
lib/librte_ipsec/rte_ipsec_sa.h | 174 ++
lib/librte_ipsec/rte_ipsec_version.map | 15 +
lib/librte_ipsec/sa.c | 1527 ++++++++++++++
lib/librte_ipsec/sa.h | 106 +
lib/librte_ipsec/ses.c | 45 +
lib/librte_net/rte_esp.h | 10 +-
lib/librte_security/rte_security.h | 2 +
lib/meson.build | 2 +
mk/rte.app.mk | 2 +
test/test/Makefile | 3 +
test/test/meson.build | 3 +
test/test/test_ipsec.c | 2555 ++++++++++++++++++++++++
27 files changed, 5576 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/prog_guide/ipsec_lib.rst
create mode 100644 lib/librte_ipsec/Makefile
create mode 100644 lib/librte_ipsec/crypto.h
create mode 100644 lib/librte_ipsec/iph.h
create mode 100644 lib/librte_ipsec/ipsec_sqn.h
create mode 100644 lib/librte_ipsec/meson.build
create mode 100644 lib/librte_ipsec/pad.h
create mode 100644 lib/librte_ipsec/rte_ipsec.h
create mode 100644 lib/librte_ipsec/rte_ipsec_group.h
create mode 100644 lib/librte_ipsec/rte_ipsec_sa.h
create mode 100644 lib/librte_ipsec/rte_ipsec_version.map
create mode 100644 lib/librte_ipsec/sa.c
create mode 100644 lib/librte_ipsec/sa.h
create mode 100644 lib/librte_ipsec/ses.c
create mode 100644 test/test/test_ipsec.c
--
2.17.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v6 00/10] ipsec: new library for IPsec data-path processing
@ 2019-01-03 20:16 2% ` Konstantin Ananyev
2019-01-11 1:09 2% ` Xu, Yanjie
1 sibling, 1 reply; 200+ results
From: Konstantin Ananyev @ 2019-01-03 20:16 UTC (permalink / raw)
To: dev, dev; +Cc: akhil.goyal, Konstantin Ananyev
v5 -> v6
- Fix issues reported by Akhil:
rte_ipsec_session_prepare() fails for lookaside-proto
v4 -> v5
- Fix issue with SQN overflows
- Address Akhil comments:
documentation update
spell checks spacing etc.
fix input crypto_xform check/prepcess
test cases for lookaside and inline proto
v3 -> v4
- Changes to adress Declan comments
- Update docs
v2 -> v3
- Several fixes for IPv6 support
- Extra checks for input parameters in public APi functions
v1 -> v2
- Changes to get into account l2_len for outbound transport packets
(Qi comments)
- Several bug fixes
- Some code restructured
- Update MAINTAINERS file
RFCv2 -> v1
- Changes per Jerin comments
- Implement transport mode
- Several bug fixes
- UT largely reworked and extended
This patch introduces a new library within DPDK: librte_ipsec.
The aim is to provide DPDK native high performance library for IPsec
data-path processing.
The library is supposed to utilize existing DPDK crypto-dev and
security API to provide application with transparent IPsec
processing API.
The library is concentrated on data-path protocols processing
(ESP and AH), IKE protocol(s) implementation is out of scope
for that library.
Current patch introduces SA-level API.
SA (low) level API
==================
API described below operates on SA level.
It provides functionality that allows user for given SA to process
inbound and outbound IPsec packets.
To be more specific:
- for inbound ESP/AH packets perform decryption, authentication,
integrity checking, remove ESP/AH related headers
- for outbound packets perform payload encryption, attach ICV,
update/add IP headers, add ESP/AH headers/trailers,
setup related mbuf felids (ol_flags, tx_offloads, etc.).
- initialize/un-initialize given SA based on user provided parameters.
The following functionality:
- match inbound/outbound packets to particular SA
- manage crypto/security devices
- provide SAD/SPD related functionality
- determine what crypto/security device has to be used
for given packet(s)
is out of scope for SA-level API.
SA-level API is based on top of crypto-dev/security API and relies on them
to perform actual cipher and integrity checking.
To have an ability to easily map crypto/security sessions into related
IPSec SA opaque userdata field was added into
rte_cryptodev_sym_session and rte_security_session structures.
That implies ABI change for both librte_crytpodev and librte_security.
Due to the nature of crypto-dev API (enqueue/deque model) we use
asynchronous API for IPsec packets destined to be processed by
crypto-device.
Expected API call sequence would be:
/* enqueue for processing by crypto-device */
rte_ipsec_pkt_crypto_prepare(...);
rte_cryptodev_enqueue_burst(...);
/* dequeue from crypto-device and do final processing (if any) */
rte_cryptodev_dequeue_burst(...);
rte_ipsec_pkt_crypto_group(...); /* optional */
rte_ipsec_pkt_process(...);
Though for packets destined for inline processing no extra overhead
is required and synchronous API call: rte_ipsec_pkt_process()
is sufficient for that case.
Current implementation supports all four currently defined
rte_security types.
Though to accommodate future custom implementations function pointers
model is used for both for *crypto_prepare* and *process*
impelementations.
Konstantin Ananyev (10):
cryptodev: add opaque userdata pointer into crypto sym session
security: add opaque userdata pointer into security session
net: add ESP trailer structure definition
lib: introduce ipsec library
ipsec: add SA data-path API
ipsec: implement SA data-path API
ipsec: rework SA replay window/SQN for MT environment
ipsec: helper functions to group completed crypto-ops
test/ipsec: introduce functional test
doc: add IPsec library guide
MAINTAINERS | 8 +-
config/common_base | 5 +
doc/guides/prog_guide/index.rst | 1 +
doc/guides/prog_guide/ipsec_lib.rst | 168 ++
doc/guides/rel_notes/release_19_02.rst | 11 +
lib/Makefile | 2 +
lib/librte_cryptodev/rte_cryptodev.h | 2 +
lib/librte_ipsec/Makefile | 27 +
lib/librte_ipsec/crypto.h | 123 ++
lib/librte_ipsec/iph.h | 84 +
lib/librte_ipsec/ipsec_sqn.h | 343 ++++
lib/librte_ipsec/meson.build | 10 +
lib/librte_ipsec/pad.h | 45 +
lib/librte_ipsec/rte_ipsec.h | 154 ++
lib/librte_ipsec/rte_ipsec_group.h | 151 ++
lib/librte_ipsec/rte_ipsec_sa.h | 174 ++
lib/librte_ipsec/rte_ipsec_version.map | 15 +
lib/librte_ipsec/sa.c | 1527 ++++++++++++++
lib/librte_ipsec/sa.h | 106 +
lib/librte_ipsec/ses.c | 52 +
lib/librte_net/rte_esp.h | 10 +-
lib/librte_security/rte_security.h | 2 +
lib/meson.build | 2 +
mk/rte.app.mk | 2 +
test/test/Makefile | 3 +
test/test/meson.build | 3 +
test/test/test_ipsec.c | 2555 ++++++++++++++++++++++++
27 files changed, 5583 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/prog_guide/ipsec_lib.rst
create mode 100644 lib/librte_ipsec/Makefile
create mode 100644 lib/librte_ipsec/crypto.h
create mode 100644 lib/librte_ipsec/iph.h
create mode 100644 lib/librte_ipsec/ipsec_sqn.h
create mode 100644 lib/librte_ipsec/meson.build
create mode 100644 lib/librte_ipsec/pad.h
create mode 100644 lib/librte_ipsec/rte_ipsec.h
create mode 100644 lib/librte_ipsec/rte_ipsec_group.h
create mode 100644 lib/librte_ipsec/rte_ipsec_sa.h
create mode 100644 lib/librte_ipsec/rte_ipsec_version.map
create mode 100644 lib/librte_ipsec/sa.c
create mode 100644 lib/librte_ipsec/sa.h
create mode 100644 lib/librte_ipsec/ses.c
create mode 100644 test/test/test_ipsec.c
--
2.17.1
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH v6 01/10] cryptodev: add opaque userdata pointer into crypto sym session
@ 2019-01-04 0:25 3% ` Stephen Hemminger
2019-01-04 9:29 0% ` Ananyev, Konstantin
2019-01-10 14:20 4% ` [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
` (2 subsequent siblings)
3 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-01-04 0:25 UTC (permalink / raw)
To: Konstantin Ananyev; +Cc: dev, akhil.goyal
On Thu, 3 Jan 2019 20:16:17 +0000
Konstantin Ananyev <konstantin.ananyev@intel.com> wrote:
> Add 'uint64_t opaque_data' inside struct rte_cryptodev_sym_session.
> That allows upper layer to easily associate some user defined
> data with the session.
>
> Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Acked-by: Fiona Trahe <fiona.trahe@intel.com>
> Acked-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
> Acked-by: Declan Doherty <declan.doherty@intel.com>
> Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
> ---
> lib/librte_cryptodev/rte_cryptodev.h | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
> index 4099823f1..009860e7b 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev.h
> @@ -954,6 +954,8 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
> * has a fixed algo, key, op-type, digest_len etc.
> */
> struct rte_cryptodev_sym_session {
> + uint64_t opaque_data;
> + /**< Opaque user defined data */
> __extension__ void *sess_private_data[0];
> /**< Private symmetric session material */
> };
This will cause ABI breakage.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v6 01/10] cryptodev: add opaque userdata pointer into crypto sym session
2019-01-04 0:25 3% ` Stephen Hemminger
@ 2019-01-04 9:29 0% ` Ananyev, Konstantin
2019-01-09 23:41 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-01-04 9:29 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, akhil.goyal
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, January 4, 2019 12:26 AM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: dev@dpdk.org; akhil.goyal@nxp.com
> Subject: Re: [dpdk-dev] [PATCH v6 01/10] cryptodev: add opaque userdata pointer into crypto sym session
>
> On Thu, 3 Jan 2019 20:16:17 +0000
> Konstantin Ananyev <konstantin.ananyev@intel.com> wrote:
>
> > Add 'uint64_t opaque_data' inside struct rte_cryptodev_sym_session.
> > That allows upper layer to easily associate some user defined
> > data with the session.
> >
> > Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> > Acked-by: Fiona Trahe <fiona.trahe@intel.com>
> > Acked-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
> > Acked-by: Declan Doherty <declan.doherty@intel.com>
> > Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
> > ---
> > lib/librte_cryptodev/rte_cryptodev.h | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
> > index 4099823f1..009860e7b 100644
> > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > @@ -954,6 +954,8 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
> > * has a fixed algo, key, op-type, digest_len etc.
> > */
> > struct rte_cryptodev_sym_session {
> > + uint64_t opaque_data;
> > + /**< Opaque user defined data */
> > __extension__ void *sess_private_data[0];
> > /**< Private symmetric session material */
> > };
>
> This will cause ABI breakage.
Yes, it surely would.
That's why we submitted deprecation notice in 18.11 and got 3 acks for it.
Konstantin
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 1/2] cryptodev: change queue pair configure structure
2018-12-21 13:55 1% ` [dpdk-dev] [PATCH v3 1/2] cryptodev: change queue pair configure structure Fan Zhang
@ 2019-01-08 23:20 3% ` De Lara Guarch, Pablo
2019-01-09 11:30 0% ` Zhang, Roy Fan
0 siblings, 1 reply; 200+ results
From: De Lara Guarch, Pablo @ 2019-01-08 23:20 UTC (permalink / raw)
To: Zhang, Roy Fan, dev; +Cc: akhil.goyal, Trahe, Fiona
> -----Original Message-----
> From: Zhang, Roy Fan
> Sent: Friday, December 21, 2018 1:56 PM
> To: dev@dpdk.org
> Cc: akhil.goyal@nxp.com; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>
> Subject: [PATCH v3 1/2] cryptodev: change queue pair configure structure
>
> This patch changes the cryptodev queue pair configure structure
> to enable two mempool passed into cryptodev PMD simutaneously.
>
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> Acked-by: Fiona Trahe <fiona.trahe@@intel.com>
...
> diff --git a/doc/guides/rel_notes/release_19_02.rst
> b/doc/guides/rel_notes/release_19_02.rst
> index 47768288a..4420c2441 100644
> --- a/doc/guides/rel_notes/release_19_02.rst
> +++ b/doc/guides/rel_notes/release_19_02.rst
> @@ -130,6 +130,11 @@ API Changes
> ``rte_pdump_init()`` and enum ``rte_pdump_socktype`` were deprecated
> since 18.05 and are removed in this release.
>
> +* cryptodev: as shown in the the 18.08 deprecation notice, the structure
Typo. "the 18.11" deprecation notice.
> + ``rte_cryptodev_qp_conf`` has been added two parameters of symmetric
> session
> + mempool and symmetric session private data mempool, and the last
> parameter of
> + ``rte_cryptodev_queue_pair_setup()`` is removed.
> +
>
> ABI Changes
> -----------
I think we need to bump the ABI version of cryptodev due to this, in release notes.
Also, the deprecation notice added for this change, should be removed in this patch.
> diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> index ebdf7c35a..abc7a6d5f 100644
...
> --- a/examples/fips_validation/main.c
> +++ b/examples/fips_validation/main.c
> @@ -39,7 +39,7 @@ static int
> cryptodev_fips_validate_app_int(void)
> {
> struct rte_cryptodev_config conf = {rte_socket_id(), 1};
> - struct rte_cryptodev_qp_conf qp_conf = {128};
> + struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL};
Is this OK? Below, it looks like a mempool was passes (env.mpool), but now it is NULL here.
> int ret;
>
> ret = rte_cryptodev_configure(env.dev_id, &conf);
> @@ -52,7 +52,7 @@ cryptodev_fips_validate_app_int(void)
> return ret;
>
> ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
> - rte_socket_id(), env.mpool);
> + rte_socket_id());
> if (ret < 0)
> return ret;
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 1/2] cryptodev: change queue pair configure structure
2019-01-08 23:20 3% ` De Lara Guarch, Pablo
@ 2019-01-09 11:30 0% ` Zhang, Roy Fan
0 siblings, 0 replies; 200+ results
From: Zhang, Roy Fan @ 2019-01-09 11:30 UTC (permalink / raw)
To: De Lara Guarch, Pablo, dev; +Cc: akhil.goyal, Trahe, Fiona
Hi Pablo,
Thanks for the review.
Comments inline.
> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Tuesday, January 8, 2019 11:21 PM
> To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> Cc: akhil.goyal@nxp.com; Trahe, Fiona <fiona.trahe@intel.com>
> Subject: RE: [PATCH v3 1/2] cryptodev: change queue pair configure
> structure
>
>
>
> > -----Original Message-----
> > From: Zhang, Roy Fan
> > Sent: Friday, December 21, 2018 1:56 PM
> > To: dev@dpdk.org
> > Cc: akhil.goyal@nxp.com; De Lara Guarch, Pablo
> > <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>
> > Subject: [PATCH v3 1/2] cryptodev: change queue pair configure
> > structure
> >
> > This patch changes the cryptodev queue pair configure structure to
> > enable two mempool passed into cryptodev PMD simutaneously.
> >
> > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> > Acked-by: Fiona Trahe <fiona.trahe@@intel.com>
>
> ...
>
> > diff --git a/doc/guides/rel_notes/release_19_02.rst
> > b/doc/guides/rel_notes/release_19_02.rst
> > index 47768288a..4420c2441 100644
> > --- a/doc/guides/rel_notes/release_19_02.rst
> > +++ b/doc/guides/rel_notes/release_19_02.rst
> > @@ -130,6 +130,11 @@ API Changes
> > ``rte_pdump_init()`` and enum ``rte_pdump_socktype`` were deprecated
> > since 18.05 and are removed in this release.
> >
> > +* cryptodev: as shown in the the 18.08 deprecation notice, the
> > +structure
>
> Typo. "the 18.11" deprecation notice.
[Fan: Will change]
>
> > + ``rte_cryptodev_qp_conf`` has been added two parameters of
> > + symmetric
> > session
> > + mempool and symmetric session private data mempool, and the last
> > parameter of
> > + ``rte_cryptodev_queue_pair_setup()`` is removed.
> > +
> >
> > ABI Changes
> > -----------
>
> I think we need to bump the ABI version of cryptodev due to this, in release
> notes.
> Also, the deprecation notice added for this change, should be removed in
> this patch.
[Fan: Will do]
>
> > diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> > b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> > index ebdf7c35a..abc7a6d5f 100644
>
> ...
>
> > --- a/examples/fips_validation/main.c
> > +++ b/examples/fips_validation/main.c
> > @@ -39,7 +39,7 @@ static int
> > cryptodev_fips_validate_app_int(void)
> > {
> > struct rte_cryptodev_config conf = {rte_socket_id(), 1};
> > - struct rte_cryptodev_qp_conf qp_conf = {128};
> > + struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL};
>
> Is this OK? Below, it looks like a mempool was passes (env.mpool), but now it
> is NULL here.
[Fan: we do not need a mempool here as none of the session-less scheme will be tested]
>
> > int ret;
> >
> > ret = rte_cryptodev_configure(env.dev_id, &conf); @@ -52,7 +52,7
> @@
> > cryptodev_fips_validate_app_int(void)
> > return ret;
> >
> > ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
> > - rte_socket_id(), env.mpool);
> > + rte_socket_id());
> > if (ret < 0)
> > return ret;
> >
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4 01/12] cryptodev: change queue pair configure structure
@ 2019-01-09 22:55 3% ` Fan Zhang
2019-01-10 9:47 3% ` De Lara Guarch, Pablo
2019-01-09 22:55 3% ` [dpdk-dev] [PATCH v4 02/12] cryptodev: add sym session mempool create Fan Zhang
` (3 subsequent siblings)
4 siblings, 1 reply; 200+ results
From: Fan Zhang @ 2019-01-09 22:55 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, fiona.trahe
This patch changes the cryptodev queue pair configure structure
to enable two mempool passed into cryptodev PMD simutaneously.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@@intel.com>
---
app/test-crypto-perf/main.c | 6 ++--
doc/guides/prog_guide/cryptodev_lib.rst | 12 ++++++-
doc/guides/rel_notes/release_19_02.rst | 7 ++++
drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 7 ++--
drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c | 5 +--
drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h | 2 ++
drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 7 ++--
drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c | 5 +--
drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h | 2 ++
drivers/crypto/armv8/rte_armv8_pmd.c | 7 ++--
drivers/crypto/armv8/rte_armv8_pmd_ops.c | 5 +--
drivers/crypto/armv8/rte_armv8_pmd_private.h | 2 ++
drivers/crypto/caam_jr/caam_jr.c | 3 +-
drivers/crypto/ccp/ccp_pmd_ops.c | 5 +--
drivers/crypto/ccp/ccp_pmd_private.h | 2 ++
drivers/crypto/ccp/rte_ccp_pmd.c | 9 +++++-
drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c | 3 +-
drivers/crypto/dpaa_sec/dpaa_sec.c | 3 +-
drivers/crypto/kasumi/rte_kasumi_pmd.c | 7 ++--
drivers/crypto/kasumi/rte_kasumi_pmd_ops.c | 5 +--
drivers/crypto/kasumi/rte_kasumi_pmd_private.h | 2 ++
drivers/crypto/mvsam/rte_mrvl_pmd_ops.c | 5 +--
drivers/crypto/mvsam/rte_mrvl_pmd_private.h | 3 ++
drivers/crypto/null/null_crypto_pmd.c | 5 +--
drivers/crypto/null/null_crypto_pmd_ops.c | 5 +--
drivers/crypto/null/null_crypto_pmd_private.h | 2 ++
drivers/crypto/octeontx/otx_cryptodev_ops.c | 3 +-
drivers/crypto/openssl/rte_openssl_pmd.c | 7 ++--
drivers/crypto/openssl/rte_openssl_pmd_ops.c | 5 +--
drivers/crypto/openssl/rte_openssl_pmd_private.h | 2 ++
drivers/crypto/qat/qat_sym_pmd.c | 2 +-
drivers/crypto/scheduler/scheduler_pmd_ops.c | 5 ++-
drivers/crypto/snow3g/rte_snow3g_pmd.c | 7 ++--
drivers/crypto/snow3g/rte_snow3g_pmd_ops.c | 5 +--
drivers/crypto/snow3g/rte_snow3g_pmd_private.h | 2 ++
drivers/crypto/virtio/virtio_cryptodev.c | 6 ++--
drivers/crypto/zuc/rte_zuc_pmd.c | 7 ++--
drivers/crypto/zuc/rte_zuc_pmd_ops.c | 5 +--
drivers/crypto/zuc/rte_zuc_pmd_private.h | 2 ++
drivers/net/softnic/rte_eth_softnic_cryptodev.c | 2 +-
examples/fips_validation/main.c | 4 +--
examples/ip_pipeline/cryptodev.c | 2 +-
examples/ipsec-secgw/ipsec-secgw.c | 7 ++--
examples/l2fwd-crypto/main.c | 4 ++-
examples/vhost_crypto/main.c | 9 ++++--
lib/librte_cryptodev/Makefile | 4 +--
lib/librte_cryptodev/rte_cryptodev.c | 16 ++++++++--
lib/librte_cryptodev/rte_cryptodev.h | 7 ++--
lib/librte_cryptodev/rte_cryptodev_pmd.h | 3 +-
test/test/test_cryptodev.c | 37 +++++++++-------------
test/test/test_cryptodev_asym.c | 8 ++---
test/test/test_event_crypto_adapter.c | 5 +--
52 files changed, 182 insertions(+), 110 deletions(-)
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 953e058c9..38a2e429f 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -218,6 +218,9 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
session_pool_socket[socket_id] = sess_mp;
}
+ qp_conf.mp_session = session_pool_socket[socket_id];
+ qp_conf.mp_session_private = session_pool_socket[socket_id];
+
ret = rte_cryptodev_configure(cdev_id, &conf);
if (ret < 0) {
printf("Failed to configure cryptodev %u", cdev_id);
@@ -226,8 +229,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
for (j = 0; j < opts->nb_qps; j++) {
ret = rte_cryptodev_queue_pair_setup(cdev_id, j,
- &qp_conf, socket_id,
- session_pool_socket[socket_id]);
+ &qp_conf, socket_id);
if (ret < 0) {
printf("Failed to setup queue pair %u on "
"cryptodev %u", j, cdev_id);
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 8ee33c875..050a58dc4 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -121,11 +121,21 @@ Each queue pairs resources may be allocated on a specified socket.
const struct rte_cryptodev_qp_conf *qp_conf,
int socket_id)
- struct rte_cryptodev_qp_conf {
+ struct rte_cryptodev_qp_conf {
uint32_t nb_descriptors; /**< Number of descriptors per queue pair */
+ struct rte_mempool *mp_session;
+ /**< The mempool for creating session in sessionless mode */
+ struct rte_mempool *mp_session_private;
+ /**< The mempool for creating sess private data in sessionless mode */
};
+The fields ``mp_session`` and ``mp_session_private`` are used for creating
+temporary session to process the crypto operations in the session-less mode.
+They can be the same other different mempools. Please note not all Cryptodev
+PMDs supports session-less mode.
+
+
Logical Cores, Memory and Queues Pair Relationships
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index e3b2055d0..75128f8f2 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -164,6 +164,9 @@ API Changes
``rte_pdump_init()`` and enum ``rte_pdump_socktype`` were deprecated
since 18.05 and are removed in this release.
+* cryptodev: as shown in the the 18.11 deprecation notice, the last parameter
+ of ``rte_cryptodev_queue_pair_setup()``, ``session_pool``, is removed.
+
ABI Changes
-----------
@@ -183,6 +186,10 @@ ABI Changes
* mbuf: The format of the sched field of ``rte_mbuf`` has been changed
to include the following fields: ``queue ID``, ``traffic class``, ``color``.
+* cryptodev: as shown in the the 18.11 deprecation notice, the structure
+ ``rte_cryptodev_qp_conf`` has been added two parameters of symmetric session
+ mempool and symmetric session private data mempool.
+
Shared Library Versions
-----------------------
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index ebdf7c35a..abc7a6d5f 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -151,7 +151,8 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct aesni_gcm_session *)_sess_private_data;
@@ -159,7 +160,7 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_op *op)
if (unlikely(aesni_gcm_set_session_parameters(qp->ops,
sess, sym_op->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
sym_op->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -419,7 +420,7 @@ handle_completed_gcm_crypto_op(struct aesni_gcm_qp *qp,
memset(sess, 0, sizeof(struct aesni_gcm_session));
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sess);
+ rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
index cd15245bd..bf69dde54 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
@@ -206,7 +206,7 @@ aesni_gcm_pmd_qp_create_processed_pkts_ring(struct aesni_gcm_qp *qp,
static int
aesni_gcm_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct aesni_gcm_qp *qp = NULL;
struct aesni_gcm_private *internals = dev->data->dev_private;
@@ -234,7 +234,8 @@ aesni_gcm_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_pkts == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
index 92b041354..903e7503d 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
@@ -48,6 +48,8 @@ struct aesni_gcm_qp {
/**< Queue pair statistics */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
uint16_t id;
/**< Queue Pair Identifier */
char name[RTE_CRYPTODEV_NAME_MAX_LEN];
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index 83250e32c..b0f5c4d67 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -668,7 +668,8 @@ get_session(struct aesni_mb_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct aesni_mb_session *)_sess_private_data;
@@ -676,7 +677,7 @@ get_session(struct aesni_mb_qp *qp, struct rte_crypto_op *op)
if (unlikely(aesni_mb_set_session_parameters(qp->op_fns,
sess, op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -951,7 +952,7 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job)
memset(sess, 0, sizeof(struct aesni_mb_session));
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sess);
+ rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
index f3eff2685..af3021616 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
@@ -566,7 +566,7 @@ aesni_mb_pmd_qp_create_processed_ops_ring(struct aesni_mb_qp *qp,
static int
aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct aesni_mb_qp *qp = NULL;
struct aesni_mb_private *internals = dev->data->dev_private;
@@ -604,7 +604,8 @@ aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
goto qp_setup_cleanup;
}
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
index d8021cdaa..923403336 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
@@ -131,6 +131,8 @@ struct aesni_mb_qp {
/**< Ring for placing operations ready for processing */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats stats;
/**< Queue pair statistics */
uint8_t digest_idx;
diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
index 9d15fee53..3b2d7fb2f 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd.c
@@ -514,7 +514,8 @@ get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct armv8_crypto_session *)_sess_private_data;
@@ -522,7 +523,7 @@ get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op)
if (unlikely(armv8_crypto_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -656,7 +657,7 @@ process_op(struct armv8_crypto_qp *qp, struct rte_crypto_op *op,
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
rte_mempool_put(qp->sess_mp, sess);
- rte_mempool_put(qp->sess_mp, op->sym->session);
+ rte_mempool_put(qp->sess_mp_priv, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
index ae03117ea..a4fee83a8 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
@@ -220,7 +220,7 @@ armv8_crypto_pmd_qp_create_processed_ops_ring(struct armv8_crypto_qp *qp,
static int
armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct armv8_crypto_qp *qp = NULL;
@@ -245,7 +245,8 @@ armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_private.h b/drivers/crypto/armv8/rte_armv8_pmd_private.h
index 7feb021db..0afd9c7c5 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_private.h
+++ b/drivers/crypto/armv8/rte_armv8_pmd_private.h
@@ -116,6 +116,8 @@ struct armv8_crypto_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats stats;
/**< Queue pair statistics */
char name[RTE_CRYPTODEV_NAME_MAX_LEN];
diff --git a/drivers/crypto/caam_jr/caam_jr.c b/drivers/crypto/caam_jr/caam_jr.c
index f505adf6b..45b281331 100644
--- a/drivers/crypto/caam_jr/caam_jr.c
+++ b/drivers/crypto/caam_jr/caam_jr.c
@@ -1540,8 +1540,7 @@ static int
caam_jr_queue_pair_setup(
struct rte_cryptodev *dev, uint16_t qp_id,
__rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
- __rte_unused int socket_id,
- __rte_unused struct rte_mempool *session_pool)
+ __rte_unused int socket_id)
{
struct sec_job_ring_t *internals;
struct caam_jr_qp *qp = NULL;
diff --git a/drivers/crypto/ccp/ccp_pmd_ops.c b/drivers/crypto/ccp/ccp_pmd_ops.c
index 6984913f1..d5041f0ec 100644
--- a/drivers/crypto/ccp/ccp_pmd_ops.c
+++ b/drivers/crypto/ccp/ccp_pmd_ops.c
@@ -685,7 +685,7 @@ ccp_pmd_qp_create_batch_info_ring(struct ccp_qp *qp,
static int
ccp_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct ccp_private *internals = dev->data->dev_private;
struct ccp_qp *qp;
@@ -726,7 +726,8 @@ ccp_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
goto qp_setup_cleanup;
}
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
/* mempool for batch info */
qp->batch_mp = rte_mempool_create(
diff --git a/drivers/crypto/ccp/ccp_pmd_private.h b/drivers/crypto/ccp/ccp_pmd_private.h
index 79752f687..7f2979e89 100644
--- a/drivers/crypto/ccp/ccp_pmd_private.h
+++ b/drivers/crypto/ccp/ccp_pmd_private.h
@@ -76,6 +76,8 @@ struct ccp_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_mempool *batch_mp;
/**< Session Mempool for batch info */
struct rte_cryptodev_stats qp_stats;
diff --git a/drivers/crypto/ccp/rte_ccp_pmd.c b/drivers/crypto/ccp/rte_ccp_pmd.c
index 92d8a9559..b4bb5528f 100644
--- a/drivers/crypto/ccp/rte_ccp_pmd.c
+++ b/drivers/crypto/ccp/rte_ccp_pmd.c
@@ -179,7 +179,7 @@ get_ccp_session(struct ccp_qp *qp, struct rte_crypto_op *op)
if (unlikely(ccp_set_session_parameters(sess, op->sym->xform,
internals) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -241,6 +241,13 @@ ccp_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
for (i = 0; i < nb_dequeued; i++)
if (unlikely(ops[i]->sess_type ==
RTE_CRYPTO_OP_SESSIONLESS)) {
+ struct ccp_session *sess = (struct ccp_session *)
+ get_sym_session_private_data(
+ ops[i]->sym->session,
+ ccp_cryptodev_driver_id);
+
+ rte_mempool_put(qp->sess_mp_priv,
+ sess);
rte_mempool_put(qp->sess_mp,
ops[i]->sym->session);
ops[i]->sym->session = NULL;
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 6095c6021..82220ac4f 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -1518,8 +1518,7 @@ dpaa2_sec_queue_pair_release(struct rte_cryptodev *dev, uint16_t queue_pair_id)
static int
dpaa2_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
__rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
- __rte_unused int socket_id,
- __rte_unused struct rte_mempool *session_pool)
+ __rte_unused int socket_id)
{
struct dpaa2_sec_dev_private *priv = dev->data->dev_private;
struct dpaa2_sec_qp *qp;
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index d83e74541..c95e43b7f 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -1661,8 +1661,7 @@ dpaa_sec_queue_pair_release(struct rte_cryptodev *dev,
static int
dpaa_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
__rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
- __rte_unused int socket_id,
- __rte_unused struct rte_mempool *session_pool)
+ __rte_unused int socket_id)
{
struct dpaa_sec_dev_private *internals;
struct dpaa_sec_qp *qp = NULL;
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index 239a1cf44..6df645a23 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -145,7 +145,8 @@ kasumi_get_session(struct kasumi_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct kasumi_session *)_sess_private_data;
@@ -153,7 +154,7 @@ kasumi_get_session(struct kasumi_qp *qp, struct rte_crypto_op *op)
if (unlikely(kasumi_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -325,7 +326,7 @@ process_ops(struct rte_crypto_op **ops, struct kasumi_session *session,
memset(session, 0, sizeof(struct kasumi_session));
memset(ops[i]->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, session);
+ rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
}
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
index 9e4bf1b52..a4982f091 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
@@ -192,7 +192,7 @@ kasumi_pmd_qp_create_processed_ops_ring(struct kasumi_qp *qp,
static int
kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct kasumi_qp *qp = NULL;
@@ -217,7 +217,8 @@ kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
index 488777ca8..76f746c03 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
@@ -36,6 +36,8 @@ struct kasumi_qp {
/**< Ring for placing processed ops */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
uint8_t temp_digest[KASUMI_DIGEST_LENGTH];
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
index 9956f051f..ef520356f 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
@@ -633,7 +633,7 @@ mrvl_crypto_pmd_close(struct rte_cryptodev *dev)
static int
mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct mrvl_crypto_qp *qp = NULL;
char match[RTE_CRYPTODEV_NAME_MAX_LEN];
@@ -690,7 +690,8 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (sam_cio_init(&qp->cio_params, &qp->cio) < 0)
break;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
dev->data->queue_pairs[qp_id] = qp;
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
index 6f8cf5624..deb80c55d 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
@@ -51,6 +51,9 @@ struct mrvl_crypto_qp {
/** Session Mempool. */
struct rte_mempool *sess_mp;
+ /** Session Private Data Mempool. */
+ struct rte_mempool *sess_mp_priv;
+
/** Queue pair statistics. */
struct rte_cryptodev_stats stats;
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index 6e29a21a6..d5e3064f2 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -87,7 +87,8 @@ get_session(struct null_crypto_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct null_crypto_session *)_sess_private_data;
@@ -95,7 +96,7 @@ get_session(struct null_crypto_qp *qp, struct rte_crypto_op *op)
if (unlikely(null_crypto_set_session_parameters(sess,
sym_op->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
sym_op->session = (struct rte_cryptodev_sym_session *)_sess;
diff --git a/drivers/crypto/null/null_crypto_pmd_ops.c b/drivers/crypto/null/null_crypto_pmd_ops.c
index 2bdcd019e..941d62bed 100644
--- a/drivers/crypto/null/null_crypto_pmd_ops.c
+++ b/drivers/crypto/null/null_crypto_pmd_ops.c
@@ -184,7 +184,7 @@ null_crypto_pmd_qp_create_processed_pkts_ring(struct null_crypto_qp *qp,
static int
null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct null_crypto_private *internals = dev->data->dev_private;
struct null_crypto_qp *qp;
@@ -228,7 +228,8 @@ null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
goto qp_setup_cleanup;
}
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/null/null_crypto_pmd_private.h b/drivers/crypto/null/null_crypto_pmd_private.h
index d5905afd8..d7bfd9cc8 100644
--- a/drivers/crypto/null/null_crypto_pmd_private.h
+++ b/drivers/crypto/null/null_crypto_pmd_private.h
@@ -31,6 +31,8 @@ struct null_crypto_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
} __rte_cache_aligned;
diff --git a/drivers/crypto/octeontx/otx_cryptodev_ops.c b/drivers/crypto/octeontx/otx_cryptodev_ops.c
index 90d0c14b8..6a0cf83f4 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_ops.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_ops.c
@@ -186,8 +186,7 @@ static int
otx_cpt_que_pair_setup(struct rte_cryptodev *dev,
uint16_t que_pair_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id __rte_unused,
- struct rte_mempool *session_pool __rte_unused)
+ int socket_id __rte_unused)
{
void *cptvf = dev->data->dev_private;
struct cpt_instance *instance = NULL;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index a0ccacb1e..a193af642 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -768,7 +768,8 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct openssl_session *)_sess_private_data;
@@ -776,7 +777,7 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
if (unlikely(openssl_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -2020,7 +2021,7 @@ process_op(struct openssl_qp *qp, struct rte_crypto_op *op,
memset(sess, 0, sizeof(struct openssl_session));
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sess);
+ rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index d382476a6..40217cf0d 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -715,7 +715,7 @@ openssl_pmd_qp_create_processed_ops_ring(struct openssl_qp *qp,
static int
openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct openssl_qp *qp = NULL;
@@ -740,7 +740,8 @@ openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_private.h b/drivers/crypto/openssl/rte_openssl_pmd_private.h
index a8f2c8482..43ac3813d 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_private.h
+++ b/drivers/crypto/openssl/rte_openssl_pmd_private.h
@@ -64,6 +64,8 @@ struct openssl_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats stats;
/**< Queue pair statistics */
uint8_t temp_digest[DIGEST_LENGTH_MAX];
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index c3f700406..31ccab32e 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -127,7 +127,7 @@ static int qat_sym_qp_release(struct rte_cryptodev *dev, uint16_t queue_pair_id)
static int qat_sym_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool __rte_unused)
+ int socket_id)
{
struct qat_qp *qp;
int ret = 0;
diff --git a/drivers/crypto/scheduler/scheduler_pmd_ops.c b/drivers/crypto/scheduler/scheduler_pmd_ops.c
index 939105aa8..cf70218b7 100644
--- a/drivers/crypto/scheduler/scheduler_pmd_ops.c
+++ b/drivers/crypto/scheduler/scheduler_pmd_ops.c
@@ -390,8 +390,7 @@ scheduler_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
/** Setup a queue pair */
static int
scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
- const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
- struct rte_mempool *session_pool)
+ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
{
struct scheduler_ctx *sched_ctx = dev->data->dev_private;
struct scheduler_qp_ctx *qp_ctx;
@@ -419,7 +418,7 @@ scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
* must be big enough for all the drivers used.
*/
ret = rte_cryptodev_queue_pair_setup(slave_id, qp_id,
- qp_conf, socket_id, session_pool);
+ qp_conf, socket_id);
if (ret < 0)
return ret;
}
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index a17536b77..7d131f780 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -147,7 +147,8 @@ snow3g_get_session(struct snow3g_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct snow3g_session *)_sess_private_data;
@@ -155,7 +156,7 @@ snow3g_get_session(struct snow3g_qp *qp, struct rte_crypto_op *op)
if (unlikely(snow3g_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -340,7 +341,7 @@ process_ops(struct rte_crypto_op **ops, struct snow3g_session *session,
memset(session, 0, sizeof(struct snow3g_session));
memset(ops[i]->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, session);
+ rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
}
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
index a367ee9a0..d2125233f 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
@@ -198,7 +198,7 @@ snow3g_pmd_qp_create_processed_ops_ring(struct snow3g_qp *qp,
static int
snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct snow3g_qp *qp = NULL;
@@ -223,7 +223,8 @@ snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
index b7807b621..df5c6092b 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
@@ -36,6 +36,8 @@ struct snow3g_qp {
/**< Ring for placing processed ops */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
uint8_t temp_digest[SNOW3G_DIGEST_LENGTH];
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 568b5a406..4bae3b865 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -36,8 +36,7 @@ static void virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev);
static int virtio_crypto_qp_setup(struct rte_cryptodev *dev,
uint16_t queue_pair_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id,
- struct rte_mempool *session_pool);
+ int socket_id);
static int virtio_crypto_qp_release(struct rte_cryptodev *dev,
uint16_t queue_pair_id);
static void virtio_crypto_dev_free_mbufs(struct rte_cryptodev *dev);
@@ -585,8 +584,7 @@ virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev)
static int
virtio_crypto_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id,
- struct rte_mempool *session_pool __rte_unused)
+ int socket_id)
{
int ret;
struct virtqueue *vq;
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index 313f4590b..997c2092f 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -144,7 +144,8 @@ zuc_get_session(struct zuc_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct zuc_session *)_sess_private_data;
@@ -152,7 +153,7 @@ zuc_get_session(struct zuc_qp *qp, struct rte_crypto_op *op)
if (unlikely(zuc_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -327,7 +328,7 @@ process_ops(struct rte_crypto_op **ops, enum zuc_operation op_type,
memset(sessions[i], 0, sizeof(struct zuc_session));
memset(ops[i]->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sessions[i]);
+ rte_mempool_put(qp->sess_mp_priv, sessions[i]);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
}
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_ops.c b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
index 04d45e449..1b88947eb 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_ops.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
@@ -198,7 +198,7 @@ zuc_pmd_qp_create_processed_ops_ring(struct zuc_qp *qp,
static int
zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct zuc_qp *qp = NULL;
@@ -223,7 +223,8 @@ zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_private.h b/drivers/crypto/zuc/rte_zuc_pmd_private.h
index 5e5906ddb..aa73c0016 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_private.h
+++ b/drivers/crypto/zuc/rte_zuc_pmd_private.h
@@ -36,6 +36,8 @@ struct zuc_qp {
/**< Ring for placing processed ops */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
uint8_t temp_digest[ZUC_DIGEST_LENGTH];
diff --git a/drivers/net/softnic/rte_eth_softnic_cryptodev.c b/drivers/net/softnic/rte_eth_softnic_cryptodev.c
index 1480f6dd5..f031d8803 100644
--- a/drivers/net/softnic/rte_eth_softnic_cryptodev.c
+++ b/drivers/net/softnic/rte_eth_softnic_cryptodev.c
@@ -101,7 +101,7 @@ softnic_cryptodev_create(struct pmd_internals *p,
queue_conf.nb_descriptors = params->queue_size;
for (i = 0; i < params->n_queues; i++) {
status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id, NULL);
+ &queue_conf, socket_id);
if (status < 0)
return NULL;
}
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index e7559c633..384b7a240 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -39,7 +39,7 @@ static int
cryptodev_fips_validate_app_int(void)
{
struct rte_cryptodev_config conf = {rte_socket_id(), 1};
- struct rte_cryptodev_qp_conf qp_conf = {128};
+ struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL};
int ret;
ret = rte_cryptodev_configure(env.dev_id, &conf);
@@ -52,7 +52,7 @@ cryptodev_fips_validate_app_int(void)
return ret;
ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
- rte_socket_id(), env.mpool);
+ rte_socket_id());
if (ret < 0)
return ret;
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
index c4ba72bec..b365810de 100644
--- a/examples/ip_pipeline/cryptodev.c
+++ b/examples/ip_pipeline/cryptodev.c
@@ -93,7 +93,7 @@ cryptodev_create(const char *name, struct cryptodev_params *params)
queue_conf.nb_descriptors = params->queue_size;
for (i = 0; i < params->n_queues; i++) {
status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id, NULL);
+ &queue_conf, socket_id);
if (status < 0)
return NULL;
}
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 1bc0b5b50..a0ff8f7f7 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -1493,10 +1493,13 @@ cryptodevs_init(void)
cdev_id);
qp_conf.nb_descriptors = CDEV_QUEUE_DESC;
+ qp_conf.mp_session =
+ socket_ctx[dev_conf.socket_id].session_pool;
+ qp_conf.mp_session_private =
+ socket_ctx[dev_conf.socket_id].session_pool;
for (qp = 0; qp < dev_conf.nb_queue_pairs; qp++)
if (rte_cryptodev_queue_pair_setup(cdev_id, qp,
- &qp_conf, dev_conf.socket_id,
- socket_ctx[dev_conf.socket_id].session_pool))
+ &qp_conf, dev_conf.socket_id))
rte_panic("Failed to setup queue %u for "
"cdev_id %u\n", 0, cdev_id);
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index f12fd266e..1df7ba743 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -2443,9 +2443,11 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
}
qp_conf.nb_descriptors = 2048;
+ qp_conf.mp_session = session_pool_socket[socket_id];
+ qp_conf.mp_session_private = session_pool_socket[socket_id];
retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
- socket_id, session_pool_socket[socket_id]);
+ socket_id);
if (retval < 0) {
printf("Failed to setup queue pair %u on cryptodev %u",
0, cdev_id);
diff --git a/examples/vhost_crypto/main.c b/examples/vhost_crypto/main.c
index 3deb5263f..cb30f84c0 100644
--- a/examples/vhost_crypto/main.c
+++ b/examples/vhost_crypto/main.c
@@ -463,7 +463,7 @@ free_resource(void)
int
main(int argc, char *argv[])
{
- struct rte_cryptodev_qp_conf qp_conf = {NB_CRYPTO_DESCRIPTORS};
+ struct rte_cryptodev_qp_conf qp_conf;
struct rte_cryptodev_config config;
struct rte_cryptodev_info dev_info;
char name[128];
@@ -551,11 +551,14 @@ main(int argc, char *argv[])
options.infos[i] = info;
+ qp_conf.nb_descriptors = NB_CRYPTO_DESCRIPTORS;
+ qp_conf.mp_session = info->sess_pool;
+ qp_conf.mp_session_private = info->sess_pool;
+
for (j = 0; j < dev_info.max_nb_queue_pairs; j++) {
ret = rte_cryptodev_queue_pair_setup(info->cid, j,
&qp_conf, rte_lcore_to_socket_id(
- lo->lcore_id),
- info->sess_pool);
+ lo->lcore_id));
if (ret < 0) {
RTE_LOG(ERR, USER1, "Failed to configure qp\n");
goto error_exit;
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index a8f94c097..b734d144a 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2015 Intel Corporation
+# Copyright(c) 2015-2018 Intel Corporation
include $(RTE_SDK)/mk/rte.vars.mk
@@ -7,7 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_cryptodev.a
# library version
-LIBABIVER := 5
+LIBABIVER := 6
# build flags
CFLAGS += -O3
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index a52eaaa45..4929d0451 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -941,8 +941,7 @@ rte_cryptodev_close(uint8_t dev_id)
int
rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
- const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
- struct rte_mempool *session_pool)
+ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
{
struct rte_cryptodev *dev;
@@ -958,6 +957,17 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
return -EINVAL;
}
+ if (!qp_conf) {
+ CDEV_LOG_ERR("qp_conf cannot be NULL\n");
+ return -EINVAL;
+ }
+
+ if ((qp_conf->mp_session && !qp_conf->mp_session_private) ||
+ (!qp_conf->mp_session && qp_conf->mp_session_private)) {
+ CDEV_LOG_ERR("Invalid mempools\n");
+ return -EINVAL;
+ }
+
if (dev->data->dev_started) {
CDEV_LOG_ERR(
"device %d must be stopped to allow configuration", dev_id);
@@ -967,7 +977,7 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_setup, -ENOTSUP);
return (*dev->dev_ops->queue_pair_setup)(dev, queue_pair_id, qp_conf,
- socket_id, session_pool);
+ socket_id);
}
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 4099823f1..f9e7507da 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -495,6 +495,10 @@ enum rte_cryptodev_event_type {
/** Crypto device queue pair configuration structure. */
struct rte_cryptodev_qp_conf {
uint32_t nb_descriptors; /**< Number of descriptors per queue pair */
+ struct rte_mempool *mp_session;
+ /**< The mempool for creating session in sessionless mode */
+ struct rte_mempool *mp_session_private;
+ /**< The mempool for creating sess private data in sessionless mode */
};
/**
@@ -689,8 +693,7 @@ rte_cryptodev_close(uint8_t dev_id);
*/
extern int
rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
- const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
- struct rte_mempool *session_pool);
+ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id);
/**
* Get the number of queue pairs on a specific crypto device
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index 1b6cafd17..f15c9af30 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -188,13 +188,12 @@ typedef void (*cryptodev_info_get_t)(struct rte_cryptodev *dev,
* @param qp_id Queue Pair Index
* @param qp_conf Queue configuration structure
* @param socket_id Socket Index
- * @param session_pool Pointer to device session mempool
*
* @return Returns 0 on success.
*/
typedef int (*cryptodev_queue_pair_setup_t)(struct rte_cryptodev *dev,
uint16_t qp_id, const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool);
+ int socket_id);
/**
* Release memory resources allocated by given queue pair.
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 84065eb49..aac0b1f0b 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -461,12 +461,13 @@ testsuite_setup(void)
dev_id, ts_params->conf.nb_queue_pairs);
ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+ ts_params->qp_conf.mp_session = ts_params->session_mpool;
+ ts_params->qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
dev_id, qp_id, &ts_params->qp_conf,
- rte_cryptodev_socket_id(dev_id),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(dev_id)),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, dev_id);
}
@@ -519,8 +520,7 @@ ut_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id,
&ts_params->qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
}
@@ -709,13 +709,14 @@ test_queue_pair_descriptor_setup(void)
* freed so are re-used if ring is released and re-created.
*/
qp_conf.nb_descriptors = MIN_NUM_OPS_INFLIGHT; /* min size*/
+ qp_conf.mp_session = ts_params->session_mpool;
+ qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for "
"rte_cryptodev_queue_pair_setup: num_inflights "
"%u on qp %u on cryptodev %u",
@@ -729,8 +730,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for"
" rte_cryptodev_queue_pair_setup: num_inflights"
" %u on qp %u on cryptodev %u",
@@ -744,8 +744,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for "
"rte_cryptodev_queue_pair_setup: num_inflights"
" %u on qp %u on cryptodev %u",
@@ -760,8 +759,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Unexpectedly passed test for "
"rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -776,8 +774,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Unexpectedly passed test for "
"rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -791,8 +788,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for"
" rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -807,8 +803,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Unexpectedly passed test for "
"rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -824,8 +819,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0],
qp_id, &qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed test for rte_cryptodev_queue_pair_setup:"
"invalid qp %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
@@ -835,8 +829,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0],
qp_id, &qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed test for rte_cryptodev_queue_pair_setup:"
"invalid qp %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
diff --git a/test/test/test_cryptodev_asym.c b/test/test/test_cryptodev_asym.c
index a899f9973..0f6fc5767 100644
--- a/test/test/test_cryptodev_asym.c
+++ b/test/test/test_cryptodev_asym.c
@@ -383,11 +383,12 @@ testsuite_setup(void)
/* configure qp */
ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+ ts_params->qp_conf.mp_session = ts_params->session_mpool;
+ ts_params->qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
dev_id, qp_id, &ts_params->qp_conf,
- rte_cryptodev_socket_id(dev_id),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(dev_id)),
"Failed to setup queue pair %u on cryptodev %u ASYM",
qp_id, dev_id);
}
@@ -449,8 +450,7 @@ ut_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id,
&ts_params->qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
}
diff --git a/test/test/test_event_crypto_adapter.c b/test/test/test_event_crypto_adapter.c
index de258c346..54717870e 100644
--- a/test/test/test_event_crypto_adapter.c
+++ b/test/test/test_event_crypto_adapter.c
@@ -546,11 +546,12 @@ configure_cryptodev(void)
TEST_CDEV_ID, conf.nb_queue_pairs);
qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+ qp_conf.mp_session = params.session_mpool;
+ qp_conf.mp_session_private = params.session_mpool;
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
TEST_CDEV_ID, TEST_CDEV_QP_ID, &qp_conf,
- rte_cryptodev_socket_id(TEST_CDEV_ID),
- params.session_mpool),
+ rte_cryptodev_socket_id(TEST_CDEV_ID)),
"Failed to setup queue pair %u on cryptodev %u\n",
TEST_CDEV_QP_ID, TEST_CDEV_ID);
--
2.13.6
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v4 02/12] cryptodev: add sym session mempool create
2019-01-09 22:55 3% ` [dpdk-dev] [PATCH v4 01/12] cryptodev: change queue pair configure structure Fan Zhang
@ 2019-01-09 22:55 3% ` Fan Zhang
2019-01-10 11:22 0% ` De Lara Guarch, Pablo
2019-01-09 22:56 3% ` [dpdk-dev] [PATCH v4 08/12] cryptodev: add sym session header size API Fan Zhang
` (2 subsequent siblings)
4 siblings, 1 reply; 200+ results
From: Fan Zhang @ 2019-01-09 22:55 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, fiona.trahe
This patch adds a new API "rte_cryptodev_sym_session_pool_create()" to
cryptodev library. All applications are required to use this API to
create sym session mempool as it adds private data and nb_drivers
information to the mempool private data.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
---
doc/guides/prog_guide/cryptodev_lib.rst | 28 ++++++++++-----
doc/guides/rel_notes/release_19_02.rst | 5 +++
lib/librte_cryptodev/rte_cryptodev.c | 50 ++++++++++++++++++++++++++
lib/librte_cryptodev/rte_cryptodev.h | 31 ++++++++++++++++
lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++++
5 files changed, 112 insertions(+), 9 deletions(-)
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 050a58dc4..366508618 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -455,13 +455,15 @@ Crypto workloads.
.. figure:: img/cryptodev_sym_sess.*
-The Crypto device framework provides APIs to allocate and initialize sessions
-for crypto devices, where sessions are mempool objects.
+The Crypto device framework provides APIs to create session mempool and allocate
+and initialize sessions for crypto devices, where sessions are mempool objects.
It is the application's responsibility to create and manage the session mempools.
This approach allows for different scenarios such as having a single session
mempool for all crypto devices (where the mempool object size is big
enough to hold the private session of any crypto device), as well as having
-multiple session mempools of different sizes for better memory usage.
+multiple session mempools of different sizes for better memory usage. However,
+the application is required to use ``rte_cryptodev_sym_session_pool_create()``
+to create symmetric session mempool.
An application can use ``rte_cryptodev_sym_get_private_session_size()`` to
get the private session size of given crypto device. This function would allow
@@ -623,7 +625,8 @@ using one of the crypto PMDs available in DPDK.
#define IV_OFFSET (sizeof(struct rte_crypto_op) + \
sizeof(struct rte_crypto_sym_op))
- struct rte_mempool *mbuf_pool, *crypto_op_pool, *session_pool;
+ struct rte_mempool *mbuf_pool, *crypto_op_pool;
+ struct *session_pool, *session_priv_pool;
unsigned int session_size;
int ret;
@@ -673,13 +676,20 @@ using one of the crypto PMDs available in DPDK.
/* Get private session data size. */
session_size = rte_cryptodev_sym_get_private_session_size(cdev_id);
+ /* Create session mempool for the session header. */
+ session_pool = rte_cryptodev_sym_session_pool_create("session_pool",
+ MAX_SESSIONS,
+ 0,
+ POOL_CACHE_SIZE,
+ 0,
+ socket_id);
+
/*
- * Create session mempool, with two objects per session,
- * one for the session header and another one for the
+ * Create session private data mempool for the
* private session data for the crypto device.
*/
- session_pool = rte_mempool_create("session_pool",
- MAX_SESSIONS * 2,
+ session_priv_pool = rte_mempool_create("session_pool",
+ MAX_SESSIONS,
session_size,
POOL_CACHE_SIZE,
0, NULL, NULL, NULL,
@@ -731,7 +741,7 @@ using one of the crypto PMDs available in DPDK.
rte_exit(EXIT_FAILURE, "Session could not be created\n");
if (rte_cryptodev_sym_session_init(cdev_id, session,
- &cipher_xform, session_pool) < 0)
+ &cipher_xform, session_priv_pool) < 0)
rte_exit(EXIT_FAILURE, "Session could not be initialized "
"for the crypto device\n");
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 75128f8f2..0b3c30c80 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -167,6 +167,11 @@ API Changes
* cryptodev: as shown in the the 18.11 deprecation notice, the last parameter
of ``rte_cryptodev_queue_pair_setup()`` is removed.
+* cryptodev: a new function ``rte_cryptodev_sym_session_pool_create()`` is
+ introduced. This function is used to create symmetric session mempool safely
+ and all crypto applications are required to use this function to create
+ symmetric session mempool from now on.
+
ABI Changes
-----------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 4929d0451..5b1449d14 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -189,6 +189,16 @@ const char *rte_crypto_asym_op_strings[] = {
[RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE] = "sharedsecret_compute",
};
+/**
+ * The private data structure stored in the session mempool private data.
+ */
+struct rte_cryptodev_sym_session_pool_private_data {
+ uint16_t nb_drivers;
+ /**< number of elements in sess_data array */
+ uint16_t user_data_sz;
+ /**< session user data will be placed after sess_data */
+};
+
int
rte_cryptodev_get_cipher_algo_enum(enum rte_crypto_cipher_algorithm *algo_enum,
const char *algo_string)
@@ -1223,6 +1233,46 @@ rte_cryptodev_asym_session_init(uint8_t dev_id,
return 0;
}
+struct rte_mempool *
+rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
+ uint32_t elt_size, uint32_t cache_size, uint16_t user_data_size,
+ int socket_id)
+{
+ struct rte_mempool *mp;
+ struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
+ uint32_t obj_sz;
+
+ obj_sz = rte_cryptodev_sym_get_header_session_size() + user_data_size;
+ if (obj_sz > elt_size)
+ CDEV_LOG_INFO("elt_size %u is expanded to %u\n", elt_size,
+ obj_sz);
+ else
+ obj_sz = elt_size;
+
+ mp = rte_mempool_create(name, nb_elts, obj_sz, cache_size,
+ (uint32_t)(sizeof(*pool_priv)),
+ NULL, NULL, NULL, NULL,
+ socket_id, 0);
+ if (mp == NULL) {
+ CDEV_LOG_ERR("%s(name=%s) failed, rte_errno=%d\n",
+ __func__, name, rte_errno);
+ return NULL;
+ }
+
+ pool_priv = rte_mempool_get_priv(mp);
+ if (!pool_priv) {
+ CDEV_LOG_ERR("%s(name=%s) failed to get private data\n",
+ __func__, name);
+ rte_mempool_free(mp);
+ return NULL;
+ }
+
+ pool_priv->nb_drivers = nb_drivers;
+ pool_priv->user_data_sz = user_data_size;
+
+ return mp;
+}
+
struct rte_cryptodev_sym_session *
rte_cryptodev_sym_session_create(struct rte_mempool *mp)
{
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index f9e7507da..265f02cbe 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -968,6 +968,37 @@ struct rte_cryptodev_asym_session {
};
/**
+ * Create a symmetric session mempool.
+ *
+ * @param name
+ * The unique mempool name.
+ * @param nb_elts
+ * The number of elements in the mempool.
+ * @param elt_size
+ * The size of the element. This value will be ignored if it is smaller than
+ * the minimum session header size required for the system. For the user who
+ * want to use the same mempool for sym session and session private data it
+ * can be the maximum value of all existing devices' private data and session
+ * header sizes.
+ * @param cache_size
+ * The number of per-lcore cache elements
+ * @param priv_size
+ * The private data size of each session.
+ * @param socket_id
+ * The *socket_id* argument is the socket identifier in the case of
+ * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
+ * constraint for the reserved zone.
+ *
+ * @return
+ * - On success return size of the session
+ * - On failure returns 0
+ */
+struct rte_mempool *
+rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
+ uint32_t elt_size, uint32_t cache_size, uint16_t priv_size,
+ int socket_id);
+
+/**
* Create symmetric crypto session header (generic with no private data)
*
* @param mempool Symmetric session mempool to allocate session
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index a695b61dc..5b6b679f5 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -88,6 +88,13 @@ DPDK_18.05 {
} DPDK_17.11;
+DPDK_19.02 {
+ global:
+
+ rte_cryptodev_sym_session_pool_create;
+
+} DPDK_18.05;
+
EXPERIMENTAL {
global:
--
2.13.6
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v4 08/12] cryptodev: add sym session header size API
2019-01-09 22:55 3% ` [dpdk-dev] [PATCH v4 01/12] cryptodev: change queue pair configure structure Fan Zhang
2019-01-09 22:55 3% ` [dpdk-dev] [PATCH v4 02/12] cryptodev: add sym session mempool create Fan Zhang
@ 2019-01-09 22:56 3% ` Fan Zhang
2019-01-09 22:56 1% ` [dpdk-dev] [PATCH v4 09/12] cryptodev: update symmetric session structure Fan Zhang
4 siblings, 0 replies; 200+ results
From: Fan Zhang @ 2019-01-09 22:56 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, fiona.trahe
This patch adds a new API in Cryptodev Framework. The API is used
to get the header size for the created symmetric Cryptodev session.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
---
doc/guides/prog_guide/cryptodev_lib.rst | 3 ++-
doc/guides/rel_notes/release_19_02.rst | 7 +++++++
drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 3 ++-
drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 3 ++-
drivers/crypto/armv8/rte_armv8_pmd.c | 3 ++-
drivers/crypto/kasumi/rte_kasumi_pmd.c | 3 ++-
drivers/crypto/openssl/rte_openssl_pmd.c | 3 ++-
drivers/crypto/snow3g/rte_snow3g_pmd.c | 3 ++-
drivers/crypto/zuc/rte_zuc_pmd.c | 3 ++-
lib/librte_cryptodev/rte_cryptodev.c | 10 ++++++++++
lib/librte_cryptodev/rte_cryptodev.h | 15 +++++++++++++++
lib/librte_cryptodev/rte_cryptodev_version.map | 1 +
12 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 366508618..9dc2d2aa4 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -471,7 +471,8 @@ an application to calculate the max device session size of all crypto devices
to create a single session mempool.
If instead an application creates multiple session mempools, the Crypto device
framework also provides ``rte_cryptodev_sym_get_header_session_size`` to get
-the size of an uninitialized session.
+the size of an uninitialized session. For the initialized session, the function
+``rte_cryptodev_sym_get_existing_header_session_size`` should be used instead.
Once the session mempools have been created, ``rte_cryptodev_sym_session_create()``
is used to allocate an uninitialized session from the given mempool.
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 0b3c30c80..445d6a809 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -172,6 +172,13 @@ API Changes
and all crypto applications are required to use this function to create
symmetric session mempool from now on.
+* cryptodev: introduced a new function
+ ``rte_cryptodev_sym_get_existing_header_session_size()``. The function is
+ used to get the session header size from existing symmetric session. Since
+ different sessions may be created from the mempools with different elt size,
+ using this function help pinpoint the exact header data for the session
+ header.
+
ABI Changes
-----------
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index abc7a6d5f..948ff0763 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -419,7 +419,8 @@ handle_completed_gcm_crypto_op(struct aesni_gcm_qp *qp,
if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(sess, 0, sizeof(struct aesni_gcm_session));
memset(op->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ op->sym->session));
rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index b0f5c4d67..f3b270d09 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -951,7 +951,8 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job)
if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(sess, 0, sizeof(struct aesni_mb_session));
memset(op->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ op->sym->session));
rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
index 3b2d7fb2f..0d4649adc 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd.c
@@ -655,7 +655,8 @@ process_op(struct armv8_crypto_qp *qp, struct rte_crypto_op *op,
if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(sess, 0, sizeof(struct armv8_crypto_session));
memset(op->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ op->sym->session));
rte_mempool_put(qp->sess_mp, sess);
rte_mempool_put(qp->sess_mp_priv, op->sym->session);
op->sym->session = NULL;
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index 6df645a23..3abdb01a9 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -325,7 +325,8 @@ process_ops(struct rte_crypto_op **ops, struct kasumi_session *session,
if (ops[i]->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(session, 0, sizeof(struct kasumi_session));
memset(ops[i]->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ ops[i]->sym->session));
rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index a193af642..ea5aac69e 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -2020,7 +2020,8 @@ process_op(struct openssl_qp *qp, struct rte_crypto_op *op,
openssl_reset_session(sess);
memset(sess, 0, sizeof(struct openssl_session));
memset(op->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ op->sym->session));
rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index 7d131f780..5fd94b686 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -340,7 +340,8 @@ process_ops(struct rte_crypto_op **ops, struct snow3g_session *session,
if (ops[i]->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(session, 0, sizeof(struct snow3g_session));
memset(ops[i]->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ ops[i]->sym->session));
rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index 997c2092f..637994dfd 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -327,7 +327,8 @@ process_ops(struct rte_crypto_op **ops, enum zuc_operation op_type,
if (ops[i]->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
memset(sessions[i], 0, sizeof(struct zuc_session));
memset(ops[i]->sym->session, 0,
- rte_cryptodev_sym_get_header_session_size());
+ rte_cryptodev_sym_get_existing_header_session_size(
+ ops[i]->sym->session));
rte_mempool_put(qp->sess_mp_priv, sessions[i]);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 5b1449d14..f4f1cf598 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -1407,6 +1407,16 @@ rte_cryptodev_sym_get_header_session_size(void)
return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
}
+unsigned int
+rte_cryptodev_sym_get_existing_header_session_size(
+ struct rte_cryptodev_sym_session *sess)
+{
+ if (!sess)
+ return 0;
+ else
+ return rte_cryptodev_sym_get_header_session_size();
+}
+
unsigned int __rte_experimental
rte_cryptodev_asym_get_header_session_size(void)
{
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 265f02cbe..c4db3aa0b 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -1137,6 +1137,21 @@ unsigned int
rte_cryptodev_sym_get_header_session_size(void);
/**
+ * Get the size of the header session from created session.
+ *
+ * @param sess
+ * The sym cryptodev session pointer
+ *
+ * @return
+ * - If sess is not NULL, return the size of the header session including
+ * the private data size defined within sess.
+ * - If sess is NULL, return 0.
+ */
+unsigned int
+rte_cryptodev_sym_get_existing_header_session_size(
+ struct rte_cryptodev_sym_session *sess);
+
+/**
* Get the size of the asymmetric session header, for all registered drivers.
*
* @return
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 5b6b679f5..0c8d67223 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -91,6 +91,7 @@ DPDK_18.05 {
DPDK_19.02 {
global:
+ rte_cryptodev_sym_get_existing_header_session_size;
rte_cryptodev_sym_session_pool_create;
} DPDK_18.05;
--
2.13.6
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v4 09/12] cryptodev: update symmetric session structure
` (2 preceding siblings ...)
2019-01-09 22:56 3% ` [dpdk-dev] [PATCH v4 08/12] cryptodev: add sym session header size API Fan Zhang
@ 2019-01-09 22:56 1% ` Fan Zhang
4 siblings, 0 replies; 200+ results
From: Fan Zhang @ 2019-01-09 22:56 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, fiona.trahe
This patch updates the rte_cryptodev_sym_session structure for
cryptodev library. The updates include a changed session private
data array and an added nb_drivers field. They are used to
calculate the correct session header size and ensure safe access
of the session private data.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
---
doc/guides/prog_guide/img/cryptodev_sym_sess.svg | 701 ++++++++++++-----------
doc/guides/rel_notes/release_19_02.rst | 7 +-
lib/librte_cryptodev/rte_cryptodev.c | 100 +++-
lib/librte_cryptodev/rte_cryptodev.h | 8 +-
lib/librte_cryptodev/rte_cryptodev_pmd.h | 13 +-
5 files changed, 444 insertions(+), 385 deletions(-)
diff --git a/doc/guides/prog_guide/img/cryptodev_sym_sess.svg b/doc/guides/prog_guide/img/cryptodev_sym_sess.svg
index a807cebac..5c843f736 100644
--- a/doc/guides/prog_guide/img/cryptodev_sym_sess.svg
+++ b/doc/guides/prog_guide/img/cryptodev_sym_sess.svg
@@ -19,33 +19,31 @@
id="svg70"
sodipodi:docname="cryptodev_sym_sess.svg"
style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-rule:evenodd;stroke-linecap:square;stroke-miterlimit:3"
- inkscape:version="0.92.1 r15371"><metadata
- id="metadata74"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="1051"
- id="namedview72"
- showgrid="false"
- inkscape:zoom="1.7495789"
- inkscape:cx="208.74719"
- inkscape:cy="216.52777"
- inkscape:window-x="-9"
- inkscape:window-y="-9"
- inkscape:window-maximized="0"
- inkscape:current-layer="g68-0" />
- <style
- type="text/css"
- id="style2">
- <![CDATA[
+ inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"><metadata
+ id="metadata74"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="956"
+ id="namedview72"
+ showgrid="false"
+ inkscape:zoom="1.7495789"
+ inkscape:cx="208.74719"
+ inkscape:cy="216.52777"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="shape18-1-4" /><style
+ type="text/css"
+ id="style2"><![CDATA[
.st1 {fill:url(#grad0-4);stroke:#386288;stroke-width:0.75}
.st2 {fill:#386288;font-family:Calibri;font-size:0.833336em}
.st3 {visibility:visible}
@@ -56,337 +54,340 @@
.st8 {font-size:0.799995em}
.st9 {font-size:0.799995em;font-weight:bold}
.st10 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
- ]]>
- </style>
-
- <defs
- id="Patterns_And_Gradients"><marker
- inkscape:isstock="true"
- style="overflow:visible"
- id="marker5421"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow2Lend"><path
- transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- style="fill:#41719c;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
- id="path5419"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:stockid="Arrow2Lend"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow2Lend"
- style="overflow:visible"
- inkscape:isstock="true"><path
- id="path5004"
- style="fill:#41719c;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:stockid="Arrow1Lend"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Lend"
- style="overflow:visible"
- inkscape:isstock="true"><path
- id="path4986"
- d="M 0,0 5,-5 -12.5,0 5,5 Z"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
- transform="matrix(-0.8,0,0,-0.8,-10,0)"
- inkscape:connector-curvature="0" /></marker>
- <linearGradient
- id="grad0-4"
- x1="0"
- y1="0"
- x2="1"
- y2="0"
- gradientTransform="rotate(60,0.5,0.5)">
- <stop
- offset="0"
- stop-color="#e8ebef"
- stop-opacity="1"
- id="stop4" />
- <stop
- offset="0.24"
- stop-color="#f4f5f7"
- stop-opacity="1"
- id="stop6" />
- <stop
- offset="0.54"
- stop-color="#feffff"
- stop-opacity="1"
- id="stop8" />
- </linearGradient>
- <filter
- id="filter_2-4"><feGaussianBlur
- stdDeviation="2"
- id="feGaussianBlur12-0" /></filter><linearGradient
- inkscape:collect="always"
- xlink:href="#grad0-4"
- id="linearGradient189"
- gradientTransform="scale(0.8787489,1.1379815)"
- x1="-0.42674366"
- y1="0.98859203"
- x2="176.71146"
- y2="0.98859203"
- gradientUnits="userSpaceOnUse" /><filter
- id="filter_2-5"><feGaussianBlur
- stdDeviation="2"
- id="feGaussianBlur12-8" /></filter><filter
- id="filter_2-3"><feGaussianBlur
- stdDeviation="2"
- id="feGaussianBlur12-2" /></filter><linearGradient
- inkscape:collect="always"
- xlink:href="#grad0-4"
- id="linearGradient189-7"
- gradientTransform="scale(0.8787489,1.1379815)"
- x1="-0.42674366"
- y1="0.98859203"
- x2="176.71146"
- y2="0.98859203"
- gradientUnits="userSpaceOnUse" /><linearGradient
- inkscape:collect="always"
- xlink:href="#grad0-4"
- id="linearGradient500"
- gradientTransform="matrix(0.8787489,0,0,1.1379815,12.431599,21.739241)"
- x1="-0.42674366"
- y1="0.98859203"
- x2="176.71146"
- y2="0.98859203"
- gradientUnits="userSpaceOnUse" /></defs>
- <defs
- id="Filters">
- <filter
- id="filter_2">
- <feGaussianBlur
- stdDeviation="2"
- id="feGaussianBlur12" />
- </filter>
- </defs>
- <g
- id="g68"
- transform="matrix(1,0,0,0.41409874,-12.807629,-5.4621159)">
- <title
- id="title16">Page-1</title>
- <g
- id="shape18-1"
- transform="translate(0.749889,-0.75)">
- <title
- id="title18">Rounded Rectangle.12</title>
- <desc
- id="desc20">Crypto Symmetric Session</desc>
- <path
- d="M 19.211599,224.06924 H 160.5716 a 6.77735,6.77735 0 0 0 6.77,-6.77 V 30.019241 a 6.77735,6.77735 0 0 0 -6.77,-6.78 H 19.211599 a 6.77735,6.77735 0 0 0 -6.78,6.78 V 217.29924 a 6.77735,6.77735 0 0 0 6.78,6.77 z"
- class="st1"
- id="path22"
- style="fill:url(#linearGradient500);stroke:#386288;stroke-width:0.75"
- inkscape:connector-curvature="0" />
- <text
- x="63.123039"
- y="28.531481"
- class="st2"
- id="text24"
- style="font-size:16.97244835px;font-family:Calibri;fill:#386288;stroke-width:1.69723928"
- transform="scale(0.58919214,1.6972392)">Crypto Symmetric Session</text>
-
- </g>
- <g
- id="shape19-6"
- transform="translate(10.6711,-9.82087)">
- <title
- id="title27">Rounded Rectangle.13</title>
- <desc
- id="desc29">Private Session Data</desc>
- </g>
- <g
- id="shape20-12"
- transform="matrix(1,0,0,2.5278193,23.531375,-309.78186)">
- <title
- id="title39">Rounded Rectangle.15</title>
- <desc
- id="desc41">void *sess_private_data[]</desc>
- <path
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -36.37 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,160.06 v 36.37 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st7"
- id="path43"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:#41719c;stroke-width:0.75" />
- <text
- x="14.072042"
- y="159.1931"
- class="st6"
- id="text65"
- style="font-size:11.41061592px;font-family:Calibri;fill:#41719c;stroke-width:1.14105785"
- transform="scale(0.92359087,1.0827305)">void *sess_private_data[] <tspan
- x="-3.5230706"
- class="st9"
- id="tspan47"
- style="font-weight:bold;font-size:9.12843513px;stroke-width:1.14105785" /></text>
-
- <rect
- style="fill:none;fill-opacity:1;stroke:#41719c;stroke-width:0.73305672;stroke-opacity:1"
- id="rect4604"
- width="15.968175"
- height="14.230948"
- x="13.494645"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7"
- width="15.968174"
- height="14.230948"
- x="29.46282"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6"
- width="15.968174"
- height="14.230948"
- x="45.430992"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6-9"
- width="15.968174"
- height="14.230948"
- x="61.399166"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6-9-8"
- width="15.968174"
- height="14.230948"
- x="77.36734"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6-9-8-9"
- width="15.968174"
- height="14.230948"
- x="93.33551"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6-9-8-9-6"
- width="15.968174"
- height="14.230948"
- x="109.30369"
- y="181.68814" /><path
- style="fill:none;fill-opacity:1;stroke:#41719c;stroke-width:0.72427988px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
- d="m 117.64885,196.01764 0.22164,18.77485 44.6966,-0.0725 -0.22163,-20.00716 16.84434,0.43494"
- id="path5030"
- inkscape:connector-curvature="0" /></g>
- </g>
-<g
- transform="translate(190.70887,-0.53319281)"
- id="g68-0"><title
- id="title16-2">Page-1</title><g
- id="shape18-1-4"
- transform="matrix(1,0,0,0.57815109,0.749889,-0.11722686)"><title
- id="title18-4">Rounded Rectangle.12</title><desc
- id="desc20-6">Crypto Symmetric Session</desc><path
- inkscape:connector-curvature="0"
- d="m 6.78,202.33 h 141.36 a 6.77735,6.77735 -180 0 0 6.77,-6.77 V 8.28 A 6.77735,6.77735 -180 0 0 148.14,1.5 H 6.78 A 6.77735,6.77735 -180 0 0 0,8.28 v 187.28 a 6.77735,6.77735 -180 0 0 6.78,6.77 z"
- class="st1"
- id="path22-0"
- style="fill:url(#linearGradient189);stroke:#386288;stroke-width:0.75" /><text
- x="26.317923"
- y="17.335487"
- class="st2"
- id="text24-5"
- style="font-size:14.02988338px;font-family:Calibri;fill:#386288;stroke-width:1.40298378"
- transform="scale(0.71276665,1.4029837)">Crypto Driver Private Session</text>
-
-</g><g
- id="shape19-6-5"
- transform="matrix(1.022976,0,0,0.71529071,9.1114734,-39.403506)"><title
- id="title27-2">Rounded Rectangle.13</title><desc
- id="desc29-0">Private Session Data</desc><g
- id="shadow19-7-1"
- transform="translate(0.345598,1.97279)"
- class="st3"
- style="visibility:visible"><path
+ ]]></style><defs
+ id="Patterns_And_Gradients"><marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker5421"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Lend"><path
+ transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ style="fill:#41719c;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ id="path5419"
+ inkscape:connector-curvature="0" /></marker><marker
+ inkscape:stockid="Arrow2Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Lend"
+ style="overflow:visible"
+ inkscape:isstock="true"><path
+ id="path5004"
+ style="fill:#41719c;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+ inkscape:connector-curvature="0" /></marker><marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Lend"
+ style="overflow:visible"
+ inkscape:isstock="true"><path
+ id="path4986"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ inkscape:connector-curvature="0" /></marker><linearGradient
+ id="grad0-4"
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientTransform="rotate(60,0.5,0.5)"><stop
+ offset="0"
+ stop-color="#e8ebef"
+ stop-opacity="1"
+ id="stop4" /><stop
+ offset="0.24"
+ stop-color="#f4f5f7"
+ stop-opacity="1"
+ id="stop6" /><stop
+ offset="0.54"
+ stop-color="#feffff"
+ stop-opacity="1"
+ id="stop8" /></linearGradient><filter
+ id="filter_2-4"><feGaussianBlur
+ stdDeviation="2"
+ id="feGaussianBlur12-0" /></filter><linearGradient
+ inkscape:collect="always"
+ xlink:href="#grad0-4"
+ id="linearGradient189"
+ gradientTransform="scale(0.8787489,1.1379815)"
+ x1="-0.42674366"
+ y1="0.98859203"
+ x2="176.71146"
+ y2="0.98859203"
+ gradientUnits="userSpaceOnUse" /><filter
+ id="filter_2-5"><feGaussianBlur
+ stdDeviation="2"
+ id="feGaussianBlur12-8" /></filter><filter
+ id="filter_2-3"><feGaussianBlur
+ stdDeviation="2"
+ id="feGaussianBlur12-2" /></filter><linearGradient
+ inkscape:collect="always"
+ xlink:href="#grad0-4"
+ id="linearGradient189-7"
+ gradientTransform="scale(0.8787489,1.1379815)"
+ x1="-0.42674366"
+ y1="0.98859203"
+ x2="176.71146"
+ y2="0.98859203"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#grad0-4"
+ id="linearGradient500"
+ gradientTransform="matrix(0.87785006,0,0,2.0116303,15.940232,20.619826)"
+ x1="-0.42674366"
+ y1="0.98859203"
+ x2="176.71146"
+ y2="0.98859203"
+ gradientUnits="userSpaceOnUse" /></defs><defs
+ id="Filters"><filter
+ id="filter_2"><feGaussianBlur
+ stdDeviation="2"
+ id="feGaussianBlur12" /></filter></defs><g
+ transform="matrix(1,0,0,0.41409874,-12.05774,-5.77269)"
+ id="shape18-1"><title
+ id="title18">Rounded Rectangle.12</title><desc
+ id="desc20">Crypto Symmetric Session</desc><path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient500);stroke:#386288;stroke-width:0.99665654"
+ id="path22"
+ class="st1"
+ d="M 22.713297,378.28219 H 163.92871 a 6.7704177,11.980443 0 0 0 6.76307,-11.96745 V 35.256532 A 6.7704177,11.980443 0 0 0 163.92871,23.271405 H 22.713297 A 6.7704177,11.980443 0 0 0 15.940232,35.256532 V 366.31474 a 6.7704177,11.980443 0 0 0 6.773065,11.96745 z" /></g><g
+ transform="matrix(1,0,0,0.41409874,-2.136529,-9.5289258)"
+ id="shape19-6"><title
+ id="title27">Rounded Rectangle.13</title><desc
+ id="desc29">Private Session Data</desc></g><g
+ id="g4079"
+ transform="matrix(0.9997031,0,0,1.070998,206.15511,-5.6465883)"><path
+ style="fill:#ffffff;stroke:#41719c;stroke-width:1.15444767"
+ inkscape:connector-curvature="0"
+ id="path43"
+ class="st7"
+ d="m -189.55935,139.62776 h 123.25 a 5.90925,14.000977 0 0 0 5.91,-13.97905 V 39.476089 a 5.90925,14.000977 0 0 0 -5.91,-14.002757 h -123.25 a 5.90925,14.000977 0 0 0 -5.91,14.002757 v 86.172621 a 5.90925,14.000977 0 0 0 5.91,13.97905 z" /><rect
+ y="118.60072"
+ x="-181.11736"
+ height="14.896484"
+ width="15.968175"
+ id="rect4604"
+ style="fill:none;fill-opacity:1;stroke:#41719c;stroke-width:0.75000221;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-165.14919"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-149.181"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-133.21283"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6-9"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-117.24466"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6-9-8"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-101.27649"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6-9-8-9"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-85.308311"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6-9-8-9-6"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><text
+ transform="scale(0.48757738,2.0509565)"
+ style="font-size:21.61449814px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#41719c;fill-rule:evenodd;stroke-width:2.16144276;stroke-linecap:square;stroke-miterlimit:3"
+ id="text65-3"
+ class="st6"
+ y="50.793892"
+ x="-374.07562" />
+<text
+ xml:space="preserve"
+ style="font-style:normal;font-weight:normal;font-size:28.99296951px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.72482425"
+ x="-172.30693"
+ y="83.585136"
+ id="text4129"
+ transform="scale(1.035044,0.96614251)"><tspan
+ sodipodi:role="line"
+ id="tspan4127"
+ x="-172.30693"
+ y="109.23712"
+ style="stroke-width:0.72482425"></tspan></text>
+<text
+ xml:space="preserve"
+ style="font-style:normal;font-weight:normal;font-size:28.99296951px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.72482425"
+ x="-174.79263"
+ y="75.713715"
+ id="text4139"
+ transform="scale(1.035044,0.96614251)"><tspan
+ sodipodi:role="line"
+ id="tspan4137"
+ x="-174.79263"
+ y="101.3657"
+ style="stroke-width:0.72482425"></tspan></text>
+</g><path
+ style="fill:none;fill-opacity:1;stroke:#41719c;stroke-width:0.86738265px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
+ d="m 128.80127,137.90141 -0.20704,20.06801 44.6966,-0.10399 0.20705,-93.424256 16.84434,0.62379"
+ id="path5030"
inkscape:connector-curvature="0"
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st4"
- id="path31-8"
- style="fill:#bdd0e9;fill-opacity:0.25;stroke:#bdd0e9;stroke-opacity:0.25;filter:url(#filter_2)" /></g><path
- inkscape:connector-curvature="0"
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st5"
- id="path34-8"
- style="fill:#a6b6cd;stroke:#41719c;stroke-width:0.75" /><text
- x="34.639763"
- y="119.96548"
- class="st6"
- id="text36-7"
- style="font-size:13.15105343px;font-family:Calibri;fill:#41719c;stroke-width:1.31510115"
- transform="scale(0.76039781,1.3151011)">Private Session Data</text>
-
+ sodipodi:nodetypes="ccccc" /><g
+ transform="matrix(1,0,0,0.57815109,191.45876,-0.65041967)"
+ id="shape18-1-4"><title
+ id="title18-4">Rounded Rectangle.12</title><desc
+ id="desc20-6">Crypto Symmetric Session</desc><path
+ style="fill:url(#linearGradient189);stroke:#386288;stroke-width:0.75"
+ id="path22-0"
+ class="st1"
+ d="m 6.78,202.33 h 141.36 a 6.77735,6.77735 -180 0 0 6.77,-6.77 V 8.28 A 6.77735,6.77735 -180 0 0 148.14,1.5 H 6.78 A 6.77735,6.77735 -180 0 0 0,8.28 v 187.28 a 6.77735,6.77735 -180 0 0 6.78,6.77 z"
+ inkscape:connector-curvature="0" /><text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;fill:#386288;stroke-width:1.40298378"
+ id="text24-5"
+ class="st2"
+ y="17.335487"
+ x="26.317923">Crypto Driver Private Session</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-3"
+ class="st2"
+ y="19.076277"
+ x="-240.04274">Crypto Symmetric Session</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-5"
+ class="st2"
+ y="46.557648"
+ x="-241.24557">uint16_t nb_drivers;</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-6"
+ class="st2"
+ y="98.349464"
+ x="-240.04272">struct {</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-2"
+ class="st2"
+ y="115.26107"
+ x="-204.55865">void *data;</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-9"
+ class="st2"
+ y="144.3279"
+ x="-240.04274">} session_data[];</text>
</g><g
- id="shape18-1-4-7"
- transform="matrix(1,0,0,0.57815109,0.90591369,163.94402)"><title
- id="title18-4-3">Rounded Rectangle.12</title><desc
- id="desc20-6-5">Crypto Symmetric Session</desc><path
- inkscape:connector-curvature="0"
- d="m 6.78,202.33 h 141.36 a 6.77735,6.77735 -180 0 0 6.77,-6.77 V 8.28 A 6.77735,6.77735 -180 0 0 148.14,1.5 H 6.78 A 6.77735,6.77735 -180 0 0 0,8.28 v 187.28 a 6.77735,6.77735 -180 0 0 6.78,6.77 z"
- class="st1"
- id="path22-0-8"
- style="fill:url(#linearGradient189-7);stroke:#386288;stroke-width:0.75" /><text
- x="26.317923"
- y="17.335487"
- class="st2"
- id="text24-5-1"
- style="font-size:14.02988338px;font-family:Calibri;fill:#386288;stroke-width:1.40298378"
- transform="scale(0.71276665,1.4029837)">Crypto Driver Private Session</text>
-
+ transform="matrix(1.022976,0,0,0.71529071,199.82034,-39.936699)"
+ id="shape19-6-5"><title
+ id="title27-2">Rounded Rectangle.13</title><desc
+ id="desc29-0">Private Session Data</desc><g
+ style="visibility:visible"
+ class="st3"
+ transform="translate(0.345598,1.97279)"
+ id="shadow19-7-1"><path
+ style="fill:#bdd0e9;fill-opacity:0.25;stroke:#bdd0e9;stroke-opacity:0.25;filter:url(#filter_2)"
+ id="path31-8"
+ class="st4"
+ d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
+ inkscape:connector-curvature="0" /></g><path
+ style="fill:#a6b6cd;stroke:#41719c;stroke-width:0.75"
+ id="path34-8"
+ class="st5"
+ d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
+ inkscape:connector-curvature="0" /><text
+ transform="scale(0.76039781,1.3151011)"
+ style="font-size:13.15105343px;font-family:Calibri;fill:#41719c;stroke-width:1.31510115"
+ id="text36-7"
+ class="st6"
+ y="119.96548"
+ x="34.639763">Private Session Data</text>
</g><g
- id="shape19-6-5-1"
- transform="matrix(1.022976,0,0,0.71529071,9.2675037,124.65774)"><title
- id="title27-2-4">Rounded Rectangle.13</title><desc
- id="desc29-0-9">Private Session Data</desc><g
- id="shadow19-7-1-8"
- transform="translate(0.345598,1.97279)"
- class="st3"
- style="visibility:visible"><path
- inkscape:connector-curvature="0"
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st4"
- id="path31-8-4"
- style="fill:#bdd0e9;fill-opacity:0.25;stroke:#bdd0e9;stroke-opacity:0.25;filter:url(#filter_2-3)" /></g><path
- inkscape:connector-curvature="0"
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st5"
- id="path34-8-3"
- style="fill:#a6b6cd;stroke:#41719c;stroke-width:0.75" /><text
- x="34.639763"
- y="119.96548"
- class="st6"
- id="text36-7-6"
- style="font-size:13.15105343px;font-family:Calibri;fill:#41719c;stroke-width:1.31510115"
- transform="scale(0.76039781,1.3151011)">Private Session Data</text>
-
+ transform="matrix(1,0,0,0.57815109,191.61478,163.41083)"
+ id="shape18-1-4-7"><title
+ id="title18-4-3">Rounded Rectangle.12</title><desc
+ id="desc20-6-5">Crypto Symmetric Session</desc><path
+ style="fill:url(#linearGradient189-7);stroke:#386288;stroke-width:0.75"
+ id="path22-0-8"
+ class="st1"
+ d="m 6.78,202.33 h 141.36 a 6.77735,6.77735 -180 0 0 6.77,-6.77 V 8.28 A 6.77735,6.77735 -180 0 0 148.14,1.5 H 6.78 A 6.77735,6.77735 -180 0 0 0,8.28 v 187.28 a 6.77735,6.77735 -180 0 0 6.78,6.77 z"
+ inkscape:connector-curvature="0" /><text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;fill:#386288;stroke-width:1.40298378"
+ id="text24-5-1"
+ class="st2"
+ y="17.335487"
+ x="26.317923">Crypto Driver Private Session</text>
+</g><g
+ transform="matrix(1.022976,0,0,0.71529071,199.97637,124.12455)"
+ id="shape19-6-5-1"><title
+ id="title27-2-4">Rounded Rectangle.13</title><desc
+ id="desc29-0-9">Private Session Data</desc><g
+ style="visibility:visible"
+ class="st3"
+ transform="translate(0.345598,1.97279)"
+ id="shadow19-7-1-8"><path
+ style="fill:#bdd0e9;fill-opacity:0.25;stroke:#bdd0e9;stroke-opacity:0.25;filter:url(#filter_2-3)"
+ id="path31-8-4"
+ class="st4"
+ d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
+ inkscape:connector-curvature="0" /></g><path
+ style="fill:#a6b6cd;stroke:#41719c;stroke-width:0.75"
+ id="path34-8-3"
+ class="st5"
+ d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
+ inkscape:connector-curvature="0" /><text
+ transform="scale(0.76039781,1.3151011)"
+ style="font-size:13.15105343px;font-family:Calibri;fill:#41719c;stroke-width:1.31510115"
+ id="text36-7-6"
+ class="st6"
+ y="119.96548"
+ x="34.639763">Private Session Data</text>
</g><text
- xml:space="preserve"
+ id="text5070"
+ y="145.4136"
+ x="248.24945"
style="font-style:normal;font-weight:normal;font-size:30.00008774px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.75000221"
- x="57.540585"
- y="145.94679"
- id="text5070"><tspan
- sodipodi:role="line"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.75000221"
+ y="171.95665"
+ x="248.24945"
id="tspan5068"
- x="57.540585"
- y="173.31679"
- style="stroke-width:0.75000221"></tspan></text>
+ sodipodi:role="line" /></text>
<text
- xml:space="preserve"
+ id="text5074"
+ y="142.68553"
+ x="251.28064"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.00006485px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.75000221"
- x="60.571766"
- y="143.21872"
- id="text5074"><tspan
- sodipodi:role="line"
+ xml:space="preserve"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.00006485px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.75000221"
+ y="142.68553"
+ x="251.28064"
id="tspan5072"
- x="60.571766"
- y="143.21872"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.00006485px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.75000221">...</tspan></text>
+ sodipodi:role="line">...</tspan></text>
<path
- style="fill:none;stroke:#41719c;stroke-width:0.74499911px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker5421)"
- d="M -158.57624,71.371238 -157.38,232.04055 -1.1215065,232.19212"
+ inkscape:connector-curvature="0"
id="path5076"
- inkscape:connector-curvature="0" /></g></svg>
+ d="m 32.13263,137.96494 1.19624,93.60569 156.25849,0.0883"
+ style="fill:none;stroke:#41719c;stroke-width:0.56864393px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker5421)" /></svg>
\ No newline at end of file
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 445d6a809..740b24dd7 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -170,7 +170,8 @@ API Changes
* cryptodev: a new function ``rte_cryptodev_sym_session_pool_create()`` is
introduced. This function is used to create symmetric session mempool safely
and all crypto applications are required to use this function to create
- symmetric session mempool from now on.
+ symmetric session mempool from now on. Failed to do so will cause
+ ``rte_cryptodev_sym_session_create()`` function call return error.
* cryptodev: introduced a new function
``rte_cryptodev_sym_get_existing_header_session_size()``. The function is
@@ -202,6 +203,10 @@ ABI Changes
``rte_cryptodev_qp_conf`` has been added two parameters of symmetric session
mempool and symmetric session private data mempool.
+* cryptodev: as shown in the the 18.11 deprecation notice, the structure
+ ``rte_cryptodev_sym_session`` has been updated to contain more information
+ to ensure safely accessing the session and session private data.
+
Shared Library Versions
-----------------------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index f4f1cf598..ea61f9269 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -978,6 +978,30 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
return -EINVAL;
}
+ if (qp_conf->mp_session) {
+ struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
+ uint32_t obj_size = qp_conf->mp_session->elt_size;
+ uint32_t obj_priv_size = qp_conf->mp_session_private->elt_size;
+ struct rte_cryptodev_sym_session s = {0};
+
+ pool_priv = rte_mempool_get_priv(qp_conf->mp_session);
+ if (!pool_priv || qp_conf->mp_session->private_data_size <
+ sizeof(*pool_priv)) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return -EINVAL;
+ }
+
+ s.nb_drivers = pool_priv->nb_drivers;
+
+ if ((rte_cryptodev_sym_get_existing_header_session_size(&s) >
+ obj_size) || (s.nb_drivers <= dev->driver_id) ||
+ rte_cryptodev_sym_get_private_session_size(dev_id) >
+ obj_priv_size) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return -EINVAL;
+ }
+ }
+
if (dev->data->dev_started) {
CDEV_LOG_ERR(
"device %d must be stopped to allow configuration", dev_id);
@@ -1172,6 +1196,8 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
struct rte_mempool *mp)
{
struct rte_cryptodev *dev;
+ uint32_t sess_priv_sz = rte_cryptodev_sym_get_private_session_size(
+ dev_id);
uint8_t index;
int ret;
@@ -1180,11 +1206,16 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
if (sess == NULL || xforms == NULL || dev == NULL)
return -EINVAL;
+ if (mp->elt_size < sess_priv_sz)
+ return -EINVAL;
+
index = dev->driver_id;
+ if (index >= sess->nb_drivers)
+ return -EINVAL;
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->sym_session_configure, -ENOTSUP);
- if (sess->sess_private_data[index] == NULL) {
+ if (sess->sess_data[index].data == NULL) {
ret = dev->dev_ops->sym_session_configure(dev, xforms,
sess, mp);
if (ret < 0) {
@@ -1273,10 +1304,29 @@ rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
return mp;
}
+static unsigned int
+rte_cryptodev_sym_session_data_size(struct rte_cryptodev_sym_session *sess)
+{
+ return (sizeof(sess->sess_data[0]) * sess->nb_drivers);
+}
+
struct rte_cryptodev_sym_session *
rte_cryptodev_sym_session_create(struct rte_mempool *mp)
{
struct rte_cryptodev_sym_session *sess;
+ struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
+
+ if (!mp) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return NULL;
+ }
+
+ pool_priv = rte_mempool_get_priv(mp);
+
+ if (!pool_priv || mp->private_data_size < sizeof(*pool_priv)) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return NULL;
+ }
/* Allocate a session structure from the session pool */
if (rte_mempool_get(mp, (void **)&sess)) {
@@ -1284,10 +1334,14 @@ rte_cryptodev_sym_session_create(struct rte_mempool *mp)
return NULL;
}
+ sess->nb_drivers = pool_priv->nb_drivers;
+
+
/* Clear device session pointer.
* Include the flag indicating presence of user data
*/
- memset(sess, 0, (sizeof(void *) * nb_drivers) + sizeof(uint8_t));
+ memset(sess->sess_data, 0,
+ rte_cryptodev_sym_session_data_size(sess));
return sess;
}
@@ -1395,16 +1449,20 @@ rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session *sess)
return 0;
}
-
unsigned int
rte_cryptodev_sym_get_header_session_size(void)
{
/*
- * Header contains pointers to the private data
- * of all registered drivers, and a flag which
- * indicates presence of user data
+ * Header contains pointers to the private data of all registered
+ * drivers and all necessary information to ensure safely clear
+ * or free al session.
*/
- return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
+ struct rte_cryptodev_sym_session s = {0};
+
+ s.nb_drivers = nb_drivers;
+
+ return (unsigned int)(sizeof(s) +
+ rte_cryptodev_sym_session_data_size(&s));
}
unsigned int
@@ -1414,7 +1472,8 @@ rte_cryptodev_sym_get_existing_header_session_size(
if (!sess)
return 0;
else
- return rte_cryptodev_sym_get_header_session_size();
+ return (unsigned int)(sizeof(*sess) +
+ rte_cryptodev_sym_session_data_size(sess));
}
unsigned int __rte_experimental
@@ -1432,7 +1491,6 @@ unsigned int
rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
{
struct rte_cryptodev *dev;
- unsigned int header_size = sizeof(void *) * nb_drivers;
unsigned int priv_sess_size;
if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
@@ -1445,16 +1503,7 @@ rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
priv_sess_size = (*dev->dev_ops->sym_session_get_size)(dev);
- /*
- * If size is less than session header size,
- * return the latter, as this guarantees that
- * sessionless operations will work
- */
- if (priv_sess_size < header_size)
- return header_size;
-
return priv_sess_size;
-
}
unsigned int __rte_experimental
@@ -1486,15 +1535,10 @@ rte_cryptodev_sym_session_set_user_data(
void *data,
uint16_t size)
{
- uint16_t off_set = sizeof(void *) * nb_drivers;
- uint8_t *user_data_present = (uint8_t *)sess + off_set;
-
if (sess == NULL)
return -EINVAL;
- *user_data_present = 1;
- off_set += sizeof(uint8_t);
- rte_memcpy((uint8_t *)sess + off_set, data, size);
+ rte_memcpy(sess->sess_data + sess->nb_drivers, data, size);
return 0;
}
@@ -1502,14 +1546,10 @@ void * __rte_experimental
rte_cryptodev_sym_session_get_user_data(
struct rte_cryptodev_sym_session *sess)
{
- uint16_t off_set = sizeof(void *) * nb_drivers;
- uint8_t *user_data_present = (uint8_t *)sess + off_set;
-
- if (sess == NULL || !*user_data_present)
+ if (sess == NULL)
return NULL;
- off_set += sizeof(uint8_t);
- return (uint8_t *)sess + off_set;
+ return (void *)(sess->sess_data + sess->nb_drivers);
}
/** Initialise rte_crypto_op mempool element */
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index c4db3aa0b..81b7fd1aa 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -957,8 +957,12 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
* has a fixed algo, key, op-type, digest_len etc.
*/
struct rte_cryptodev_sym_session {
- __extension__ void *sess_private_data[0];
- /**< Private symmetric session material */
+ uint16_t nb_drivers;
+ /**< number of elements in sess_data array */
+ __extension__ struct {
+ void *data;
+ } sess_data[0];
+ /**< Driver specific session material, variable size */
};
/** Cryptodev asymmetric crypto session */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index f15c9af30..defe05ea0 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -475,14 +475,23 @@ RTE_INIT(init_ ##driver_id)\
static inline void *
get_sym_session_private_data(const struct rte_cryptodev_sym_session *sess,
uint8_t driver_id) {
- return sess->sess_private_data[driver_id];
+ if (unlikely(sess->nb_drivers <= driver_id))
+ return NULL;
+
+ return sess->sess_data[driver_id].data;
}
static inline void
set_sym_session_private_data(struct rte_cryptodev_sym_session *sess,
uint8_t driver_id, void *private_data)
{
- sess->sess_private_data[driver_id] = private_data;
+ if (unlikely(sess->nb_drivers <= driver_id)) {
+ CDEV_LOG_ERR("Set private data for driver %u not allowed\n",
+ driver_id);
+ return;
+ }
+
+ sess->sess_data[driver_id].data = private_data;
}
static inline void *
--
2.13.6
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH v6 01/10] cryptodev: add opaque userdata pointer into crypto sym session
2019-01-04 9:29 0% ` Ananyev, Konstantin
@ 2019-01-09 23:41 4% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-01-09 23:41 UTC (permalink / raw)
To: Ananyev, Konstantin; +Cc: dev, Stephen Hemminger, akhil.goyal
04/01/2019 10:29, Ananyev, Konstantin:
>
> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Friday, January 4, 2019 12:26 AM
> > To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> > Cc: dev@dpdk.org; akhil.goyal@nxp.com
> > Subject: Re: [dpdk-dev] [PATCH v6 01/10] cryptodev: add opaque userdata pointer into crypto sym session
> >
> > On Thu, 3 Jan 2019 20:16:17 +0000
> > Konstantin Ananyev <konstantin.ananyev@intel.com> wrote:
> >
> > > Add 'uint64_t opaque_data' inside struct rte_cryptodev_sym_session.
> > > That allows upper layer to easily associate some user defined
> > > data with the session.
> > >
> > > Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> > > Acked-by: Fiona Trahe <fiona.trahe@intel.com>
> > > Acked-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
> > > Acked-by: Declan Doherty <declan.doherty@intel.com>
> > > Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
> > > ---
> > > lib/librte_cryptodev/rte_cryptodev.h | 2 ++
> > > 1 file changed, 2 insertions(+)
> > >
> > > diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
> > > index 4099823f1..009860e7b 100644
> > > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > > @@ -954,6 +954,8 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
> > > * has a fixed algo, key, op-type, digest_len etc.
> > > */
> > > struct rte_cryptodev_sym_session {
> > > + uint64_t opaque_data;
> > > + /**< Opaque user defined data */
> > > __extension__ void *sess_private_data[0];
> > > /**< Private symmetric session material */
> > > };
> >
> > This will cause ABI breakage.
>
> Yes, it surely would.
> That's why we submitted deprecation notice in 18.11 and got 3 acks for it.
So you should remove the deprecation notice in this patch,
and bump the ABI version,
and update the release notes for ABI + version changes.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] ethdev: support double precision RED queue weight
2018-12-10 16:01 0% ` Stephen Hemminger
@ 2019-01-10 6:23 0% ` Rao, Nikhil
0 siblings, 0 replies; 200+ results
From: Rao, Nikhil @ 2019-01-10 6:23 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Dumitrescu, Cristian, Singh, Jasvinder, dev
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Monday, December 10, 2018 9:31 PM
Hi Stephen,
> To: Rao, Nikhil <nikhil.rao@intel.com>
> Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Singh, Jasvinder
> <jasvinder.singh@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH] ethdev: support double precision RED queue
> weight
>
> On Mon, 10 Dec 2018 05:43:37 +0000
> "Rao, Nikhil" <nikhil.rao@intel.com> wrote:
>
> > > -----Original Message-----
> > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > Sent: Thursday, November 29, 2018 11:43 AM
> > > To: Rao, Nikhil <nikhil.rao@intel.com>
> > > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Singh,
> > > Jasvinder <jasvinder.singh@intel.com>; dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH] ethdev: support double precision RED
> > > queue weight
> > >
> > > On Thu, 29 Nov 2018 11:24:42 +0530
> > > Nikhil Rao <nikhil.rao@intel.com> wrote:
> > >
> > > > RED queue weight is currently specified as a negated log of 2.
> > > >
> > > > Add support for RED queue weight to be specified in double
> > > > precision and TM capability flags for double precision and negated
> > > > log2 RED queue weight support.
> > > >
> > > > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> > >
> > > Since this is an ABI break anyway, why not just commit to the new format?
> >
> > Hi Stephen,
> >
> > Can you please provide more detail on your comment ? are you suggesting
> replacing the wq_log2/wq_dp with a double ?
> >
> > Thanks,
> > Nikhil
>
>
> My comment is that since you are changing a structure layout, which would
> break existing users; why not go farther and just fix the API to a better
> version. I don't think any projects use this code anyway, see my talk
> (https://github.com/shemminger/dpdk-metrics).
Sorry for the delay. I don't get your reference to a better version, the structure supports both formats using a union,
similar to how it's done in other DPDK APIs (struct rte_crypto_sym_xform for example). If you have a suggestion for a better layout,
please let me know.
>
> Isn't floating point going to be expensive. Or is it only during the setup
> process, not enqueue/dequeue.
Yes, floating point may end up to be more expensive (and the RED computation is invoked at every enqueue)
Nikhil
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4 01/12] cryptodev: change queue pair configure structure
2019-01-09 22:55 3% ` [dpdk-dev] [PATCH v4 01/12] cryptodev: change queue pair configure structure Fan Zhang
@ 2019-01-10 9:47 3% ` De Lara Guarch, Pablo
2019-01-10 11:24 0% ` De Lara Guarch, Pablo
0 siblings, 1 reply; 200+ results
From: De Lara Guarch, Pablo @ 2019-01-10 9:47 UTC (permalink / raw)
To: Zhang, Roy Fan, dev; +Cc: akhil.goyal, Trahe, Fiona
> -----Original Message-----
> From: Zhang, Roy Fan
> Sent: Wednesday, January 9, 2019 10:56 PM
> To: dev@dpdk.org
> Cc: akhil.goyal@nxp.com; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>
> Subject: [PATCH v4 01/12] cryptodev: change queue pair configure structure
>
> This patch changes the cryptodev queue pair configure structure
> to enable two mempool passed into cryptodev PMD simutaneously.
>
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> Acked-by: Fiona Trahe <fiona.trahe@@intel.com>
> ---
...
> diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
> index 953e058c9..38a2e429f 100644
...
> +++ b/doc/guides/prog_guide/cryptodev_lib.rst
Could you also update the sample code which calls queue_pair_setup?
> +
> +
> Logical Cores, Memory and Queues Pair Relationships
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> diff --git a/doc/guides/rel_notes/release_19_02.rst
> b/doc/guides/rel_notes/release_19_02.rst
> index e3b2055d0..75128f8f2 100644
> --- a/doc/guides/rel_notes/release_19_02.rst
> +++ b/doc/guides/rel_notes/release_19_02.rst
> @@ -164,6 +164,9 @@ API Changes
> ``rte_pdump_init()`` and enum ``rte_pdump_socktype`` were deprecated
> since 18.05 and are removed in this release.
>
> +* cryptodev: as shown in the the 18.11 deprecation notice, the last
> parameter
> + of ``rte_cryptodev_queue_pair_setup()``, ``session_pool``, is removed.
> +
ABI versioning should be bumped in this document.
>
> ABI Changes
> -----------
> @@ -183,6 +186,10 @@ ABI Changes
> * mbuf: The format of the sched field of ``rte_mbuf`` has been changed
> to include the following fields: ``queue ID``, ``traffic class``, ``color``.
>
> +* cryptodev: as shown in the the 18.11 deprecation notice, the structure
> + ``rte_cryptodev_qp_conf`` has been added two parameters of symmetric
> session
> + mempool and symmetric session private data mempool.
> +
>
> Shared Library Versions
> -----------------------
> diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> index ebdf7c35a..abc7a6d5f 100644
...
> +++ b/lib/librte_cryptodev/Makefile
> @@ -1,5 +1,5 @@
> # SPDX-License-Identifier: BSD-3-Clause
> -# Copyright(c) 2015 Intel Corporation
> +# Copyright(c) 2015-2018 Intel Corporation
Welcome to 2019 :D
>
> include $(RTE_SDK)/mk/rte.vars.mk
>
> @@ -7,7 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
> LIB = librte_cryptodev.a
>
> # library version
> -LIBABIVER := 5
> +LIBABIVER := 6
Version should also be bumped in the meson.build file.
>
> # build flags
> CFLAGS += -O3
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v4 02/12] cryptodev: add sym session mempool create
2019-01-09 22:55 3% ` [dpdk-dev] [PATCH v4 02/12] cryptodev: add sym session mempool create Fan Zhang
@ 2019-01-10 11:22 0% ` De Lara Guarch, Pablo
0 siblings, 0 replies; 200+ results
From: De Lara Guarch, Pablo @ 2019-01-10 11:22 UTC (permalink / raw)
To: Zhang, Roy Fan, dev; +Cc: akhil.goyal, Trahe, Fiona
> -----Original Message-----
> From: Zhang, Roy Fan
> Sent: Wednesday, January 9, 2019 10:56 PM
> To: dev@dpdk.org
> Cc: akhil.goyal@nxp.com; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>
> Subject: [PATCH v4 02/12] cryptodev: add sym session mempool create
>
> This patch adds a new API "rte_cryptodev_sym_session_pool_create()" to
> cryptodev library. All applications are required to use this API to create sym
> session mempool as it adds private data and nb_drivers information to the
> mempool private data.
>
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> Acked-by: Fiona Trahe <fiona.trahe@intel.com>
> ---
> doc/guides/prog_guide/cryptodev_lib.rst | 28 ++++++++++-----
> doc/guides/rel_notes/release_19_02.rst | 5 +++
> lib/librte_cryptodev/rte_cryptodev.c | 50
> ++++++++++++++++++++++++++
> lib/librte_cryptodev/rte_cryptodev.h | 31 ++++++++++++++++
> lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++++
> 5 files changed, 112 insertions(+), 9 deletions(-)
>
> diff --git a/doc/guides/prog_guide/cryptodev_lib.rst
> b/doc/guides/prog_guide/cryptodev_lib.rst
> index 050a58dc4..366508618 100644
> --- a/doc/guides/prog_guide/cryptodev_lib.rst
> +++ b/doc/guides/prog_guide/cryptodev_lib.rst
> @@ -455,13 +455,15 @@ Crypto workloads.
>
> .. figure:: img/cryptodev_sym_sess.*
>
> -The Crypto device framework provides APIs to allocate and initialize
> sessions -for crypto devices, where sessions are mempool objects.
> +The Crypto device framework provides APIs to create session mempool and
> +allocate and initialize sessions for crypto devices, where sessions are
> mempool objects.
> It is the application's responsibility to create and manage the session
> mempools.
> This approach allows for different scenarios such as having a single session
> mempool for all crypto devices (where the mempool object size is big
> enough to hold the private session of any crypto device), as well as having -
> multiple session mempools of different sizes for better memory usage.
> +multiple session mempools of different sizes for better memory usage.
> +However, the application is required to use
> +``rte_cryptodev_sym_session_pool_create()``
> +to create symmetric session mempool.
>
> An application can use ``rte_cryptodev_sym_get_private_session_size()`` to
> get the private session size of given crypto device. This function would allow
> @@ -623,7 +625,8 @@ using one of the crypto PMDs available in DPDK.
> #define IV_OFFSET (sizeof(struct rte_crypto_op) + \
> sizeof(struct rte_crypto_sym_op))
>
> - struct rte_mempool *mbuf_pool, *crypto_op_pool, *session_pool;
> + struct rte_mempool *mbuf_pool, *crypto_op_pool;
> + struct *session_pool, *session_priv_pool;
Missing rte_mempool here.
> unsigned int session_size;
> int ret;
>
...
> +++ b/doc/guides/rel_notes/release_19_02.rst
> @@ -167,6 +167,11 @@ API Changes
> * cryptodev: as shown in the the 18.11 deprecation notice, the last
> parameter
> of ``rte_cryptodev_queue_pair_setup()`` is removed.
>
> +* cryptodev: a new function ``rte_cryptodev_sym_session_pool_create()``
> +is
> + introduced. This function is used to create symmetric session mempool
> +safely
> + and all crypto applications are required to use this function to
> +create
> + symmetric session mempool from now on.
Even though this is new API, it is replacing a necessary call to
rte_mempool_create() which was used to create the session pools.
I think we should also include that it needs to be used instead of mempool_create (being more explicit).
> +
>
> ABI Changes
> -----------
...
> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
> @@ -88,6 +88,13 @@ DPDK_18.05 {
>
> } DPDK_17.11;
>
> +DPDK_19.02 {
> + global:
> +
> + rte_cryptodev_sym_session_pool_create;
Just saw that check-symbol-change is complaining about this new API being stable.
Apologies for having you changing from experimental to stable, when the API needs to be experimental.
> +
> +} DPDK_18.05;
> +
> EXPERIMENTAL {
> global:
>
> --
> 2.13.6
Apart from this, patch looks ok to me:
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4 01/12] cryptodev: change queue pair configure structure
2019-01-10 9:47 3% ` De Lara Guarch, Pablo
@ 2019-01-10 11:24 0% ` De Lara Guarch, Pablo
0 siblings, 0 replies; 200+ results
From: De Lara Guarch, Pablo @ 2019-01-10 11:24 UTC (permalink / raw)
To: De Lara Guarch, Pablo, Zhang, Roy Fan, dev; +Cc: akhil.goyal, Trahe, Fiona
Hi,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of De Lara Guarch,
> Pablo
> Sent: Thursday, January 10, 2019 9:47 AM
> To: Zhang, Roy Fan <roy.fan.zhang@intel.com>; dev@dpdk.org
> Cc: akhil.goyal@nxp.com; Trahe, Fiona <fiona.trahe@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v4 01/12] cryptodev: change queue pair
> configure structure
>
>
>
> > -----Original Message-----
> > From: Zhang, Roy Fan
> > Sent: Wednesday, January 9, 2019 10:56 PM
> > To: dev@dpdk.org
> > Cc: akhil.goyal@nxp.com; De Lara Guarch, Pablo
> > <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>
> > Subject: [PATCH v4 01/12] cryptodev: change queue pair configure
> > structure
> >
> > This patch changes the cryptodev queue pair configure structure to
> > enable two mempool passed into cryptodev PMD simutaneously.
> >
> > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> > Acked-by: Fiona Trahe <fiona.trahe@@intel.com>
> > ---
>
> ...
>
> > diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
> > index 953e058c9..38a2e429f 100644
>
> ...
>
> > +++ b/doc/guides/prog_guide/cryptodev_lib.rst
>
> Could you also update the sample code which calls queue_pair_setup?
>
> > +
> > +
> > Logical Cores, Memory and Queues Pair Relationships
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >
> > diff --git a/doc/guides/rel_notes/release_19_02.rst
> > b/doc/guides/rel_notes/release_19_02.rst
> > index e3b2055d0..75128f8f2 100644
> > --- a/doc/guides/rel_notes/release_19_02.rst
> > +++ b/doc/guides/rel_notes/release_19_02.rst
> > @@ -164,6 +164,9 @@ API Changes
> > ``rte_pdump_init()`` and enum ``rte_pdump_socktype`` were deprecated
> > since 18.05 and are removed in this release.
> >
> > +* cryptodev: as shown in the the 18.11 deprecation notice, the last
> > parameter
> > + of ``rte_cryptodev_queue_pair_setup()``, ``session_pool``, is removed.
> > +
>
> ABI versioning should be bumped in this document.
>
>
> >
> > ABI Changes
> > -----------
> > @@ -183,6 +186,10 @@ ABI Changes
> > * mbuf: The format of the sched field of ``rte_mbuf`` has been changed
> > to include the following fields: ``queue ID``, ``traffic class``, ``color``.
> >
> > +* cryptodev: as shown in the the 18.11 deprecation notice, the
> > +structure
> > + ``rte_cryptodev_qp_conf`` has been added two parameters of
> > +symmetric
> > session
> > + mempool and symmetric session private data mempool.
> > +
> >
> > Shared Library Versions
> > -----------------------
> > diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> > b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
> > index ebdf7c35a..abc7a6d5f 100644
>
> ...
>
> > +++ b/lib/librte_cryptodev/Makefile
> > @@ -1,5 +1,5 @@
> > # SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2015 Intel
> > Corporation
> > +# Copyright(c) 2015-2018 Intel Corporation
>
> Welcome to 2019 :D
>
> >
> > include $(RTE_SDK)/mk/rte.vars.mk
> >
> > @@ -7,7 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk LIB =
> > librte_cryptodev.a
> >
> > # library version
> > -LIBABIVER := 5
> > +LIBABIVER := 6
>
> Version should also be bumped in the meson.build file.
>
> >
> > # build flags
> > CFLAGS += -O3
Forgot to say that the deprecation notice sent for the structure and
the API changed needs to be removed from deprecation.rst.
Apart from that:
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] eal: fix strdup usages in internal config
@ 2019-01-10 13:38 2% Anatoly Burakov
2019-01-14 14:18 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Anatoly Burakov @ 2019-01-10 13:38 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson, thomas, ferruh.yigit, andy01011501
Currently, we use strdup in a few places to store command-line
parameter values for certain internal config values. There are
several issues with that.
First of all, they're never freed, so memory ends up leaking
either after EAL exit, or when these command-line options are
supplied multiple times.
Second of all, they're defined as `const char *`, so they
*cannot* be freed even if we wanted to.
Finally, strdup may return NULL, which will be stored in the
config. For most fields, NULL is a valid value, but for the
default prefix, the value is always expected to be valid.
To fix all of this, three things are done. First, we change
the definitions of these values to `char *` as opposed to
`const char *`. This does not break the ABI, and previous
code assumes constness (which is more restrictive), so it's
safe to do so.
Then, fix all usages of strdup to check return value, and add
a cleanup function that will free the memory occupied by
these strings, as well as freeing them before assigning a new
value to prevent leaks when parameter is specified multiple
times.
And finally, add an internal API to query hugefile prefix, so
that, absent of a valid value, a default value will be
returned, and also fix up all usages of hugefile prefix to
use this API instead of accessing hugefile prefix directly.
Bugzilla ID: 108
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
lib/librte_eal/bsdapp/eal/eal.c | 19 +++++++--
lib/librte_eal/common/eal_common_options.c | 25 +++++++++++-
lib/librte_eal/common/eal_filesystem.h | 6 ++-
lib/librte_eal/common/eal_internal_cfg.h | 6 +--
lib/librte_eal/common/eal_options.h | 1 +
lib/librte_eal/linuxapp/eal/eal.c | 46 ++++++++++++++++++----
lib/librte_eal/linuxapp/eal/eal_memory.c | 2 +-
7 files changed, 87 insertions(+), 18 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index c8e0da097..1ba9bd7cf 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -117,7 +117,7 @@ eal_create_runtime_dir(void)
/* create prefix-specific subdirectory under DPDK runtime dir */
ret = snprintf(runtime_dir, sizeof(runtime_dir), "%s/%s",
- tmp, internal_config.hugefile_prefix);
+ tmp, eal_get_hugefile_prefix());
if (ret < 0 || ret == sizeof(runtime_dir)) {
RTE_LOG(ERR, EAL, "Error creating prefix-specific runtime path name\n");
return -1;
@@ -535,9 +535,21 @@ eal_parse_args(int argc, char **argv)
switch (opt) {
case OPT_MBUF_POOL_OPS_NAME_NUM:
- internal_config.user_mbuf_pool_ops_name =
- strdup(optarg);
+ {
+ char *ops_name = strdup(optarg);
+ if (ops_name == NULL)
+ RTE_LOG(ERR, EAL, "Could not store mbuf pool ops name\n");
+ else {
+ /* free old ops name */
+ if (internal_config.user_mbuf_pool_ops_name !=
+ NULL)
+ free(internal_config.user_mbuf_pool_ops_name);
+
+ internal_config.user_mbuf_pool_ops_name =
+ ops_name;
+ }
break;
+ }
case 'h':
eal_usage(prgname);
exit(EXIT_SUCCESS);
@@ -923,6 +935,7 @@ rte_eal_cleanup(void)
{
rte_service_finalize();
rte_mp_channel_cleanup();
+ eal_cleanup_config(&internal_config);
return 0;
}
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6e3a83b98..a2d862b5f 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -169,6 +169,14 @@ eal_option_device_parse(void)
return ret;
}
+const char *
+eal_get_hugefile_prefix(void)
+{
+ if (internal_config.hugefile_prefix != NULL)
+ return internal_config.hugefile_prefix;
+ return HUGEFILE_PREFIX_DEFAULT;
+}
+
void
eal_reset_internal_config(struct internal_config *internal_cfg)
{
@@ -177,7 +185,7 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
internal_cfg->memory = 0;
internal_cfg->force_nrank = 0;
internal_cfg->force_nchannel = 0;
- internal_cfg->hugefile_prefix = HUGEFILE_PREFIX_DEFAULT;
+ internal_cfg->hugefile_prefix = NULL;
internal_cfg->hugepage_dir = NULL;
internal_cfg->force_sockets = 0;
/* zero out the NUMA config */
@@ -1347,6 +1355,19 @@ eal_auto_detect_cores(struct rte_config *cfg)
cfg->lcore_count -= removed;
}
+int
+eal_cleanup_config(struct internal_config *internal_cfg)
+{
+ if (internal_cfg->hugefile_prefix != NULL)
+ free(internal_cfg->hugefile_prefix);
+ if (internal_cfg->hugepage_dir != NULL)
+ free(internal_cfg->hugepage_dir);
+ if (internal_cfg->user_mbuf_pool_ops_name != NULL)
+ free(internal_cfg->user_mbuf_pool_ops_name);
+
+ return 0;
+}
+
int
eal_adjust_config(struct internal_config *internal_cfg)
{
@@ -1387,7 +1408,7 @@ eal_check_common_options(struct internal_config *internal_cfg)
RTE_LOG(ERR, EAL, "Invalid process type specified\n");
return -1;
}
- if (index(internal_cfg->hugefile_prefix, '%') != NULL) {
+ if (index(eal_get_hugefile_prefix(), '%') != NULL) {
RTE_LOG(ERR, EAL, "Invalid char, '%%', in --"OPT_FILE_PREFIX" "
"option\n");
return -1;
diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h
index 64a028db7..89a3added 100644
--- a/lib/librte_eal/common/eal_filesystem.h
+++ b/lib/librte_eal/common/eal_filesystem.h
@@ -28,6 +28,10 @@ eal_create_runtime_dir(void);
int
eal_clean_runtime_dir(void);
+/** Function to return hugefile prefix that's currently set up */
+const char *
+eal_get_hugefile_prefix(void);
+
#define RUNTIME_CONFIG_FNAME "config"
static inline const char *
eal_runtime_config_path(void)
@@ -89,7 +93,7 @@ static inline const char *
eal_get_hugefile_path(char *buffer, size_t buflen, const char *hugedir, int f_id)
{
snprintf(buffer, buflen, HUGEFILE_FMT, hugedir,
- internal_config.hugefile_prefix, f_id);
+ eal_get_hugefile_prefix(), f_id);
buffer[buflen - 1] = '\0';
return buffer;
}
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 98e314fef..60eaead8f 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -66,9 +66,9 @@ struct internal_config {
volatile int syslog_facility; /**< facility passed to openlog() */
/** default interrupt mode for VFIO */
volatile enum rte_intr_mode vfio_intr_mode;
- const char *hugefile_prefix; /**< the base filename of hugetlbfs files */
- const char *hugepage_dir; /**< specific hugetlbfs directory to use */
- const char *user_mbuf_pool_ops_name;
+ char *hugefile_prefix; /**< the base filename of hugetlbfs files */
+ char *hugepage_dir; /**< specific hugetlbfs directory to use */
+ char *user_mbuf_pool_ops_name;
/**< user defined mbuf pool ops name */
unsigned num_hugepage_sizes; /**< how many sizes on this system */
struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index 1480c5d77..58ee9ae33 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -77,6 +77,7 @@ int eal_parse_common_option(int opt, const char *argv,
struct internal_config *conf);
int eal_option_device_parse(void);
int eal_adjust_config(struct internal_config *internal_cfg);
+int eal_cleanup_config(struct internal_config *internal_cfg);
int eal_check_common_options(struct internal_config *internal_cfg);
void eal_common_usage(void);
enum rte_proc_type_t eal_proc_type_detect(void);
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 2d8d470b8..a386829f3 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -125,7 +125,7 @@ eal_create_runtime_dir(void)
/* create prefix-specific subdirectory under DPDK runtime dir */
ret = snprintf(runtime_dir, sizeof(runtime_dir), "%s/%s",
- tmp, internal_config.hugefile_prefix);
+ tmp, eal_get_hugefile_prefix());
if (ret < 0 || ret == sizeof(runtime_dir)) {
RTE_LOG(ERR, EAL, "Error creating prefix-specific runtime path name\n");
return -1;
@@ -727,13 +727,31 @@ eal_parse_args(int argc, char **argv)
exit(EXIT_SUCCESS);
case OPT_HUGE_DIR_NUM:
- internal_config.hugepage_dir = strdup(optarg);
+ {
+ char *hdir = strdup(optarg);
+ if (hdir == NULL)
+ RTE_LOG(ERR, EAL, "Could not store hugepage directory\n");
+ else {
+ /* free old hugepage dir */
+ if (internal_config.hugepage_dir != NULL)
+ free(internal_config.hugepage_dir);
+ internal_config.hugepage_dir = hdir;
+ }
break;
-
+ }
case OPT_FILE_PREFIX_NUM:
- internal_config.hugefile_prefix = strdup(optarg);
+ {
+ char *prefix = strdup(optarg);
+ if (prefix == NULL)
+ RTE_LOG(ERR, EAL, "Could not store file prefix\n");
+ else {
+ /* free old prefix */
+ if (internal_config.hugefile_prefix != NULL)
+ free(internal_config.hugefile_prefix);
+ internal_config.hugefile_prefix = prefix;
+ }
break;
-
+ }
case OPT_SOCKET_MEM_NUM:
if (eal_parse_socket_arg(optarg,
internal_config.socket_mem) < 0) {
@@ -783,10 +801,21 @@ eal_parse_args(int argc, char **argv)
break;
case OPT_MBUF_POOL_OPS_NAME_NUM:
- internal_config.user_mbuf_pool_ops_name =
- strdup(optarg);
- break;
+ {
+ char *ops_name = strdup(optarg);
+ if (ops_name == NULL)
+ RTE_LOG(ERR, EAL, "Could not store mbuf pool ops name\n");
+ else {
+ /* free old ops name */
+ if (internal_config.user_mbuf_pool_ops_name !=
+ NULL)
+ free(internal_config.user_mbuf_pool_ops_name);
+ internal_config.user_mbuf_pool_ops_name =
+ ops_name;
+ }
+ break;
+ }
case OPT_MATCH_ALLOCATIONS_NUM:
internal_config.match_allocations = 1;
break;
@@ -1238,6 +1267,7 @@ rte_eal_cleanup(void)
rte_memseg_walk(mark_freeable, NULL);
rte_service_finalize();
rte_mp_channel_cleanup();
+ eal_cleanup_config(&internal_config);
return 0;
}
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 7d922a965..1b96b576e 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -438,7 +438,7 @@ find_numasocket(struct hugepage_file *hugepg_tbl, struct hugepage_info *hpi)
}
snprintf(hugedir_str, sizeof(hugedir_str),
- "%s/%s", hpi->hugedir, internal_config.hugefile_prefix);
+ "%s/%s", hpi->hugedir, eal_get_hugefile_prefix());
/* parse numa map */
while (fgets(buf, sizeof(buf), f) != NULL) {
--
2.17.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v2] compat: merge compat library into EAL
@ 2019-01-10 13:47 4% ` Bruce Richardson
2019-01-10 13:57 0% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2019-01-10 13:47 UTC (permalink / raw)
To: dev; +Cc: David Marchand, Thomas Monjalon, anatoly.burakov, Bruce Richardson
Since compat library is only a single header, we can easily move it into
the EAL common headers instead of tracking it separately. The downside of
this is that it becomes a little more difficult to have any libs that are
built before EAL depend on it. Thankfully, this is not a major problem as
the only library which uses rte_compat.h and is built before EAL (kvargs)
already has the path to the compat.h header file explicitly called out as
an include path.
However, to ensure that we don't later hit problems later with this, we can
add EAL common headers folder to the global include list in the meson build
which means that all common headers can be safely used by all libraries, no
matter what their build order.
As a side-effect, this patch also fixes an issue with building on BSD using
meson, due to compat lib no longer needing to be listed as a dependency.
Fixes: a8499f65a1d1 ("log: add missing experimental tag")
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
V2: Clean up a few missed references to the compat library in our
documentation and MAINTAINERS file.
Added in fixes tag, as this patch should also fix build issues
with BSD.
---
MAINTAINERS | 1 -
doc/api/doxy-api.conf.in | 1 -
doc/guides/contributing/documentation.rst | 1 -
doc/guides/contributing/versioning.rst | 2 +-
lib/Makefile | 2 --
lib/librte_cmdline/meson.build | 1 -
lib/librte_compat/Makefile | 13 -------------
lib/librte_compat/meson.build | 8 --------
lib/librte_eal/common/Makefile | 2 +-
.../common/include}/rte_compat.h | 0
lib/librte_eal/common/meson.build | 1 +
lib/librte_eal/linuxapp/eal/meson.build | 2 +-
lib/librte_eal/meson.build | 1 -
lib/librte_kvargs/meson.build | 3 ---
lib/meson.build | 2 +-
meson.build | 2 +-
16 files changed, 6 insertions(+), 36 deletions(-)
delete mode 100644 lib/librte_compat/Makefile
delete mode 100644 lib/librte_compat/meson.build
rename lib/{librte_compat => librte_eal/common/include}/rte_compat.h (100%)
diff --git a/MAINTAINERS b/MAINTAINERS
index 470f36b9c..4dbb111a0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -121,7 +121,6 @@ F: buildtools/symlink-drivers-solibs.sh
ABI versioning
M: Neil Horman <nhorman@tuxdriver.com>
-F: lib/librte_compat/
F: doc/guides/rel_notes/deprecation.rst
F: devtools/validate-abi.sh
F: devtools/check-symbol-change.sh
diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index 77ba327a8..498306c51 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -22,7 +22,6 @@ INPUT = @TOPDIR@/doc/api/doxy-api-index.md \
@TOPDIR@/lib/librte_bpf \
@TOPDIR@/lib/librte_cfgfile \
@TOPDIR@/lib/librte_cmdline \
- @TOPDIR@/lib/librte_compat \
@TOPDIR@/lib/librte_compressdev \
@TOPDIR@/lib/librte_cryptodev \
@TOPDIR@/lib/librte_distributor \
diff --git a/doc/guides/contributing/documentation.rst b/doc/guides/contributing/documentation.rst
index c28a95c34..ad33d9e46 100644
--- a/doc/guides/contributing/documentation.rst
+++ b/doc/guides/contributing/documentation.rst
@@ -22,7 +22,6 @@ The main directories that contain files related to documentation are shown below
|-- librte_acl
|-- librte_cfgfile
|-- librte_cmdline
- |-- librte_compat
|-- librte_eal
| |-- ...
...
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 01b36247e..18b031998 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -167,7 +167,7 @@ functionality or behavior. When that occurs, it is desirable to allow for
backward compatibility for a time with older binaries that are dynamically
linked to the DPDK.
-To support backward compatibility the ``lib/librte_compat/rte_compat.h``
+To support backward compatibility the ``rte_compat.h``
header file provides macros to use when updating exported functions. These
macros are used in conjunction with the ``rte_<library>_version.map`` file for
a given library to allow multiple versions of a symbol to exist in a shared
diff --git a/lib/Makefile b/lib/Makefile
index 8dbdc9bca..91a8de4af 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -3,9 +3,7 @@
include $(RTE_SDK)/mk/rte.vars.mk
-DIRS-y += librte_compat
DIRS-$(CONFIG_RTE_LIBRTE_KVARGS) += librte_kvargs
-DEPDIRS-librte_kvargs := librte_compat
DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
DEPDIRS-librte_eal := librte_kvargs
DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci
diff --git a/lib/librte_cmdline/meson.build b/lib/librte_cmdline/meson.build
index 30498906c..0fa61385f 100644
--- a/lib/librte_cmdline/meson.build
+++ b/lib/librte_cmdline/meson.build
@@ -3,7 +3,6 @@
# This library is processed before EAL
includes = [global_inc]
-includes += include_directories('../librte_eal/common/include')
version = 2
sources = files('cmdline.c',
diff --git a/lib/librte_compat/Makefile b/lib/librte_compat/Makefile
deleted file mode 100644
index 61089fe77..000000000
--- a/lib/librte_compat/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2013 Neil Horman <nhorman@tuxdriver.com>
-# All rights reserved.
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-
-LIBABIVER := 1
-
-# install includes
-SYMLINK-y-include := rte_compat.h
-
-include $(RTE_SDK)/mk/rte.install.mk
diff --git a/lib/librte_compat/meson.build b/lib/librte_compat/meson.build
deleted file mode 100644
index 82c7eea55..000000000
--- a/lib/librte_compat/meson.build
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017 Intel Corporation
-
-
-install_headers('rte_compat.h')
-
-set_variable('dep_rte_compat',
- declare_dependency(include_directories: include_directories('.')))
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 87d8c455d..c487201b3 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -3,7 +3,7 @@
include $(RTE_SDK)/mk/rte.vars.mk
-INC := rte_branch_prediction.h rte_common.h
+INC := rte_branch_prediction.h rte_common.h rte_compat.h
INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
INC += rte_errno.h rte_launch.h rte_lcore.h
INC += rte_log.h rte_memory.h rte_memzone.h
diff --git a/lib/librte_compat/rte_compat.h b/lib/librte_eal/common/include/rte_compat.h
similarity index 100%
rename from lib/librte_compat/rte_compat.h
rename to lib/librte_eal/common/include/rte_compat.h
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 2a10d57d8..5ecae0b1f 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -53,6 +53,7 @@ common_headers = files(
'include/rte_bitmap.h',
'include/rte_class.h',
'include/rte_common.h',
+ 'include/rte_compat.h',
'include/rte_debug.h',
'include/rte_devargs.h',
'include/rte_dev.h',
diff --git a/lib/librte_eal/linuxapp/eal/meson.build b/lib/librte_eal/linuxapp/eal/meson.build
index 6e31c2aaa..7e68b2c0d 100644
--- a/lib/librte_eal/linuxapp/eal/meson.build
+++ b/lib/librte_eal/linuxapp/eal/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-eal_inc += include_directories('include', '../../../librte_compat')
+eal_inc += include_directories('include')
install_subdir('include/exec-env', install_dir: get_option('includedir'))
env_objs = []
diff --git a/lib/librte_eal/meson.build b/lib/librte_eal/meson.build
index a18f3a826..64d857a4a 100644
--- a/lib/librte_eal/meson.build
+++ b/lib/librte_eal/meson.build
@@ -23,7 +23,6 @@ endif
version = 9 # the version of the EAL API
allow_experimental_apis = true
-deps += 'compat'
deps += 'kvargs'
sources = common_sources + env_sources
objs = common_objs + env_objs
diff --git a/lib/librte_kvargs/meson.build b/lib/librte_kvargs/meson.build
index acd3e5432..ecaedf5a5 100644
--- a/lib/librte_kvargs/meson.build
+++ b/lib/librte_kvargs/meson.build
@@ -2,10 +2,7 @@
# Copyright(c) 2017 Intel Corporation
includes = [global_inc]
-includes += include_directories('../librte_eal/common/include')
version = 1
sources = files('rte_kvargs.c')
headers = files('rte_kvargs.h')
-
-deps += 'compat'
diff --git a/lib/meson.build b/lib/meson.build
index 93d7901d4..46ba363ce 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -8,7 +8,7 @@
# sometimes skip deps that would be implied by others, e.g. if mempool is
# given as a dep, no need to mention ring. This is especially true for the
# core libs which are widely reused, so their deps are kept to a minimum.
-libraries = [ 'compat', # just a header, used for versioning
+libraries = [
'cmdline', # ethdev depends on cmdline for parsing functions
'kvargs', # eal depends on kvargs
'eal', 'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
diff --git a/meson.build b/meson.build
index 7cee3c94a..29944f127 100644
--- a/meson.build
+++ b/meson.build
@@ -32,7 +32,7 @@ eal_pmd_path = join_paths(get_option('prefix'), driver_install_path)
# configure the build, and make sure configs here and in config folder are
# able to be included in any file. We also store a global array of include dirs
# for passing to pmdinfogen scripts
-global_inc = include_directories('.', 'config')
+global_inc = include_directories('.', 'config', 'lib/librte_eal/common/include')
subdir('config')
# build libs and drivers
--
2.20.1
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2] compat: merge compat library into EAL
2019-01-10 13:47 4% ` [dpdk-dev] [PATCH v2] " Bruce Richardson
@ 2019-01-10 13:57 0% ` David Marchand
2019-01-10 14:01 0% ` Bruce Richardson
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2019-01-10 13:57 UTC (permalink / raw)
To: Bruce Richardson; +Cc: dev, Thomas Monjalon, Burakov, Anatoly, dpdk stable
On Thu, Jan 10, 2019 at 2:48 PM Bruce Richardson <bruce.richardson@intel.com>
wrote:
> Since compat library is only a single header, we can easily move it into
> the EAL common headers instead of tracking it separately. The downside of
> this is that it becomes a little more difficult to have any libs that are
> built before EAL depend on it. Thankfully, this is not a major problem as
> the only library which uses rte_compat.h and is built before EAL (kvargs)
> already has the path to the compat.h header file explicitly called out as
> an include path.
>
> However, to ensure that we don't later hit problems later with this, we can
> add EAL common headers folder to the global include list in the meson build
> which means that all common headers can be safely used by all libraries, no
> matter what their build order.
>
> As a side-effect, this patch also fixes an issue with building on BSD using
> meson, due to compat lib no longer needing to be listed as a dependency.
>
CC stable.
>
> Fixes: a8499f65a1d1 ("log: add missing experimental tag")
>
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
>
> ---
> V2: Clean up a few missed references to the compat library in our
> documentation and MAINTAINERS file.
> Added in fixes tag, as this patch should also fix build issues
> with BSD.
> ---
> MAINTAINERS | 1 -
> doc/api/doxy-api.conf.in | 1 -
> doc/guides/contributing/documentation.rst | 1 -
> doc/guides/contributing/versioning.rst | 2 +-
> lib/Makefile | 2 --
> lib/librte_cmdline/meson.build | 1 -
> lib/librte_compat/Makefile | 13 -------------
> lib/librte_compat/meson.build | 8 --------
> lib/librte_eal/common/Makefile | 2 +-
> .../common/include}/rte_compat.h | 0
> lib/librte_eal/common/meson.build | 1 +
> lib/librte_eal/linuxapp/eal/meson.build | 2 +-
> lib/librte_eal/meson.build | 1 -
> lib/librte_kvargs/meson.build | 3 ---
> lib/meson.build | 2 +-
> meson.build | 2 +-
> 16 files changed, 6 insertions(+), 36 deletions(-)
> delete mode 100644 lib/librte_compat/Makefile
> delete mode 100644 lib/librte_compat/meson.build
> rename lib/{librte_compat => librte_eal/common/include}/rte_compat.h
> (100%)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 470f36b9c..4dbb111a0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -121,7 +121,6 @@ F: buildtools/symlink-drivers-solibs.sh
>
> ABI versioning
> M: Neil Horman <nhorman@tuxdriver.com>
> -F: lib/librte_compat/
>
Maybe ?
+F: lib/librte_eal/common/include/rte_compat.h
Tested-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] compat: merge compat library into EAL
2019-01-10 13:57 0% ` David Marchand
@ 2019-01-10 14:01 0% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-01-10 14:01 UTC (permalink / raw)
To: David Marchand
Cc: dev, Thomas Monjalon, Burakov, Anatoly, dpdk stable, nhorman
On Thu, Jan 10, 2019 at 02:57:41PM +0100, David Marchand wrote:
> On Thu, Jan 10, 2019 at 2:48 PM Bruce Richardson
> <[1]bruce.richardson@intel.com> wrote:
>
> Since compat library is only a single header, we can easily move it
> into
> the EAL common headers instead of tracking it separately. The
> downside of
> this is that it becomes a little more difficult to have any libs
> that are
> built before EAL depend on it. Thankfully, this is not a major
> problem as
> the only library which uses rte_compat.h and is built before EAL
> (kvargs)
> already has the path to the compat.h header file explicitly called
> out as
> an include path.
> However, to ensure that we don't later hit problems later with this,
> we can
> add EAL common headers folder to the global include list in the
> meson build
> which means that all common headers can be safely used by all
> libraries, no
> matter what their build order.
> As a side-effect, this patch also fixes an issue with building on
> BSD using
> meson, due to compat lib no longer needing to be listed as a
> dependency.
>
> CC stable.
>
Not needed. Defect introduced in a commit earlier in this release.
> Fixes: a8499f65a1d1 ("log: add missing experimental tag")
> Signed-off-by: Bruce Richardson <[2]bruce.richardson@intel.com>
> ---
> V2: Clean up a few missed references to the compat library in our
> documentation and MAINTAINERS file.
> Added in fixes tag, as this patch should also fix build issues
> with BSD.
> ---
> MAINTAINERS | 1 -
> doc/api/[3]doxy-api.conf.in | 1 -
> doc/guides/contributing/documentation.rst | 1 -
> doc/guides/contributing/versioning.rst | 2 +-
> lib/Makefile | 2 --
> lib/librte_cmdline/meson.build | 1 -
> lib/librte_compat/Makefile | 13
> -------------
> lib/librte_compat/meson.build | 8 --------
> lib/librte_eal/common/Makefile | 2 +-
> .../common/include}/rte_compat.h | 0
> lib/librte_eal/common/meson.build | 1 +
> lib/librte_eal/linuxapp/eal/meson.build | 2 +-
> lib/librte_eal/meson.build | 1 -
> lib/librte_kvargs/meson.build | 3 ---
> lib/meson.build | 2 +-
> meson.build | 2 +-
> 16 files changed, 6 insertions(+), 36 deletions(-)
> delete mode 100644 lib/librte_compat/Makefile
> delete mode 100644 lib/librte_compat/meson.build
> rename lib/{librte_compat =>
> librte_eal/common/include}/rte_compat.h (100%)
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 470f36b9c..4dbb111a0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -121,7 +121,6 @@ F: buildtools/symlink-drivers-solibs.sh
> ABI versioning
> M: Neil Horman <[4]nhorman@tuxdriver.com>
> -F: lib/librte_compat/
>
> Maybe ?
> +F: lib/librte_eal/common/include/rte_compat.h
> Tested-by: David Marchand <[5]david.marchand@redhat.com>
> Reviewed-by: David Marchand <[6]david.marchand@redhat.com>
> --
CC: Neil
Not sure. I was thinking it would be covered just as part of the EAL
generally, but I'm ok if Neil still wants explicit ownership of the file.
If it is to be added, hopefully that could just be done on apply.
/Bruce
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
2019-01-04 0:25 3% ` Stephen Hemminger
@ 2019-01-10 14:20 4% ` Konstantin Ananyev
2019-01-10 14:25 0% ` Thomas Monjalon
2019-01-10 14:51 0% ` Akhil Goyal
2019-01-10 14:20 5% ` [dpdk-dev] [PATCH v7 01/10] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
2019-01-10 14:20 9% ` [dpdk-dev] [PATCH v7 02/10] " Konstantin Ananyev
3 siblings, 2 replies; 200+ results
From: Konstantin Ananyev @ 2019-01-10 14:20 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, thomas, Konstantin Ananyev
v6 -> v7
- Changes to address Thomas comments:
bump ABI version
remove related deprecation notice
update release notes, ABI changes section
v5 -> v6
- Fix issues reported by Akhil:
rte_ipsec_session_prepare() fails for lookaside-proto
v4 -> v5
- Fix issue with SQN overflows
- Address Akhil comments:
documentation update
spell checks spacing etc.
fix input crypto_xform check/prepcess
test cases for lookaside and inline proto
v3 -> v4
- Changes to address Declan comments
- Update docs
v2 -> v3
- Several fixes for IPv6 support
- Extra checks for input parameters in public APi functions
v1 -> v2
- Changes to get into account l2_len for outbound transport packets
(Qi comments)
- Several bug fixes
- Some code restructured
- Update MAINTAINERS file
RFCv2 -> v1
- Changes per Jerin comments
- Implement transport mode
- Several bug fixes
- UT largely reworked and extended
This patch introduces a new library within DPDK: librte_ipsec.
The aim is to provide DPDK native high performance library for IPsec
data-path processing.
The library is supposed to utilize existing DPDK crypto-dev and
security API to provide application with transparent IPsec
processing API.
The library is concentrated on data-path protocols processing
(ESP and AH), IKE protocol(s) implementation is out of scope
for that library.
Current patch introduces SA-level API.
SA level API
============
API described below operates on SA level.
It provides functionality that allows user for given SA to process
inbound and outbound IPsec packets.
To be more specific:
- for inbound ESP/AH packets perform decryption, authentication,
integrity checking, remove ESP/AH related headers
- for outbound packets perform payload encryption, attach ICV,
update/add IP headers, add ESP/AH headers/trailers,
setup related mbuf felids (ol_flags, tx_offloads, etc.).
- initialize/un-initialize given SA based on user provided parameters.
The following functionality:
- match inbound/outbound packets to particular SA
- manage crypto/security devices
- provide SAD/SPD related functionality
- determine what crypto/security device has to be used
for given packet(s)
is out of scope for SA-level API.
SA-level API is based on top of crypto-dev/security API and relies on them
to perform actual cipher and integrity checking.
To have an ability to easily map crypto/security sessions into related
IPSec SA opaque userdata field was added into
rte_cryptodev_sym_session and rte_security_session structures.
That implies ABI change for both librte_crytpodev and librte_security.
Due to the nature of crypto-dev API (enqueue/deque model) we use
asynchronous API for IPsec packets destined to be processed by
crypto-device.
Expected API call sequence would be:
/* enqueue for processing by crypto-device */
rte_ipsec_pkt_crypto_prepare(...);
rte_cryptodev_enqueue_burst(...);
/* dequeue from crypto-device and do final processing (if any) */
rte_cryptodev_dequeue_burst(...);
rte_ipsec_pkt_crypto_group(...); /* optional */
rte_ipsec_pkt_process(...);
Though for packets destined for inline processing no extra overhead
is required and synchronous API call: rte_ipsec_pkt_process()
is sufficient for that case.
Current implementation supports all four currently defined
rte_security types.
Though to accommodate future custom implementations function pointers
model is used for both for *crypto_prepare* and *process* impelementations.
Konstantin Ananyev (10):
cryptodev: add opaque userdata pointer into crypto sym session
security: add opaque userdata pointer into security session
net: add ESP trailer structure definition
lib: introduce ipsec library
ipsec: add SA data-path API
ipsec: implement SA data-path API
ipsec: rework SA replay window/SQN for MT environment
ipsec: helper functions to group completed crypto-ops
test/ipsec: introduce functional test
doc: add IPsec library guide
MAINTAINERS | 8 +-
config/common_base | 5 +
doc/guides/prog_guide/index.rst | 1 +
doc/guides/prog_guide/ipsec_lib.rst | 168 ++
doc/guides/rel_notes/deprecation.rst | 4 -
doc/guides/rel_notes/release_19_02.rst | 20 +
lib/Makefile | 2 +
lib/librte_cryptodev/Makefile | 4 +-
lib/librte_cryptodev/meson.build | 4 +-
lib/librte_cryptodev/rte_cryptodev.h | 2 +
lib/librte_ipsec/Makefile | 27 +
lib/librte_ipsec/crypto.h | 123 ++
lib/librte_ipsec/iph.h | 84 +
lib/librte_ipsec/ipsec_sqn.h | 343 ++++
lib/librte_ipsec/meson.build | 10 +
lib/librte_ipsec/pad.h | 45 +
lib/librte_ipsec/rte_ipsec.h | 154 ++
lib/librte_ipsec/rte_ipsec_group.h | 151 ++
lib/librte_ipsec/rte_ipsec_sa.h | 174 ++
lib/librte_ipsec/rte_ipsec_version.map | 15 +
lib/librte_ipsec/sa.c | 1527 ++++++++++++++
lib/librte_ipsec/sa.h | 106 +
lib/librte_ipsec/ses.c | 52 +
lib/librte_net/rte_esp.h | 10 +-
lib/librte_security/Makefile | 4 +-
lib/librte_security/meson.build | 3 +-
lib/librte_security/rte_security.h | 2 +
lib/meson.build | 2 +
mk/rte.app.mk | 2 +
test/test/Makefile | 3 +
test/test/meson.build | 3 +
test/test/test_ipsec.c | 2555 ++++++++++++++++++++++++
32 files changed, 5600 insertions(+), 13 deletions(-)
create mode 100644 doc/guides/prog_guide/ipsec_lib.rst
create mode 100644 lib/librte_ipsec/Makefile
create mode 100644 lib/librte_ipsec/crypto.h
create mode 100644 lib/librte_ipsec/iph.h
create mode 100644 lib/librte_ipsec/ipsec_sqn.h
create mode 100644 lib/librte_ipsec/meson.build
create mode 100644 lib/librte_ipsec/pad.h
create mode 100644 lib/librte_ipsec/rte_ipsec.h
create mode 100644 lib/librte_ipsec/rte_ipsec_group.h
create mode 100644 lib/librte_ipsec/rte_ipsec_sa.h
create mode 100644 lib/librte_ipsec/rte_ipsec_version.map
create mode 100644 lib/librte_ipsec/sa.c
create mode 100644 lib/librte_ipsec/sa.h
create mode 100644 lib/librte_ipsec/ses.c
create mode 100644 test/test/test_ipsec.c
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 01/10] cryptodev: add opaque userdata pointer into crypto sym session
2019-01-04 0:25 3% ` Stephen Hemminger
2019-01-10 14:20 4% ` [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
@ 2019-01-10 14:20 5% ` Konstantin Ananyev
2019-01-10 21:06 4% ` [dpdk-dev] [PATCH v8 0/9] ipsec: new library for IPsec data-path processing Konstantin Ananyev
2019-01-10 21:06 5% ` [dpdk-dev] [PATCH v8 1/9] security: add opaque userdata pointer into security session Konstantin Ananyev
2019-01-10 14:20 9% ` [dpdk-dev] [PATCH v7 02/10] " Konstantin Ananyev
3 siblings, 2 replies; 200+ results
From: Konstantin Ananyev @ 2019-01-10 14:20 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, thomas, Konstantin Ananyev
Add 'uint64_t opaque_data' inside struct rte_cryptodev_sym_session.
That allows upper layer to easily associate some user defined
data with the session.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
Acked-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Acked-by: Declan Doherty <declan.doherty@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
doc/guides/rel_notes/release_19_02.rst | 5 +++++
lib/librte_cryptodev/Makefile | 4 ++--
lib/librte_cryptodev/meson.build | 4 ++--
lib/librte_cryptodev/rte_cryptodev.h | 2 ++
4 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 22c2dff4e..9aa482a84 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -178,6 +178,11 @@ ABI Changes
* mbuf: The format of the sched field of ``rte_mbuf`` has been changed
to include the following fields: ``queue ID``, ``traffic class``, ``color``.
+* cryptodev: New field ``uint64_t opaque_data`` is added into
+ ``rte_cryptodev_sym_session`` structure. That would allow upper layer to
+ easily associate/de-associate some user defined data with the
+ cryptodev session.
+
Shared Library Versions
-----------------------
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index a8f94c097..e38018183 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2015 Intel Corporation
+# Copyright(c) 2015-2019 Intel Corporation
include $(RTE_SDK)/mk/rte.vars.mk
@@ -7,7 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_cryptodev.a
# library version
-LIBABIVER := 5
+LIBABIVER := 6
# build flags
CFLAGS += -O3
diff --git a/lib/librte_cryptodev/meson.build b/lib/librte_cryptodev/meson.build
index 990dd3d44..44bd83212 100644
--- a/lib/librte_cryptodev/meson.build
+++ b/lib/librte_cryptodev/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017 Intel Corporation
+# Copyright(c) 2017-2019 Intel Corporation
-version = 5
+version = 6
sources = files('rte_cryptodev.c', 'rte_cryptodev_pmd.c')
headers = files('rte_cryptodev.h',
'rte_cryptodev_pmd.h',
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 4099823f1..009860e7b 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -954,6 +954,8 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
* has a fixed algo, key, op-type, digest_len etc.
*/
struct rte_cryptodev_sym_session {
+ uint64_t opaque_data;
+ /**< Opaque user defined data */
__extension__ void *sess_private_data[0];
/**< Private symmetric session material */
};
--
2.17.1
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCH v7 02/10] security: add opaque userdata pointer into security session
` (2 preceding siblings ...)
2019-01-10 14:20 5% ` [dpdk-dev] [PATCH v7 01/10] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
@ 2019-01-10 14:20 9% ` Konstantin Ananyev
3 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2019-01-10 14:20 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, thomas, Konstantin Ananyev
Add 'uint64_t opaque_data' inside struct rte_security_session.
That allows upper layer to easily associate some user defined
data with the session.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Acked-by: Declan Doherty <declan.doherty@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
doc/guides/rel_notes/deprecation.rst | 4 ----
doc/guides/rel_notes/release_19_02.rst | 4 ++++
lib/librte_security/Makefile | 4 ++--
lib/librte_security/meson.build | 3 ++-
lib/librte_security/rte_security.h | 2 ++
5 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d4aea4b46..2ea1b86bc 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -71,10 +71,6 @@ Deprecation Notices
- Member ``uint16_t min_mtu`` the minimum MTU allowed.
- Member ``uint16_t max_mtu`` the maximum MTU allowed.
-* security: New field ``uint64_t opaque_data`` is planned to be added into
- ``rte_security_session`` structure. That would allow upper layer to easily
- associate/de-associate some user defined data with the security session.
-
* cryptodev: several API and ABI changes are planned for rte_cryptodev
in v19.02:
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 9aa482a84..fafed0416 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -183,6 +183,10 @@ ABI Changes
easily associate/de-associate some user defined data with the
cryptodev session.
+* security: New field ``uint64_t opaque_data`` is added into
+ ``rte_security_session`` structure. That would allow upper layer to easily
+ associate/de-associate some user defined data with the security session.
+
Shared Library Versions
-----------------------
diff --git a/lib/librte_security/Makefile b/lib/librte_security/Makefile
index bd92343bd..6708effdb 100644
--- a/lib/librte_security/Makefile
+++ b/lib/librte_security/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017 Intel Corporation
+# Copyright(c) 2017-2019 Intel Corporation
include $(RTE_SDK)/mk/rte.vars.mk
@@ -7,7 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_security.a
# library version
-LIBABIVER := 1
+LIBABIVER := 2
# build flags
CFLAGS += -O3
diff --git a/lib/librte_security/meson.build b/lib/librte_security/meson.build
index 532953fcc..a5130d2f6 100644
--- a/lib/librte_security/meson.build
+++ b/lib/librte_security/meson.build
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017 Intel Corporation
+# Copyright(c) 2017-2019 Intel Corporation
+version = 2
sources = files('rte_security.c')
headers = files('rte_security.h', 'rte_security_driver.h')
deps += ['mempool', 'cryptodev']
diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
index 718147e00..c8e438fdd 100644
--- a/lib/librte_security/rte_security.h
+++ b/lib/librte_security/rte_security.h
@@ -317,6 +317,8 @@ struct rte_security_session_conf {
struct rte_security_session {
void *sess_private_data;
/**< Private session material */
+ uint64_t opaque_data;
+ /**< Opaque user defined data */
};
/**
--
2.17.1
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
2019-01-10 14:20 4% ` [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
@ 2019-01-10 14:25 0% ` Thomas Monjalon
2019-01-10 14:40 0% ` De Lara Guarch, Pablo
2019-01-10 14:52 3% ` Ananyev, Konstantin
2019-01-10 14:51 0% ` Akhil Goyal
1 sibling, 2 replies; 200+ results
From: Thomas Monjalon @ 2019-01-10 14:25 UTC (permalink / raw)
To: Konstantin Ananyev; +Cc: dev, akhil.goyal, pablo.de.lara.guarch
10/01/2019 15:20, Konstantin Ananyev:
> v6 -> v7
> - Changes to address Thomas comments:
> bump ABI version
> remove related deprecation notice
> update release notes, ABI changes section
You did not update the lib versions in the release notes.
I think you missed a deprecation notice removal in patch 1.
Have you checked the doxygen warnings in last patch?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
2019-01-10 14:25 0% ` Thomas Monjalon
@ 2019-01-10 14:40 0% ` De Lara Guarch, Pablo
2019-01-10 14:52 3% ` Ananyev, Konstantin
1 sibling, 0 replies; 200+ results
From: De Lara Guarch, Pablo @ 2019-01-10 14:40 UTC (permalink / raw)
To: Thomas Monjalon, Ananyev, Konstantin; +Cc: dev, akhil.goyal
Hi Thomas,
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Thursday, January 10, 2019 2:25 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: dev@dpdk.org; akhil.goyal@nxp.com; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>
> Subject: Re: [PATCH v7 00/10] ipsec: new library for IPsec data-path
> processing
>
> 10/01/2019 15:20, Konstantin Ananyev:
> > v6 -> v7
> > - Changes to address Thomas comments:
> > bump ABI version
> > remove related deprecation notice
> > update release notes, ABI changes section
>
> You did not update the lib versions in the release notes.
> I think you missed a deprecation notice removal in patch 1.
> Have you checked the doxygen warnings in last patch?
>
>
It doesn't matter. Fan is modifying that structure too and he is making these changes, so I will drop this patch after applying his patchset. Therefore, this won't be relevant anymore.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v5 01/12] cryptodev: change queue pair configure structure
@ 2019-01-10 14:50 3% ` Fan Zhang
2019-01-10 14:50 3% ` [dpdk-dev] [PATCH v5 02/12] cryptodev: add sym session mempool create Fan Zhang
2019-01-10 14:50 5% ` [dpdk-dev] [PATCH v5 09/12] cryptodev: update symmetric session structure Fan Zhang
2 siblings, 0 replies; 200+ results
From: Fan Zhang @ 2019-01-10 14:50 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, fiona.trahe
This patch changes the cryptodev queue pair configure structure
to enable two mempool passed into cryptodev PMD simutaneously.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@@intel.com>
---
app/test-crypto-perf/main.c | 6 ++--
doc/guides/prog_guide/cryptodev_lib.rst | 19 ++++++++---
doc/guides/rel_notes/deprecation.rst | 3 --
doc/guides/rel_notes/release_19_02.rst | 9 +++++-
drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 7 ++--
drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c | 5 +--
drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h | 2 ++
drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 7 ++--
drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c | 5 +--
drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h | 2 ++
drivers/crypto/armv8/rte_armv8_pmd.c | 7 ++--
drivers/crypto/armv8/rte_armv8_pmd_ops.c | 5 +--
drivers/crypto/armv8/rte_armv8_pmd_private.h | 2 ++
drivers/crypto/caam_jr/caam_jr.c | 3 +-
drivers/crypto/ccp/ccp_pmd_ops.c | 5 +--
drivers/crypto/ccp/ccp_pmd_private.h | 2 ++
drivers/crypto/ccp/rte_ccp_pmd.c | 9 +++++-
drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c | 3 +-
drivers/crypto/dpaa_sec/dpaa_sec.c | 3 +-
drivers/crypto/kasumi/rte_kasumi_pmd.c | 7 ++--
drivers/crypto/kasumi/rte_kasumi_pmd_ops.c | 5 +--
drivers/crypto/kasumi/rte_kasumi_pmd_private.h | 2 ++
drivers/crypto/mvsam/rte_mrvl_pmd_ops.c | 5 +--
drivers/crypto/mvsam/rte_mrvl_pmd_private.h | 3 ++
drivers/crypto/null/null_crypto_pmd.c | 5 +--
drivers/crypto/null/null_crypto_pmd_ops.c | 5 +--
drivers/crypto/null/null_crypto_pmd_private.h | 2 ++
drivers/crypto/octeontx/otx_cryptodev_ops.c | 3 +-
drivers/crypto/openssl/rte_openssl_pmd.c | 7 ++--
drivers/crypto/openssl/rte_openssl_pmd_ops.c | 5 +--
drivers/crypto/openssl/rte_openssl_pmd_private.h | 2 ++
drivers/crypto/qat/qat_sym_pmd.c | 2 +-
drivers/crypto/scheduler/scheduler_pmd_ops.c | 5 ++-
drivers/crypto/snow3g/rte_snow3g_pmd.c | 7 ++--
drivers/crypto/snow3g/rte_snow3g_pmd_ops.c | 5 +--
drivers/crypto/snow3g/rte_snow3g_pmd_private.h | 2 ++
drivers/crypto/virtio/virtio_cryptodev.c | 6 ++--
drivers/crypto/zuc/rte_zuc_pmd.c | 7 ++--
drivers/crypto/zuc/rte_zuc_pmd_ops.c | 5 +--
drivers/crypto/zuc/rte_zuc_pmd_private.h | 2 ++
drivers/net/softnic/rte_eth_softnic_cryptodev.c | 2 +-
examples/fips_validation/main.c | 4 +--
examples/ip_pipeline/cryptodev.c | 2 +-
examples/ipsec-secgw/ipsec-secgw.c | 7 ++--
examples/l2fwd-crypto/main.c | 4 ++-
examples/vhost_crypto/main.c | 9 ++++--
lib/librte_cryptodev/Makefile | 4 +--
lib/librte_cryptodev/meson.build | 4 +--
lib/librte_cryptodev/rte_cryptodev.c | 16 ++++++++--
lib/librte_cryptodev/rte_cryptodev.h | 7 ++--
lib/librte_cryptodev/rte_cryptodev_pmd.h | 3 +-
test/test/test_cryptodev.c | 37 +++++++++-------------
test/test/test_cryptodev_asym.c | 8 ++---
test/test/test_event_crypto_adapter.c | 5 +--
54 files changed, 189 insertions(+), 119 deletions(-)
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 953e058c9..38a2e429f 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -218,6 +218,9 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
session_pool_socket[socket_id] = sess_mp;
}
+ qp_conf.mp_session = session_pool_socket[socket_id];
+ qp_conf.mp_session_private = session_pool_socket[socket_id];
+
ret = rte_cryptodev_configure(cdev_id, &conf);
if (ret < 0) {
printf("Failed to configure cryptodev %u", cdev_id);
@@ -226,8 +229,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs,
for (j = 0; j < opts->nb_qps; j++) {
ret = rte_cryptodev_queue_pair_setup(cdev_id, j,
- &qp_conf, socket_id,
- session_pool_socket[socket_id]);
+ &qp_conf, socket_id);
if (ret < 0) {
printf("Failed to setup queue pair %u on "
"cryptodev %u", j, cdev_id);
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 8ee33c875..0bb6a8841 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -121,11 +121,21 @@ Each queue pairs resources may be allocated on a specified socket.
const struct rte_cryptodev_qp_conf *qp_conf,
int socket_id)
- struct rte_cryptodev_qp_conf {
+ struct rte_cryptodev_qp_conf {
uint32_t nb_descriptors; /**< Number of descriptors per queue pair */
+ struct rte_mempool *mp_session;
+ /**< The mempool for creating session in sessionless mode */
+ struct rte_mempool *mp_session_private;
+ /**< The mempool for creating sess private data in sessionless mode */
};
+The fields ``mp_session`` and ``mp_session_private`` are used for creating
+temporary session to process the crypto operations in the session-less mode.
+They can be the same other different mempools. Please note not all Cryptodev
+PMDs supports session-less mode.
+
+
Logical Cores, Memory and Queues Pair Relationships
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -682,14 +692,15 @@ using one of the crypto PMDs available in DPDK.
.socket_id = socket_id
};
struct rte_cryptodev_qp_conf qp_conf = {
- .nb_descriptors = 2048
+ .nb_descriptors = 2048,
+ .mp_session = session_pool,
+ .mp_session_private = session_pool
};
if (rte_cryptodev_configure(cdev_id, &conf) < 0)
rte_exit(EXIT_FAILURE, "Failed to configure cryptodev %u", cdev_id);
- if (rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
- socket_id, session_pool) < 0)
+ if (rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf, socket_id) < 0)
rte_exit(EXIT_FAILURE, "Failed to setup queue pair\n");
if (rte_cryptodev_start(cdev_id) < 0)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d4aea4b46..df12835eb 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -80,6 +80,3 @@ Deprecation Notices
- The size and layout of ``rte_cryptodev_sym_session`` will change
to fix existing issues.
- - The size and layout of ``rte_cryptodev_qp_conf`` and syntax of
- ``rte_cryptodev_queue_pair_setup`` will change to to allow to use
- two different mempools for crypto and device private sessions.
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index e3b2055d0..527705926 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -164,6 +164,9 @@ API Changes
``rte_pdump_init()`` and enum ``rte_pdump_socktype`` were deprecated
since 18.05 and are removed in this release.
+* cryptodev: The parameter ``session_pool`` in the function
+ ``rte_cryptodev_queue_pair_setup()`` is removed.
+
ABI Changes
-----------
@@ -183,6 +186,10 @@ ABI Changes
* mbuf: The format of the sched field of ``rte_mbuf`` has been changed
to include the following fields: ``queue ID``, ``traffic class``, ``color``.
+* cryptodev: as shown in the the 18.11 deprecation notice, the structure
+ ``rte_cryptodev_qp_conf`` has been added two parameters of symmetric session
+ mempool and symmetric session private data mempool.
+
Shared Library Versions
-----------------------
@@ -214,7 +221,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_cfgfile.so.2
librte_cmdline.so.2
librte_compressdev.so.1
- librte_cryptodev.so.5
+ + librte_cryptodev.so.6
librte_distributor.so.1
librte_eal.so.9
librte_efd.so.1
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index ebdf7c35a..abc7a6d5f 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -151,7 +151,8 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct aesni_gcm_session *)_sess_private_data;
@@ -159,7 +160,7 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_op *op)
if (unlikely(aesni_gcm_set_session_parameters(qp->ops,
sess, sym_op->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
sym_op->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -419,7 +420,7 @@ handle_completed_gcm_crypto_op(struct aesni_gcm_qp *qp,
memset(sess, 0, sizeof(struct aesni_gcm_session));
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sess);
+ rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
index cd15245bd..bf69dde54 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c
@@ -206,7 +206,7 @@ aesni_gcm_pmd_qp_create_processed_pkts_ring(struct aesni_gcm_qp *qp,
static int
aesni_gcm_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct aesni_gcm_qp *qp = NULL;
struct aesni_gcm_private *internals = dev->data->dev_private;
@@ -234,7 +234,8 @@ aesni_gcm_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_pkts == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
index 92b041354..903e7503d 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h
@@ -48,6 +48,8 @@ struct aesni_gcm_qp {
/**< Queue pair statistics */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
uint16_t id;
/**< Queue Pair Identifier */
char name[RTE_CRYPTODEV_NAME_MAX_LEN];
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index 83250e32c..b0f5c4d67 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -668,7 +668,8 @@ get_session(struct aesni_mb_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct aesni_mb_session *)_sess_private_data;
@@ -676,7 +677,7 @@ get_session(struct aesni_mb_qp *qp, struct rte_crypto_op *op)
if (unlikely(aesni_mb_set_session_parameters(qp->op_fns,
sess, op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -951,7 +952,7 @@ post_process_mb_job(struct aesni_mb_qp *qp, JOB_AES_HMAC *job)
memset(sess, 0, sizeof(struct aesni_mb_session));
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sess);
+ rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
index f3eff2685..af3021616 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
@@ -566,7 +566,7 @@ aesni_mb_pmd_qp_create_processed_ops_ring(struct aesni_mb_qp *qp,
static int
aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct aesni_mb_qp *qp = NULL;
struct aesni_mb_private *internals = dev->data->dev_private;
@@ -604,7 +604,8 @@ aesni_mb_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
goto qp_setup_cleanup;
}
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
index d8021cdaa..923403336 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
@@ -131,6 +131,8 @@ struct aesni_mb_qp {
/**< Ring for placing operations ready for processing */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats stats;
/**< Queue pair statistics */
uint8_t digest_idx;
diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
index 9d15fee53..3b2d7fb2f 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd.c
@@ -514,7 +514,8 @@ get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct armv8_crypto_session *)_sess_private_data;
@@ -522,7 +523,7 @@ get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op)
if (unlikely(armv8_crypto_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -656,7 +657,7 @@ process_op(struct armv8_crypto_qp *qp, struct rte_crypto_op *op,
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
rte_mempool_put(qp->sess_mp, sess);
- rte_mempool_put(qp->sess_mp, op->sym->session);
+ rte_mempool_put(qp->sess_mp_priv, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
index ae03117ea..a4fee83a8 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
+++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
@@ -220,7 +220,7 @@ armv8_crypto_pmd_qp_create_processed_ops_ring(struct armv8_crypto_qp *qp,
static int
armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct armv8_crypto_qp *qp = NULL;
@@ -245,7 +245,8 @@ armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
diff --git a/drivers/crypto/armv8/rte_armv8_pmd_private.h b/drivers/crypto/armv8/rte_armv8_pmd_private.h
index 7feb021db..0afd9c7c5 100644
--- a/drivers/crypto/armv8/rte_armv8_pmd_private.h
+++ b/drivers/crypto/armv8/rte_armv8_pmd_private.h
@@ -116,6 +116,8 @@ struct armv8_crypto_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats stats;
/**< Queue pair statistics */
char name[RTE_CRYPTODEV_NAME_MAX_LEN];
diff --git a/drivers/crypto/caam_jr/caam_jr.c b/drivers/crypto/caam_jr/caam_jr.c
index f505adf6b..45b281331 100644
--- a/drivers/crypto/caam_jr/caam_jr.c
+++ b/drivers/crypto/caam_jr/caam_jr.c
@@ -1540,8 +1540,7 @@ static int
caam_jr_queue_pair_setup(
struct rte_cryptodev *dev, uint16_t qp_id,
__rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
- __rte_unused int socket_id,
- __rte_unused struct rte_mempool *session_pool)
+ __rte_unused int socket_id)
{
struct sec_job_ring_t *internals;
struct caam_jr_qp *qp = NULL;
diff --git a/drivers/crypto/ccp/ccp_pmd_ops.c b/drivers/crypto/ccp/ccp_pmd_ops.c
index 6984913f1..d5041f0ec 100644
--- a/drivers/crypto/ccp/ccp_pmd_ops.c
+++ b/drivers/crypto/ccp/ccp_pmd_ops.c
@@ -685,7 +685,7 @@ ccp_pmd_qp_create_batch_info_ring(struct ccp_qp *qp,
static int
ccp_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct ccp_private *internals = dev->data->dev_private;
struct ccp_qp *qp;
@@ -726,7 +726,8 @@ ccp_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
goto qp_setup_cleanup;
}
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
/* mempool for batch info */
qp->batch_mp = rte_mempool_create(
diff --git a/drivers/crypto/ccp/ccp_pmd_private.h b/drivers/crypto/ccp/ccp_pmd_private.h
index 79752f687..7f2979e89 100644
--- a/drivers/crypto/ccp/ccp_pmd_private.h
+++ b/drivers/crypto/ccp/ccp_pmd_private.h
@@ -76,6 +76,8 @@ struct ccp_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_mempool *batch_mp;
/**< Session Mempool for batch info */
struct rte_cryptodev_stats qp_stats;
diff --git a/drivers/crypto/ccp/rte_ccp_pmd.c b/drivers/crypto/ccp/rte_ccp_pmd.c
index 92d8a9559..b4bb5528f 100644
--- a/drivers/crypto/ccp/rte_ccp_pmd.c
+++ b/drivers/crypto/ccp/rte_ccp_pmd.c
@@ -179,7 +179,7 @@ get_ccp_session(struct ccp_qp *qp, struct rte_crypto_op *op)
if (unlikely(ccp_set_session_parameters(sess, op->sym->xform,
internals) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -241,6 +241,13 @@ ccp_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
for (i = 0; i < nb_dequeued; i++)
if (unlikely(ops[i]->sess_type ==
RTE_CRYPTO_OP_SESSIONLESS)) {
+ struct ccp_session *sess = (struct ccp_session *)
+ get_sym_session_private_data(
+ ops[i]->sym->session,
+ ccp_cryptodev_driver_id);
+
+ rte_mempool_put(qp->sess_mp_priv,
+ sess);
rte_mempool_put(qp->sess_mp,
ops[i]->sym->session);
ops[i]->sym->session = NULL;
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 6095c6021..82220ac4f 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -1518,8 +1518,7 @@ dpaa2_sec_queue_pair_release(struct rte_cryptodev *dev, uint16_t queue_pair_id)
static int
dpaa2_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
__rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
- __rte_unused int socket_id,
- __rte_unused struct rte_mempool *session_pool)
+ __rte_unused int socket_id)
{
struct dpaa2_sec_dev_private *priv = dev->data->dev_private;
struct dpaa2_sec_qp *qp;
diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c
index d83e74541..c95e43b7f 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -1661,8 +1661,7 @@ dpaa_sec_queue_pair_release(struct rte_cryptodev *dev,
static int
dpaa_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
__rte_unused const struct rte_cryptodev_qp_conf *qp_conf,
- __rte_unused int socket_id,
- __rte_unused struct rte_mempool *session_pool)
+ __rte_unused int socket_id)
{
struct dpaa_sec_dev_private *internals;
struct dpaa_sec_qp *qp = NULL;
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd.c b/drivers/crypto/kasumi/rte_kasumi_pmd.c
index 239a1cf44..6df645a23 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd.c
@@ -145,7 +145,8 @@ kasumi_get_session(struct kasumi_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct kasumi_session *)_sess_private_data;
@@ -153,7 +154,7 @@ kasumi_get_session(struct kasumi_qp *qp, struct rte_crypto_op *op)
if (unlikely(kasumi_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -325,7 +326,7 @@ process_ops(struct rte_crypto_op **ops, struct kasumi_session *session,
memset(session, 0, sizeof(struct kasumi_session));
memset(ops[i]->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, session);
+ rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
}
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
index 9e4bf1b52..a4982f091 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_ops.c
@@ -192,7 +192,7 @@ kasumi_pmd_qp_create_processed_ops_ring(struct kasumi_qp *qp,
static int
kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct kasumi_qp *qp = NULL;
@@ -217,7 +217,8 @@ kasumi_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
index 488777ca8..76f746c03 100644
--- a/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
+++ b/drivers/crypto/kasumi/rte_kasumi_pmd_private.h
@@ -36,6 +36,8 @@ struct kasumi_qp {
/**< Ring for placing processed ops */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
uint8_t temp_digest[KASUMI_DIGEST_LENGTH];
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
index 9956f051f..ef520356f 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
@@ -633,7 +633,7 @@ mrvl_crypto_pmd_close(struct rte_cryptodev *dev)
static int
mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct mrvl_crypto_qp *qp = NULL;
char match[RTE_CRYPTODEV_NAME_MAX_LEN];
@@ -690,7 +690,8 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (sam_cio_init(&qp->cio_params, &qp->cio) < 0)
break;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
dev->data->queue_pairs[qp_id] = qp;
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
index 6f8cf5624..deb80c55d 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_private.h
@@ -51,6 +51,9 @@ struct mrvl_crypto_qp {
/** Session Mempool. */
struct rte_mempool *sess_mp;
+ /** Session Private Data Mempool. */
+ struct rte_mempool *sess_mp_priv;
+
/** Queue pair statistics. */
struct rte_cryptodev_stats stats;
diff --git a/drivers/crypto/null/null_crypto_pmd.c b/drivers/crypto/null/null_crypto_pmd.c
index 6e29a21a6..d5e3064f2 100644
--- a/drivers/crypto/null/null_crypto_pmd.c
+++ b/drivers/crypto/null/null_crypto_pmd.c
@@ -87,7 +87,8 @@ get_session(struct null_crypto_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct null_crypto_session *)_sess_private_data;
@@ -95,7 +96,7 @@ get_session(struct null_crypto_qp *qp, struct rte_crypto_op *op)
if (unlikely(null_crypto_set_session_parameters(sess,
sym_op->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
sym_op->session = (struct rte_cryptodev_sym_session *)_sess;
diff --git a/drivers/crypto/null/null_crypto_pmd_ops.c b/drivers/crypto/null/null_crypto_pmd_ops.c
index 2bdcd019e..941d62bed 100644
--- a/drivers/crypto/null/null_crypto_pmd_ops.c
+++ b/drivers/crypto/null/null_crypto_pmd_ops.c
@@ -184,7 +184,7 @@ null_crypto_pmd_qp_create_processed_pkts_ring(struct null_crypto_qp *qp,
static int
null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct null_crypto_private *internals = dev->data->dev_private;
struct null_crypto_qp *qp;
@@ -228,7 +228,8 @@ null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
goto qp_setup_cleanup;
}
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/null/null_crypto_pmd_private.h b/drivers/crypto/null/null_crypto_pmd_private.h
index d5905afd8..d7bfd9cc8 100644
--- a/drivers/crypto/null/null_crypto_pmd_private.h
+++ b/drivers/crypto/null/null_crypto_pmd_private.h
@@ -31,6 +31,8 @@ struct null_crypto_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
} __rte_cache_aligned;
diff --git a/drivers/crypto/octeontx/otx_cryptodev_ops.c b/drivers/crypto/octeontx/otx_cryptodev_ops.c
index 90d0c14b8..6a0cf83f4 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_ops.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_ops.c
@@ -186,8 +186,7 @@ static int
otx_cpt_que_pair_setup(struct rte_cryptodev *dev,
uint16_t que_pair_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id __rte_unused,
- struct rte_mempool *session_pool __rte_unused)
+ int socket_id __rte_unused)
{
void *cptvf = dev->data->dev_private;
struct cpt_instance *instance = NULL;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index a0ccacb1e..a193af642 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -768,7 +768,8 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct openssl_session *)_sess_private_data;
@@ -776,7 +777,7 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
if (unlikely(openssl_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -2020,7 +2021,7 @@ process_op(struct openssl_qp *qp, struct rte_crypto_op *op,
memset(sess, 0, sizeof(struct openssl_session));
memset(op->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sess);
+ rte_mempool_put(qp->sess_mp_priv, sess);
rte_mempool_put(qp->sess_mp, op->sym->session);
op->sym->session = NULL;
}
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index d382476a6..40217cf0d 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -715,7 +715,7 @@ openssl_pmd_qp_create_processed_ops_ring(struct openssl_qp *qp,
static int
openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct openssl_qp *qp = NULL;
@@ -740,7 +740,8 @@ openssl_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_private.h b/drivers/crypto/openssl/rte_openssl_pmd_private.h
index a8f2c8482..43ac3813d 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_private.h
+++ b/drivers/crypto/openssl/rte_openssl_pmd_private.h
@@ -64,6 +64,8 @@ struct openssl_qp {
/**< Ring for placing process packets */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats stats;
/**< Queue pair statistics */
uint8_t temp_digest[DIGEST_LENGTH_MAX];
diff --git a/drivers/crypto/qat/qat_sym_pmd.c b/drivers/crypto/qat/qat_sym_pmd.c
index c3f700406..31ccab32e 100644
--- a/drivers/crypto/qat/qat_sym_pmd.c
+++ b/drivers/crypto/qat/qat_sym_pmd.c
@@ -127,7 +127,7 @@ static int qat_sym_qp_release(struct rte_cryptodev *dev, uint16_t queue_pair_id)
static int qat_sym_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool __rte_unused)
+ int socket_id)
{
struct qat_qp *qp;
int ret = 0;
diff --git a/drivers/crypto/scheduler/scheduler_pmd_ops.c b/drivers/crypto/scheduler/scheduler_pmd_ops.c
index 939105aa8..cf70218b7 100644
--- a/drivers/crypto/scheduler/scheduler_pmd_ops.c
+++ b/drivers/crypto/scheduler/scheduler_pmd_ops.c
@@ -390,8 +390,7 @@ scheduler_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
/** Setup a queue pair */
static int
scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
- const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
- struct rte_mempool *session_pool)
+ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
{
struct scheduler_ctx *sched_ctx = dev->data->dev_private;
struct scheduler_qp_ctx *qp_ctx;
@@ -419,7 +418,7 @@ scheduler_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
* must be big enough for all the drivers used.
*/
ret = rte_cryptodev_queue_pair_setup(slave_id, qp_id,
- qp_conf, socket_id, session_pool);
+ qp_conf, socket_id);
if (ret < 0)
return ret;
}
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index a17536b77..7d131f780 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -147,7 +147,8 @@ snow3g_get_session(struct snow3g_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct snow3g_session *)_sess_private_data;
@@ -155,7 +156,7 @@ snow3g_get_session(struct snow3g_qp *qp, struct rte_crypto_op *op)
if (unlikely(snow3g_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -340,7 +341,7 @@ process_ops(struct rte_crypto_op **ops, struct snow3g_session *session,
memset(session, 0, sizeof(struct snow3g_session));
memset(ops[i]->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, session);
+ rte_mempool_put(qp->sess_mp_priv, session);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
}
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
index a367ee9a0..d2125233f 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_ops.c
@@ -198,7 +198,7 @@ snow3g_pmd_qp_create_processed_ops_ring(struct snow3g_qp *qp,
static int
snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct snow3g_qp *qp = NULL;
@@ -223,7 +223,8 @@ snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
index b7807b621..df5c6092b 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
@@ -36,6 +36,8 @@ struct snow3g_qp {
/**< Ring for placing processed ops */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
uint8_t temp_digest[SNOW3G_DIGEST_LENGTH];
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 568b5a406..4bae3b865 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -36,8 +36,7 @@ static void virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev);
static int virtio_crypto_qp_setup(struct rte_cryptodev *dev,
uint16_t queue_pair_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id,
- struct rte_mempool *session_pool);
+ int socket_id);
static int virtio_crypto_qp_release(struct rte_cryptodev *dev,
uint16_t queue_pair_id);
static void virtio_crypto_dev_free_mbufs(struct rte_cryptodev *dev);
@@ -585,8 +584,7 @@ virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev)
static int
virtio_crypto_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id,
- struct rte_mempool *session_pool __rte_unused)
+ int socket_id)
{
int ret;
struct virtqueue *vq;
diff --git a/drivers/crypto/zuc/rte_zuc_pmd.c b/drivers/crypto/zuc/rte_zuc_pmd.c
index 313f4590b..997c2092f 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd.c
@@ -144,7 +144,8 @@ zuc_get_session(struct zuc_qp *qp, struct rte_crypto_op *op)
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
return NULL;
- if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data))
+ if (rte_mempool_get(qp->sess_mp_priv,
+ (void **)&_sess_private_data))
return NULL;
sess = (struct zuc_session *)_sess_private_data;
@@ -152,7 +153,7 @@ zuc_get_session(struct zuc_qp *qp, struct rte_crypto_op *op)
if (unlikely(zuc_set_session_parameters(sess,
op->sym->xform) != 0)) {
rte_mempool_put(qp->sess_mp, _sess);
- rte_mempool_put(qp->sess_mp, _sess_private_data);
+ rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
sess = NULL;
}
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
@@ -327,7 +328,7 @@ process_ops(struct rte_crypto_op **ops, enum zuc_operation op_type,
memset(sessions[i], 0, sizeof(struct zuc_session));
memset(ops[i]->sym->session, 0,
rte_cryptodev_sym_get_header_session_size());
- rte_mempool_put(qp->sess_mp, sessions[i]);
+ rte_mempool_put(qp->sess_mp_priv, sessions[i]);
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
ops[i]->sym->session = NULL;
}
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_ops.c b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
index 04d45e449..1b88947eb 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_ops.c
+++ b/drivers/crypto/zuc/rte_zuc_pmd_ops.c
@@ -198,7 +198,7 @@ zuc_pmd_qp_create_processed_ops_ring(struct zuc_qp *qp,
static int
zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct zuc_qp *qp = NULL;
@@ -223,7 +223,8 @@ zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
if (qp->processed_ops == NULL)
goto qp_setup_cleanup;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
diff --git a/drivers/crypto/zuc/rte_zuc_pmd_private.h b/drivers/crypto/zuc/rte_zuc_pmd_private.h
index 5e5906ddb..aa73c0016 100644
--- a/drivers/crypto/zuc/rte_zuc_pmd_private.h
+++ b/drivers/crypto/zuc/rte_zuc_pmd_private.h
@@ -36,6 +36,8 @@ struct zuc_qp {
/**< Ring for placing processed ops */
struct rte_mempool *sess_mp;
/**< Session Mempool */
+ struct rte_mempool *sess_mp_priv;
+ /**< Session Private Data Mempool */
struct rte_cryptodev_stats qp_stats;
/**< Queue pair statistics */
uint8_t temp_digest[ZUC_DIGEST_LENGTH];
diff --git a/drivers/net/softnic/rte_eth_softnic_cryptodev.c b/drivers/net/softnic/rte_eth_softnic_cryptodev.c
index 1480f6dd5..f031d8803 100644
--- a/drivers/net/softnic/rte_eth_softnic_cryptodev.c
+++ b/drivers/net/softnic/rte_eth_softnic_cryptodev.c
@@ -101,7 +101,7 @@ softnic_cryptodev_create(struct pmd_internals *p,
queue_conf.nb_descriptors = params->queue_size;
for (i = 0; i < params->n_queues; i++) {
status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id, NULL);
+ &queue_conf, socket_id);
if (status < 0)
return NULL;
}
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index e7559c633..384b7a240 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -39,7 +39,7 @@ static int
cryptodev_fips_validate_app_int(void)
{
struct rte_cryptodev_config conf = {rte_socket_id(), 1};
- struct rte_cryptodev_qp_conf qp_conf = {128};
+ struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL};
int ret;
ret = rte_cryptodev_configure(env.dev_id, &conf);
@@ -52,7 +52,7 @@ cryptodev_fips_validate_app_int(void)
return ret;
ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
- rte_socket_id(), env.mpool);
+ rte_socket_id());
if (ret < 0)
return ret;
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
index c4ba72bec..b365810de 100644
--- a/examples/ip_pipeline/cryptodev.c
+++ b/examples/ip_pipeline/cryptodev.c
@@ -93,7 +93,7 @@ cryptodev_create(const char *name, struct cryptodev_params *params)
queue_conf.nb_descriptors = params->queue_size;
for (i = 0; i < params->n_queues; i++) {
status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id, NULL);
+ &queue_conf, socket_id);
if (status < 0)
return NULL;
}
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 1bc0b5b50..a0ff8f7f7 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -1493,10 +1493,13 @@ cryptodevs_init(void)
cdev_id);
qp_conf.nb_descriptors = CDEV_QUEUE_DESC;
+ qp_conf.mp_session =
+ socket_ctx[dev_conf.socket_id].session_pool;
+ qp_conf.mp_session_private =
+ socket_ctx[dev_conf.socket_id].session_pool;
for (qp = 0; qp < dev_conf.nb_queue_pairs; qp++)
if (rte_cryptodev_queue_pair_setup(cdev_id, qp,
- &qp_conf, dev_conf.socket_id,
- socket_ctx[dev_conf.socket_id].session_pool))
+ &qp_conf, dev_conf.socket_id))
rte_panic("Failed to setup queue %u for "
"cdev_id %u\n", 0, cdev_id);
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index f12fd266e..1df7ba743 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -2443,9 +2443,11 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
}
qp_conf.nb_descriptors = 2048;
+ qp_conf.mp_session = session_pool_socket[socket_id];
+ qp_conf.mp_session_private = session_pool_socket[socket_id];
retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
- socket_id, session_pool_socket[socket_id]);
+ socket_id);
if (retval < 0) {
printf("Failed to setup queue pair %u on cryptodev %u",
0, cdev_id);
diff --git a/examples/vhost_crypto/main.c b/examples/vhost_crypto/main.c
index 3deb5263f..cb30f84c0 100644
--- a/examples/vhost_crypto/main.c
+++ b/examples/vhost_crypto/main.c
@@ -463,7 +463,7 @@ free_resource(void)
int
main(int argc, char *argv[])
{
- struct rte_cryptodev_qp_conf qp_conf = {NB_CRYPTO_DESCRIPTORS};
+ struct rte_cryptodev_qp_conf qp_conf;
struct rte_cryptodev_config config;
struct rte_cryptodev_info dev_info;
char name[128];
@@ -551,11 +551,14 @@ main(int argc, char *argv[])
options.infos[i] = info;
+ qp_conf.nb_descriptors = NB_CRYPTO_DESCRIPTORS;
+ qp_conf.mp_session = info->sess_pool;
+ qp_conf.mp_session_private = info->sess_pool;
+
for (j = 0; j < dev_info.max_nb_queue_pairs; j++) {
ret = rte_cryptodev_queue_pair_setup(info->cid, j,
&qp_conf, rte_lcore_to_socket_id(
- lo->lcore_id),
- info->sess_pool);
+ lo->lcore_id));
if (ret < 0) {
RTE_LOG(ERR, USER1, "Failed to configure qp\n");
goto error_exit;
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index a8f94c097..e38018183 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2015 Intel Corporation
+# Copyright(c) 2015-2019 Intel Corporation
include $(RTE_SDK)/mk/rte.vars.mk
@@ -7,7 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_cryptodev.a
# library version
-LIBABIVER := 5
+LIBABIVER := 6
# build flags
CFLAGS += -O3
diff --git a/lib/librte_cryptodev/meson.build b/lib/librte_cryptodev/meson.build
index 990dd3d44..44bd83212 100644
--- a/lib/librte_cryptodev/meson.build
+++ b/lib/librte_cryptodev/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017 Intel Corporation
+# Copyright(c) 2017-2019 Intel Corporation
-version = 5
+version = 6
sources = files('rte_cryptodev.c', 'rte_cryptodev_pmd.c')
headers = files('rte_cryptodev.h',
'rte_cryptodev_pmd.h',
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index a52eaaa45..4929d0451 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -941,8 +941,7 @@ rte_cryptodev_close(uint8_t dev_id)
int
rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
- const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
- struct rte_mempool *session_pool)
+ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
{
struct rte_cryptodev *dev;
@@ -958,6 +957,17 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
return -EINVAL;
}
+ if (!qp_conf) {
+ CDEV_LOG_ERR("qp_conf cannot be NULL\n");
+ return -EINVAL;
+ }
+
+ if ((qp_conf->mp_session && !qp_conf->mp_session_private) ||
+ (!qp_conf->mp_session && qp_conf->mp_session_private)) {
+ CDEV_LOG_ERR("Invalid mempools\n");
+ return -EINVAL;
+ }
+
if (dev->data->dev_started) {
CDEV_LOG_ERR(
"device %d must be stopped to allow configuration", dev_id);
@@ -967,7 +977,7 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_setup, -ENOTSUP);
return (*dev->dev_ops->queue_pair_setup)(dev, queue_pair_id, qp_conf,
- socket_id, session_pool);
+ socket_id);
}
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 4099823f1..f9e7507da 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -495,6 +495,10 @@ enum rte_cryptodev_event_type {
/** Crypto device queue pair configuration structure. */
struct rte_cryptodev_qp_conf {
uint32_t nb_descriptors; /**< Number of descriptors per queue pair */
+ struct rte_mempool *mp_session;
+ /**< The mempool for creating session in sessionless mode */
+ struct rte_mempool *mp_session_private;
+ /**< The mempool for creating sess private data in sessionless mode */
};
/**
@@ -689,8 +693,7 @@ rte_cryptodev_close(uint8_t dev_id);
*/
extern int
rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
- const struct rte_cryptodev_qp_conf *qp_conf, int socket_id,
- struct rte_mempool *session_pool);
+ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id);
/**
* Get the number of queue pairs on a specific crypto device
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index 1b6cafd17..f15c9af30 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -188,13 +188,12 @@ typedef void (*cryptodev_info_get_t)(struct rte_cryptodev *dev,
* @param qp_id Queue Pair Index
* @param qp_conf Queue configuration structure
* @param socket_id Socket Index
- * @param session_pool Pointer to device session mempool
*
* @return Returns 0 on success.
*/
typedef int (*cryptodev_queue_pair_setup_t)(struct rte_cryptodev *dev,
uint16_t qp_id, const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool);
+ int socket_id);
/**
* Release memory resources allocated by given queue pair.
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 84065eb49..aac0b1f0b 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -461,12 +461,13 @@ testsuite_setup(void)
dev_id, ts_params->conf.nb_queue_pairs);
ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+ ts_params->qp_conf.mp_session = ts_params->session_mpool;
+ ts_params->qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
dev_id, qp_id, &ts_params->qp_conf,
- rte_cryptodev_socket_id(dev_id),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(dev_id)),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, dev_id);
}
@@ -519,8 +520,7 @@ ut_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id,
&ts_params->qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
}
@@ -709,13 +709,14 @@ test_queue_pair_descriptor_setup(void)
* freed so are re-used if ring is released and re-created.
*/
qp_conf.nb_descriptors = MIN_NUM_OPS_INFLIGHT; /* min size*/
+ qp_conf.mp_session = ts_params->session_mpool;
+ qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for "
"rte_cryptodev_queue_pair_setup: num_inflights "
"%u on qp %u on cryptodev %u",
@@ -729,8 +730,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for"
" rte_cryptodev_queue_pair_setup: num_inflights"
" %u on qp %u on cryptodev %u",
@@ -744,8 +744,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for "
"rte_cryptodev_queue_pair_setup: num_inflights"
" %u on qp %u on cryptodev %u",
@@ -760,8 +759,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Unexpectedly passed test for "
"rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -776,8 +774,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Unexpectedly passed test for "
"rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -791,8 +788,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Failed test for"
" rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -807,8 +803,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id, &qp_conf,
rte_cryptodev_socket_id(
- ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ ts_params->valid_devs[0])),
"Unexpectedly passed test for "
"rte_cryptodev_queue_pair_setup:"
"num_inflights %u on qp %u on cryptodev %u",
@@ -824,8 +819,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0],
qp_id, &qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed test for rte_cryptodev_queue_pair_setup:"
"invalid qp %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
@@ -835,8 +829,7 @@ test_queue_pair_descriptor_setup(void)
TEST_ASSERT_FAIL(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0],
qp_id, &qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed test for rte_cryptodev_queue_pair_setup:"
"invalid qp %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
diff --git a/test/test/test_cryptodev_asym.c b/test/test/test_cryptodev_asym.c
index a899f9973..0f6fc5767 100644
--- a/test/test/test_cryptodev_asym.c
+++ b/test/test/test_cryptodev_asym.c
@@ -383,11 +383,12 @@ testsuite_setup(void)
/* configure qp */
ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+ ts_params->qp_conf.mp_session = ts_params->session_mpool;
+ ts_params->qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
dev_id, qp_id, &ts_params->qp_conf,
- rte_cryptodev_socket_id(dev_id),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(dev_id)),
"Failed to setup queue pair %u on cryptodev %u ASYM",
qp_id, dev_id);
}
@@ -449,8 +450,7 @@ ut_setup(void)
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id,
&ts_params->qp_conf,
- rte_cryptodev_socket_id(ts_params->valid_devs[0]),
- ts_params->session_mpool),
+ rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
}
diff --git a/test/test/test_event_crypto_adapter.c b/test/test/test_event_crypto_adapter.c
index de258c346..54717870e 100644
--- a/test/test/test_event_crypto_adapter.c
+++ b/test/test/test_event_crypto_adapter.c
@@ -546,11 +546,12 @@ configure_cryptodev(void)
TEST_CDEV_ID, conf.nb_queue_pairs);
qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
+ qp_conf.mp_session = params.session_mpool;
+ qp_conf.mp_session_private = params.session_mpool;
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
TEST_CDEV_ID, TEST_CDEV_QP_ID, &qp_conf,
- rte_cryptodev_socket_id(TEST_CDEV_ID),
- params.session_mpool),
+ rte_cryptodev_socket_id(TEST_CDEV_ID)),
"Failed to setup queue pair %u on cryptodev %u\n",
TEST_CDEV_QP_ID, TEST_CDEV_ID);
--
2.13.6
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v5 02/12] cryptodev: add sym session mempool create
2019-01-10 14:50 3% ` [dpdk-dev] [PATCH v5 01/12] cryptodev: change queue pair configure structure Fan Zhang
@ 2019-01-10 14:50 3% ` Fan Zhang
2019-01-10 14:50 5% ` [dpdk-dev] [PATCH v5 09/12] cryptodev: update symmetric session structure Fan Zhang
2 siblings, 0 replies; 200+ results
From: Fan Zhang @ 2019-01-10 14:50 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, fiona.trahe
This patch adds a new API "rte_cryptodev_sym_session_pool_create()" to
cryptodev library. All applications are required to use this API to
create sym session mempool as it adds private data and nb_drivers
information to the mempool private data.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
---
doc/guides/prog_guide/cryptodev_lib.rst | 69 ++++++++++++++++++--------
doc/guides/rel_notes/release_19_02.rst | 5 ++
lib/librte_cryptodev/rte_cryptodev.c | 50 +++++++++++++++++++
lib/librte_cryptodev/rte_cryptodev.h | 31 ++++++++++++
lib/librte_cryptodev/rte_cryptodev_version.map | 1 +
5 files changed, 134 insertions(+), 22 deletions(-)
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 0bb6a8841..f68fb72d3 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -455,21 +455,23 @@ Crypto workloads.
.. figure:: img/cryptodev_sym_sess.*
-The Crypto device framework provides APIs to allocate and initialize sessions
-for crypto devices, where sessions are mempool objects.
-It is the application's responsibility to create and manage the session mempools.
-This approach allows for different scenarios such as having a single session
-mempool for all crypto devices (where the mempool object size is big
-enough to hold the private session of any crypto device), as well as having
-multiple session mempools of different sizes for better memory usage.
-
-An application can use ``rte_cryptodev_sym_get_private_session_size()`` to
-get the private session size of given crypto device. This function would allow
-an application to calculate the max device session size of all crypto devices
-to create a single session mempool.
-If instead an application creates multiple session mempools, the Crypto device
-framework also provides ``rte_cryptodev_sym_get_header_session_size`` to get
-the size of an uninitialized session.
+The Crypto device framework provides APIs to create session mempool and allocate
+and initialize sessions for crypto devices, where sessions are mempool objects.
+The application has to use ``rte_cryptodev_sym_session_pool_create()`` to
+create the session header mempool that creates a mempool with proper element
+size automatically and stores necessary information for safely accessing the
+session in the mempool's private data field.
+
+To create a mempool for storing session private data, the application has two
+options. The first is to create another mempool with elt size equal to or
+bigger than the maximum session private data size of all crypto devices that
+will share the same session header. The creation of the mempool shall use the
+traditional ``rte_mempool_create()`` with the correct ``elt_size``. The other
+option is to change the ``elt_size`` parameter in
+``rte_cryptodev_sym_session_pool_create()`` to the correct value. The first
+option is more complex to implement but may result in better memory usage as
+a session header normally takes smaller memory footprint as the session private
+data.
Once the session mempools have been created, ``rte_cryptodev_sym_session_create()``
is used to allocate an uninitialized session from the given mempool.
@@ -623,7 +625,8 @@ using one of the crypto PMDs available in DPDK.
#define IV_OFFSET (sizeof(struct rte_crypto_op) + \
sizeof(struct rte_crypto_sym_op))
- struct rte_mempool *mbuf_pool, *crypto_op_pool, *session_pool;
+ struct rte_mempool *mbuf_pool, *crypto_op_pool;
+ struct rte_mempool *session_pool, *session_priv_pool;
unsigned int session_size;
int ret;
@@ -673,28 +676,50 @@ using one of the crypto PMDs available in DPDK.
/* Get private session data size. */
session_size = rte_cryptodev_sym_get_private_session_size(cdev_id);
+ #ifdef USE_TWO_MEMPOOLS
+ /* Create session mempool for the session header. */
+ session_pool = rte_cryptodev_sym_session_pool_create("session_pool",
+ MAX_SESSIONS,
+ 0,
+ POOL_CACHE_SIZE,
+ 0,
+ socket_id);
+
/*
- * Create session mempool, with two objects per session,
- * one for the session header and another one for the
+ * Create session private data mempool for the
* private session data for the crypto device.
*/
- session_pool = rte_mempool_create("session_pool",
- MAX_SESSIONS * 2,
+ session_priv_pool = rte_mempool_create("session_pool",
+ MAX_SESSIONS,
session_size,
POOL_CACHE_SIZE,
0, NULL, NULL, NULL,
NULL, socket_id,
0);
+ #else
+ /* Use of the same mempool for session header and private data */
+ session_pool = rte_cryptodev_sym_session_pool_create("session_pool",
+ MAX_SESSIONS * 2,
+ session_size,
+ POOL_CACHE_SIZE,
+ 0,
+ socket_id);
+
+ session_priv_pool = session_pool;
+
+ #endif
+
/* Configure the crypto device. */
struct rte_cryptodev_config conf = {
.nb_queue_pairs = 1,
.socket_id = socket_id
};
+
struct rte_cryptodev_qp_conf qp_conf = {
.nb_descriptors = 2048,
.mp_session = session_pool,
- .mp_session_private = session_pool
+ .mp_session_private = session_priv_pool
};
if (rte_cryptodev_configure(cdev_id, &conf) < 0)
@@ -732,7 +757,7 @@ using one of the crypto PMDs available in DPDK.
rte_exit(EXIT_FAILURE, "Session could not be created\n");
if (rte_cryptodev_sym_session_init(cdev_id, session,
- &cipher_xform, session_pool) < 0)
+ &cipher_xform, session_priv_pool) < 0)
rte_exit(EXIT_FAILURE, "Session could not be initialized "
"for the crypto device\n");
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 527705926..ace4bcfe7 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -167,6 +167,11 @@ API Changes
* cryptodev: The parameter ``session_pool`` in the function
``rte_cryptodev_queue_pair_setup()`` is removed.
+* cryptodev: a new function ``rte_cryptodev_sym_session_pool_create()`` is
+ introduced. This function is now mandatory when creating symmetric session
+ header mempool. Please note all crypto applications are required to use this
+ function from now on.
+
ABI Changes
-----------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 4929d0451..ccc4c2132 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -189,6 +189,16 @@ const char *rte_crypto_asym_op_strings[] = {
[RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE] = "sharedsecret_compute",
};
+/**
+ * The private data structure stored in the session mempool private data.
+ */
+struct rte_cryptodev_sym_session_pool_private_data {
+ uint16_t nb_drivers;
+ /**< number of elements in sess_data array */
+ uint16_t user_data_sz;
+ /**< session user data will be placed after sess_data */
+};
+
int
rte_cryptodev_get_cipher_algo_enum(enum rte_crypto_cipher_algorithm *algo_enum,
const char *algo_string)
@@ -1223,6 +1233,46 @@ rte_cryptodev_asym_session_init(uint8_t dev_id,
return 0;
}
+struct rte_mempool * __rte_experimental
+rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
+ uint32_t elt_size, uint32_t cache_size, uint16_t user_data_size,
+ int socket_id)
+{
+ struct rte_mempool *mp;
+ struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
+ uint32_t obj_sz;
+
+ obj_sz = rte_cryptodev_sym_get_header_session_size() + user_data_size;
+ if (obj_sz > elt_size)
+ CDEV_LOG_INFO("elt_size %u is expanded to %u\n", elt_size,
+ obj_sz);
+ else
+ obj_sz = elt_size;
+
+ mp = rte_mempool_create(name, nb_elts, obj_sz, cache_size,
+ (uint32_t)(sizeof(*pool_priv)),
+ NULL, NULL, NULL, NULL,
+ socket_id, 0);
+ if (mp == NULL) {
+ CDEV_LOG_ERR("%s(name=%s) failed, rte_errno=%d\n",
+ __func__, name, rte_errno);
+ return NULL;
+ }
+
+ pool_priv = rte_mempool_get_priv(mp);
+ if (!pool_priv) {
+ CDEV_LOG_ERR("%s(name=%s) failed to get private data\n",
+ __func__, name);
+ rte_mempool_free(mp);
+ return NULL;
+ }
+
+ pool_priv->nb_drivers = nb_drivers;
+ pool_priv->user_data_sz = user_data_size;
+
+ return mp;
+}
+
struct rte_cryptodev_sym_session *
rte_cryptodev_sym_session_create(struct rte_mempool *mp)
{
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index f9e7507da..052213e1f 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -968,6 +968,37 @@ struct rte_cryptodev_asym_session {
};
/**
+ * Create a symmetric session mempool.
+ *
+ * @param name
+ * The unique mempool name.
+ * @param nb_elts
+ * The number of elements in the mempool.
+ * @param elt_size
+ * The size of the element. This value will be ignored if it is smaller than
+ * the minimum session header size required for the system. For the user who
+ * want to use the same mempool for sym session and session private data it
+ * can be the maximum value of all existing devices' private data and session
+ * header sizes.
+ * @param cache_size
+ * The number of per-lcore cache elements
+ * @param priv_size
+ * The private data size of each session.
+ * @param socket_id
+ * The *socket_id* argument is the socket identifier in the case of
+ * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
+ * constraint for the reserved zone.
+ *
+ * @return
+ * - On success return size of the session
+ * - On failure returns 0
+ */
+struct rte_mempool * __rte_experimental
+rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
+ uint32_t elt_size, uint32_t cache_size, uint16_t priv_size,
+ int socket_id);
+
+/**
* Create symmetric crypto session header (generic with no private data)
*
* @param mempool Symmetric session mempool to allocate session
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index a695b61dc..5609da04b 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -102,6 +102,7 @@ EXPERIMENTAL {
rte_cryptodev_asym_xform_capability_check_modlen;
rte_cryptodev_asym_xform_capability_check_optype;
rte_cryptodev_sym_session_get_user_data;
+ rte_cryptodev_sym_session_pool_create;
rte_cryptodev_sym_session_set_user_data;
rte_crypto_asym_op_strings;
rte_crypto_asym_xform_strings;
--
2.13.6
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v5 09/12] cryptodev: update symmetric session structure
2019-01-10 14:50 3% ` [dpdk-dev] [PATCH v5 01/12] cryptodev: change queue pair configure structure Fan Zhang
2019-01-10 14:50 3% ` [dpdk-dev] [PATCH v5 02/12] cryptodev: add sym session mempool create Fan Zhang
@ 2019-01-10 14:50 5% ` Fan Zhang
2 siblings, 0 replies; 200+ results
From: Fan Zhang @ 2019-01-10 14:50 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, fiona.trahe
This patch updates the rte_cryptodev_sym_session structure for
cryptodev library. The updates include a changed session private
data array and an added nb_drivers field. They are used to
calculate the correct session header size and ensure safe access
of the session private data.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
---
doc/guides/prog_guide/img/cryptodev_sym_sess.svg | 701 ++++++++++++-----------
doc/guides/rel_notes/deprecation.rst | 6 -
doc/guides/rel_notes/release_19_02.rst | 7 +-
lib/librte_cryptodev/rte_cryptodev.c | 100 +++-
lib/librte_cryptodev/rte_cryptodev.h | 8 +-
lib/librte_cryptodev/rte_cryptodev_pmd.h | 13 +-
6 files changed, 444 insertions(+), 391 deletions(-)
diff --git a/doc/guides/prog_guide/img/cryptodev_sym_sess.svg b/doc/guides/prog_guide/img/cryptodev_sym_sess.svg
index a807cebac..5c843f736 100644
--- a/doc/guides/prog_guide/img/cryptodev_sym_sess.svg
+++ b/doc/guides/prog_guide/img/cryptodev_sym_sess.svg
@@ -19,33 +19,31 @@
id="svg70"
sodipodi:docname="cryptodev_sym_sess.svg"
style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-rule:evenodd;stroke-linecap:square;stroke-miterlimit:3"
- inkscape:version="0.92.1 r15371"><metadata
- id="metadata74"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="1051"
- id="namedview72"
- showgrid="false"
- inkscape:zoom="1.7495789"
- inkscape:cx="208.74719"
- inkscape:cy="216.52777"
- inkscape:window-x="-9"
- inkscape:window-y="-9"
- inkscape:window-maximized="0"
- inkscape:current-layer="g68-0" />
- <style
- type="text/css"
- id="style2">
- <![CDATA[
+ inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"><metadata
+ id="metadata74"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="956"
+ id="namedview72"
+ showgrid="false"
+ inkscape:zoom="1.7495789"
+ inkscape:cx="208.74719"
+ inkscape:cy="216.52777"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="shape18-1-4" /><style
+ type="text/css"
+ id="style2"><![CDATA[
.st1 {fill:url(#grad0-4);stroke:#386288;stroke-width:0.75}
.st2 {fill:#386288;font-family:Calibri;font-size:0.833336em}
.st3 {visibility:visible}
@@ -56,337 +54,340 @@
.st8 {font-size:0.799995em}
.st9 {font-size:0.799995em;font-weight:bold}
.st10 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
- ]]>
- </style>
-
- <defs
- id="Patterns_And_Gradients"><marker
- inkscape:isstock="true"
- style="overflow:visible"
- id="marker5421"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow2Lend"><path
- transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- style="fill:#41719c;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
- id="path5419"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:stockid="Arrow2Lend"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow2Lend"
- style="overflow:visible"
- inkscape:isstock="true"><path
- id="path5004"
- style="fill:#41719c;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:stockid="Arrow1Lend"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Lend"
- style="overflow:visible"
- inkscape:isstock="true"><path
- id="path4986"
- d="M 0,0 5,-5 -12.5,0 5,5 Z"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
- transform="matrix(-0.8,0,0,-0.8,-10,0)"
- inkscape:connector-curvature="0" /></marker>
- <linearGradient
- id="grad0-4"
- x1="0"
- y1="0"
- x2="1"
- y2="0"
- gradientTransform="rotate(60,0.5,0.5)">
- <stop
- offset="0"
- stop-color="#e8ebef"
- stop-opacity="1"
- id="stop4" />
- <stop
- offset="0.24"
- stop-color="#f4f5f7"
- stop-opacity="1"
- id="stop6" />
- <stop
- offset="0.54"
- stop-color="#feffff"
- stop-opacity="1"
- id="stop8" />
- </linearGradient>
- <filter
- id="filter_2-4"><feGaussianBlur
- stdDeviation="2"
- id="feGaussianBlur12-0" /></filter><linearGradient
- inkscape:collect="always"
- xlink:href="#grad0-4"
- id="linearGradient189"
- gradientTransform="scale(0.8787489,1.1379815)"
- x1="-0.42674366"
- y1="0.98859203"
- x2="176.71146"
- y2="0.98859203"
- gradientUnits="userSpaceOnUse" /><filter
- id="filter_2-5"><feGaussianBlur
- stdDeviation="2"
- id="feGaussianBlur12-8" /></filter><filter
- id="filter_2-3"><feGaussianBlur
- stdDeviation="2"
- id="feGaussianBlur12-2" /></filter><linearGradient
- inkscape:collect="always"
- xlink:href="#grad0-4"
- id="linearGradient189-7"
- gradientTransform="scale(0.8787489,1.1379815)"
- x1="-0.42674366"
- y1="0.98859203"
- x2="176.71146"
- y2="0.98859203"
- gradientUnits="userSpaceOnUse" /><linearGradient
- inkscape:collect="always"
- xlink:href="#grad0-4"
- id="linearGradient500"
- gradientTransform="matrix(0.8787489,0,0,1.1379815,12.431599,21.739241)"
- x1="-0.42674366"
- y1="0.98859203"
- x2="176.71146"
- y2="0.98859203"
- gradientUnits="userSpaceOnUse" /></defs>
- <defs
- id="Filters">
- <filter
- id="filter_2">
- <feGaussianBlur
- stdDeviation="2"
- id="feGaussianBlur12" />
- </filter>
- </defs>
- <g
- id="g68"
- transform="matrix(1,0,0,0.41409874,-12.807629,-5.4621159)">
- <title
- id="title16">Page-1</title>
- <g
- id="shape18-1"
- transform="translate(0.749889,-0.75)">
- <title
- id="title18">Rounded Rectangle.12</title>
- <desc
- id="desc20">Crypto Symmetric Session</desc>
- <path
- d="M 19.211599,224.06924 H 160.5716 a 6.77735,6.77735 0 0 0 6.77,-6.77 V 30.019241 a 6.77735,6.77735 0 0 0 -6.77,-6.78 H 19.211599 a 6.77735,6.77735 0 0 0 -6.78,6.78 V 217.29924 a 6.77735,6.77735 0 0 0 6.78,6.77 z"
- class="st1"
- id="path22"
- style="fill:url(#linearGradient500);stroke:#386288;stroke-width:0.75"
- inkscape:connector-curvature="0" />
- <text
- x="63.123039"
- y="28.531481"
- class="st2"
- id="text24"
- style="font-size:16.97244835px;font-family:Calibri;fill:#386288;stroke-width:1.69723928"
- transform="scale(0.58919214,1.6972392)">Crypto Symmetric Session</text>
-
- </g>
- <g
- id="shape19-6"
- transform="translate(10.6711,-9.82087)">
- <title
- id="title27">Rounded Rectangle.13</title>
- <desc
- id="desc29">Private Session Data</desc>
- </g>
- <g
- id="shape20-12"
- transform="matrix(1,0,0,2.5278193,23.531375,-309.78186)">
- <title
- id="title39">Rounded Rectangle.15</title>
- <desc
- id="desc41">void *sess_private_data[]</desc>
- <path
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -36.37 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,160.06 v 36.37 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st7"
- id="path43"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:#41719c;stroke-width:0.75" />
- <text
- x="14.072042"
- y="159.1931"
- class="st6"
- id="text65"
- style="font-size:11.41061592px;font-family:Calibri;fill:#41719c;stroke-width:1.14105785"
- transform="scale(0.92359087,1.0827305)">void *sess_private_data[] <tspan
- x="-3.5230706"
- class="st9"
- id="tspan47"
- style="font-weight:bold;font-size:9.12843513px;stroke-width:1.14105785" /></text>
-
- <rect
- style="fill:none;fill-opacity:1;stroke:#41719c;stroke-width:0.73305672;stroke-opacity:1"
- id="rect4604"
- width="15.968175"
- height="14.230948"
- x="13.494645"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7"
- width="15.968174"
- height="14.230948"
- x="29.46282"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6"
- width="15.968174"
- height="14.230948"
- x="45.430992"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6-9"
- width="15.968174"
- height="14.230948"
- x="61.399166"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6-9-8"
- width="15.968174"
- height="14.230948"
- x="77.36734"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6-9-8-9"
- width="15.968174"
- height="14.230948"
- x="93.33551"
- y="181.68814" /><rect
- style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.73305672;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1"
- id="rect4604-7-6-9-8-9-6"
- width="15.968174"
- height="14.230948"
- x="109.30369"
- y="181.68814" /><path
- style="fill:none;fill-opacity:1;stroke:#41719c;stroke-width:0.72427988px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
- d="m 117.64885,196.01764 0.22164,18.77485 44.6966,-0.0725 -0.22163,-20.00716 16.84434,0.43494"
- id="path5030"
- inkscape:connector-curvature="0" /></g>
- </g>
-<g
- transform="translate(190.70887,-0.53319281)"
- id="g68-0"><title
- id="title16-2">Page-1</title><g
- id="shape18-1-4"
- transform="matrix(1,0,0,0.57815109,0.749889,-0.11722686)"><title
- id="title18-4">Rounded Rectangle.12</title><desc
- id="desc20-6">Crypto Symmetric Session</desc><path
- inkscape:connector-curvature="0"
- d="m 6.78,202.33 h 141.36 a 6.77735,6.77735 -180 0 0 6.77,-6.77 V 8.28 A 6.77735,6.77735 -180 0 0 148.14,1.5 H 6.78 A 6.77735,6.77735 -180 0 0 0,8.28 v 187.28 a 6.77735,6.77735 -180 0 0 6.78,6.77 z"
- class="st1"
- id="path22-0"
- style="fill:url(#linearGradient189);stroke:#386288;stroke-width:0.75" /><text
- x="26.317923"
- y="17.335487"
- class="st2"
- id="text24-5"
- style="font-size:14.02988338px;font-family:Calibri;fill:#386288;stroke-width:1.40298378"
- transform="scale(0.71276665,1.4029837)">Crypto Driver Private Session</text>
-
-</g><g
- id="shape19-6-5"
- transform="matrix(1.022976,0,0,0.71529071,9.1114734,-39.403506)"><title
- id="title27-2">Rounded Rectangle.13</title><desc
- id="desc29-0">Private Session Data</desc><g
- id="shadow19-7-1"
- transform="translate(0.345598,1.97279)"
- class="st3"
- style="visibility:visible"><path
+ ]]></style><defs
+ id="Patterns_And_Gradients"><marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker5421"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Lend"><path
+ transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ style="fill:#41719c;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ id="path5419"
+ inkscape:connector-curvature="0" /></marker><marker
+ inkscape:stockid="Arrow2Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Lend"
+ style="overflow:visible"
+ inkscape:isstock="true"><path
+ id="path5004"
+ style="fill:#41719c;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+ inkscape:connector-curvature="0" /></marker><marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Lend"
+ style="overflow:visible"
+ inkscape:isstock="true"><path
+ id="path4986"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ inkscape:connector-curvature="0" /></marker><linearGradient
+ id="grad0-4"
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientTransform="rotate(60,0.5,0.5)"><stop
+ offset="0"
+ stop-color="#e8ebef"
+ stop-opacity="1"
+ id="stop4" /><stop
+ offset="0.24"
+ stop-color="#f4f5f7"
+ stop-opacity="1"
+ id="stop6" /><stop
+ offset="0.54"
+ stop-color="#feffff"
+ stop-opacity="1"
+ id="stop8" /></linearGradient><filter
+ id="filter_2-4"><feGaussianBlur
+ stdDeviation="2"
+ id="feGaussianBlur12-0" /></filter><linearGradient
+ inkscape:collect="always"
+ xlink:href="#grad0-4"
+ id="linearGradient189"
+ gradientTransform="scale(0.8787489,1.1379815)"
+ x1="-0.42674366"
+ y1="0.98859203"
+ x2="176.71146"
+ y2="0.98859203"
+ gradientUnits="userSpaceOnUse" /><filter
+ id="filter_2-5"><feGaussianBlur
+ stdDeviation="2"
+ id="feGaussianBlur12-8" /></filter><filter
+ id="filter_2-3"><feGaussianBlur
+ stdDeviation="2"
+ id="feGaussianBlur12-2" /></filter><linearGradient
+ inkscape:collect="always"
+ xlink:href="#grad0-4"
+ id="linearGradient189-7"
+ gradientTransform="scale(0.8787489,1.1379815)"
+ x1="-0.42674366"
+ y1="0.98859203"
+ x2="176.71146"
+ y2="0.98859203"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#grad0-4"
+ id="linearGradient500"
+ gradientTransform="matrix(0.87785006,0,0,2.0116303,15.940232,20.619826)"
+ x1="-0.42674366"
+ y1="0.98859203"
+ x2="176.71146"
+ y2="0.98859203"
+ gradientUnits="userSpaceOnUse" /></defs><defs
+ id="Filters"><filter
+ id="filter_2"><feGaussianBlur
+ stdDeviation="2"
+ id="feGaussianBlur12" /></filter></defs><g
+ transform="matrix(1,0,0,0.41409874,-12.05774,-5.77269)"
+ id="shape18-1"><title
+ id="title18">Rounded Rectangle.12</title><desc
+ id="desc20">Crypto Symmetric Session</desc><path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient500);stroke:#386288;stroke-width:0.99665654"
+ id="path22"
+ class="st1"
+ d="M 22.713297,378.28219 H 163.92871 a 6.7704177,11.980443 0 0 0 6.76307,-11.96745 V 35.256532 A 6.7704177,11.980443 0 0 0 163.92871,23.271405 H 22.713297 A 6.7704177,11.980443 0 0 0 15.940232,35.256532 V 366.31474 a 6.7704177,11.980443 0 0 0 6.773065,11.96745 z" /></g><g
+ transform="matrix(1,0,0,0.41409874,-2.136529,-9.5289258)"
+ id="shape19-6"><title
+ id="title27">Rounded Rectangle.13</title><desc
+ id="desc29">Private Session Data</desc></g><g
+ id="g4079"
+ transform="matrix(0.9997031,0,0,1.070998,206.15511,-5.6465883)"><path
+ style="fill:#ffffff;stroke:#41719c;stroke-width:1.15444767"
+ inkscape:connector-curvature="0"
+ id="path43"
+ class="st7"
+ d="m -189.55935,139.62776 h 123.25 a 5.90925,14.000977 0 0 0 5.91,-13.97905 V 39.476089 a 5.90925,14.000977 0 0 0 -5.91,-14.002757 h -123.25 a 5.90925,14.000977 0 0 0 -5.91,14.002757 v 86.172621 a 5.90925,14.000977 0 0 0 5.91,13.97905 z" /><rect
+ y="118.60072"
+ x="-181.11736"
+ height="14.896484"
+ width="15.968175"
+ id="rect4604"
+ style="fill:none;fill-opacity:1;stroke:#41719c;stroke-width:0.75000221;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-165.14919"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-149.181"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-133.21283"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6-9"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-117.24466"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6-9-8"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-101.27649"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6-9-8-9"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><rect
+ y="118.60072"
+ x="-85.308311"
+ height="14.896484"
+ width="15.968174"
+ id="rect4604-7-6-9-8-9-6"
+ style="font-size:12px;overflow:visible;color-interpolation-filters:sRGB;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#41719c;stroke-width:0.75000221;stroke-linecap:square;stroke-miterlimit:3;stroke-opacity:1" /><text
+ transform="scale(0.48757738,2.0509565)"
+ style="font-size:21.61449814px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#41719c;fill-rule:evenodd;stroke-width:2.16144276;stroke-linecap:square;stroke-miterlimit:3"
+ id="text65-3"
+ class="st6"
+ y="50.793892"
+ x="-374.07562" />
+<text
+ xml:space="preserve"
+ style="font-style:normal;font-weight:normal;font-size:28.99296951px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.72482425"
+ x="-172.30693"
+ y="83.585136"
+ id="text4129"
+ transform="scale(1.035044,0.96614251)"><tspan
+ sodipodi:role="line"
+ id="tspan4127"
+ x="-172.30693"
+ y="109.23712"
+ style="stroke-width:0.72482425"></tspan></text>
+<text
+ xml:space="preserve"
+ style="font-style:normal;font-weight:normal;font-size:28.99296951px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.72482425"
+ x="-174.79263"
+ y="75.713715"
+ id="text4139"
+ transform="scale(1.035044,0.96614251)"><tspan
+ sodipodi:role="line"
+ id="tspan4137"
+ x="-174.79263"
+ y="101.3657"
+ style="stroke-width:0.72482425"></tspan></text>
+</g><path
+ style="fill:none;fill-opacity:1;stroke:#41719c;stroke-width:0.86738265px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
+ d="m 128.80127,137.90141 -0.20704,20.06801 44.6966,-0.10399 0.20705,-93.424256 16.84434,0.62379"
+ id="path5030"
inkscape:connector-curvature="0"
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st4"
- id="path31-8"
- style="fill:#bdd0e9;fill-opacity:0.25;stroke:#bdd0e9;stroke-opacity:0.25;filter:url(#filter_2)" /></g><path
- inkscape:connector-curvature="0"
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st5"
- id="path34-8"
- style="fill:#a6b6cd;stroke:#41719c;stroke-width:0.75" /><text
- x="34.639763"
- y="119.96548"
- class="st6"
- id="text36-7"
- style="font-size:13.15105343px;font-family:Calibri;fill:#41719c;stroke-width:1.31510115"
- transform="scale(0.76039781,1.3151011)">Private Session Data</text>
-
+ sodipodi:nodetypes="ccccc" /><g
+ transform="matrix(1,0,0,0.57815109,191.45876,-0.65041967)"
+ id="shape18-1-4"><title
+ id="title18-4">Rounded Rectangle.12</title><desc
+ id="desc20-6">Crypto Symmetric Session</desc><path
+ style="fill:url(#linearGradient189);stroke:#386288;stroke-width:0.75"
+ id="path22-0"
+ class="st1"
+ d="m 6.78,202.33 h 141.36 a 6.77735,6.77735 -180 0 0 6.77,-6.77 V 8.28 A 6.77735,6.77735 -180 0 0 148.14,1.5 H 6.78 A 6.77735,6.77735 -180 0 0 0,8.28 v 187.28 a 6.77735,6.77735 -180 0 0 6.78,6.77 z"
+ inkscape:connector-curvature="0" /><text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;fill:#386288;stroke-width:1.40298378"
+ id="text24-5"
+ class="st2"
+ y="17.335487"
+ x="26.317923">Crypto Driver Private Session</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-3"
+ class="st2"
+ y="19.076277"
+ x="-240.04274">Crypto Symmetric Session</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-5"
+ class="st2"
+ y="46.557648"
+ x="-241.24557">uint16_t nb_drivers;</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-6"
+ class="st2"
+ y="98.349464"
+ x="-240.04272">struct {</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-2"
+ class="st2"
+ y="115.26107"
+ x="-204.55865">void *data;</text>
+<text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;overflow:visible;color-interpolation-filters:sRGB;fill:#386288;fill-rule:evenodd;stroke-width:1.40298378;stroke-linecap:square;stroke-miterlimit:3"
+ id="text24-5-9"
+ class="st2"
+ y="144.3279"
+ x="-240.04274">} session_data[];</text>
</g><g
- id="shape18-1-4-7"
- transform="matrix(1,0,0,0.57815109,0.90591369,163.94402)"><title
- id="title18-4-3">Rounded Rectangle.12</title><desc
- id="desc20-6-5">Crypto Symmetric Session</desc><path
- inkscape:connector-curvature="0"
- d="m 6.78,202.33 h 141.36 a 6.77735,6.77735 -180 0 0 6.77,-6.77 V 8.28 A 6.77735,6.77735 -180 0 0 148.14,1.5 H 6.78 A 6.77735,6.77735 -180 0 0 0,8.28 v 187.28 a 6.77735,6.77735 -180 0 0 6.78,6.77 z"
- class="st1"
- id="path22-0-8"
- style="fill:url(#linearGradient189-7);stroke:#386288;stroke-width:0.75" /><text
- x="26.317923"
- y="17.335487"
- class="st2"
- id="text24-5-1"
- style="font-size:14.02988338px;font-family:Calibri;fill:#386288;stroke-width:1.40298378"
- transform="scale(0.71276665,1.4029837)">Crypto Driver Private Session</text>
-
+ transform="matrix(1.022976,0,0,0.71529071,199.82034,-39.936699)"
+ id="shape19-6-5"><title
+ id="title27-2">Rounded Rectangle.13</title><desc
+ id="desc29-0">Private Session Data</desc><g
+ style="visibility:visible"
+ class="st3"
+ transform="translate(0.345598,1.97279)"
+ id="shadow19-7-1"><path
+ style="fill:#bdd0e9;fill-opacity:0.25;stroke:#bdd0e9;stroke-opacity:0.25;filter:url(#filter_2)"
+ id="path31-8"
+ class="st4"
+ d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
+ inkscape:connector-curvature="0" /></g><path
+ style="fill:#a6b6cd;stroke:#41719c;stroke-width:0.75"
+ id="path34-8"
+ class="st5"
+ d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
+ inkscape:connector-curvature="0" /><text
+ transform="scale(0.76039781,1.3151011)"
+ style="font-size:13.15105343px;font-family:Calibri;fill:#41719c;stroke-width:1.31510115"
+ id="text36-7"
+ class="st6"
+ y="119.96548"
+ x="34.639763">Private Session Data</text>
</g><g
- id="shape19-6-5-1"
- transform="matrix(1.022976,0,0,0.71529071,9.2675037,124.65774)"><title
- id="title27-2-4">Rounded Rectangle.13</title><desc
- id="desc29-0-9">Private Session Data</desc><g
- id="shadow19-7-1-8"
- transform="translate(0.345598,1.97279)"
- class="st3"
- style="visibility:visible"><path
- inkscape:connector-curvature="0"
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st4"
- id="path31-8-4"
- style="fill:#bdd0e9;fill-opacity:0.25;stroke:#bdd0e9;stroke-opacity:0.25;filter:url(#filter_2-3)" /></g><path
- inkscape:connector-curvature="0"
- d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
- class="st5"
- id="path34-8-3"
- style="fill:#a6b6cd;stroke:#41719c;stroke-width:0.75" /><text
- x="34.639763"
- y="119.96548"
- class="st6"
- id="text36-7-6"
- style="font-size:13.15105343px;font-family:Calibri;fill:#41719c;stroke-width:1.31510115"
- transform="scale(0.76039781,1.3151011)">Private Session Data</text>
-
+ transform="matrix(1,0,0,0.57815109,191.61478,163.41083)"
+ id="shape18-1-4-7"><title
+ id="title18-4-3">Rounded Rectangle.12</title><desc
+ id="desc20-6-5">Crypto Symmetric Session</desc><path
+ style="fill:url(#linearGradient189-7);stroke:#386288;stroke-width:0.75"
+ id="path22-0-8"
+ class="st1"
+ d="m 6.78,202.33 h 141.36 a 6.77735,6.77735 -180 0 0 6.77,-6.77 V 8.28 A 6.77735,6.77735 -180 0 0 148.14,1.5 H 6.78 A 6.77735,6.77735 -180 0 0 0,8.28 v 187.28 a 6.77735,6.77735 -180 0 0 6.78,6.77 z"
+ inkscape:connector-curvature="0" /><text
+ transform="scale(0.71276665,1.4029837)"
+ style="font-size:14.02988338px;font-family:Calibri;fill:#386288;stroke-width:1.40298378"
+ id="text24-5-1"
+ class="st2"
+ y="17.335487"
+ x="26.317923">Crypto Driver Private Session</text>
+</g><g
+ transform="matrix(1.022976,0,0,0.71529071,199.97637,124.12455)"
+ id="shape19-6-5-1"><title
+ id="title27-2-4">Rounded Rectangle.13</title><desc
+ id="desc29-0-9">Private Session Data</desc><g
+ style="visibility:visible"
+ class="st3"
+ transform="translate(0.345598,1.97279)"
+ id="shadow19-7-1-8"><path
+ style="fill:#bdd0e9;fill-opacity:0.25;stroke:#bdd0e9;stroke-opacity:0.25;filter:url(#filter_2-3)"
+ id="path31-8-4"
+ class="st4"
+ d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
+ inkscape:connector-curvature="0" /></g><path
+ style="fill:#a6b6cd;stroke:#41719c;stroke-width:0.75"
+ id="path34-8-3"
+ class="st5"
+ d="m 5.91,202.33 h 123.25 a 5.90925,5.90925 -180 0 0 5.91,-5.9 v -92.78 a 5.90925,5.90925 -180 0 0 -5.91,-5.91 H 5.91 A 5.90925,5.90925 -180 0 0 0,103.65 v 92.78 a 5.90925,5.90925 -180 0 0 5.91,5.9 z"
+ inkscape:connector-curvature="0" /><text
+ transform="scale(0.76039781,1.3151011)"
+ style="font-size:13.15105343px;font-family:Calibri;fill:#41719c;stroke-width:1.31510115"
+ id="text36-7-6"
+ class="st6"
+ y="119.96548"
+ x="34.639763">Private Session Data</text>
</g><text
- xml:space="preserve"
+ id="text5070"
+ y="145.4136"
+ x="248.24945"
style="font-style:normal;font-weight:normal;font-size:30.00008774px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.75000221"
- x="57.540585"
- y="145.94679"
- id="text5070"><tspan
- sodipodi:role="line"
+ xml:space="preserve"><tspan
+ style="stroke-width:0.75000221"
+ y="171.95665"
+ x="248.24945"
id="tspan5068"
- x="57.540585"
- y="173.31679"
- style="stroke-width:0.75000221"></tspan></text>
+ sodipodi:role="line" /></text>
<text
- xml:space="preserve"
+ id="text5074"
+ y="142.68553"
+ x="251.28064"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.00006485px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.75000221"
- x="60.571766"
- y="143.21872"
- id="text5074"><tspan
- sodipodi:role="line"
+ xml:space="preserve"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.00006485px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.75000221"
+ y="142.68553"
+ x="251.28064"
id="tspan5072"
- x="60.571766"
- y="143.21872"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.00006485px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.75000221">...</tspan></text>
+ sodipodi:role="line">...</tspan></text>
<path
- style="fill:none;stroke:#41719c;stroke-width:0.74499911px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker5421)"
- d="M -158.57624,71.371238 -157.38,232.04055 -1.1215065,232.19212"
+ inkscape:connector-curvature="0"
id="path5076"
- inkscape:connector-curvature="0" /></g></svg>
+ d="m 32.13263,137.96494 1.19624,93.60569 156.25849,0.0883"
+ style="fill:none;stroke:#41719c;stroke-width:0.56864393px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker5421)" /></svg>
\ No newline at end of file
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index df12835eb..f1ca879cc 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -74,9 +74,3 @@ Deprecation Notices
* security: New field ``uint64_t opaque_data`` is planned to be added into
``rte_security_session`` structure. That would allow upper layer to easily
associate/de-associate some user defined data with the security session.
-
-* cryptodev: several API and ABI changes are planned for rte_cryptodev
- in v19.02:
-
- - The size and layout of ``rte_cryptodev_sym_session`` will change
- to fix existing issues.
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index ace4bcfe7..b488a6d35 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -170,7 +170,8 @@ API Changes
* cryptodev: a new function ``rte_cryptodev_sym_session_pool_create()`` is
introduced. This function is now mandatory when creating symmetric session
header mempool. Please note all crypto applications are required to use this
- function from now on.
+ function from now on. Failed to do so will cause
+ ``rte_cryptodev_sym_session_create()`` function call return error.
ABI Changes
@@ -195,6 +196,10 @@ ABI Changes
``rte_cryptodev_qp_conf`` has been added two parameters of symmetric session
mempool and symmetric session private data mempool.
+* cryptodev: as shown in the the 18.11 deprecation notice, the structure
+ ``rte_cryptodev_sym_session`` has been updated to contain more information
+ to ensure safely accessing the session and session private data.
+
Shared Library Versions
-----------------------
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 4a105b08d..2a8e07d27 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -978,6 +978,30 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
return -EINVAL;
}
+ if (qp_conf->mp_session) {
+ struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
+ uint32_t obj_size = qp_conf->mp_session->elt_size;
+ uint32_t obj_priv_size = qp_conf->mp_session_private->elt_size;
+ struct rte_cryptodev_sym_session s = {0};
+
+ pool_priv = rte_mempool_get_priv(qp_conf->mp_session);
+ if (!pool_priv || qp_conf->mp_session->private_data_size <
+ sizeof(*pool_priv)) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return -EINVAL;
+ }
+
+ s.nb_drivers = pool_priv->nb_drivers;
+
+ if ((rte_cryptodev_sym_get_existing_header_session_size(&s) >
+ obj_size) || (s.nb_drivers <= dev->driver_id) ||
+ rte_cryptodev_sym_get_private_session_size(dev_id) >
+ obj_priv_size) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return -EINVAL;
+ }
+ }
+
if (dev->data->dev_started) {
CDEV_LOG_ERR(
"device %d must be stopped to allow configuration", dev_id);
@@ -1172,6 +1196,8 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
struct rte_mempool *mp)
{
struct rte_cryptodev *dev;
+ uint32_t sess_priv_sz = rte_cryptodev_sym_get_private_session_size(
+ dev_id);
uint8_t index;
int ret;
@@ -1180,11 +1206,16 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
if (sess == NULL || xforms == NULL || dev == NULL)
return -EINVAL;
+ if (mp->elt_size < sess_priv_sz)
+ return -EINVAL;
+
index = dev->driver_id;
+ if (index >= sess->nb_drivers)
+ return -EINVAL;
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->sym_session_configure, -ENOTSUP);
- if (sess->sess_private_data[index] == NULL) {
+ if (sess->sess_data[index].data == NULL) {
ret = dev->dev_ops->sym_session_configure(dev, xforms,
sess, mp);
if (ret < 0) {
@@ -1273,10 +1304,29 @@ rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
return mp;
}
+static unsigned int
+rte_cryptodev_sym_session_data_size(struct rte_cryptodev_sym_session *sess)
+{
+ return (sizeof(sess->sess_data[0]) * sess->nb_drivers);
+}
+
struct rte_cryptodev_sym_session *
rte_cryptodev_sym_session_create(struct rte_mempool *mp)
{
struct rte_cryptodev_sym_session *sess;
+ struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
+
+ if (!mp) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return NULL;
+ }
+
+ pool_priv = rte_mempool_get_priv(mp);
+
+ if (!pool_priv || mp->private_data_size < sizeof(*pool_priv)) {
+ CDEV_LOG_ERR("Invalid mempool\n");
+ return NULL;
+ }
/* Allocate a session structure from the session pool */
if (rte_mempool_get(mp, (void **)&sess)) {
@@ -1284,10 +1334,14 @@ rte_cryptodev_sym_session_create(struct rte_mempool *mp)
return NULL;
}
+ sess->nb_drivers = pool_priv->nb_drivers;
+
+
/* Clear device session pointer.
* Include the flag indicating presence of user data
*/
- memset(sess, 0, (sizeof(void *) * nb_drivers) + sizeof(uint8_t));
+ memset(sess->sess_data, 0,
+ rte_cryptodev_sym_session_data_size(sess));
return sess;
}
@@ -1395,16 +1449,20 @@ rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session *sess)
return 0;
}
-
unsigned int
rte_cryptodev_sym_get_header_session_size(void)
{
/*
- * Header contains pointers to the private data
- * of all registered drivers, and a flag which
- * indicates presence of user data
+ * Header contains pointers to the private data of all registered
+ * drivers and all necessary information to ensure safely clear
+ * or free al session.
*/
- return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
+ struct rte_cryptodev_sym_session s = {0};
+
+ s.nb_drivers = nb_drivers;
+
+ return (unsigned int)(sizeof(s) +
+ rte_cryptodev_sym_session_data_size(&s));
}
unsigned int __rte_experimental
@@ -1414,7 +1472,8 @@ rte_cryptodev_sym_get_existing_header_session_size(
if (!sess)
return 0;
else
- return rte_cryptodev_sym_get_header_session_size();
+ return (unsigned int)(sizeof(*sess) +
+ rte_cryptodev_sym_session_data_size(sess));
}
unsigned int __rte_experimental
@@ -1432,7 +1491,6 @@ unsigned int
rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
{
struct rte_cryptodev *dev;
- unsigned int header_size = sizeof(void *) * nb_drivers;
unsigned int priv_sess_size;
if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
@@ -1445,16 +1503,7 @@ rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
priv_sess_size = (*dev->dev_ops->sym_session_get_size)(dev);
- /*
- * If size is less than session header size,
- * return the latter, as this guarantees that
- * sessionless operations will work
- */
- if (priv_sess_size < header_size)
- return header_size;
-
return priv_sess_size;
-
}
unsigned int __rte_experimental
@@ -1486,15 +1535,10 @@ rte_cryptodev_sym_session_set_user_data(
void *data,
uint16_t size)
{
- uint16_t off_set = sizeof(void *) * nb_drivers;
- uint8_t *user_data_present = (uint8_t *)sess + off_set;
-
if (sess == NULL)
return -EINVAL;
- *user_data_present = 1;
- off_set += sizeof(uint8_t);
- rte_memcpy((uint8_t *)sess + off_set, data, size);
+ rte_memcpy(sess->sess_data + sess->nb_drivers, data, size);
return 0;
}
@@ -1502,14 +1546,10 @@ void * __rte_experimental
rte_cryptodev_sym_session_get_user_data(
struct rte_cryptodev_sym_session *sess)
{
- uint16_t off_set = sizeof(void *) * nb_drivers;
- uint8_t *user_data_present = (uint8_t *)sess + off_set;
-
- if (sess == NULL || !*user_data_present)
+ if (sess == NULL)
return NULL;
- off_set += sizeof(uint8_t);
- return (uint8_t *)sess + off_set;
+ return (void *)(sess->sess_data + sess->nb_drivers);
}
/** Initialise rte_crypto_op mempool element */
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 39e3bfffb..cc22a1878 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -957,8 +957,12 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
* has a fixed algo, key, op-type, digest_len etc.
*/
struct rte_cryptodev_sym_session {
- __extension__ void *sess_private_data[0];
- /**< Private symmetric session material */
+ uint16_t nb_drivers;
+ /**< number of elements in sess_data array */
+ __extension__ struct {
+ void *data;
+ } sess_data[0];
+ /**< Driver specific session material, variable size */
};
/** Cryptodev asymmetric crypto session */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index f15c9af30..defe05ea0 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -475,14 +475,23 @@ RTE_INIT(init_ ##driver_id)\
static inline void *
get_sym_session_private_data(const struct rte_cryptodev_sym_session *sess,
uint8_t driver_id) {
- return sess->sess_private_data[driver_id];
+ if (unlikely(sess->nb_drivers <= driver_id))
+ return NULL;
+
+ return sess->sess_data[driver_id].data;
}
static inline void
set_sym_session_private_data(struct rte_cryptodev_sym_session *sess,
uint8_t driver_id, void *private_data)
{
- sess->sess_private_data[driver_id] = private_data;
+ if (unlikely(sess->nb_drivers <= driver_id)) {
+ CDEV_LOG_ERR("Set private data for driver %u not allowed\n",
+ driver_id);
+ return;
+ }
+
+ sess->sess_data[driver_id].data = private_data;
}
static inline void *
--
2.13.6
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
2019-01-10 14:20 4% ` [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
2019-01-10 14:25 0% ` Thomas Monjalon
@ 2019-01-10 14:51 0% ` Akhil Goyal
1 sibling, 0 replies; 200+ results
From: Akhil Goyal @ 2019-01-10 14:51 UTC (permalink / raw)
To: Konstantin Ananyev, dev, pablo.de.lara.guarch; +Cc: thomas
On 1/10/2019 7:50 PM, Konstantin Ananyev wrote:
> v6 -> v7
> - Changes to address Thomas comments:
> bump ABI version
> remove related deprecation notice
> update release notes, ABI changes section
>
As Pablo suggested patch 1 can be dropped as Fan's patchset already
takes care of that.
Apart from that
Series Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
2019-01-10 14:25 0% ` Thomas Monjalon
2019-01-10 14:40 0% ` De Lara Guarch, Pablo
@ 2019-01-10 14:52 3% ` Ananyev, Konstantin
2019-01-10 14:54 0% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-01-10 14:52 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, akhil.goyal, De Lara Guarch, Pablo
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Thursday, January 10, 2019 2:25 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: dev@dpdk.org; akhil.goyal@nxp.com; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Subject: Re: [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
>
> 10/01/2019 15:20, Konstantin Ananyev:
> > v6 -> v7
> > - Changes to address Thomas comments:
> > bump ABI version
> > remove related deprecation notice
> > update release notes, ABI changes section
>
> You did not update the lib versions in the release notes.
For 'security: add opaque userdata pointer into security session':
1) removed deprecation notice
2) add ABI change into release note:
+* security: New field ``uint64_t opaque_data`` is added into
+ ``rte_security_session`` structure. That would allow upper layer to easily
+ associate/de-associate some user defined data with the security session.
+
3) Bumbed version in Makefile and meson.build
What else needs to be done here?
> I think you missed a deprecation notice removal in patch 1.
As Pablo noticed that would happen in "cryptodev: update symmetric session",
this patch will be just dropped from the series.
> Have you checked the doxygen warnings in last patch?
I think I fixed that in v7, are still seeing them?
Konstantin
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
2019-01-10 14:52 3% ` Ananyev, Konstantin
@ 2019-01-10 14:54 0% ` Thomas Monjalon
2019-01-10 14:58 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-01-10 14:54 UTC (permalink / raw)
To: Ananyev, Konstantin; +Cc: dev, akhil.goyal, De Lara Guarch, Pablo
10/01/2019 15:52, Ananyev, Konstantin:
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > 10/01/2019 15:20, Konstantin Ananyev:
> > > v6 -> v7
> > > - Changes to address Thomas comments:
> > > bump ABI version
> > > remove related deprecation notice
> > > update release notes, ABI changes section
> >
> > You did not update the lib versions in the release notes.
>
> For 'security: add opaque userdata pointer into security session':
> 1) removed deprecation notice
> 2) add ABI change into release note:
> +* security: New field ``uint64_t opaque_data`` is added into
> + ``rte_security_session`` structure. That would allow upper layer to easily
> + associate/de-associate some user defined data with the security session.
> +
> 3) Bumbed version in Makefile and meson.build
>
> What else needs to be done here?
Like I said, "update the lib versions in the release notes".
Please check at the bottom of the page, there is a list of libraries.
> > I think you missed a deprecation notice removal in patch 1.
> As Pablo noticed that would happen in "cryptodev: update symmetric session",
> this patch will be just dropped from the series.
OK
> > Have you checked the doxygen warnings in last patch?
> I think I fixed that in v7, are still seeing them?
OK
I did not check. It was just a question because it is not in the changelog.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
2019-01-10 14:54 0% ` Thomas Monjalon
@ 2019-01-10 14:58 0% ` Ananyev, Konstantin
2019-01-10 15:00 0% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-01-10 14:58 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, akhil.goyal, De Lara Guarch, Pablo
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Thursday, January 10, 2019 2:55 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: dev@dpdk.org; akhil.goyal@nxp.com; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Subject: Re: [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
>
> 10/01/2019 15:52, Ananyev, Konstantin:
> > From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > > 10/01/2019 15:20, Konstantin Ananyev:
> > > > v6 -> v7
> > > > - Changes to address Thomas comments:
> > > > bump ABI version
> > > > remove related deprecation notice
> > > > update release notes, ABI changes section
> > >
> > > You did not update the lib versions in the release notes.
> >
> > For 'security: add opaque userdata pointer into security session':
> > 1) removed deprecation notice
> > 2) add ABI change into release note:
> > +* security: New field ``uint64_t opaque_data`` is added into
> > + ``rte_security_session`` structure. That would allow upper layer to easily
> > + associate/de-associate some user defined data with the security session.
> > +
> > 3) Bumbed version in Makefile and meson.build
> >
> > What else needs to be done here?
>
> Like I said, "update the lib versions in the release notes".
> Please check at the bottom of the page, there is a list of libraries.
Ah, ok.
Will submit v8 then.
>
> > > I think you missed a deprecation notice removal in patch 1.
> > As Pablo noticed that would happen in "cryptodev: update symmetric session",
> > this patch will be just dropped from the series.
>
> OK
>
> > > Have you checked the doxygen warnings in last patch?
> > I think I fixed that in v7, are still seeing them?
>
> OK
> I did not check. It was just a question because it is not in the changelog.
>
>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
2019-01-10 14:58 0% ` Ananyev, Konstantin
@ 2019-01-10 15:00 0% ` Akhil Goyal
2019-01-10 15:09 0% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2019-01-10 15:00 UTC (permalink / raw)
To: Ananyev, Konstantin, Thomas Monjalon; +Cc: dev, De Lara Guarch, Pablo
On 1/10/2019 8:28 PM, Ananyev, Konstantin wrote:
>
>> -----Original Message-----
>> From: Thomas Monjalon [mailto:thomas@monjalon.net]
>> Sent: Thursday, January 10, 2019 2:55 PM
>> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
>> Cc: dev@dpdk.org; akhil.goyal@nxp.com; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
>> Subject: Re: [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
>>
>> 10/01/2019 15:52, Ananyev, Konstantin:
>>> From: Thomas Monjalon [mailto:thomas@monjalon.net]
>>>> 10/01/2019 15:20, Konstantin Ananyev:
>>>>> v6 -> v7
>>>>> - Changes to address Thomas comments:
>>>>> bump ABI version
>>>>> remove related deprecation notice
>>>>> update release notes, ABI changes section
>>>> You did not update the lib versions in the release notes.
>>> For 'security: add opaque userdata pointer into security session':
>>> 1) removed deprecation notice
>>> 2) add ABI change into release note:
>>> +* security: New field ``uint64_t opaque_data`` is added into
>>> + ``rte_security_session`` structure. That would allow upper layer to easily
>>> + associate/de-associate some user defined data with the security session.
>>> +
>>> 3) Bumbed version in Makefile and meson.build
>>>
>>> What else needs to be done here?
>> Like I said, "update the lib versions in the release notes".
>> Please check at the bottom of the page, there is a list of libraries.
> Ah, ok.
> Will submit v8 then.
Wait a for Pablo to apply the Fan's patchset. I think he would be
applying soon.
There will be conflict in 2-3 patches. You can rebase it and then send it
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
2019-01-10 15:00 0% ` Akhil Goyal
@ 2019-01-10 15:09 0% ` Akhil Goyal
0 siblings, 0 replies; 200+ results
From: Akhil Goyal @ 2019-01-10 15:09 UTC (permalink / raw)
To: Ananyev, Konstantin, Thomas Monjalon; +Cc: dev, De Lara Guarch, Pablo
On 1/10/2019 8:30 PM, Akhil Goyal wrote:
>
> On 1/10/2019 8:28 PM, Ananyev, Konstantin wrote:
>>> -----Original Message-----
>>> From: Thomas Monjalon [mailto:thomas@monjalon.net]
>>> Sent: Thursday, January 10, 2019 2:55 PM
>>> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
>>> Cc: dev@dpdk.org; akhil.goyal@nxp.com; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
>>> Subject: Re: [PATCH v7 00/10] ipsec: new library for IPsec data-path processing
>>>
>>> 10/01/2019 15:52, Ananyev, Konstantin:
>>>> From: Thomas Monjalon [mailto:thomas@monjalon.net]
>>>>> 10/01/2019 15:20, Konstantin Ananyev:
>>>>>> v6 -> v7
>>>>>> - Changes to address Thomas comments:
>>>>>> bump ABI version
>>>>>> remove related deprecation notice
>>>>>> update release notes, ABI changes section
>>>>> You did not update the lib versions in the release notes.
>>>> For 'security: add opaque userdata pointer into security session':
>>>> 1) removed deprecation notice
>>>> 2) add ABI change into release note:
>>>> +* security: New field ``uint64_t opaque_data`` is added into
>>>> + ``rte_security_session`` structure. That would allow upper layer to easily
>>>> + associate/de-associate some user defined data with the security session.
>>>> +
>>>> 3) Bumbed version in Makefile and meson.build
>>>>
>>>> What else needs to be done here?
>>> Like I said, "update the lib versions in the release notes".
>>> Please check at the bottom of the page, there is a list of libraries.
>> Ah, ok.
>> Will submit v8 then.
> Wait a for Pablo to apply the Fan's patchset. I think he would be
> applying soon.
> There will be conflict in 2-3 patches. You can rebase it and then send it
You can also fix the warnings of the check-git-log as well as you are
sending another version for app and lib
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH 0/6] Add non-blocking ring
@ 2019-01-10 21:01 4% Gage Eads
2019-01-15 23:52 3% ` [dpdk-dev] [PATCH v2 0/5] Add non-blocking ring Gage Eads
0 siblings, 2 replies; 200+ results
From: Gage Eads @ 2019-01-10 21:01 UTC (permalink / raw)
To: dev; +Cc: olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev
For some users, the rte ring's "non-preemptive" constraint is not acceptable;
for example, if the application uses a mixture of pinned high-priority threads
and multiplexed low-priority threads that share a mempool.
This patchset introduces a non-blocking ring, on top of which a mempool can run.
Crucially, the non-blocking algorithm relies on a 128-bit compare-and-swap, so
it is limited to x86_64 machines.
The ring uses more compare-and-swap atomic operations than the regular rte ring:
With no contention, an enqueue of n pointers uses (1 + 2n) CAS operations and a
dequeue of n pointers uses 2. This algorithm has worse average-case performance
than the regular rte ring (particularly a highly-contended ring with large bulk
accesses), however:
- For applications with preemptible pthreads, the regular rte ring's worst-case
performance (i.e. one thread being preempted in the update_tail() critical
section) is much worse than the non-blocking ring's.
- Software caching can mitigate the average case performance for ring-based
algorithms. For example, a non-blocking ring based mempool (a likely use case
for this ring) with per-thread caching.
The non-blocking ring is enabled via a new flag, RING_F_NB. For ease-of-use,
existing ring enqueue/dequeue functions work with both "regular" and
non-blocking rings.
This patchset also adds non-blocking versions of ring_autotest and
ring_perf_autotest, and a non-blocking ring based mempool.
This patchset makes ABI changes, and thus an ABI update announcement and
deprecation cycle are required.
This patchset depends on the non-blocking stack patchset[1].
[1] http://mails.dpdk.org/archives/dev/2019-January/122923.html
Gage Eads (6):
ring: change head and tail to pointer-width size
ring: add a non-blocking implementation
test_ring: add non-blocking ring autotest
test_ring_perf: add non-blocking ring perf test
mempool/ring: add non-blocking ring handlers
doc: add NB ring comment to EAL "known issues"
doc/guides/prog_guide/env_abstraction_layer.rst | 2 +-
drivers/mempool/ring/rte_mempool_ring.c | 58 ++-
lib/librte_eventdev/rte_event_ring.h | 6 +-
lib/librte_ring/rte_ring.c | 53 ++-
lib/librte_ring/rte_ring.h | 555 ++++++++++++++++++++++--
lib/librte_ring/rte_ring_generic.h | 16 +-
lib/librte_ring/rte_ring_version.map | 7 +
test/test/test_ring.c | 57 ++-
test/test/test_ring_perf.c | 19 +-
9 files changed, 689 insertions(+), 84 deletions(-)
--
2.13.6
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 0/9] ipsec: new library for IPsec data-path processing
2019-01-10 14:20 5% ` [dpdk-dev] [PATCH v7 01/10] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
@ 2019-01-10 21:06 4% ` Konstantin Ananyev
2019-01-10 21:06 5% ` [dpdk-dev] [PATCH v8 1/9] security: add opaque userdata pointer into security session Konstantin Ananyev
1 sibling, 0 replies; 200+ results
From: Konstantin Ananyev @ 2019-01-10 21:06 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, thomas, Konstantin Ananyev
v7 -> v8
- update release notes with new version for librte_security
- rebase on top of crypto-next
v6 -> v7
- Changes to address Thomas comments:
bump ABI version
remove related deprecation notice
update release notes, ABI changes section
v5 -> v6
- Fix issues reported by Akhil:
rte_ipsec_session_prepare() fails for lookaside-proto
v4 -> v5
- Fix issue with SQN overflows
- Address Akhil comments:
documentation update
spell checks spacing etc.
fix input crypto_xform check/prepcess
test cases for lookaside and inline proto
v3 -> v4
- Changes to address Declan comments
- Update docs
v2 -> v3
- Several fixes for IPv6 support
- Extra checks for input parameters in public APi functions
v1 -> v2
- Changes to get into account l2_len for outbound transport packets
(Qi comments)
- Several bug fixes
- Some code restructured
- Update MAINTAINERS file
RFCv2 -> v1
- Changes per Jerin comments
- Implement transport mode
- Several bug fixes
- UT largely reworked and extended
This patch introduces a new library within DPDK: librte_ipsec.
The aim is to provide DPDK native high performance library for IPsec
data-path processing.
The library is supposed to utilize existing DPDK crypto-dev and
security API to provide application with transparent IPsec
processing API.
The library is concentrated on data-path protocols processing
(ESP and AH), IKE protocol(s) implementation is out of scope
for that library.
Current patch introduces SA-level API.
SA level API
============
API described below operates on SA level.
It provides functionality that allows user for given SA to process
inbound and outbound IPsec packets.
To be more specific:
- for inbound ESP/AH packets perform decryption, authentication,
integrity checking, remove ESP/AH related headers
- for outbound packets perform payload encryption, attach ICV,
update/add IP headers, add ESP/AH headers/trailers,
setup related mbuf felids (ol_flags, tx_offloads, etc.).
- initialize/un-initialize given SA based on user provided parameters.
The following functionality:
- match inbound/outbound packets to particular SA
- manage crypto/security devices
- provide SAD/SPD related functionality
- determine what crypto/security device has to be used
for given packet(s)
is out of scope for SA-level API.
SA-level API is based on top of crypto-dev/security API and relies on
them
to perform actual cipher and integrity checking.
To have an ability to easily map crypto/security sessions into related
IPSec SA opaque userdata field was added into
rte_cryptodev_sym_session and rte_security_session structures.
That implies ABI change for both librte_crytpodev and librte_security.
Due to the nature of crypto-dev API (enqueue/deque model) we use
asynchronous API for IPsec packets destined to be processed by
crypto-device.
Expected API call sequence would be:
/* enqueue for processing by crypto-device */
rte_ipsec_pkt_crypto_prepare(...);
rte_cryptodev_enqueue_burst(...);
/* dequeue from crypto-device and do final processing (if any) */
rte_cryptodev_dequeue_burst(...);
rte_ipsec_pkt_crypto_group(...); /* optional */
rte_ipsec_pkt_process(...);
Though for packets destined for inline processing no extra overhead
is required and synchronous API call: rte_ipsec_pkt_process()
is sufficient for that case.
Current implementation supports all four currently defined
rte_security types.
Though to accommodate future custom implementations function pointers
model is used for both for *crypto_prepare* and *process*
impelementations.
Konstantin Ananyev (9):
security: add opaque userdata pointer into security session
net: add ESP trailer structure definition
lib: introduce ipsec library
ipsec: add SA data-path API
ipsec: implement SA data-path API
ipsec: rework SA replay window/SQN for MT environment
ipsec: helper functions to group completed crypto-ops
test/ipsec: introduce functional test
doc: add IPsec library guide
MAINTAINERS | 8 +-
config/common_base | 5 +
doc/guides/prog_guide/index.rst | 1 +
doc/guides/prog_guide/ipsec_lib.rst | 168 ++
doc/guides/rel_notes/deprecation.rst | 4 -
doc/guides/rel_notes/release_19_02.rst | 17 +-
lib/Makefile | 2 +
lib/librte_ipsec/Makefile | 27 +
lib/librte_ipsec/crypto.h | 123 ++
lib/librte_ipsec/iph.h | 84 +
lib/librte_ipsec/ipsec_sqn.h | 343 ++++
lib/librte_ipsec/meson.build | 10 +
lib/librte_ipsec/pad.h | 45 +
lib/librte_ipsec/rte_ipsec.h | 154 ++
lib/librte_ipsec/rte_ipsec_group.h | 151 ++
lib/librte_ipsec/rte_ipsec_sa.h | 174 ++
lib/librte_ipsec/rte_ipsec_version.map | 15 +
lib/librte_ipsec/sa.c | 1527 ++++++++++++++
lib/librte_ipsec/sa.h | 106 +
lib/librte_ipsec/ses.c | 52 +
lib/librte_net/rte_esp.h | 10 +-
lib/librte_security/Makefile | 4 +-
lib/librte_security/meson.build | 3 +-
lib/librte_security/rte_security.h | 2 +
lib/meson.build | 2 +
mk/rte.app.mk | 2 +
test/test/Makefile | 3 +
test/test/meson.build | 3 +
test/test/test_ipsec.c | 2565 ++++++++++++++++++++++++
29 files changed, 5600 insertions(+), 10 deletions(-)
create mode 100644 doc/guides/prog_guide/ipsec_lib.rst
create mode 100644 lib/librte_ipsec/Makefile
create mode 100644 lib/librte_ipsec/crypto.h
create mode 100644 lib/librte_ipsec/iph.h
create mode 100644 lib/librte_ipsec/ipsec_sqn.h
create mode 100644 lib/librte_ipsec/meson.build
create mode 100644 lib/librte_ipsec/pad.h
create mode 100644 lib/librte_ipsec/rte_ipsec.h
create mode 100644 lib/librte_ipsec/rte_ipsec_group.h
create mode 100644 lib/librte_ipsec/rte_ipsec_sa.h
create mode 100644 lib/librte_ipsec/rte_ipsec_version.map
create mode 100644 lib/librte_ipsec/sa.c
create mode 100644 lib/librte_ipsec/sa.h
create mode 100644 lib/librte_ipsec/ses.c
create mode 100644 test/test/test_ipsec.c
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v8 1/9] security: add opaque userdata pointer into security session
2019-01-10 14:20 5% ` [dpdk-dev] [PATCH v7 01/10] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
2019-01-10 21:06 4% ` [dpdk-dev] [PATCH v8 0/9] ipsec: new library for IPsec data-path processing Konstantin Ananyev
@ 2019-01-10 21:06 5% ` Konstantin Ananyev
1 sibling, 0 replies; 200+ results
From: Konstantin Ananyev @ 2019-01-10 21:06 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, pablo.de.lara.guarch, thomas, Konstantin Ananyev
Add 'uint64_t opaque_data' inside struct rte_security_session.
That allows upper layer to easily associate some user defined
data with the session.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Acked-by: Declan Doherty <declan.doherty@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
doc/guides/rel_notes/deprecation.rst | 4 ----
doc/guides/rel_notes/release_19_02.rst | 6 +++++-
lib/librte_security/Makefile | 4 ++--
lib/librte_security/meson.build | 3 ++-
lib/librte_security/rte_security.h | 2 ++
5 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 07a5b4cea..bab82865f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -71,9 +71,5 @@ Deprecation Notices
- Member ``uint16_t min_mtu`` the minimum MTU allowed.
- Member ``uint16_t max_mtu`` the maximum MTU allowed.
-* security: New field ``uint64_t opaque_data`` is planned to be added into
- ``rte_security_session`` structure. That would allow upper layer to easily
- associate/de-associate some user defined data with the security session.
-
* crypto/aesni_mb: the minimum supported intel-ipsec-mb library version will be
changed from 0.49.0 to 0.52.0.
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 86880275a..1aebd27c7 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -212,6 +212,10 @@ ABI Changes
``rte_cryptodev_sym_session`` has been updated to contain more information
to ensure safely accessing the session and session private data.
+* security: New field ``uint64_t opaque_data`` is added into
+ ``rte_security_session`` structure. That would allow upper layer to easily
+ associate/de-associate some user defined data with the security session.
+
Shared Library Versions
-----------------------
@@ -282,7 +286,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_reorder.so.1
librte_ring.so.2
+ librte_sched.so.2
- librte_security.so.1
+ + librte_security.so.2
librte_table.so.3
librte_timer.so.1
librte_vhost.so.4
diff --git a/lib/librte_security/Makefile b/lib/librte_security/Makefile
index bd92343bd..6708effdb 100644
--- a/lib/librte_security/Makefile
+++ b/lib/librte_security/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017 Intel Corporation
+# Copyright(c) 2017-2019 Intel Corporation
include $(RTE_SDK)/mk/rte.vars.mk
@@ -7,7 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_security.a
# library version
-LIBABIVER := 1
+LIBABIVER := 2
# build flags
CFLAGS += -O3
diff --git a/lib/librte_security/meson.build b/lib/librte_security/meson.build
index 532953fcc..a5130d2f6 100644
--- a/lib/librte_security/meson.build
+++ b/lib/librte_security/meson.build
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017 Intel Corporation
+# Copyright(c) 2017-2019 Intel Corporation
+version = 2
sources = files('rte_security.c')
headers = files('rte_security.h', 'rte_security_driver.h')
deps += ['mempool', 'cryptodev']
diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
index 718147e00..c8e438fdd 100644
--- a/lib/librte_security/rte_security.h
+++ b/lib/librte_security/rte_security.h
@@ -317,6 +317,8 @@ struct rte_security_session_conf {
struct rte_security_session {
void *sess_private_data;
/**< Private session material */
+ uint64_t opaque_data;
+ /**< Opaque user defined data */
};
/**
--
2.17.1
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH v6 00/10] ipsec: new library for IPsec data-path processing
2019-01-03 20:16 2% ` [dpdk-dev] [PATCH v6 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
@ 2019-01-11 1:09 2% ` Xu, Yanjie
0 siblings, 0 replies; 200+ results
From: Xu, Yanjie @ 2019-01-11 1:09 UTC (permalink / raw)
To: Ananyev, Konstantin, dev, dev; +Cc: akhil.goyal
The patch series latest versions be tested by yanjie xu, which work for crypto and inline ipsec cases.
-----Original Message-----
From: Ananyev, Konstantin
Sent: Friday, January 4, 2019 4:16 AM
To: dev@dpdk.org; dev@dpdk.org
Cc: akhil.goyal@nxp.com; Ananyev, Konstantin <konstantin.ananyev@intel.com>
Subject: [PATCH v6 00/10] ipsec: new library for IPsec data-path processing
v5 -> v6
- Fix issues reported by Akhil:
rte_ipsec_session_prepare() fails for lookaside-proto
v4 -> v5
- Fix issue with SQN overflows
- Address Akhil comments:
documentation update
spell checks spacing etc.
fix input crypto_xform check/prepcess
test cases for lookaside and inline proto
v3 -> v4
- Changes to adress Declan comments
- Update docs
v2 -> v3
- Several fixes for IPv6 support
- Extra checks for input parameters in public APi functions
v1 -> v2
- Changes to get into account l2_len for outbound transport packets
(Qi comments)
- Several bug fixes
- Some code restructured
- Update MAINTAINERS file
RFCv2 -> v1
- Changes per Jerin comments
- Implement transport mode
- Several bug fixes
- UT largely reworked and extended
This patch introduces a new library within DPDK: librte_ipsec.
The aim is to provide DPDK native high performance library for IPsec data-path processing.
The library is supposed to utilize existing DPDK crypto-dev and security API to provide application with transparent IPsec processing API.
The library is concentrated on data-path protocols processing (ESP and AH), IKE protocol(s) implementation is out of scope for that library.
Current patch introduces SA-level API.
SA (low) level API
==================
API described below operates on SA level.
It provides functionality that allows user for given SA to process inbound and outbound IPsec packets.
To be more specific:
- for inbound ESP/AH packets perform decryption, authentication,
integrity checking, remove ESP/AH related headers
- for outbound packets perform payload encryption, attach ICV,
update/add IP headers, add ESP/AH headers/trailers,
setup related mbuf felids (ol_flags, tx_offloads, etc.).
- initialize/un-initialize given SA based on user provided parameters.
The following functionality:
- match inbound/outbound packets to particular SA
- manage crypto/security devices
- provide SAD/SPD related functionality
- determine what crypto/security device has to be used
for given packet(s)
is out of scope for SA-level API.
SA-level API is based on top of crypto-dev/security API and relies on them to perform actual cipher and integrity checking.
To have an ability to easily map crypto/security sessions into related IPSec SA opaque userdata field was added into rte_cryptodev_sym_session and rte_security_session structures.
That implies ABI change for both librte_crytpodev and librte_security.
Due to the nature of crypto-dev API (enqueue/deque model) we use asynchronous API for IPsec packets destined to be processed by crypto-device.
Expected API call sequence would be:
/* enqueue for processing by crypto-device */
rte_ipsec_pkt_crypto_prepare(...);
rte_cryptodev_enqueue_burst(...);
/* dequeue from crypto-device and do final processing (if any) */
rte_cryptodev_dequeue_burst(...);
rte_ipsec_pkt_crypto_group(...); /* optional */
rte_ipsec_pkt_process(...);
Though for packets destined for inline processing no extra overhead is required and synchronous API call: rte_ipsec_pkt_process() is sufficient for that case.
Current implementation supports all four currently defined rte_security types.
Though to accommodate future custom implementations function pointers model is used for both for *crypto_prepare* and *process* impelementations.
Konstantin Ananyev (10):
cryptodev: add opaque userdata pointer into crypto sym session
security: add opaque userdata pointer into security session
net: add ESP trailer structure definition
lib: introduce ipsec library
ipsec: add SA data-path API
ipsec: implement SA data-path API
ipsec: rework SA replay window/SQN for MT environment
ipsec: helper functions to group completed crypto-ops
test/ipsec: introduce functional test
doc: add IPsec library guide
MAINTAINERS | 8 +-
config/common_base | 5 +
doc/guides/prog_guide/index.rst | 1 +
doc/guides/prog_guide/ipsec_lib.rst | 168 ++
doc/guides/rel_notes/release_19_02.rst | 11 +
lib/Makefile | 2 +
lib/librte_cryptodev/rte_cryptodev.h | 2 +
lib/librte_ipsec/Makefile | 27 +
lib/librte_ipsec/crypto.h | 123 ++
lib/librte_ipsec/iph.h | 84 +
lib/librte_ipsec/ipsec_sqn.h | 343 ++++
lib/librte_ipsec/meson.build | 10 +
lib/librte_ipsec/pad.h | 45 +
lib/librte_ipsec/rte_ipsec.h | 154 ++
lib/librte_ipsec/rte_ipsec_group.h | 151 ++
lib/librte_ipsec/rte_ipsec_sa.h | 174 ++
lib/librte_ipsec/rte_ipsec_version.map | 15 +
lib/librte_ipsec/sa.c | 1527 ++++++++++++++
lib/librte_ipsec/sa.h | 106 +
lib/librte_ipsec/ses.c | 52 +
lib/librte_net/rte_esp.h | 10 +-
lib/librte_security/rte_security.h | 2 +
lib/meson.build | 2 +
mk/rte.app.mk | 2 +
test/test/Makefile | 3 +
test/test/meson.build | 3 +
test/test/test_ipsec.c | 2555 ++++++++++++++++++++++++
27 files changed, 5583 insertions(+), 2 deletions(-) create mode 100644 doc/guides/prog_guide/ipsec_lib.rst
create mode 100644 lib/librte_ipsec/Makefile create mode 100644 lib/librte_ipsec/crypto.h create mode 100644 lib/librte_ipsec/iph.h create mode 100644 lib/librte_ipsec/ipsec_sqn.h create mode 100644 lib/librte_ipsec/meson.build create mode 100644 lib/librte_ipsec/pad.h create mode 100644 lib/librte_ipsec/rte_ipsec.h create mode 100644 lib/librte_ipsec/rte_ipsec_group.h
create mode 100644 lib/librte_ipsec/rte_ipsec_sa.h create mode 100644 lib/librte_ipsec/rte_ipsec_version.map
create mode 100644 lib/librte_ipsec/sa.c create mode 100644 lib/librte_ipsec/sa.h create mode 100644 lib/librte_ipsec/ses.c create mode 100644 test/test/test_ipsec.c
--
2.17.1
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width size
@ 2019-01-11 4:38 3% ` Stephen Hemminger
2019-01-11 19:07 3% ` Eads, Gage
2019-01-11 10:25 3% ` Burakov, Anatoly
2 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-01-11 4:38 UTC (permalink / raw)
To: Gage Eads
Cc: dev, olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev
On Thu, 10 Jan 2019 15:01:17 -0600
Gage Eads <gage.eads@intel.com> wrote:
> For 64-bit architectures, doubling the head and tail index widths greatly
> increases the time it takes for them to wrap-around (with current CPU
> speeds, it won't happen within the author's lifetime). This is important in
> avoiding the ABA problem -- in which a thread mistakes reading the same
> tail index in two accesses to mean that the ring was not modified in the
> intervening time -- in the upcoming non-blocking ring implementation. Using
> a 64-bit index makes the possibility of this occurring effectively zero.
>
> I tested this commit's performance impact with an x86_64 build on a
> dual-socket Xeon E5-2699 v4 using ring_perf_autotest, and the change made
> no significant difference -- the few differences appear to be system noise.
> (The test ran on isolcpus cores using a tickless scheduler, but some
> variation was stll observed.) Each test was run three times and the results
> were averaged:
>
> | 64b head/tail cycle cost minus
> Test | 32b head/tail cycle cost
> ------------------------------------------------------------------
> SP/SC single enq/dequeue | 0.33
> MP/MC single enq/dequeue | 0.00
> SP/SC burst enq/dequeue (size 8) | 0.00
> MP/MC burst enq/dequeue (size 8) | 1.00
> SP/SC burst enq/dequeue (size 32) | 0.00
> MP/MC burst enq/dequeue (size 32) | -1.00
> SC empty dequeue | 0.01
> MC empty dequeue | 0.00
>
> Single lcore:
> SP/SC bulk enq/dequeue (size 8) | -0.36
> MP/MC bulk enq/dequeue (size 8) | 0.99
> SP/SC bulk enq/dequeue (size 32) | -0.40
> MP/MC bulk enq/dequeue (size 32) | -0.57
>
> Two physical cores:
> SP/SC bulk enq/dequeue (size 8) | -0.49
> MP/MC bulk enq/dequeue (size 8) | 0.19
> SP/SC bulk enq/dequeue (size 32) | -0.28
> MP/MC bulk enq/dequeue (size 32) | -0.62
>
> Two NUMA nodes:
> SP/SC bulk enq/dequeue (size 8) | 3.25
> MP/MC bulk enq/dequeue (size 8) | 1.87
> SP/SC bulk enq/dequeue (size 32) | -0.44
> MP/MC bulk enq/dequeue (size 32) | -1.10
>
> An earlier version of this patch changed the head and tail indexes to
> uint64_t, but that caused a performance drop on 32-bit builds. With
> uintptr_t, no performance difference is observed on an i686 build.
>
> Signed-off-by: Gage Eads <gage.eads@intel.com>
> ---
> lib/librte_eventdev/rte_event_ring.h | 6 +++---
> lib/librte_ring/rte_ring.c | 10 +++++-----
> lib/librte_ring/rte_ring.h | 20 ++++++++++----------
> lib/librte_ring/rte_ring_generic.h | 16 +++++++++-------
> 4 files changed, 27 insertions(+), 25 deletions(-)
>
> diff --git a/lib/librte_eventdev/rte_event_ring.h b/lib/librte_eventdev/rte_event_ring.h
> index 827a3209e..eae70f904 100644
> --- a/lib/librte_eventdev/rte_event_ring.h
> +++ b/lib/librte_eventdev/rte_event_ring.h
> @@ -1,5 +1,5 @@
> /* SPDX-License-Identifier: BSD-3-Clause
> - * Copyright(c) 2016-2017 Intel Corporation
> + * Copyright(c) 2016-2019 Intel Corporation
> */
>
> /**
> @@ -88,7 +88,7 @@ rte_event_ring_enqueue_burst(struct rte_event_ring *r,
> const struct rte_event *events,
> unsigned int n, uint16_t *free_space)
> {
> - uint32_t prod_head, prod_next;
> + uintptr_t prod_head, prod_next;
> uint32_t free_entries;
>
> n = __rte_ring_move_prod_head(&r->r, r->r.prod.single, n,
> @@ -129,7 +129,7 @@ rte_event_ring_dequeue_burst(struct rte_event_ring *r,
> struct rte_event *events,
> unsigned int n, uint16_t *available)
> {
> - uint32_t cons_head, cons_next;
> + uintptr_t cons_head, cons_next;
> uint32_t entries;
>
> n = __rte_ring_move_cons_head(&r->r, r->r.cons.single, n,
> diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
> index d215acecc..b15ee0eb3 100644
> --- a/lib/librte_ring/rte_ring.c
> +++ b/lib/librte_ring/rte_ring.c
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: BSD-3-Clause
> *
> - * Copyright (c) 2010-2015 Intel Corporation
> + * Copyright (c) 2010-2019 Intel Corporation
> * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org
> * All rights reserved.
> * Derived from FreeBSD's bufring.h
> @@ -227,10 +227,10 @@ rte_ring_dump(FILE *f, const struct rte_ring *r)
> fprintf(f, " flags=%x\n", r->flags);
> fprintf(f, " size=%"PRIu32"\n", r->size);
> fprintf(f, " capacity=%"PRIu32"\n", r->capacity);
> - fprintf(f, " ct=%"PRIu32"\n", r->cons.tail);
> - fprintf(f, " ch=%"PRIu32"\n", r->cons.head);
> - fprintf(f, " pt=%"PRIu32"\n", r->prod.tail);
> - fprintf(f, " ph=%"PRIu32"\n", r->prod.head);
> + fprintf(f, " ct=%"PRIuPTR"\n", r->cons.tail);
> + fprintf(f, " ch=%"PRIuPTR"\n", r->cons.head);
> + fprintf(f, " pt=%"PRIuPTR"\n", r->prod.tail);
> + fprintf(f, " ph=%"PRIuPTR"\n", r->prod.head);
> fprintf(f, " used=%u\n", rte_ring_count(r));
> fprintf(f, " avail=%u\n", rte_ring_free_count(r));
> }
> diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
> index af5444a9f..12af64e13 100644
> --- a/lib/librte_ring/rte_ring.h
> +++ b/lib/librte_ring/rte_ring.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: BSD-3-Clause
> *
> - * Copyright (c) 2010-2017 Intel Corporation
> + * Copyright (c) 2010-2019 Intel Corporation
> * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
> * All rights reserved.
> * Derived from FreeBSD's bufring.h
> @@ -65,8 +65,8 @@ struct rte_memzone; /* forward declaration, so as not to require memzone.h */
>
> /* structure to hold a pair of head/tail values and other metadata */
> struct rte_ring_headtail {
> - volatile uint32_t head; /**< Prod/consumer head. */
> - volatile uint32_t tail; /**< Prod/consumer tail. */
> + volatile uintptr_t head; /**< Prod/consumer head. */
> + volatile uintptr_t tail; /**< Prod/consumer tail. */
> uint32_t single; /**< True if single prod/cons */
> };
Isn't this a major ABI change which will break existing applications?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width size
2019-01-11 4:38 3% ` Stephen Hemminger
@ 2019-01-11 10:25 3% ` Burakov, Anatoly
2019-01-11 19:12 0% ` Eads, Gage
2 siblings, 1 reply; 200+ results
From: Burakov, Anatoly @ 2019-01-11 10:25 UTC (permalink / raw)
To: Gage Eads, dev
Cc: olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev
On 10-Jan-19 9:01 PM, Gage Eads wrote:
> For 64-bit architectures, doubling the head and tail index widths greatly
> increases the time it takes for them to wrap-around (with current CPU
> speeds, it won't happen within the author's lifetime). This is important in
> avoiding the ABA problem -- in which a thread mistakes reading the same
> tail index in two accesses to mean that the ring was not modified in the
> intervening time -- in the upcoming non-blocking ring implementation. Using
> a 64-bit index makes the possibility of this occurring effectively zero.
>
> I tested this commit's performance impact with an x86_64 build on a
> dual-socket Xeon E5-2699 v4 using ring_perf_autotest, and the change made
> no significant difference -- the few differences appear to be system noise.
> (The test ran on isolcpus cores using a tickless scheduler, but some
> variation was stll observed.) Each test was run three times and the results
> were averaged:
>
> | 64b head/tail cycle cost minus
> Test | 32b head/tail cycle cost
> ------------------------------------------------------------------
> SP/SC single enq/dequeue | 0.33
> MP/MC single enq/dequeue | 0.00
> SP/SC burst enq/dequeue (size 8) | 0.00
> MP/MC burst enq/dequeue (size 8) | 1.00
> SP/SC burst enq/dequeue (size 32) | 0.00
> MP/MC burst enq/dequeue (size 32) | -1.00
> SC empty dequeue | 0.01
> MC empty dequeue | 0.00
>
> Single lcore:
> SP/SC bulk enq/dequeue (size 8) | -0.36
> MP/MC bulk enq/dequeue (size 8) | 0.99
> SP/SC bulk enq/dequeue (size 32) | -0.40
> MP/MC bulk enq/dequeue (size 32) | -0.57
>
> Two physical cores:
> SP/SC bulk enq/dequeue (size 8) | -0.49
> MP/MC bulk enq/dequeue (size 8) | 0.19
> SP/SC bulk enq/dequeue (size 32) | -0.28
> MP/MC bulk enq/dequeue (size 32) | -0.62
>
> Two NUMA nodes:
> SP/SC bulk enq/dequeue (size 8) | 3.25
> MP/MC bulk enq/dequeue (size 8) | 1.87
> SP/SC bulk enq/dequeue (size 32) | -0.44
> MP/MC bulk enq/dequeue (size 32) | -1.10
>
> An earlier version of this patch changed the head and tail indexes to
> uint64_t, but that caused a performance drop on 32-bit builds. With
> uintptr_t, no performance difference is observed on an i686 build.
>
> Signed-off-by: Gage Eads <gage.eads@intel.com>
> ---
You're breaking the ABI - version bump for affected libraries is needed.
--
Thanks,
Anatoly
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width size
2019-01-11 4:38 3% ` Stephen Hemminger
@ 2019-01-11 19:07 3% ` Eads, Gage
0 siblings, 0 replies; 200+ results
From: Eads, Gage @ 2019-01-11 19:07 UTC (permalink / raw)
To: Stephen Hemminger
Cc: dev, olivier.matz, arybchenko, Richardson, Bruce, Ananyev, Konstantin
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Thursday, January 10, 2019 10:39 PM
> To: Eads, Gage <gage.eads@intel.com>
> Cc: dev@dpdk.org; olivier.matz@6wind.com; arybchenko@solarflare.com;
> Richardson, Bruce <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width
> size
>
> On Thu, 10 Jan 2019 15:01:17 -0600
> Gage Eads <gage.eads@intel.com> wrote:
>
> > For 64-bit architectures, doubling the head and tail index widths
> > greatly increases the time it takes for them to wrap-around (with
> > current CPU speeds, it won't happen within the author's lifetime).
> > This is important in avoiding the ABA problem -- in which a thread
> > mistakes reading the same tail index in two accesses to mean that the
> > ring was not modified in the intervening time -- in the upcoming
> > non-blocking ring implementation. Using a 64-bit index makes the possibility of
> this occurring effectively zero.
> >
> > I tested this commit's performance impact with an x86_64 build on a
> > dual-socket Xeon E5-2699 v4 using ring_perf_autotest, and the change
> > made no significant difference -- the few differences appear to be system
> noise.
> > (The test ran on isolcpus cores using a tickless scheduler, but some
> > variation was stll observed.) Each test was run three times and the
> > results were averaged:
> >
> > | 64b head/tail cycle cost minus
> > Test | 32b head/tail cycle cost
> > ------------------------------------------------------------------
> > SP/SC single enq/dequeue | 0.33
> > MP/MC single enq/dequeue | 0.00
> > SP/SC burst enq/dequeue (size 8) | 0.00 MP/MC burst enq/dequeue (size
> > 8) | 1.00 SP/SC burst enq/dequeue (size 32) | 0.00 MP/MC burst
> > enq/dequeue (size 32) | -1.00
> > SC empty dequeue | 0.01
> > MC empty dequeue | 0.00
> >
> > Single lcore:
> > SP/SC bulk enq/dequeue (size 8) | -0.36
> > MP/MC bulk enq/dequeue (size 8) | 0.99
> > SP/SC bulk enq/dequeue (size 32) | -0.40 MP/MC bulk enq/dequeue (size
> > 32) | -0.57
> >
> > Two physical cores:
> > SP/SC bulk enq/dequeue (size 8) | -0.49
> > MP/MC bulk enq/dequeue (size 8) | 0.19
> > SP/SC bulk enq/dequeue (size 32) | -0.28 MP/MC bulk enq/dequeue (size
> > 32) | -0.62
> >
> > Two NUMA nodes:
> > SP/SC bulk enq/dequeue (size 8) | 3.25
> > MP/MC bulk enq/dequeue (size 8) | 1.87
> > SP/SC bulk enq/dequeue (size 32) | -0.44 MP/MC bulk enq/dequeue (size
> > 32) | -1.10
> >
> > An earlier version of this patch changed the head and tail indexes to
> > uint64_t, but that caused a performance drop on 32-bit builds. With
> > uintptr_t, no performance difference is observed on an i686 build.
> >
> > Signed-off-by: Gage Eads <gage.eads@intel.com>
> > ---
> > lib/librte_eventdev/rte_event_ring.h | 6 +++---
> > lib/librte_ring/rte_ring.c | 10 +++++-----
> > lib/librte_ring/rte_ring.h | 20 ++++++++++----------
> > lib/librte_ring/rte_ring_generic.h | 16 +++++++++-------
> > 4 files changed, 27 insertions(+), 25 deletions(-)
> >
> > diff --git a/lib/librte_eventdev/rte_event_ring.h
> > b/lib/librte_eventdev/rte_event_ring.h
> > index 827a3209e..eae70f904 100644
> > --- a/lib/librte_eventdev/rte_event_ring.h
> > +++ b/lib/librte_eventdev/rte_event_ring.h
> > @@ -1,5 +1,5 @@
> > /* SPDX-License-Identifier: BSD-3-Clause
> > - * Copyright(c) 2016-2017 Intel Corporation
> > + * Copyright(c) 2016-2019 Intel Corporation
> > */
> >
> > /**
> > @@ -88,7 +88,7 @@ rte_event_ring_enqueue_burst(struct rte_event_ring *r,
> > const struct rte_event *events,
> > unsigned int n, uint16_t *free_space) {
> > - uint32_t prod_head, prod_next;
> > + uintptr_t prod_head, prod_next;
> > uint32_t free_entries;
> >
> > n = __rte_ring_move_prod_head(&r->r, r->r.prod.single, n, @@ -129,7
> > +129,7 @@ rte_event_ring_dequeue_burst(struct rte_event_ring *r,
> > struct rte_event *events,
> > unsigned int n, uint16_t *available) {
> > - uint32_t cons_head, cons_next;
> > + uintptr_t cons_head, cons_next;
> > uint32_t entries;
> >
> > n = __rte_ring_move_cons_head(&r->r, r->r.cons.single, n, diff --git
> > a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c index
> > d215acecc..b15ee0eb3 100644
> > --- a/lib/librte_ring/rte_ring.c
> > +++ b/lib/librte_ring/rte_ring.c
> > @@ -1,6 +1,6 @@
> > /* SPDX-License-Identifier: BSD-3-Clause
> > *
> > - * Copyright (c) 2010-2015 Intel Corporation
> > + * Copyright (c) 2010-2019 Intel Corporation
> > * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org
> > * All rights reserved.
> > * Derived from FreeBSD's bufring.h
> > @@ -227,10 +227,10 @@ rte_ring_dump(FILE *f, const struct rte_ring *r)
> > fprintf(f, " flags=%x\n", r->flags);
> > fprintf(f, " size=%"PRIu32"\n", r->size);
> > fprintf(f, " capacity=%"PRIu32"\n", r->capacity);
> > - fprintf(f, " ct=%"PRIu32"\n", r->cons.tail);
> > - fprintf(f, " ch=%"PRIu32"\n", r->cons.head);
> > - fprintf(f, " pt=%"PRIu32"\n", r->prod.tail);
> > - fprintf(f, " ph=%"PRIu32"\n", r->prod.head);
> > + fprintf(f, " ct=%"PRIuPTR"\n", r->cons.tail);
> > + fprintf(f, " ch=%"PRIuPTR"\n", r->cons.head);
> > + fprintf(f, " pt=%"PRIuPTR"\n", r->prod.tail);
> > + fprintf(f, " ph=%"PRIuPTR"\n", r->prod.head);
> > fprintf(f, " used=%u\n", rte_ring_count(r));
> > fprintf(f, " avail=%u\n", rte_ring_free_count(r)); } diff --git
> > a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h index
> > af5444a9f..12af64e13 100644
> > --- a/lib/librte_ring/rte_ring.h
> > +++ b/lib/librte_ring/rte_ring.h
> > @@ -1,6 +1,6 @@
> > /* SPDX-License-Identifier: BSD-3-Clause
> > *
> > - * Copyright (c) 2010-2017 Intel Corporation
> > + * Copyright (c) 2010-2019 Intel Corporation
> > * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
> > * All rights reserved.
> > * Derived from FreeBSD's bufring.h
> > @@ -65,8 +65,8 @@ struct rte_memzone; /* forward declaration, so as
> > not to require memzone.h */
> >
> > /* structure to hold a pair of head/tail values and other metadata */
> > struct rte_ring_headtail {
> > - volatile uint32_t head; /**< Prod/consumer head. */
> > - volatile uint32_t tail; /**< Prod/consumer tail. */
> > + volatile uintptr_t head; /**< Prod/consumer head. */
> > + volatile uintptr_t tail; /**< Prod/consumer tail. */
> > uint32_t single; /**< True if single prod/cons */
> > };
>
> Isn't this a major ABI change which will break existing applications?
Correct, and this patch needs to be reworked with the RTE_NEXT_ABI ifdef, as described in the versioning guidelines. I had misunderstood the ABI change procedure, but I'll fix this in v2.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width size
2019-01-11 10:25 3% ` Burakov, Anatoly
@ 2019-01-11 19:12 0% ` Eads, Gage
2019-01-11 19:55 3% ` Stephen Hemminger
0 siblings, 1 reply; 200+ results
From: Eads, Gage @ 2019-01-11 19:12 UTC (permalink / raw)
To: Burakov, Anatoly, dev
Cc: olivier.matz, arybchenko, Richardson, Bruce, Ananyev, Konstantin
> -----Original Message-----
> From: Burakov, Anatoly
> Sent: Friday, January 11, 2019 4:25 AM
> To: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org
> Cc: olivier.matz@6wind.com; arybchenko@solarflare.com; Richardson, Bruce
> <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width
> size
>
> On 10-Jan-19 9:01 PM, Gage Eads wrote:
> > For 64-bit architectures, doubling the head and tail index widths
> > greatly increases the time it takes for them to wrap-around (with
> > current CPU speeds, it won't happen within the author's lifetime).
> > This is important in avoiding the ABA problem -- in which a thread
> > mistakes reading the same tail index in two accesses to mean that the
> > ring was not modified in the intervening time -- in the upcoming
> > non-blocking ring implementation. Using a 64-bit index makes the possibility of
> this occurring effectively zero.
> >
> > I tested this commit's performance impact with an x86_64 build on a
> > dual-socket Xeon E5-2699 v4 using ring_perf_autotest, and the change
> > made no significant difference -- the few differences appear to be system
> noise.
> > (The test ran on isolcpus cores using a tickless scheduler, but some
> > variation was stll observed.) Each test was run three times and the
> > results were averaged:
> >
> > | 64b head/tail cycle cost minus
> > Test | 32b head/tail cycle cost
> > ------------------------------------------------------------------
> > SP/SC single enq/dequeue | 0.33
> > MP/MC single enq/dequeue | 0.00
> > SP/SC burst enq/dequeue (size 8) | 0.00 MP/MC burst enq/dequeue (size
> > 8) | 1.00 SP/SC burst enq/dequeue (size 32) | 0.00 MP/MC burst
> > enq/dequeue (size 32) | -1.00
> > SC empty dequeue | 0.01
> > MC empty dequeue | 0.00
> >
> > Single lcore:
> > SP/SC bulk enq/dequeue (size 8) | -0.36
> > MP/MC bulk enq/dequeue (size 8) | 0.99
> > SP/SC bulk enq/dequeue (size 32) | -0.40 MP/MC bulk enq/dequeue (size
> > 32) | -0.57
> >
> > Two physical cores:
> > SP/SC bulk enq/dequeue (size 8) | -0.49
> > MP/MC bulk enq/dequeue (size 8) | 0.19
> > SP/SC bulk enq/dequeue (size 32) | -0.28 MP/MC bulk enq/dequeue (size
> > 32) | -0.62
> >
> > Two NUMA nodes:
> > SP/SC bulk enq/dequeue (size 8) | 3.25
> > MP/MC bulk enq/dequeue (size 8) | 1.87
> > SP/SC bulk enq/dequeue (size 32) | -0.44 MP/MC bulk enq/dequeue (size
> > 32) | -1.10
> >
> > An earlier version of this patch changed the head and tail indexes to
> > uint64_t, but that caused a performance drop on 32-bit builds. With
> > uintptr_t, no performance difference is observed on an i686 build.
> >
> > Signed-off-by: Gage Eads <gage.eads@intel.com>
> > ---
>
> You're breaking the ABI - version bump for affected libraries is needed.
>
> --
> Thanks,
> Anatoly
If I'm reading the versioning guidelines correctly, I'll need to gate the changes with the RTE_NEXT_ABI macro and provide a deprecation notice, then after a full deprecation cycle we can revert that and bump the library version. Not to mention the 3 ML ACKs.
I'll address this in v2.
Thanks,
Gage
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width size
2019-01-11 19:12 0% ` Eads, Gage
@ 2019-01-11 19:55 3% ` Stephen Hemminger
2019-01-15 15:48 4% ` Eads, Gage
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-01-11 19:55 UTC (permalink / raw)
To: Eads, Gage
Cc: Burakov, Anatoly, dev, olivier.matz, arybchenko, Richardson,
Bruce, Ananyev, Konstantin
On Fri, 11 Jan 2019 19:12:40 +0000
"Eads, Gage" <gage.eads@intel.com> wrote:
> > -----Original Message-----
> > From: Burakov, Anatoly
> > Sent: Friday, January 11, 2019 4:25 AM
> > To: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org
> > Cc: olivier.matz@6wind.com; arybchenko@solarflare.com; Richardson, Bruce
> > <bruce.richardson@intel.com>; Ananyev, Konstantin
> > <konstantin.ananyev@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width
> > size
> >
> > On 10-Jan-19 9:01 PM, Gage Eads wrote:
> > > For 64-bit architectures, doubling the head and tail index widths
> > > greatly increases the time it takes for them to wrap-around (with
> > > current CPU speeds, it won't happen within the author's lifetime).
> > > This is important in avoiding the ABA problem -- in which a thread
> > > mistakes reading the same tail index in two accesses to mean that the
> > > ring was not modified in the intervening time -- in the upcoming
> > > non-blocking ring implementation. Using a 64-bit index makes the possibility of
> > this occurring effectively zero.
> > >
> > > I tested this commit's performance impact with an x86_64 build on a
> > > dual-socket Xeon E5-2699 v4 using ring_perf_autotest, and the change
> > > made no significant difference -- the few differences appear to be system
> > noise.
> > > (The test ran on isolcpus cores using a tickless scheduler, but some
> > > variation was stll observed.) Each test was run three times and the
> > > results were averaged:
> > >
> > > | 64b head/tail cycle cost minus
> > > Test | 32b head/tail cycle cost
> > > ------------------------------------------------------------------
> > > SP/SC single enq/dequeue | 0.33
> > > MP/MC single enq/dequeue | 0.00
> > > SP/SC burst enq/dequeue (size 8) | 0.00 MP/MC burst enq/dequeue (size
> > > 8) | 1.00 SP/SC burst enq/dequeue (size 32) | 0.00 MP/MC burst
> > > enq/dequeue (size 32) | -1.00
> > > SC empty dequeue | 0.01
> > > MC empty dequeue | 0.00
> > >
> > > Single lcore:
> > > SP/SC bulk enq/dequeue (size 8) | -0.36
> > > MP/MC bulk enq/dequeue (size 8) | 0.99
> > > SP/SC bulk enq/dequeue (size 32) | -0.40 MP/MC bulk enq/dequeue (size
> > > 32) | -0.57
> > >
> > > Two physical cores:
> > > SP/SC bulk enq/dequeue (size 8) | -0.49
> > > MP/MC bulk enq/dequeue (size 8) | 0.19
> > > SP/SC bulk enq/dequeue (size 32) | -0.28 MP/MC bulk enq/dequeue (size
> > > 32) | -0.62
> > >
> > > Two NUMA nodes:
> > > SP/SC bulk enq/dequeue (size 8) | 3.25
> > > MP/MC bulk enq/dequeue (size 8) | 1.87
> > > SP/SC bulk enq/dequeue (size 32) | -0.44 MP/MC bulk enq/dequeue (size
> > > 32) | -1.10
> > >
> > > An earlier version of this patch changed the head and tail indexes to
> > > uint64_t, but that caused a performance drop on 32-bit builds. With
> > > uintptr_t, no performance difference is observed on an i686 build.
> > >
> > > Signed-off-by: Gage Eads <gage.eads@intel.com>
> > > ---
> >
> > You're breaking the ABI - version bump for affected libraries is needed.
> >
> > --
> > Thanks,
> > Anatoly
>
> If I'm reading the versioning guidelines correctly, I'll need to gate the changes with the RTE_NEXT_ABI macro and provide a deprecation notice, then after a full deprecation cycle we can revert that and bump the library version. Not to mention the 3 ML ACKs.
>
> I'll address this in v2.
My understanding is that RTE_NEXT_API method is not used any more. Replaced by rte_experimental.
But this kind of change is more of a flag day event. Which means it needs to be pushed
off to a release that is planned as an ABI break (usually once a year) which would
mean 19.11.
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH 1/2] mbuf: remove deprecated macro
@ 2019-01-14 5:20 4% Yongseok Koh
0 siblings, 0 replies; 200+ results
From: Yongseok Koh @ 2019-01-14 5:20 UTC (permalink / raw)
To: konstantin.ananyev, olivier.matz, thomas; +Cc: dev
RTE_MBUF_INDIRECT() is replaced with RTE_MBUF_CLONED() and removed.
This macro was deprecated in release 18.05 when EXT_ATTACHED_MBUF was
introduced.
Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
---
doc/guides/rel_notes/deprecation.rst | 7 -------
doc/guides/rel_notes/release_19_02.rst | 3 +++
drivers/net/mlx4/mlx4_rxtx.h | 2 +-
drivers/net/mlx5/mlx5_rxtx.h | 2 +-
lib/librte_mbuf/rte_mbuf.h | 8 +-------
test/bpf/mbuf.h | 13 ++++++++++---
6 files changed, 16 insertions(+), 19 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index bab82865fb..5f03443f88 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -44,13 +44,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* mbuf: the macro ``RTE_MBUF_INDIRECT()`` will be removed in v18.08 or later and
- replaced with ``RTE_MBUF_CLONED()`` which is already added in v18.05. As
- ``EXT_ATTACHED_MBUF`` is newly introduced in v18.05, ``RTE_MBUF_INDIRECT()``
- can no longer be mutually exclusive with ``RTE_MBUF_DIRECT()`` if the new
- experimental API ``rte_pktmbuf_attach_extbuf()`` is used. Removal of the macro
- is to fix this semantic inconsistency.
-
* ethdev: the legacy filter API, including
``rte_eth_dev_filter_supported()``, ``rte_eth_dev_filter_ctrl()`` as well
as filter types MACVLAN, ETHERTYPE, FLEXIBLE, SYN, NTUPLE, TUNNEL, FDIR,
diff --git a/doc/guides/rel_notes/release_19_02.rst b/doc/guides/rel_notes/release_19_02.rst
index 5a46f1acdc..c4ad072412 100644
--- a/doc/guides/rel_notes/release_19_02.rst
+++ b/doc/guides/rel_notes/release_19_02.rst
@@ -210,6 +210,9 @@ API Changes
function from now on. Failed to do so will cause
``rte_cryptodev_sym_session_create()`` function call return error.
+* mbuf: ``RTE_MBUF_INDIRECT()``, which was deprecated in 18.05, was replaced
+ with ``RTE_MBUF_CLONED()`` and removed in 19.02.
+
ABI Changes
-----------
diff --git a/drivers/net/mlx4/mlx4_rxtx.h b/drivers/net/mlx4/mlx4_rxtx.h
index d7ec4e0c5f..a5ef5c2ae8 100644
--- a/drivers/net/mlx4/mlx4_rxtx.h
+++ b/drivers/net/mlx4/mlx4_rxtx.h
@@ -179,7 +179,7 @@ uint32_t mlx4_tx_update_ext_mp(struct txq *txq, uintptr_t addr,
static inline struct rte_mempool *
mlx4_mb2mp(struct rte_mbuf *buf)
{
- if (unlikely(RTE_MBUF_INDIRECT(buf)))
+ if (unlikely(RTE_MBUF_CLONED(buf)))
return rte_mbuf_from_indirect(buf)->pool;
return buf->pool;
}
diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h
index 75194a3fac..c2529f96bc 100644
--- a/drivers/net/mlx5/mlx5_rxtx.h
+++ b/drivers/net/mlx5/mlx5_rxtx.h
@@ -622,7 +622,7 @@ mlx5_tx_complete(struct mlx5_txq_data *txq)
static inline struct rte_mempool *
mlx5_mb2mp(struct rte_mbuf *buf)
{
- if (unlikely(RTE_MBUF_INDIRECT(buf)))
+ if (unlikely(RTE_MBUF_CLONED(buf)))
return rte_mbuf_from_indirect(buf)->pool;
return buf->pool;
}
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index bc562dc8a9..6f1f7e3d8e 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -831,12 +831,6 @@ rte_mbuf_to_priv(struct rte_mbuf *m)
#define RTE_MBUF_CLONED(mb) ((mb)->ol_flags & IND_ATTACHED_MBUF)
/**
- * Deprecated.
- * Use RTE_MBUF_CLONED().
- */
-#define RTE_MBUF_INDIRECT(mb) RTE_MBUF_CLONED(mb)
-
-/**
* Returns TRUE if given mbuf has an external buffer, or FALSE otherwise.
*
* External buffer is a user-provided anonymous buffer.
@@ -1629,7 +1623,7 @@ __rte_pktmbuf_free_direct(struct rte_mbuf *m)
{
struct rte_mbuf *md;
- RTE_ASSERT(RTE_MBUF_INDIRECT(m));
+ RTE_ASSERT(RTE_MBUF_CLONED(m));
md = rte_mbuf_from_indirect(m);
diff --git a/test/bpf/mbuf.h b/test/bpf/mbuf.h
index f24f908d72..b623d8694f 100644
--- a/test/bpf/mbuf.h
+++ b/test/bpf/mbuf.h
@@ -520,14 +520,21 @@ struct rte_mbuf {
/**
- * Returns TRUE if given mbuf is indirect, or FALSE otherwise.
+ * Returns TRUE if given mbuf is cloned by mbuf indirection, or FALSE
+ * otherwise.
+ *
+ * If a mbuf has its data in another mbuf and references it by mbuf
+ * indirection, this mbuf can be defined as a cloned mbuf.
*/
-#define RTE_MBUF_INDIRECT(mb) ((mb)->ol_flags & IND_ATTACHED_MBUF)
+#define RTE_MBUF_CLONED(mb) ((mb)->ol_flags & IND_ATTACHED_MBUF)
/**
* Returns TRUE if given mbuf is direct, or FALSE otherwise.
+ *
+ * If a mbuf embeds its own data after the rte_mbuf structure, this mbuf
+ * can be defined as a direct mbuf.
*/
-#define RTE_MBUF_DIRECT(mb) (!RTE_MBUF_INDIRECT(mb))
+#define RTE_MBUF_DIRECT(mb) (!RTE_MBUF_CLONED(mb))
/**
* Private data in case of pktmbuf pool.
--
2.11.0
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [EXT] [PATCH v3 5/6] spinlock: reimplement with atomic one-way barrier builtins
@ 2019-01-14 5:54 3% ` Honnappa Nagarahalli
2019-01-14 7:39 0% ` Jerin Jacob Kollanukkaran
2019-01-14 7:57 0% ` Gavin Hu (Arm Technology China)
0 siblings, 2 replies; 200+ results
From: Honnappa Nagarahalli @ 2019-01-14 5:54 UTC (permalink / raw)
To: Gavin Hu (Arm Technology China), jerinj, dev
Cc: david.marchand, chaozhu, nd, bruce.richardson, thomas,
hemant.agrawal, stephen, Joyce Kong (Arm Technology China),
nd
> >
> > On Thu, 2018-12-27 at 12:13 +0800, Gavin Hu wrote:
> > -------------------------------------------------------------------
> > > ---
> > > The __sync builtin based implementation generates full memory
> > > barriers ('dmb ish') on Arm platforms. Using C11 atomic builtins to
> > > generate one way barriers.
> > >
> > > Here is the assembly code of __sync_compare_and_swap builtin.
> > > __sync_bool_compare_and_swap(dst, exp, src);
> > > 0x000000000090f1b0 <+16>: e0 07 40 f9 ldr x0, [sp, #8]
> > > 0x000000000090f1b4 <+20>: e1 0f 40 79 ldrh w1, [sp, #6]
> > > 0x000000000090f1b8 <+24>: e2 0b 40 79 ldrh w2, [sp, #4]
> > > 0x000000000090f1bc <+28>: 21 3c 00 12 and w1, w1, #0xffff
> > > 0x000000000090f1c0 <+32>: 03 7c 5f 48 ldxrh w3, [x0]
> > > 0x000000000090f1c4 <+36>: 7f 00 01 6b cmp w3, w1
> > > 0x000000000090f1c8 <+40>: 61 00 00 54 b.ne 0x90f1d4
> > > <rte_atomic16_cmpset+52> // b.any
> > > 0x000000000090f1cc <+44>: 02 fc 04 48 stlxrh w4, w2, [x0]
> > > 0x000000000090f1d0 <+48>: 84 ff ff 35 cbnz w4, 0x90f1c0
> > > <rte_atomic16_cmpset+32>
> > > 0x000000000090f1d4 <+52>: bf 3b 03 d5 dmb ish
> > > 0x000000000090f1d8 <+56>: e0 17 9f 1a cset w0, eq // eq =
> > > none
> > >
> > > The benchmarking results showed 3X performance gain on Cavium
> > > ThunderX2 and
> > > 13% on Qualcomm Falmon and 3.7% on 4-A72 Marvell macchiatobin.
> > > Here is the example test result on TX2:
> > >
> > > *** spinlock_autotest without this patch *** Core [123] Cost Time =
> > > 639822 us Core [124] Cost Time = 633253 us Core [125] Cost Time =
> > > 646030 us Core [126] Cost Time = 643189 us Core [127] Cost Time =
> > > 647039 us Total Cost Time = 95433298 us
> > >
> > > *** spinlock_autotest with this patch *** Core [123] Cost Time =
> > > 163615 us Core [124] Cost Time = 166471 us Core [125] Cost Time =
> > > 189044 us Core [126] Cost Time = 195745 us Core [127] Cost Time =
> > > 78423 us Total Cost Time = 27339656 us
> > >
> > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > Reviewed-by: Phil Yang <phil.yang@arm.com>
> > > Reviewed-by: Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>
> > > Reviewed-by: Ola Liljedahl <Ola.Liljedahl@arm.com>
> > > Reviewed-by: Steve Capper <Steve.Capper@arm.com>
> > > ---
> > > lib/librte_eal/common/include/generic/rte_spinlock.h | 18
> > > +++++++++++++-----
> > > 1 file changed, 13 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > b/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > index c4c3fc31e..87ae7a4f1 100644
> > > --- a/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > +++ b/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > @@ -61,9 +61,14 @@ rte_spinlock_lock(rte_spinlock_t *sl); static
> > > inline void rte_spinlock_lock(rte_spinlock_t *sl) {
> > > - while (__sync_lock_test_and_set(&sl->locked, 1))
> > > - while(sl->locked)
> > > + int exp = 0;
> > > +
> > > + while (!__atomic_compare_exchange_n(&sl->locked, &exp, 1, 0,
> > > + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
> > {
> >
> > How about remove explict exp = 0 and change to
> > __atomic_test_and_set(flag, __ATOMIC_ACQUIRE);
>
> Yes, __atomic_test_and_set means simpler code and better, but
> __atomic_test_and_set takes the first argument as a pointer to type bool or
> char, in our case, sl->locked is of type uint32.
> We can force it to uint8, or just pass in the 32bit pointer, only one byte/bit is
> really used in this case, is that ok?
>
> "It should be only used for operands of type bool or char. For other types only
> part of the value may be set."
> https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/_005f_005fatomic-
> Builtins.html
>
> From performance perspective, in our testing, the performance was very close,
> compared to __atomic.
If performance is close, I suggest we go with the existing patch. Changing sl->locked to bool/char would be an ABI change and will affect x86 TM based implementation as well.
Jerin, what do you think?
>
> >
> > i.e
> > while (_atomic_test_and_set(flag, __ATOMIC_ACQUIRE))
> >
> >
> >
> > > + while (__atomic_load_n(&sl->locked, __ATOMIC_RELAXED))
> > > rte_pause();
> > > + exp = 0;
> >
> > We can remove exp = 0 with above scheme.
> >
> > > + }
> > > }
> > > #endif
> > >
> > > @@ -80,7 +85,7 @@ rte_spinlock_unlock (rte_spinlock_t *sl); static
> > > inline void rte_spinlock_unlock (rte_spinlock_t *sl) {
> > > - __sync_lock_release(&sl->locked);
> > > + __atomic_store_n(&sl->locked, 0, __ATOMIC_RELEASE);
> > }
> > > #endif
> > >
> > > @@ -99,7 +104,10 @@ rte_spinlock_trylock (rte_spinlock_t *sl);
> > > static inline int rte_spinlock_trylock (rte_spinlock_t *sl) {
> > > - return __sync_lock_test_and_set(&sl->locked,1) == 0;
> > > + int exp = 0;
> > > + return __atomic_compare_exchange_n(&sl->locked, &exp, 1,
> > > + 0, /* disallow spurious failure */
> > > + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
> >
> > Here to remove explicit exp.
> >
> > return (__atomic_test_and_set(flag, __ATOMIC_ACQUIRE) == 0)
> >
> >
> > > }
> > > #endif
> > >
> > > @@ -113,7 +121,7 @@ rte_spinlock_trylock (rte_spinlock_t *sl)
> > > */
> > > static inline int rte_spinlock_is_locked (rte_spinlock_t *sl) {
> > > - return sl->locked;
> > > + return __atomic_load_n(&sl->locked, __ATOMIC_ACQUIRE);
> >
> > __ATOMIC_RELAXED would be enough here. Right ?
> >
> >
> > > }
> > >
> > > /**
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [EXT] [PATCH v3 5/6] spinlock: reimplement with atomic one-way barrier builtins
2019-01-14 5:54 3% ` Honnappa Nagarahalli
@ 2019-01-14 7:39 0% ` Jerin Jacob Kollanukkaran
2019-01-14 17:08 0% ` Gavin Hu (Arm Technology China)
2019-01-14 7:57 0% ` Gavin Hu (Arm Technology China)
1 sibling, 1 reply; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-01-14 7:39 UTC (permalink / raw)
To: Honnappa.Nagarahalli, Gavin.Hu, dev
Cc: david.marchand, chaozhu, nd, bruce.richardson, thomas,
Joyce.Kong, hemant.agrawal, stephen
On Mon, 2019-01-14 at 05:54 +0000, Honnappa Nagarahalli wrote:
> > > On Thu, 2018-12-27 at 12:13 +0800, Gavin Hu wrote:
> > > ---------------------------------------------------------------
> > > ----
> > > > ---
> > > > The __sync builtin based implementation generates full memory
> > > > barriers ('dmb ish') on Arm platforms. Using C11 atomic
> > > > builtins to
> > > > generate one way barriers.
> > > >
> > > > Here is the assembly code of __sync_compare_and_swap builtin.
> > > > __sync_bool_compare_and_swap(dst, exp, src);
> > > > 0x000000000090f1b0 <+16>: e0 07 40 f9 ldr x0, [sp, #8]
> > > > 0x000000000090f1b4 <+20>: e1 0f 40 79 ldrh w1, [sp,
> > > > #6]
> > > > 0x000000000090f1b8 <+24>: e2 0b 40 79 ldrh w2, [sp,
> > > > #4]
> > > > 0x000000000090f1bc <+28>: 21 3c 00 12 and w1, w1, #0xffff
> > > > 0x000000000090f1c0 <+32>: 03 7c 5f 48 ldxrh w3, [x0]
> > > > 0x000000000090f1c4 <+36>: 7f 00 01 6b cmp w3, w1
> > > > 0x000000000090f1c8 <+40>: 61 00 00 54 b.ne 0x90f1d4
> > > > <rte_atomic16_cmpset+52> // b.any
> > > > 0x000000000090f1cc <+44>: 02 fc 04 48 stlxrh w4, w2,
> > > > [x0]
> > > > 0x000000000090f1d0 <+48>: 84 ff ff 35 cbnz w4,
> > > > 0x90f1c0
> > > > <rte_atomic16_cmpset+32>
> > > > 0x000000000090f1d4 <+52>: bf 3b 03 d5 dmb ish
> > > > 0x000000000090f1d8 <+56>: e0 17 9f 1a cset w0, eq //
> > > > eq =
> > > > none
> > > >
> > > > The benchmarking results showed 3X performance gain on Cavium
> > > > ThunderX2 and
> > > > 13% on Qualcomm Falmon and 3.7% on 4-A72 Marvell macchiatobin.
> > > > Here is the example test result on TX2:
> > > >
> > > > *** spinlock_autotest without this patch *** Core [123] Cost
> > > > Time =
> > > > 639822 us Core [124] Cost Time = 633253 us Core [125] Cost Time
> > > > =
> > > > 646030 us Core [126] Cost Time = 643189 us Core [127] Cost Time
> > > > =
> > > > 647039 us Total Cost Time = 95433298 us
> > > >
> > > > *** spinlock_autotest with this patch *** Core [123] Cost Time
> > > > =
> > > > 163615 us Core [124] Cost Time = 166471 us Core [125] Cost Time
> > > > =
> > > > 189044 us Core [126] Cost Time = 195745 us Core [127] Cost Time
> > > > =
> > > > 78423 us Total Cost Time = 27339656 us
> > > >
> > > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > > Reviewed-by: Phil Yang <phil.yang@arm.com>
> > > > Reviewed-by: Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com
> > > > >
> > > > Reviewed-by: Ola Liljedahl <Ola.Liljedahl@arm.com>
> > > > Reviewed-by: Steve Capper <Steve.Capper@arm.com>
> > > > ---
> > > > lib/librte_eal/common/include/generic/rte_spinlock.h | 18
> > > > +++++++++++++-----
> > > > 1 file changed, 13 insertions(+), 5 deletions(-)
> > > >
> > > > diff --git
> > > > a/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > > b/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > > index c4c3fc31e..87ae7a4f1 100644
> > > > --- a/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > > +++ b/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > > @@ -61,9 +61,14 @@ rte_spinlock_lock(rte_spinlock_t
> > > > *sl); static
> > > > inline void rte_spinlock_lock(rte_spinlock_t *sl) {
> > > > - while (__sync_lock_test_and_set(&sl->locked, 1))
> > > > - while(sl->locked)
> > > > + int exp = 0;
> > > > +
> > > > + while (!__atomic_compare_exchange_n(&sl->locked, &exp,
> > > > 1, 0,
> > > > + __ATOMIC_ACQUIRE,
> > > > __ATOMIC_RELAXED))
> > > {
> > >
> > > How about remove explict exp = 0 and change to
> > > __atomic_test_and_set(flag, __ATOMIC_ACQUIRE);
> >
> > Yes, __atomic_test_and_set means simpler code and better, but
> > __atomic_test_and_set takes the first argument as a pointer to type
> > bool or
> > char, in our case, sl->locked is of type uint32.
> > We can force it to uint8, or just pass in the 32bit pointer, only
> > one byte/bit is
> > really used in this case, is that ok?
> >
> > "It should be only used for operands of type bool or char. For
> > other types only
> > part of the value may be set."
> > https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/_005f_005fatomic-
> > Builtins.html
> >
> > From performance perspective, in our testing, the performance was
> > very close,
> > compared to __atomic.
> If performance is close, I suggest we go with the existing patch.
> Changing sl->locked to bool/char would be an ABI change and will
> affect x86 TM based implementation as well.
> Jerin, what do you think?
Looks good to me.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [EXT] [PATCH v3 5/6] spinlock: reimplement with atomic one-way barrier builtins
2019-01-14 5:54 3% ` Honnappa Nagarahalli
2019-01-14 7:39 0% ` Jerin Jacob Kollanukkaran
@ 2019-01-14 7:57 0% ` Gavin Hu (Arm Technology China)
1 sibling, 0 replies; 200+ results
From: Gavin Hu (Arm Technology China) @ 2019-01-14 7:57 UTC (permalink / raw)
To: Honnappa Nagarahalli, jerinj, dev
Cc: david.marchand, chaozhu, nd, bruce.richardson, thomas,
hemant.agrawal, stephen, Joyce Kong (Arm Technology China),
nd
> -----Original Message-----
> From: Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>
> Sent: Monday, January 14, 2019 1:55 PM
> To: Gavin Hu (Arm Technology China) <Gavin.Hu@arm.com>;
> jerinj@marvell.com; dev@dpdk.org
> Cc: david.marchand@redhat.com; chaozhu@linux.vnet.ibm.com; nd
> <nd@arm.com>; bruce.richardson@intel.com; thomas@monjalon.net;
> hemant.agrawal@nxp.com; stephen@networkplumber.org; Joyce Kong (Arm
> Technology China) <Joyce.Kong@arm.com>; nd <nd@arm.com>
> Subject: RE: [EXT] [PATCH v3 5/6] spinlock: reimplement with atomic one-
> way barrier builtins
>
> > >
> > > On Thu, 2018-12-27 at 12:13 +0800, Gavin Hu wrote:
> > > -------------------------------------------------------------------
> > > > ---
> > > > The __sync builtin based implementation generates full memory
> > > > barriers ('dmb ish') on Arm platforms. Using C11 atomic builtins to
> > > > generate one way barriers.
> > > >
> > > > Here is the assembly code of __sync_compare_and_swap builtin.
> > > > __sync_bool_compare_and_swap(dst, exp, src);
> > > > 0x000000000090f1b0 <+16>: e0 07 40 f9 ldr x0, [sp, #8]
> > > > 0x000000000090f1b4 <+20>: e1 0f 40 79 ldrh w1, [sp, #6]
> > > > 0x000000000090f1b8 <+24>: e2 0b 40 79 ldrh w2, [sp, #4]
> > > > 0x000000000090f1bc <+28>: 21 3c 00 12 and w1, w1, #0xffff
> > > > 0x000000000090f1c0 <+32>: 03 7c 5f 48 ldxrh w3, [x0]
> > > > 0x000000000090f1c4 <+36>: 7f 00 01 6b cmp w3, w1
> > > > 0x000000000090f1c8 <+40>: 61 00 00 54 b.ne 0x90f1d4
> > > > <rte_atomic16_cmpset+52> // b.any
> > > > 0x000000000090f1cc <+44>: 02 fc 04 48 stlxrh w4, w2, [x0]
> > > > 0x000000000090f1d0 <+48>: 84 ff ff 35 cbnz w4, 0x90f1c0
> > > > <rte_atomic16_cmpset+32>
> > > > 0x000000000090f1d4 <+52>: bf 3b 03 d5 dmb ish
> > > > 0x000000000090f1d8 <+56>: e0 17 9f 1a cset w0, eq // eq =
> > > > none
> > > >
> > > > The benchmarking results showed 3X performance gain on Cavium
> > > > ThunderX2 and
> > > > 13% on Qualcomm Falmon and 3.7% on 4-A72 Marvell macchiatobin.
> > > > Here is the example test result on TX2:
> > > >
> > > > *** spinlock_autotest without this patch *** Core [123] Cost Time =
> > > > 639822 us Core [124] Cost Time = 633253 us Core [125] Cost Time =
> > > > 646030 us Core [126] Cost Time = 643189 us Core [127] Cost Time =
> > > > 647039 us Total Cost Time = 95433298 us
> > > >
> > > > *** spinlock_autotest with this patch *** Core [123] Cost Time =
> > > > 163615 us Core [124] Cost Time = 166471 us Core [125] Cost Time =
> > > > 189044 us Core [126] Cost Time = 195745 us Core [127] Cost Time =
> > > > 78423 us Total Cost Time = 27339656 us
> > > >
> > > > Signed-off-by: Gavin Hu <gavin.hu@arm.com>
> > > > Reviewed-by: Phil Yang <phil.yang@arm.com>
> > > > Reviewed-by: Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>
> > > > Reviewed-by: Ola Liljedahl <Ola.Liljedahl@arm.com>
> > > > Reviewed-by: Steve Capper <Steve.Capper@arm.com>
> > > > ---
> > > > lib/librte_eal/common/include/generic/rte_spinlock.h | 18
> > > > +++++++++++++-----
> > > > 1 file changed, 13 insertions(+), 5 deletions(-)
> > > >
> > > > diff --git a/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > > b/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > > index c4c3fc31e..87ae7a4f1 100644
> > > > --- a/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > > +++ b/lib/librte_eal/common/include/generic/rte_spinlock.h
> > > > @@ -61,9 +61,14 @@ rte_spinlock_lock(rte_spinlock_t *sl); static
> > > > inline void rte_spinlock_lock(rte_spinlock_t *sl) {
> > > > - while (__sync_lock_test_and_set(&sl->locked, 1))
> > > > - while(sl->locked)
> > > > + int exp = 0;
> > > > +
> > > > + while (!__atomic_compare_exchange_n(&sl->locked, &exp, 1, 0,
> > > > + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
> > > {
> > >
> > > How about remove explict exp = 0 and change to
> > > __atomic_test_and_set(flag, __ATOMIC_ACQUIRE);
> >
> > Yes, __atomic_test_and_set means simpler code and better, but
> > __atomic_test_and_set takes the first argument as a pointer to type bool
> or
> > char, in our case, sl->locked is of type uint32.
> > We can force it to uint8, or just pass in the 32bit pointer, only one byte/bit
> is
> > really used in this case, is that ok?
> >
> > "It should be only used for operands of type bool or char. For other types
> only
> > part of the value may be set."
> > https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/_005f_005fatomic-
> > Builtins.html
> >
> > From performance perspective, in our testing, the performance was very
> close,
> > compared to __atomic.
> If performance is close, I suggest we go with the existing patch. Changing sl-
> >locked to bool/char would be an ABI change and will affect x86 TM based
> implementation as well.
> Jerin, what do you think?
I have benchmarked on Qualcomm, ThunderX2 and Context A72.
In comparison to the existing patch, on the new patch using __atomic_test_and_set, Qualcomm Falkor gained 60% performance, 4-core A72 degraded 13%, ThunderX2 even worse, degraded 10 times.
I am not sure why ThunderX2 degraded so much, maybe it was caused by two many cores (128 cores) with high contention?
>
> >
> > >
> > > i.e
> > > while (_atomic_test_and_set(flag, __ATOMIC_ACQUIRE))
> > >
> > >
> > >
> > > > + while (__atomic_load_n(&sl->locked, __ATOMIC_RELAXED))
> > > > rte_pause();
> > > > + exp = 0;
> > >
> > > We can remove exp = 0 with above scheme.
> > >
> > > > + }
> > > > }
> > > > #endif
> > > >
> > > > @@ -80,7 +85,7 @@ rte_spinlock_unlock (rte_spinlock_t *sl); static
> > > > inline void rte_spinlock_unlock (rte_spinlock_t *sl) {
> > > > - __sync_lock_release(&sl->locked);
> > > > + __atomic_store_n(&sl->locked, 0, __ATOMIC_RELEASE);
> > > }
> > > > #endif
> > > >
> > > > @@ -99,7 +104,10 @@ rte_spinlock_trylock (rte_spinlock_t *sl);
> > > > static inline int rte_spinlock_trylock (rte_spinlock_t *sl) {
> > > > - return __sync_lock_test_and_set(&sl->locked,1) == 0;
> > > > + int exp = 0;
> > > > + return __atomic_compare_exchange_n(&sl->locked, &exp, 1,
> > > > + 0, /* disallow spurious failure */
> > > > + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
> > >
> > > Here to remove explicit exp.
> > >
> > > return (__atomic_test_and_set(flag, __ATOMIC_ACQUIRE) == 0)
> > >
> > >
> > > > }
> > > > #endif
> > > >
> > > > @@ -113,7 +121,7 @@ rte_spinlock_trylock (rte_spinlock_t *sl)
> > > > */
> > > > static inline int rte_spinlock_is_locked (rte_spinlock_t *sl) {
> > > > - return sl->locked;
> > > > + return __atomic_load_n(&sl->locked, __ATOMIC_ACQUIRE);
> > >
> > > __ATOMIC_RELAXED would be enough here. Right ?
> > >
> > >
> > > > }
> > > >
> > > > /**
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] eal: fix strdup usages in internal config
2019-01-10 13:38 2% [dpdk-dev] [PATCH] eal: fix strdup usages in internal config Anatoly Burakov
@ 2019-01-14 14:18 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-01-14 14:18 UTC (permalink / raw)
To: Anatoly Burakov; +Cc: dev, Bruce Richardson, ferruh.yigit, andy01011501
10/01/2019 14:38, Anatoly Burakov:
> Currently, we use strdup in a few places to store command-line
> parameter values for certain internal config values. There are
> several issues with that.
>
> First of all, they're never freed, so memory ends up leaking
> either after EAL exit, or when these command-line options are
> supplied multiple times.
>
> Second of all, they're defined as `const char *`, so they
> *cannot* be freed even if we wanted to.
>
> Finally, strdup may return NULL, which will be stored in the
> config. For most fields, NULL is a valid value, but for the
> default prefix, the value is always expected to be valid.
>
> To fix all of this, three things are done. First, we change
> the definitions of these values to `char *` as opposed to
> `const char *`. This does not break the ABI, and previous
> code assumes constness (which is more restrictive), so it's
> safe to do so.
>
> Then, fix all usages of strdup to check return value, and add
> a cleanup function that will free the memory occupied by
> these strings, as well as freeing them before assigning a new
> value to prevent leaks when parameter is specified multiple
> times.
>
> And finally, add an internal API to query hugefile prefix, so
> that, absent of a valid value, a default value will be
> returned, and also fix up all usages of hugefile prefix to
> use this API instead of accessing hugefile prefix directly.
>
> Bugzilla ID: 108
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Applied, thanks
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [EXT] [PATCH v3 5/6] spinlock: reimplement with atomic one-way barrier builtins
2019-01-14 7:39 0% ` Jerin Jacob Kollanukkaran
@ 2019-01-14 17:08 0% ` Gavin Hu (Arm Technology China)
0 siblings, 0 replies; 200+ results
From: Gavin Hu (Arm Technology China) @ 2019-01-14 17:08 UTC (permalink / raw)
To: jerinj, Honnappa Nagarahalli, dev
Cc: david.marchand, chaozhu, nd, bruce.richardson, thomas,
Joyce Kong (Arm Technology China),
hemant.agrawal, stephen
> > > > > *sl); static
> > > > > inline void rte_spinlock_lock(rte_spinlock_t *sl) {
> > > > > - while (__sync_lock_test_and_set(&sl->locked, 1))
> > > > > - while(sl->locked)
> > > > > + int exp = 0;
> > > > > +
> > > > > + while (!__atomic_compare_exchange_n(&sl->locked, &exp,
> > > > > 1, 0,
> > > > > + __ATOMIC_ACQUIRE,
> > > > > __ATOMIC_RELAXED))
> > > > {
> > > >
> > > > How about remove explict exp = 0 and change to
> > > > __atomic_test_and_set(flag, __ATOMIC_ACQUIRE);
> > >
> > > Yes, __atomic_test_and_set means simpler code and better, but
> > > __atomic_test_and_set takes the first argument as a pointer to type
> > > bool or
> > > char, in our case, sl->locked is of type uint32.
> > > We can force it to uint8, or just pass in the 32bit pointer, only
> > > one byte/bit is
> > > really used in this case, is that ok?
> > >
> > > "It should be only used for operands of type bool or char. For
> > > other types only
> > > part of the value may be set."
> > > https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/_005f_005fatomic-
> > > Builtins.html
> > >
> > > From performance perspective, in our testing, the performance was
> > > very close,
> > > compared to __atomic.
> > If performance is close, I suggest we go with the existing patch.
> > Changing sl->locked to bool/char would be an ABI change and will
> > affect x86 TM based implementation as well.
> > Jerin, what do you think?
>
> Looks good to me.
>
I tested __atomic_test_and_test based patch(I did not push this, it is in internal review), it caused 10 times performance degradation on ThunderX2.
In the internal review, Ola Liljedahl's comment well explained the degradation:
"Unlike the old code, the new code will write the lock location (and thus get exclusive access to the whole cache line) repeatedly while it is busy waiting. This is bad for the lock owner if it is accessing other data located in the same cache line as the lock (which is often the case)."
The real difference is __atomic_test_and_test keeps writing the lock location(whether it is locked or not) and monopolizing the cache line, it is bad to the lock owner and other contenders.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width size
2019-01-11 19:55 3% ` Stephen Hemminger
@ 2019-01-15 15:48 4% ` Eads, Gage
0 siblings, 0 replies; 200+ results
From: Eads, Gage @ 2019-01-15 15:48 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Burakov, Anatoly, dev, olivier.matz, arybchenko, Richardson,
Bruce, Ananyev, Konstantin
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, January 11, 2019 1:55 PM
> To: Eads, Gage <gage.eads@intel.com>
> Cc: Burakov, Anatoly <anatoly.burakov@intel.com>; dev@dpdk.org;
> olivier.matz@6wind.com; arybchenko@solarflare.com; Richardson, Bruce
> <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width
> size
>
> On Fri, 11 Jan 2019 19:12:40 +0000
> "Eads, Gage" <gage.eads@intel.com> wrote:
>
> > > -----Original Message-----
> > > From: Burakov, Anatoly
> > > Sent: Friday, January 11, 2019 4:25 AM
> > > To: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org
> > > Cc: olivier.matz@6wind.com; arybchenko@solarflare.com; Richardson,
> > > Bruce <bruce.richardson@intel.com>; Ananyev, Konstantin
> > > <konstantin.ananyev@intel.com>
> > > Subject: Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to
> > > pointer-width size
> > >
> > > On 10-Jan-19 9:01 PM, Gage Eads wrote:
> > > > For 64-bit architectures, doubling the head and tail index widths
> > > > greatly increases the time it takes for them to wrap-around (with
> > > > current CPU speeds, it won't happen within the author's lifetime).
> > > > This is important in avoiding the ABA problem -- in which a thread
> > > > mistakes reading the same tail index in two accesses to mean that
> > > > the ring was not modified in the intervening time -- in the
> > > > upcoming non-blocking ring implementation. Using a 64-bit index
> > > > makes the possibility of
> > > this occurring effectively zero.
> > > >
> > > > I tested this commit's performance impact with an x86_64 build on
> > > > a dual-socket Xeon E5-2699 v4 using ring_perf_autotest, and the
> > > > change made no significant difference -- the few differences
> > > > appear to be system
> > > noise.
> > > > (The test ran on isolcpus cores using a tickless scheduler, but
> > > > some variation was stll observed.) Each test was run three times
> > > > and the results were averaged:
> > > >
> > > > | 64b head/tail cycle cost minus
> > > > Test | 32b head/tail cycle cost
> > > > ------------------------------------------------------------------
> > > > SP/SC single enq/dequeue | 0.33
> > > > MP/MC single enq/dequeue | 0.00
> > > > SP/SC burst enq/dequeue (size 8) | 0.00 MP/MC burst enq/dequeue
> > > > (size
> > > > 8) | 1.00 SP/SC burst enq/dequeue (size 32) | 0.00 MP/MC burst
> > > > enq/dequeue (size 32) | -1.00
> > > > SC empty dequeue | 0.01
> > > > MC empty dequeue | 0.00
> > > >
> > > > Single lcore:
> > > > SP/SC bulk enq/dequeue (size 8) | -0.36
> > > > MP/MC bulk enq/dequeue (size 8) | 0.99
> > > > SP/SC bulk enq/dequeue (size 32) | -0.40 MP/MC bulk enq/dequeue
> > > > (size
> > > > 32) | -0.57
> > > >
> > > > Two physical cores:
> > > > SP/SC bulk enq/dequeue (size 8) | -0.49
> > > > MP/MC bulk enq/dequeue (size 8) | 0.19
> > > > SP/SC bulk enq/dequeue (size 32) | -0.28 MP/MC bulk enq/dequeue
> > > > (size
> > > > 32) | -0.62
> > > >
> > > > Two NUMA nodes:
> > > > SP/SC bulk enq/dequeue (size 8) | 3.25
> > > > MP/MC bulk enq/dequeue (size 8) | 1.87
> > > > SP/SC bulk enq/dequeue (size 32) | -0.44 MP/MC bulk enq/dequeue
> > > > (size
> > > > 32) | -1.10
> > > >
> > > > An earlier version of this patch changed the head and tail indexes
> > > > to uint64_t, but that caused a performance drop on 32-bit builds.
> > > > With uintptr_t, no performance difference is observed on an i686 build.
> > > >
> > > > Signed-off-by: Gage Eads <gage.eads@intel.com>
> > > > ---
> > >
> > > You're breaking the ABI - version bump for affected libraries is needed.
> > >
> > > --
> > > Thanks,
> > > Anatoly
> >
> > If I'm reading the versioning guidelines correctly, I'll need to gate the changes
> with the RTE_NEXT_ABI macro and provide a deprecation notice, then after a
> full deprecation cycle we can revert that and bump the library version. Not to
> mention the 3 ML ACKs.
> >
> > I'll address this in v2.
>
> My understanding is that RTE_NEXT_API method is not used any more. Replaced
> by rte_experimental.
> But this kind of change is more of a flag day event. Which means it needs to be
> pushed off to a release that is planned as an ABI break (usually once a year)
> which would mean 19.11.
In recent release notes, I see ABI changes can happen more frequently than once per year; 18.11, 18.05, 17.11, and 17.08 have ABI changes -- and soon 19.02 will too.
At any rate, I'll create a separate deprecation notice patch and update this patchset accordingly.
Thanks,
Gage
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field
2018-12-20 12:16 1% ` [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field Reshma Pattan
2018-12-20 14:55 0% ` Rao, Nikhil
@ 2019-01-15 22:37 3% ` Stephen Hemminger
2019-01-16 9:19 0% ` Pattan, Reshma
2019-01-15 23:11 4% ` Stephen Hemminger
2 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-01-15 22:37 UTC (permalink / raw)
To: Reshma Pattan
Cc: dev, jerin.jacob, nikhil.rao, olivier.matz, thomas,
jasvinder.singh, cristian.dumitrescu, konstantin.ananyev
On Thu, 20 Dec 2018 12:16:09 +0000
Reshma Pattan <reshma.pattan@intel.com> wrote:
> This patch implements the changes proposed in the deprecation
> notes [1][2].
>
> librte_mbuf changes:
> The mbuf->hash.sched field is updated to support generic
> definition in line with the ethdev traffic manager and meter APIs.
> The new generic format contains: queue ID, traffic class, color.
>
> Added public APIs to set and get these new fields to and from mbuf.
>
> librte_sched changes:
> In addtion, following API functions of the sched library have
> been modified with an additional parameter of type struct
> rte_sched_port to accommodate the changes made to mbuf sched field.
> (i)rte_sched_port_pkt_write()
> (ii) rte_sched_port_pkt_read_tree_path()
>
> librte_pipeline, qos_sched UT, qos_sched app are updated
> to make use of new changes.
>
> Also mbuf->hash.txadapter has been added for eventdev txq,
> rte_event_eth_tx_adapter_txq_set and rte_event_eth_tx_adapter_txq_get()
> are updated to use mbuf->hash.txadapter.txq.
>
> doc:
> Release notes updated.
> Removed deprecation notice for mbuf->hash.sched and sched API.
>
> [1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
> [2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
>
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
This patch breaks build of VPP because it refers to sched.hi and sched.lo.
Breaking source compatibility is as bad (if not worse) than ABI breakage.
Maybe make the sched field a union?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field
2018-12-20 12:16 1% ` [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field Reshma Pattan
2018-12-20 14:55 0% ` Rao, Nikhil
2019-01-15 22:37 3% ` Stephen Hemminger
@ 2019-01-15 23:11 4% ` Stephen Hemminger
2019-01-16 8:41 0% ` Thomas Monjalon
2 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-01-15 23:11 UTC (permalink / raw)
To: Reshma Pattan
Cc: dev, jerin.jacob, nikhil.rao, olivier.matz, thomas,
jasvinder.singh, cristian.dumitrescu, konstantin.ananyev
On Thu, 20 Dec 2018 12:16:09 +0000
Reshma Pattan <reshma.pattan@intel.com> wrote:
> void
> -rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> - uint32_t subport, uint32_t pipe, uint32_t traffic_class,
> +rte_sched_port_pkt_write(struct rte_sched_port *port,
> + struct rte_mbuf *pkt,
> + uint32_t subport, uint32_t pipe,
> + uint32_t traffic_class,
> uint32_t queue, enum rte_meter_color color)
Sorry I didn't notice this earlier, but changing the function signature like
this is a complete ABI breakage. Old code will be passing different arguments than
new code; therefore this change breaks both source and binary compatibility.
Is 19.02 supposed to be an ABI/API breaking release? Or only an incremental update.
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 0/5] Add non-blocking ring
2019-01-10 21:01 4% [dpdk-dev] [PATCH 0/6] Add non-blocking ring Gage Eads
@ 2019-01-15 23:52 3% ` Gage Eads
2019-01-16 0:26 3% ` Stephen Hemminger
2019-01-18 15:23 3% ` [dpdk-dev] [PATCH v3 " Gage Eads
1 sibling, 2 replies; 200+ results
From: Gage Eads @ 2019-01-15 23:52 UTC (permalink / raw)
To: dev
Cc: olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev, stephen
For some users, the rte ring's "non-preemptive" constraint is not acceptable;
for example, if the application uses a mixture of pinned high-priority threads
and multiplexed low-priority threads that share a mempool.
This patchset introduces a non-blocking ring, on top of which a mempool can run.
Crucially, the non-blocking algorithm relies on a 128-bit compare-and-swap, so
it is limited to x86_64 machines.
The ring uses more compare-and-swap atomic operations than the regular rte ring:
With no contention, an enqueue of n pointers uses (1 + 2n) CAS operations and a
dequeue of n pointers uses 2. This algorithm has worse average-case performance
than the regular rte ring (particularly a highly-contended ring with large bulk
accesses), however:
- For applications with preemptible pthreads, the regular rte ring's worst-case
performance (i.e. one thread being preempted in the update_tail() critical
section) is much worse than the non-blocking ring's.
- Software caching can mitigate the average case performance for ring-based
algorithms. For example, a non-blocking ring based mempool (a likely use case
for this ring) with per-thread caching.
The non-blocking ring is enabled via a new flag, RING_F_NB. For ease-of-use,
existing ring enqueue/dequeue functions work with both "regular" and
non-blocking rings.
This patchset also adds non-blocking versions of ring_autotest and
ring_perf_autotest, and a non-blocking ring based mempool.
This patchset makes ABI and API changes; a deprecation notice will be
posted in a separate commit.
This patchset depends on the non-blocking stack patchset[1].
[1] http://mails.dpdk.org/archives/dev/2019-January/123470.html
v2:
- Merge separate docs commit into patch #5
- Convert uintptr_t to size_t
- Add a compile-time check for the size of size_t
- Fix a space-after-typecast issue
- Fix an unnecessary-parentheses checkpatch warning
- Bump librte_ring's library version
Gage Eads (5):
ring: change head and tail to pointer-width size
ring: add a non-blocking implementation
test_ring: add non-blocking ring autotest
test_ring_perf: add non-blocking ring perf test
mempool/ring: add non-blocking ring handlers
doc/guides/prog_guide/env_abstraction_layer.rst | 2 +-
drivers/mempool/ring/rte_mempool_ring.c | 58 ++-
lib/librte_eventdev/rte_event_ring.h | 6 +-
lib/librte_ring/Makefile | 2 +-
lib/librte_ring/meson.build | 2 +-
lib/librte_ring/rte_ring.c | 53 ++-
lib/librte_ring/rte_ring.h | 564 ++++++++++++++++++++++--
lib/librte_ring/rte_ring_generic.h | 16 +-
lib/librte_ring/rte_ring_version.map | 7 +
test/test/test_ring.c | 57 ++-
test/test/test_ring_perf.c | 19 +-
11 files changed, 699 insertions(+), 87 deletions(-)
--
2.13.6
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH] doc: announce ring ABI and API changes
@ 2019-01-15 23:59 7% Gage Eads
2019-01-16 0:34 7% ` Stephen Hemminger
2019-01-18 15:28 3% ` [dpdk-dev] [PATCH v2] doc: announce ring API change Gage Eads
0 siblings, 2 replies; 200+ results
From: Gage Eads @ 2019-01-15 23:59 UTC (permalink / raw)
To: dev
Cc: olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev, stephen
In order to support the non-blocking ring[1], one ABI change and one API
change are required in librte_ring. This commit updates the deprecation
notice to pave the way for their inclusion in 19.05.
[1] http://mails.dpdk.org/archives/dev/2019-January/123475.html
Signed-off-by: Gage Eads <gage.eads@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d4aea4b46..d74cff467 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -83,3 +83,14 @@ Deprecation Notices
- The size and layout of ``rte_cryptodev_qp_conf`` and syntax of
``rte_cryptodev_queue_pair_setup`` will change to to allow to use
two different mempools for crypto and device private sessions.
+
+* ring: two changes are planned for rte_ring in v19.05:
+
+ - The ring head and tail values are planned to be changed from ``uint32_t``
+ to ``size_t``. This reduces the likelihood of wrap-around to effectively
+ zero for 64-bit builds, which is important in avoiding the ABA problem in
+ the upcoming non-blocking ring implementation. (32-bit builds are
+ unaffected by this change.)
+ - rte_ring_get_memsize() will get a new ``flags`` parameter, so it can
+ calculate the memory required for rings that require more than 8B per entry
+ (such as the upcoming non-blocking ring).
--
2.13.6
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH v2 0/5] Add non-blocking ring
2019-01-15 23:52 3% ` [dpdk-dev] [PATCH v2 0/5] Add non-blocking ring Gage Eads
@ 2019-01-16 0:26 3% ` Stephen Hemminger
2019-01-18 15:23 3% ` [dpdk-dev] [PATCH v3 " Gage Eads
1 sibling, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-01-16 0:26 UTC (permalink / raw)
To: Gage Eads
Cc: dev, olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev
On Tue, 15 Jan 2019 17:52:22 -0600
Gage Eads <gage.eads@intel.com> wrote:
> For some users, the rte ring's "non-preemptive" constraint is not acceptable;
> for example, if the application uses a mixture of pinned high-priority threads
> and multiplexed low-priority threads that share a mempool.
>
> This patchset introduces a non-blocking ring, on top of which a mempool can run.
> Crucially, the non-blocking algorithm relies on a 128-bit compare-and-swap, so
> it is limited to x86_64 machines.
>
> The ring uses more compare-and-swap atomic operations than the regular rte ring:
> With no contention, an enqueue of n pointers uses (1 + 2n) CAS operations and a
> dequeue of n pointers uses 2. This algorithm has worse average-case performance
> than the regular rte ring (particularly a highly-contended ring with large bulk
> accesses), however:
> - For applications with preemptible pthreads, the regular rte ring's worst-case
> performance (i.e. one thread being preempted in the update_tail() critical
> section) is much worse than the non-blocking ring's.
> - Software caching can mitigate the average case performance for ring-based
> algorithms. For example, a non-blocking ring based mempool (a likely use case
> for this ring) with per-thread caching.
>
> The non-blocking ring is enabled via a new flag, RING_F_NB. For ease-of-use,
> existing ring enqueue/dequeue functions work with both "regular" and
> non-blocking rings.
>
> This patchset also adds non-blocking versions of ring_autotest and
> ring_perf_autotest, and a non-blocking ring based mempool.
>
> This patchset makes ABI and API changes; a deprecation notice will be
> posted in a separate commit.
>
> This patchset depends on the non-blocking stack patchset[1].
>
> [1] http://mails.dpdk.org/archives/dev/2019-January/123470.html
>
> v2:
> - Merge separate docs commit into patch #5
> - Convert uintptr_t to size_t
> - Add a compile-time check for the size of size_t
> - Fix a space-after-typecast issue
> - Fix an unnecessary-parentheses checkpatch warning
> - Bump librte_ring's library version
>
> Gage Eads (5):
> ring: change head and tail to pointer-width size
> ring: add a non-blocking implementation
> test_ring: add non-blocking ring autotest
> test_ring_perf: add non-blocking ring perf test
> mempool/ring: add non-blocking ring handlers
>
> doc/guides/prog_guide/env_abstraction_layer.rst | 2 +-
> drivers/mempool/ring/rte_mempool_ring.c | 58 ++-
> lib/librte_eventdev/rte_event_ring.h | 6 +-
> lib/librte_ring/Makefile | 2 +-
> lib/librte_ring/meson.build | 2 +-
> lib/librte_ring/rte_ring.c | 53 ++-
> lib/librte_ring/rte_ring.h | 564 ++++++++++++++++++++++--
> lib/librte_ring/rte_ring_generic.h | 16 +-
> lib/librte_ring/rte_ring_version.map | 7 +
> test/test/test_ring.c | 57 ++-
> test/test/test_ring_perf.c | 19 +-
> 11 files changed, 699 insertions(+), 87 deletions(-)
>
Just bumping the version number is not enough.
This looks like an ABI breakage for existing users.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] doc: announce ring ABI and API changes
2019-01-15 23:59 7% [dpdk-dev] [PATCH] doc: announce ring ABI and API changes Gage Eads
@ 2019-01-16 0:34 7% ` Stephen Hemminger
2019-01-16 18:21 8% ` Eads, Gage
2019-01-18 15:28 3% ` [dpdk-dev] [PATCH v2] doc: announce ring API change Gage Eads
1 sibling, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-01-16 0:34 UTC (permalink / raw)
To: Gage Eads
Cc: dev, olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev
On Tue, 15 Jan 2019 17:59:34 -0600
Gage Eads <gage.eads@intel.com> wrote:
> In order to support the non-blocking ring[1], one ABI change and one API
> change are required in librte_ring. This commit updates the deprecation
> notice to pave the way for their inclusion in 19.05.
>
> [1] http://mails.dpdk.org/archives/dev/2019-January/123475.html
>
> Signed-off-by: Gage Eads <gage.eads@intel.com>
> ---
> doc/guides/rel_notes/deprecation.rst | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index d4aea4b46..d74cff467 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -83,3 +83,14 @@ Deprecation Notices
> - The size and layout of ``rte_cryptodev_qp_conf`` and syntax of
> ``rte_cryptodev_queue_pair_setup`` will change to to allow to use
> two different mempools for crypto and device private sessions.
> +
> +* ring: two changes are planned for rte_ring in v19.05:
> +
> + - The ring head and tail values are planned to be changed from ``uint32_t``
> + to ``size_t``. This reduces the likelihood of wrap-around to effectively
> + zero for 64-bit builds, which is important in avoiding the ABA problem in
> + the upcoming non-blocking ring implementation. (32-bit builds are
> + unaffected by this change.)
> + - rte_ring_get_memsize() will get a new ``flags`` parameter, so it can
> + calculate the memory required for rings that require more than 8B per entry
> + (such as the upcoming non-blocking ring).
Would it be possible to support new and old ring types, either through naming
tricks and/or new ring flag? Changing things like ring buffer and mbuf are basically
a flag day for all users.
I admit to having a personal interest in this since the API/ABI churn is this
project causes vendors to stay on older code. And older code does not correctly
support newer networks.
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field
2019-01-15 23:11 4% ` Stephen Hemminger
@ 2019-01-16 8:41 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-01-16 8:41 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Reshma Pattan, jerin.jacob, nikhil.rao,
olivier.matz, jasvinder.singh, cristian.dumitrescu,
konstantin.ananyev
16/01/2019 00:11, Stephen Hemminger:
> On Thu, 20 Dec 2018 12:16:09 +0000
> Reshma Pattan <reshma.pattan@intel.com> wrote:
>
> > void
> > -rte_sched_port_pkt_write(struct rte_mbuf *pkt,
> > - uint32_t subport, uint32_t pipe, uint32_t traffic_class,
> > +rte_sched_port_pkt_write(struct rte_sched_port *port,
> > + struct rte_mbuf *pkt,
> > + uint32_t subport, uint32_t pipe,
> > + uint32_t traffic_class,
> > uint32_t queue, enum rte_meter_color color)
>
> Sorry I didn't notice this earlier, but changing the function signature like
> this is a complete ABI breakage. Old code will be passing different arguments than
> new code; therefore this change breaks both source and binary compatibility.
>
> Is 19.02 supposed to be an ABI/API breaking release? Or only an incremental update.
It is an API breaking release.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field
2019-01-15 22:37 3% ` Stephen Hemminger
@ 2019-01-16 9:19 0% ` Pattan, Reshma
2019-01-16 9:33 0% ` Dumitrescu, Cristian
0 siblings, 1 reply; 200+ results
From: Pattan, Reshma @ 2019-01-16 9:19 UTC (permalink / raw)
To: Stephen Hemminger
Cc: dev, jerin.jacob, Rao, Nikhil, olivier.matz, thomas, Singh,
Jasvinder, Dumitrescu, Cristian, Ananyev, Konstantin
Hi
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, January 15, 2019 10:37 PM
> To: Pattan, Reshma <reshma.pattan@intel.com>
> Cc: dev@dpdk.org; jerin.jacob@caviumnetworks.com; Rao, Nikhil
> <nikhil.rao@intel.com>; olivier.matz@6wind.com; thomas@monjalon.net;
> Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
> <cristian.dumitrescu@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for
> sched field
>
> On Thu, 20 Dec 2018 12:16:09 +0000
> Reshma Pattan <reshma.pattan@intel.com> wrote:
>
> > This patch implements the changes proposed in the deprecation notes
> > [1][2].
> >
> > librte_mbuf changes:
> > The mbuf->hash.sched field is updated to support generic definition in
> > line with the ethdev traffic manager and meter APIs.
> > The new generic format contains: queue ID, traffic class, color.
> >
> > Added public APIs to set and get these new fields to and from mbuf.
> >
> > librte_sched changes:
> > In addtion, following API functions of the sched library have been
> > modified with an additional parameter of type struct rte_sched_port to
> > accommodate the changes made to mbuf sched field.
> > (i)rte_sched_port_pkt_write()
> > (ii) rte_sched_port_pkt_read_tree_path()
> >
> > librte_pipeline, qos_sched UT, qos_sched app are updated to make use
> > of new changes.
> >
> > Also mbuf->hash.txadapter has been added for eventdev txq,
> > rte_event_eth_tx_adapter_txq_set and
> > rte_event_eth_tx_adapter_txq_get()
> > are updated to use mbuf->hash.txadapter.txq.
> >
> > doc:
> > Release notes updated.
> > Removed deprecation notice for mbuf->hash.sched and sched API.
> >
> > [1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
> > [2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
> >
> > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> > Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
> > Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
>
>
> This patch breaks build of VPP because it refers to sched.hi and sched.lo.
> Breaking source compatibility is as bad (if not worse) than ABI breakage.
>
Yes this breaks the build and we have actions to fix VPP Qos Sched when DPDK 19.02 is formally integrated to VPP.
Thanks,
Reshma
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field
2019-01-16 9:19 0% ` Pattan, Reshma
@ 2019-01-16 9:33 0% ` Dumitrescu, Cristian
2019-01-16 10:09 0% ` Singh, Jasvinder
0 siblings, 1 reply; 200+ results
From: Dumitrescu, Cristian @ 2019-01-16 9:33 UTC (permalink / raw)
To: Pattan, Reshma, Stephen Hemminger
Cc: dev, jerin.jacob, Rao, Nikhil, olivier.matz, thomas, Singh,
Jasvinder, Ananyev, Konstantin
> -----Original Message-----
> From: Pattan, Reshma
> Sent: Wednesday, January 16, 2019 9:19 AM
> To: Stephen Hemminger <stephen@networkplumber.org>
> Cc: dev@dpdk.org; jerin.jacob@caviumnetworks.com; Rao, Nikhil
> <nikhil.rao@intel.com>; olivier.matz@6wind.com; thomas@monjalon.net;
> Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
> <cristian.dumitrescu@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for
> sched field
>
> Hi
>
> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Tuesday, January 15, 2019 10:37 PM
> > To: Pattan, Reshma <reshma.pattan@intel.com>
> > Cc: dev@dpdk.org; jerin.jacob@caviumnetworks.com; Rao, Nikhil
> > <nikhil.rao@intel.com>; olivier.matz@6wind.com; thomas@monjalon.net;
> > Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
> > <cristian.dumitrescu@intel.com>; Ananyev, Konstantin
> > <konstantin.ananyev@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format
> for
> > sched field
> >
> > On Thu, 20 Dec 2018 12:16:09 +0000
> > Reshma Pattan <reshma.pattan@intel.com> wrote:
> >
> > > This patch implements the changes proposed in the deprecation notes
> > > [1][2].
> > >
> > > librte_mbuf changes:
> > > The mbuf->hash.sched field is updated to support generic definition in
> > > line with the ethdev traffic manager and meter APIs.
> > > The new generic format contains: queue ID, traffic class, color.
> > >
> > > Added public APIs to set and get these new fields to and from mbuf.
> > >
> > > librte_sched changes:
> > > In addtion, following API functions of the sched library have been
> > > modified with an additional parameter of type struct rte_sched_port to
> > > accommodate the changes made to mbuf sched field.
> > > (i)rte_sched_port_pkt_write()
> > > (ii) rte_sched_port_pkt_read_tree_path()
> > >
> > > librte_pipeline, qos_sched UT, qos_sched app are updated to make use
> > > of new changes.
> > >
> > > Also mbuf->hash.txadapter has been added for eventdev txq,
> > > rte_event_eth_tx_adapter_txq_set and
> > > rte_event_eth_tx_adapter_txq_get()
> > > are updated to use mbuf->hash.txadapter.txq.
> > >
> > > doc:
> > > Release notes updated.
> > > Removed deprecation notice for mbuf->hash.sched and sched API.
> > >
> > > [1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
> > > [2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
> > >
> > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> > > Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
> > > Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > > Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> >
> >
> > This patch breaks build of VPP because it refers to sched.hi and sched.lo.
> > Breaking source compatibility is as bad (if not worse) than ABI breakage.
> >
>
> Yes this breaks the build and we have actions to fix VPP Qos Sched when
> DPDK 19.02 is formally integrated to VPP.
>
> Thanks,
> Reshma
Yes, Jasvinder is the maintainer of the VPP HQoS code, this is on his plate to fix in VPP for the next VPP release using DPDK release 19.02.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] DPDK techboard minutes of January 2
@ 2019-01-16 9:55 3% Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-01-16 9:55 UTC (permalink / raw)
To: dev; +Cc: techboard
Meeting notes for the DPDK technical board meeting held on 2019-01-02
Attendees: 7/9
- Ferruh Yigit
- Jerin Jacob
- Konstantin Ananyev
- Maxime Coquelin
- Olivier Matz
- Stephen Hemminger
- Thomas Monjalon
1) Mentoring
Stephen will check Google Code and other possible initiatives.
Project scope must be well defined, useful, easy to ramp up and testable.
Idea of projects: automatic testing of vhost/virtio or Hyper-V.
AWS and Azure can be some targets.
Project suggestions will be discussed on the mailing list.
We are looking for mentors. Maxime proposed to mentor vhost/virtio testing.
2) Deprecation process
- How new API or ABI is introduced
No need to require introducing new code in RTE_NEXT_ABI ifdef
while sending deprecation notice.
Instead, a draft of the new code (RFC patch) must be submitted
and referenced in the deprecation notice.
So the deprecation notice may be better discussed before giving ack,
and the users can prepare their application for the next DPDK release.
- How old API is removed
We must not remove a deprecated API if the replacement is still experimental.
It is recommended to remove deprecated APIs after a LTS release.
The process change must adjusted by Ferruh. Initial proposal was sent:
https://patches.dpdk.org/project/dpdk/list/?series=2927
3) Next techboard meeting
- It will be on January 16
- Bruce Richardson will chair it
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field
2019-01-16 9:33 0% ` Dumitrescu, Cristian
@ 2019-01-16 10:09 0% ` Singh, Jasvinder
0 siblings, 0 replies; 200+ results
From: Singh, Jasvinder @ 2019-01-16 10:09 UTC (permalink / raw)
To: Dumitrescu, Cristian, Pattan, Reshma, Stephen Hemminger
Cc: dev, jerin.jacob, Rao, Nikhil, olivier.matz, thomas, Ananyev, Konstantin
<snip>
> >
> > > -----Original Message-----
> > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > Sent: Tuesday, January 15, 2019 10:37 PM
> > > To: Pattan, Reshma <reshma.pattan@intel.com>
> > > Cc: dev@dpdk.org; jerin.jacob@caviumnetworks.com; Rao, Nikhil
> > > <nikhil.rao@intel.com>; olivier.matz@6wind.com; thomas@monjalon.net;
> > > Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
> > > <cristian.dumitrescu@intel.com>; Ananyev, Konstantin
> > > <konstantin.ananyev@intel.com>
> > > Subject: Re: [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic
> > > format
> > for
> > > sched field
> > >
> > > On Thu, 20 Dec 2018 12:16:09 +0000
> > > Reshma Pattan <reshma.pattan@intel.com> wrote:
> > >
> > > > This patch implements the changes proposed in the deprecation
> > > > notes [1][2].
> > > >
> > > > librte_mbuf changes:
> > > > The mbuf->hash.sched field is updated to support generic
> > > > definition in line with the ethdev traffic manager and meter APIs.
> > > > The new generic format contains: queue ID, traffic class, color.
> > > >
> > > > Added public APIs to set and get these new fields to and from mbuf.
> > > >
> > > > librte_sched changes:
> > > > In addtion, following API functions of the sched library have been
> > > > modified with an additional parameter of type struct
> > > > rte_sched_port to accommodate the changes made to mbuf sched field.
> > > > (i)rte_sched_port_pkt_write()
> > > > (ii) rte_sched_port_pkt_read_tree_path()
> > > >
> > > > librte_pipeline, qos_sched UT, qos_sched app are updated to make
> > > > use of new changes.
> > > >
> > > > Also mbuf->hash.txadapter has been added for eventdev txq,
> > > > rte_event_eth_tx_adapter_txq_set and
> > > > rte_event_eth_tx_adapter_txq_get()
> > > > are updated to use mbuf->hash.txadapter.txq.
> > > >
> > > > doc:
> > > > Release notes updated.
> > > > Removed deprecation notice for mbuf->hash.sched and sched API.
> > > >
> > > > [1] http://mails.dpdk.org/archives/dev/2018-February/090651.html
> > > > [2] https://mails.dpdk.org/archives/dev/2018-November/119051.html
> > > >
> > > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> > > > Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
> > > > Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > > > Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> > >
> > >
> > > This patch breaks build of VPP because it refers to sched.hi and sched.lo.
> > > Breaking source compatibility is as bad (if not worse) than ABI breakage.
> > >
> >
> > Yes this breaks the build and we have actions to fix VPP Qos Sched
> > when DPDK 19.02 is formally integrated to VPP.
> >
> > Thanks,
> > Reshma
>
> Yes, Jasvinder is the maintainer of the VPP HQoS code, this is on his plate to fix
> in VPP for the next VPP release using DPDK release 19
Yes, patch will be up streamed as soon as dpdk19.02 is out.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] doc: increase minimal supported Linux version
@ 2019-01-16 11:45 5% Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-01-16 11:45 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, marko.kovacevic, Kevin Traynor, Stephen Hemminger
Update the Linux user guide to restrict the supported kernels
to reasonnably recent enough versions.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
Cc: Kevin Traynor <ktraynor@redhat.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
---
doc/guides/linux_gsg/sys_reqs.rst | 10 ++--------
doc/guides/rel_notes/deprecation.rst | 6 ------
2 files changed, 2 insertions(+), 14 deletions(-)
diff --git a/doc/guides/linux_gsg/sys_reqs.rst b/doc/guides/linux_gsg/sys_reqs.rst
index 29c5f47a5..8ec3af491 100644
--- a/doc/guides/linux_gsg/sys_reqs.rst
+++ b/doc/guides/linux_gsg/sys_reqs.rst
@@ -98,22 +98,16 @@ System Software
**Required:**
-* Kernel version >= 3.2
+* Kernel version >= 3.16
The kernel version required is based on the oldest long term stable kernel available
at kernel.org when the DPDK version is in development.
+ Compatibility for recent distribution kernels will be kept, notably RHEL/CentOS 7.
The kernel version in use can be checked using the command::
uname -r
-.. note::
-
- Kernel version 3.2 is no longer a kernel.org longterm stable kernel.
- For DPDK 19.02 the minimum required kernel will be updated to
- the current kernel.org oldest longterm stable supported kernel 3.16,
- or recent versions of common distributions, notably RHEL/CentOS 7.
-
* glibc >= 2.7 (for features related to cpuset)
The version can be checked using the ``ldd --version`` command.
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 5f03443f8..f9a1f8188 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -11,12 +11,6 @@ API and ABI deprecation notices are to be posted here.
Deprecation Notices
-------------------
-* linux: Linux kernel version 3.2 (which is the current minimum required
- version for the DPDK) is not maintained anymore. Therefore the planned
- minimum required kernel version for DPDK 19.02 will be the next oldest
- Long Term Stable (LTS) version which is 3.16, but compatibility for
- recent distribution kernels will be kept.
-
* kvargs: The function ``rte_kvargs_process`` will get a new parameter
for returning key match count. It will ease handling of no-match case.
--
2.20.1
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH] doc: announce ring ABI and API changes
2019-01-16 0:34 7% ` Stephen Hemminger
@ 2019-01-16 18:21 8% ` Eads, Gage
0 siblings, 0 replies; 200+ results
From: Eads, Gage @ 2019-01-16 18:21 UTC (permalink / raw)
To: Stephen Hemminger
Cc: dev, olivier.matz, arybchenko, Richardson, Bruce, Ananyev, Konstantin
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, January 15, 2019 6:34 PM
> To: Eads, Gage <gage.eads@intel.com>
> Cc: dev@dpdk.org; olivier.matz@6wind.com; arybchenko@solarflare.com;
> Richardson, Bruce <bruce.richardson@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>
> Subject: Re: [PATCH] doc: announce ring ABI and API changes
>
> On Tue, 15 Jan 2019 17:59:34 -0600
> Gage Eads <gage.eads@intel.com> wrote:
>
> > In order to support the non-blocking ring[1], one ABI change and one
> > API change are required in librte_ring. This commit updates the
> > deprecation notice to pave the way for their inclusion in 19.05.
> >
> > [1] http://mails.dpdk.org/archives/dev/2019-January/123475.html
> >
> > Signed-off-by: Gage Eads <gage.eads@intel.com>
> > ---
> > doc/guides/rel_notes/deprecation.rst | 11 +++++++++++
> > 1 file changed, 11 insertions(+)
> >
> > diff --git a/doc/guides/rel_notes/deprecation.rst
> > b/doc/guides/rel_notes/deprecation.rst
> > index d4aea4b46..d74cff467 100644
> > --- a/doc/guides/rel_notes/deprecation.rst
> > +++ b/doc/guides/rel_notes/deprecation.rst
> > @@ -83,3 +83,14 @@ Deprecation Notices
> > - The size and layout of ``rte_cryptodev_qp_conf`` and syntax of
> > ``rte_cryptodev_queue_pair_setup`` will change to to allow to use
> > two different mempools for crypto and device private sessions.
> > +
> > +* ring: two changes are planned for rte_ring in v19.05:
> > +
> > + - The ring head and tail values are planned to be changed from ``uint32_t``
> > + to ``size_t``. This reduces the likelihood of wrap-around to effectively
> > + zero for 64-bit builds, which is important in avoiding the ABA problem in
> > + the upcoming non-blocking ring implementation. (32-bit builds are
> > + unaffected by this change.)
> > + - rte_ring_get_memsize() will get a new ``flags`` parameter, so it can
> > + calculate the memory required for rings that require more than 8B per
> entry
> > + (such as the upcoming non-blocking ring).
>
>
> Would it be possible to support new and old ring types, either through naming
> tricks and/or new ring flag? Changing things like ring buffer and mbuf are
> basically a flag day for all users.
>
> I admit to having a personal interest in this since the API/ABI churn is this project
> causes vendors to stay on older code. And older code does not correctly support
> newer networks.
Fair enough -- I appreciate the additional context wrt avoiding churn.
This might be doable with the following change:
"
@@ -70,6 +70,15 @@ struct rte_ring_headtail {
uint32_t single; /**< True if single prod/cons */
};
+/* 64-bit version of rte_ring_headtail, for use by rings that need to avoid
+ * head/tail wrap-around.
+ */
+struct rte_ring_headtail_64 {
+ volatile uint64_t head; /**< Prod/consumer head. */
+ volatile uint64_t tail; /**< Prod/consumer tail. */
+ uint32_t single; /**< True if single prod/cons */
+};
+
/**
* An RTE ring structure.
*
@@ -97,11 +106,19 @@ struct rte_ring {
char pad0 __rte_cache_aligned; /**< empty cache line */
/** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail prod __rte_cache_aligned;
+ struct rte_ring_headtail_64 prod_64 __rte_cache_aligned;
+ };
char pad1 __rte_cache_aligned; /**< empty cache line */
/** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail cons __rte_cache_aligned;
+ struct rte_ring_headtail_64 cons_64 __rte_cache_aligned;
+ };
char pad2 __rte_cache_aligned; /**< empty cache line */
};
"
The ABI compatibility hinges on the fact that today's prod and cons are both padded out to a full cache line, and the 64-bit version fits within a single cache line. (Confirmed with pahole.)
abi-compliance-checker reports two issues, but both appear to be false positives:
1. "Field cons has been removed from this type"
2. "Field prod has been removed from this type"
I need to do more work to see whether/how the ring functions are affected by such a change, but I first want to check if the community agrees with this approach. Note that I don't see any way to avoid the API change to rte_ring_get_memsize, but I doubt that would have near the impact of a ring data structure change.
Thanks,
Gage
^ permalink raw reply [relevance 8%]
* [dpdk-dev] [PATCH] doc: announce ABI change for cryptodev config
@ 2019-01-17 9:39 4% Anoob Joseph
2019-01-17 11:37 4% ` Trahe, Fiona
0 siblings, 1 reply; 200+ results
From: Anoob Joseph @ 2019-01-17 9:39 UTC (permalink / raw)
To: Akhil Goyal, Pablo de Lara, Fiona Trahe
Cc: Anoob Joseph, Jerin Jacob Kollanukkaran,
Narayana Prasad Raju Athreya, Shally Verma, dev
Add new field ff_enable in rte_cryptodev_config. This enables
applications to control the features enabled on the crypto device.
Proposed new layout:
/** Crypto device configuration structure */
struct rte_cryptodev_config {
int socket_id; /**< Socket to allocate resources on */
uint16_t nb_queue_pairs;
/**< Number of queue pairs to configure on device */
+ uint64_t ff_enable;
+ /**< Feature flags to be enabled on the device. Only the features set
+ * on rte_cryptodev_info.feature_flags are allowed to be set.
+ */
};
For eth devices, rte_eth_conf.rx_mode.offloads and
rte_eth_conf.tx_mode.offloads fields are used by applications to
control the offloads enabled on the eth device. This proposal adds a
similar ability for the crypto device.
Signed-off-by: Anoob Joseph <anoobj@marvell.com>
---
doc/guides/rel_notes/deprecation.rst | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 5f03443..e289c2d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -66,3 +66,13 @@ Deprecation Notices
* crypto/aesni_mb: the minimum supported intel-ipsec-mb library version will be
changed from 0.49.0 to 0.52.0.
+
+* cryptodev: New member in ``rte_cryptodev_config`` to allow applications to
+ specify the features to be enabled on the crypto device. For eth devices,
+ applications can use ``rte_eth_conf.rxmode.offloads`` and
+ ``rte_eth_conf.txmode.offloads`` to control the offloads enabled. Adding
+ a similar field to facilitate efficient usage of HW/SW offloads.
+
+ - Member ``uint64_t ff_enable`` in ``rte_cryptodev_config``
+
+ The field would be added in v19.05.
--
2.7.4
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] doc: announce ABI change for cryptodev config
2019-01-17 9:39 4% [dpdk-dev] [PATCH] doc: announce ABI change for cryptodev config Anoob Joseph
@ 2019-01-17 11:37 4% ` Trahe, Fiona
2019-01-17 13:47 4% ` Anoob Joseph
0 siblings, 1 reply; 200+ results
From: Trahe, Fiona @ 2019-01-17 11:37 UTC (permalink / raw)
To: Anoob Joseph, Akhil Goyal, De Lara Guarch, Pablo
Cc: Jerin Jacob Kollanukkaran, Narayana Prasad Raju Athreya,
Shally Verma, dev, Trahe, Fiona
Hi Joseph,
> -----Original Message-----
> From: Anoob Joseph [mailto:anoobj@marvell.com]
> Sent: Thursday, January 17, 2019 9:40 AM
> To: Akhil Goyal <akhil.goyal@nxp.com>; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Trahe,
> Fiona <fiona.trahe@intel.com>
> Cc: Anoob Joseph <anoobj@marvell.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Narayana
> Prasad Raju Athreya <pathreya@marvell.com>; Shally Verma <shallyv@marvell.com>; dev@dpdk.org
> Subject: [PATCH] doc: announce ABI change for cryptodev config
>
> Add new field ff_enable in rte_cryptodev_config. This enables
> applications to control the features enabled on the crypto device.
>
> Proposed new layout:
>
> /** Crypto device configuration structure */
> struct rte_cryptodev_config {
> int socket_id; /**< Socket to allocate resources on */
> uint16_t nb_queue_pairs;
> /**< Number of queue pairs to configure on device */
> + uint64_t ff_enable;
> + /**< Feature flags to be enabled on the device. Only the features set
> + * on rte_cryptodev_info.feature_flags are allowed to be set.
> + */
> };
>
> For eth devices, rte_eth_conf.rx_mode.offloads and
> rte_eth_conf.tx_mode.offloads fields are used by applications to
> control the offloads enabled on the eth device. This proposal adds a
> similar ability for the crypto device.
[Fiona] I'm unfamiliar with eth config so can you explain a bit more how this works?
e.g. if a crypto device's info says it supports
RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO
RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING
RTE_CRYPTODEV_FF_CPU_AESNI
RTE_CRYPTODEV_FF_SECURITY
RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT
these things are all already enabled.
Is the param a way to disable some of them?
If so, it would be better to call it ff_disable.
And to limit it to the subset of features that it makes sense to disable.
i.e. why would an application disable chaining or any of the SGL flags? It would just add extra cycles
in the PMD to error check on these cases, instead the appl can just not send such commands.
And it doesn't make sense to disable AESNI or RTE_CRYPTODEV_FF_HW_ACCELERATED.
Actually I can't see what an application would want to achieve by disabling any flag?
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] doc: announce ABI change for cryptodev config
2019-01-17 11:37 4% ` Trahe, Fiona
@ 2019-01-17 13:47 4% ` Anoob Joseph
2019-01-18 6:59 4% ` Shally Verma
0 siblings, 1 reply; 200+ results
From: Anoob Joseph @ 2019-01-17 13:47 UTC (permalink / raw)
To: Trahe, Fiona, Akhil Goyal, De Lara Guarch, Pablo
Cc: Jerin Jacob Kollanukkaran, Narayana Prasad Raju Athreya,
Shally Verma, dev
Hi Fiona,
Please see inline.
Thanks,
Anoob
> -----Original Message-----
> From: Trahe, Fiona <fiona.trahe@intel.com>
> Sent: 17 January 2019 17:07
> To: Anoob Joseph <anoobj@marvell.com>; Akhil Goyal <akhil.goyal@nxp.com>;
> De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Narayana Prasad Raju
> Athreya <pathreya@marvell.com>; Shally Verma <shallyv@marvell.com>;
> dev@dpdk.org; Trahe, Fiona <fiona.trahe@intel.com>
> Subject: RE: [PATCH] doc: announce ABI change for cryptodev config
>
> Hi Joseph,
>
> > -----Original Message-----
> > From: Anoob Joseph [mailto:anoobj@marvell.com]
> > Sent: Thursday, January 17, 2019 9:40 AM
> > To: Akhil Goyal <akhil.goyal@nxp.com>; De Lara Guarch, Pablo
> > <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>
> > Cc: Anoob Joseph <anoobj@marvell.com>; Jerin Jacob Kollanukkaran
> > <jerinj@marvell.com>; Narayana Prasad Raju Athreya
> > <pathreya@marvell.com>; Shally Verma <shallyv@marvell.com>;
> > dev@dpdk.org
> > Subject: [PATCH] doc: announce ABI change for cryptodev config
> >
> > Add new field ff_enable in rte_cryptodev_config. This enables
> > applications to control the features enabled on the crypto device.
> >
> > Proposed new layout:
> >
> > /** Crypto device configuration structure */ struct
> > rte_cryptodev_config {
> > int socket_id; /**< Socket to allocate resources on */
> > uint16_t nb_queue_pairs;
> > /**< Number of queue pairs to configure on device */
> > + uint64_t ff_enable;
> > + /**< Feature flags to be enabled on the device. Only the features set
> > + * on rte_cryptodev_info.feature_flags are allowed to be set.
> > + */
> > };
> >
> > For eth devices, rte_eth_conf.rx_mode.offloads and
> > rte_eth_conf.tx_mode.offloads fields are used by applications to
> > control the offloads enabled on the eth device. This proposal adds a
> > similar ability for the crypto device.
> [Fiona] I'm unfamiliar with eth config so can you explain a bit more how this
> works?
[Anoob] For eth devices, application would first do rte_eth_dev_info_get() and gets the capabilities. The device would expose it's capabilities using dev_info.rx_offload_capa & dev_info.tx_offload_capa. The application can enable/disable these features while configuring the eth ports.
>From ipsec-secgw:
https://git.dpdk.org/dpdk/tree/examples/ipsec-secgw/ipsec-secgw.c#n1866
if (frame_size) {
local_port_conf.rxmode.max_rx_pkt_len = frame_size;
local_port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
}
<snip>
ret = rte_eth_dev_configure(portid, nb_rx_queue, nb_tx_queue,
&local_port_conf);
<snip>
This way application can choose to disable unwanted offloads.
Port init in ipsec-secgw: https://git.dpdk.org/dpdk/tree/examples/ipsec-secgw/ipsec-secgw.c#n1826
> e.g. if a crypto device's info says it supports
> RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO
> RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING
> RTE_CRYPTODEV_FF_CPU_AESNI
> RTE_CRYPTODEV_FF_SECURITY
> RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT
> these things are all already enabled.
> Is the param a way to disable some of them?
[Anoob] Yes. There are few other flags in addition to the above. Like RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO.
> If so, it would be better to call it ff_disable.
[Anoob] Calling it ff_enable is to make it similar to how it's done with eth devices. Either way should be fine.
> And to limit it to the subset of features that it makes sense to disable.
> i.e. why would an application disable chaining or any of the SGL flags? It would
> just add extra cycles in the PMD to error check on these cases, instead the appl
> can just not send such commands.
> And it doesn't make sense to disable AESNI or
> RTE_CRYPTODEV_FF_HW_ACCELERATED.
> Actually I can't see what an application would want to achieve by disabling any
> flag?
[Anoob] Features like ASYMMETRIC or SECURITY is not required for every application. SECURITY is added for eth devices also. But since the feature can be disabled while configuring the port, applications are given a choice to disable it. That way apps like l2fwd doesn't enable SECURITY. With crypto this option is not available.
If the unused offloads can be communicated to the PMD before initialization, the PMD will be allowed to optimize hardware usage. Otherwise, supporting more features would affect performance, even if application is not making use of those features.
Ex: test-crypto-perf doesn't use ASYM/SECURITY. Now adding these features would affect the performance of this app.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] doc: announce ABI change for cryptodev config
2019-01-17 13:47 4% ` Anoob Joseph
@ 2019-01-18 6:59 4% ` Shally Verma
2019-01-22 9:31 4% ` Anoob Joseph
0 siblings, 1 reply; 200+ results
From: Shally Verma @ 2019-01-18 6:59 UTC (permalink / raw)
To: Anoob Joseph, Trahe, Fiona, Akhil Goyal, De Lara Guarch, Pablo
Cc: Jerin Jacob Kollanukkaran, Narayana Prasad Raju Athreya, dev
HI Fiona, Anoob
>-----Original Message-----
>From: Anoob Joseph
>Sent: 17 January 2019 19:17
>To: Trahe, Fiona <fiona.trahe@intel.com>; Akhil Goyal <akhil.goyal@nxp.com>; De Lara Guarch, Pablo
><pablo.de.lara.guarch@intel.com>
>Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Narayana Prasad Raju Athreya <pathreya@marvell.com>; Shally Verma
><shallyv@marvell.com>; dev@dpdk.org
>Subject: RE: [PATCH] doc: announce ABI change for cryptodev config
>
>Hi Fiona,
>
>Please see inline.
>
>Thanks,
>Anoob
>
>> -----Original Message-----
>> From: Trahe, Fiona <fiona.trahe@intel.com>
>> Sent: 17 January 2019 17:07
>> To: Anoob Joseph <anoobj@marvell.com>; Akhil Goyal <akhil.goyal@nxp.com>;
>> De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
>> Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Narayana Prasad Raju
>> Athreya <pathreya@marvell.com>; Shally Verma <shallyv@marvell.com>;
>> dev@dpdk.org; Trahe, Fiona <fiona.trahe@intel.com>
>> Subject: RE: [PATCH] doc: announce ABI change for cryptodev config
>>
>> Hi Joseph,
>>
>> > -----Original Message-----
>> > From: Anoob Joseph [mailto:anoobj@marvell.com]
>> > Sent: Thursday, January 17, 2019 9:40 AM
>> > To: Akhil Goyal <akhil.goyal@nxp.com>; De Lara Guarch, Pablo
>> > <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>
>> > Cc: Anoob Joseph <anoobj@marvell.com>; Jerin Jacob Kollanukkaran
>> > <jerinj@marvell.com>; Narayana Prasad Raju Athreya
>> > <pathreya@marvell.com>; Shally Verma <shallyv@marvell.com>;
>> > dev@dpdk.org
>> > Subject: [PATCH] doc: announce ABI change for cryptodev config
>> >
>> > Add new field ff_enable in rte_cryptodev_config. This enables
>> > applications to control the features enabled on the crypto device.
>> >
>> > Proposed new layout:
>> >
>> > /** Crypto device configuration structure */ struct
>> > rte_cryptodev_config {
>> > int socket_id; /**< Socket to allocate resources on */
>> > uint16_t nb_queue_pairs;
>> > /**< Number of queue pairs to configure on device */
>> > + uint64_t ff_enable;
>> > + /**< Feature flags to be enabled on the device. Only the features set
>> > + * on rte_cryptodev_info.feature_flags are allowed to be set.
>> > + */
>> > };
>> >
>> > For eth devices, rte_eth_conf.rx_mode.offloads and
>> > rte_eth_conf.tx_mode.offloads fields are used by applications to
>> > control the offloads enabled on the eth device. This proposal adds a
>> > similar ability for the crypto device.
>> [Fiona] I'm unfamiliar with eth config so can you explain a bit more how this
>> works?
>
>[Anoob] For eth devices, application would first do rte_eth_dev_info_get() and gets the capabilities. The device would expose it's
>capabilities using dev_info.rx_offload_capa & dev_info.tx_offload_capa. The application can enable/disable these features while
>configuring the eth ports.
>
>From ipsec-secgw:
>https://git.dpdk.org/dpdk/tree/examples/ipsec-secgw/ipsec-secgw.c#n1866
>
>if (frame_size) {
> local_port_conf.rxmode.max_rx_pkt_len = frame_size;
> local_port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
> }
>
><snip>
>
>ret = rte_eth_dev_configure(portid, nb_rx_queue, nb_tx_queue,
> &local_port_conf);
>
><snip>
>
>This way application can choose to disable unwanted offloads.
>
>Port init in ipsec-secgw: https://git.dpdk.org/dpdk/tree/examples/ipsec-secgw/ipsec-secgw.c#n1826
>
>> e.g. if a crypto device's info says it supports
>> RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO
>> RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING
>> RTE_CRYPTODEV_FF_CPU_AESNI
>> RTE_CRYPTODEV_FF_SECURITY
>> RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT
>> these things are all already enabled.
>> Is the param a way to disable some of them?
>
>[Anoob] Yes. There are few other flags in addition to the above. Like RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO.
>
>> If so, it would be better to call it ff_disable.
>
>[Anoob] Calling it ff_enable is to make it similar to how it's done with eth devices. Either way should be fine.
[Shally] keeping it as "ff_enable" will require application to set these flags to configure PMD. If we define it other way around, then it would be mean to mask out unwanted features which can be quite many.
Though purpose can be achieved both ways but keeping it as "enable" looks more easy to use, readable and inline with how ethdev handle multi feature support.
So I would prefer to keep it as "ff_enable"
Thanks
Shally
>
>> And to limit it to the subset of features that it makes sense to disable.
>> i.e. why would an application disable chaining or any of the SGL flags? It would
>> just add extra cycles in the PMD to error check on these cases, instead the appl
>> can just not send such commands.
>> And it doesn't make sense to disable AESNI or
>> RTE_CRYPTODEV_FF_HW_ACCELERATED.
>> Actually I can't see what an application would want to achieve by disabling any
>> flag?
>
>[Anoob] Features like ASYMMETRIC or SECURITY is not required for every application. SECURITY is added for eth devices also. But
>since the feature can be disabled while configuring the port, applications are given a choice to disable it. That way apps like l2fwd
>doesn't enable SECURITY. With crypto this option is not available.
>
>If the unused offloads can be communicated to the PMD before initialization, the PMD will be allowed to optimize hardware usage.
>Otherwise, supporting more features would affect performance, even if application is not making use of those features.
>
>Ex: test-crypto-perf doesn't use ASYM/SECURITY. Now adding these features would affect the performance of this app.
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring
2019-01-15 23:52 3% ` [dpdk-dev] [PATCH v2 0/5] Add non-blocking ring Gage Eads
2019-01-16 0:26 3% ` Stephen Hemminger
@ 2019-01-18 15:23 3% ` Gage Eads
2019-01-18 15:23 2% ` [dpdk-dev] [PATCH v3 1/5] ring: add 64-bit headtail structure Gage Eads
2019-01-22 9:27 0% ` [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring Ola Liljedahl
1 sibling, 2 replies; 200+ results
From: Gage Eads @ 2019-01-18 15:23 UTC (permalink / raw)
To: dev
Cc: olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev, stephen
For some users, the rte ring's "non-preemptive" constraint is not acceptable;
for example, if the application uses a mixture of pinned high-priority threads
and multiplexed low-priority threads that share a mempool.
This patchset introduces a non-blocking ring, on top of which a mempool can run.
Crucially, the non-blocking algorithm relies on a 128-bit compare-and-swap, so
it is currently limited to x86_64 machines. This is also an experimental API,
so RING_F_NB users must build with the ALLOW_EXPERIMENTAL_API flag.
The ring uses more compare-and-swap atomic operations than the regular rte ring:
With no contention, an enqueue of n pointers uses (1 + 2n) CAS operations and a
dequeue of n pointers uses 2. This algorithm has worse average-case performance
than the regular rte ring (particularly a highly-contended ring with large bulk
accesses), however:
- For applications with preemptible pthreads, the regular rte ring's worst-case
performance (i.e. one thread being preempted in the update_tail() critical
section) is much worse than the non-blocking ring's.
- Software caching can mitigate the average case performance for ring-based
algorithms. For example, a non-blocking ring based mempool (a likely use case
for this ring) with per-thread caching.
The non-blocking ring is enabled via a new flag, RING_F_NB. For ease-of-use,
existing ring enqueue/dequeue functions work with both "regular" and
non-blocking rings.
This patchset also adds non-blocking versions of ring_autotest and
ring_perf_autotest, and a non-blocking ring based mempool.
This patchset makes one API change; a deprecation notice will be posted in a
separate commit.
This patchset depends on the non-blocking stack patchset[1].
[1] http://mails.dpdk.org/archives/dev/2019-January/123653.html
v3:
- Avoid the ABI break by putting 64-bit head and tail values in the same
cacheline as struct rte_ring's prod and cons members.
- Don't attempt to compile rte_atomic128_cmpset without
ALLOW_EXPERIMENTAL_API, as this would break a large number of libraries.
- Add a helpful warning to __rte_ring_do_nb_enqueue_mp() in case someone tries
to use RING_F_NB without the ALLOW_EXPERIMENTAL_API flag.
- Update the ring mempool to use experimental APIs
- Clarify that RINB_F_NB is only limited to x86_64 currently; ARMv8.1-A builds
can eventually support it with the CASP instruction.
v2:
- Merge separate docs commit into patch #5
- Convert uintptr_t to size_t
- Add a compile-time check for the size of size_t
- Fix a space-after-typecast issue
- Fix an unnecessary-parentheses checkpatch warning
- Bump librte_ring's library version
Gage Eads (5):
ring: add 64-bit headtail structure
ring: add a non-blocking implementation
test_ring: add non-blocking ring autotest
test_ring_perf: add non-blocking ring perf test
mempool/ring: add non-blocking ring handlers
doc/guides/prog_guide/env_abstraction_layer.rst | 2 +-
drivers/mempool/ring/Makefile | 1 +
drivers/mempool/ring/meson.build | 2 +
drivers/mempool/ring/rte_mempool_ring.c | 58 ++-
lib/librte_eventdev/rte_event_ring.h | 2 +-
lib/librte_ring/Makefile | 3 +-
lib/librte_ring/rte_ring.c | 72 ++-
lib/librte_ring/rte_ring.h | 574 ++++++++++++++++++++++--
lib/librte_ring/rte_ring_generic_64.h | 152 +++++++
lib/librte_ring/rte_ring_version.map | 7 +
test/test/test_ring.c | 57 ++-
test/test/test_ring_perf.c | 19 +-
12 files changed, 874 insertions(+), 75 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_generic_64.h
--
2.13.6
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v3 1/5] ring: add 64-bit headtail structure
2019-01-18 15:23 3% ` [dpdk-dev] [PATCH v3 " Gage Eads
@ 2019-01-18 15:23 2% ` Gage Eads
2019-01-22 9:27 0% ` [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring Ola Liljedahl
1 sibling, 0 replies; 200+ results
From: Gage Eads @ 2019-01-18 15:23 UTC (permalink / raw)
To: dev
Cc: olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev, stephen
64-bit head and tail index widths greatly increases the time it takes for
them to wrap-around (with current CPU speeds, it won't happen within the
author's lifetime). This is important in avoiding the ABA problem -- in
which a thread mistakes reading the same tail index in two accesses to mean
that the ring was not modified in the intervening time -- in the upcoming
non-blocking ring implementation. Using a 64-bit index makes the
possibility of this occurring effectively zero.
This commit places the new producer and consumer structures in the same
location in struct rte_ring as their 32-bit counterparts. Since the 32-bit
versions are padded out to a cache line, there is space for the new
structure without affecting the layout of struct rte_ring. Thus, the ABI is
preserved.
Signed-off-by: Gage Eads <gage.eads@intel.com>
---
lib/librte_eventdev/rte_event_ring.h | 2 +-
lib/librte_ring/Makefile | 3 +-
lib/librte_ring/rte_ring.h | 24 +++++-
lib/librte_ring/rte_ring_generic_64.h | 152 ++++++++++++++++++++++++++++++++++
4 files changed, 176 insertions(+), 5 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_generic_64.h
diff --git a/lib/librte_eventdev/rte_event_ring.h b/lib/librte_eventdev/rte_event_ring.h
index 827a3209e..5fcb2d5f7 100644
--- a/lib/librte_eventdev/rte_event_ring.h
+++ b/lib/librte_eventdev/rte_event_ring.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016-2017 Intel Corporation
+ * Copyright(c) 2016-2019 Intel Corporation
*/
/**
diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile
index 21a36770d..18c48fbc8 100644
--- a/lib/librte_ring/Makefile
+++ b/lib/librte_ring/Makefile
@@ -19,6 +19,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_RING) := rte_ring.c
# install includes
SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
rte_ring_generic.h \
- rte_ring_c11_mem.h
+ rte_ring_c11_mem.h \
+ rte_ring_generic_64.h
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index af5444a9f..b270a4746 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright (c) 2010-2017 Intel Corporation
+ * Copyright (c) 2010-2019 Intel Corporation
* Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
* All rights reserved.
* Derived from FreeBSD's bufring.h
@@ -70,6 +70,15 @@ struct rte_ring_headtail {
uint32_t single; /**< True if single prod/cons */
};
+/* 64-bit version of rte_ring_headtail, for use by rings that need to avoid
+ * head/tail wrap-around.
+ */
+struct rte_ring_headtail_64 {
+ volatile uint64_t head; /**< Prod/consumer head. */
+ volatile uint64_t tail; /**< Prod/consumer tail. */
+ uint32_t single; /**< True if single prod/cons */
+};
+
/**
* An RTE ring structure.
*
@@ -97,11 +106,19 @@ struct rte_ring {
char pad0 __rte_cache_aligned; /**< empty cache line */
/** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail prod __rte_cache_aligned;
+ struct rte_ring_headtail_64 prod_64 __rte_cache_aligned;
+ };
char pad1 __rte_cache_aligned; /**< empty cache line */
/** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail cons __rte_cache_aligned;
+ struct rte_ring_headtail_64 cons_64 __rte_cache_aligned;
+ };
char pad2 __rte_cache_aligned; /**< empty cache line */
};
@@ -312,6 +329,7 @@ void rte_ring_dump(FILE *f, const struct rte_ring *r);
#else
#include "rte_ring_generic.h"
#endif
+#include "rte_ring_generic_64.h"
/**
* @internal Enqueue several objects on the ring
diff --git a/lib/librte_ring/rte_ring_generic_64.h b/lib/librte_ring/rte_ring_generic_64.h
new file mode 100644
index 000000000..58de144c6
--- /dev/null
+++ b/lib/librte_ring/rte_ring_generic_64.h
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2019 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_GENERIC_64_H_
+#define _RTE_RING_GENERIC_64_H_
+
+/**
+ * @internal This function updates the producer head for enqueue using
+ * 64-bit head/tail values.
+ *
+ * @param r
+ * A pointer to the ring structure
+ * @param is_sp
+ * Indicates whether multi-producer path is needed or not
+ * @param n
+ * The number of elements we will want to enqueue, i.e. how far should the
+ * head be moved
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Enqueue as many items as possible from ring
+ * @param old_head
+ * Returns head value as it was before the move, i.e. where enqueue starts
+ * @param new_head
+ * Returns the current/new head value i.e. where enqueue finishes
+ * @param free_entries
+ * Returns the amount of free space in the ring BEFORE head was moved
+ * @return
+ * Actual number of objects enqueued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_move_prod_head_64(struct rte_ring *r, unsigned int is_sp,
+ unsigned int n, enum rte_ring_queue_behavior behavior,
+ uint64_t *old_head, uint64_t *new_head,
+ uint32_t *free_entries)
+{
+ const uint32_t capacity = r->capacity;
+ unsigned int max = n;
+ int success;
+
+ do {
+ /* Reset n to the initial burst count */
+ n = max;
+
+ *old_head = r->prod_64.head;
+
+ /* add rmb barrier to avoid load/load reorder in weak
+ * memory model. It is noop on x86
+ */
+ rte_smp_rmb();
+
+ /*
+ * The subtraction is done between two unsigned 64bits value
+ * (the result is always modulo 64 bits even if we have
+ * *old_head > cons_tail). So 'free_entries' is always between 0
+ * and capacity (which is < size).
+ */
+ *free_entries = (capacity + r->cons_64.tail - *old_head);
+
+ /* check that we have enough room in ring */
+ if (unlikely(n > *free_entries))
+ n = (behavior == RTE_RING_QUEUE_FIXED) ?
+ 0 : *free_entries;
+
+ if (n == 0)
+ return 0;
+
+ *new_head = *old_head + n;
+ if (is_sp)
+ r->prod_64.head = *new_head, success = 1;
+ else
+ success = rte_atomic64_cmpset(&r->prod_64.head,
+ *old_head, *new_head);
+ } while (unlikely(success == 0));
+ return n;
+}
+
+/**
+ * @internal This function updates the consumer head for dequeue using
+ * 64-bit head/tail values.
+ *
+ * @param r
+ * A pointer to the ring structure
+ * @param is_sc
+ * Indicates whether multi-consumer path is needed or not
+ * @param n
+ * The number of elements we will want to enqueue, i.e. how far should the
+ * head be moved
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Dequeue as many items as possible from ring
+ * @param old_head
+ * Returns head value as it was before the move, i.e. where dequeue starts
+ * @param new_head
+ * Returns the current/new head value i.e. where dequeue finishes
+ * @param entries
+ * Returns the number of entries in the ring BEFORE head was moved
+ * @return
+ * - Actual number of objects dequeued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_move_cons_head_64(struct rte_ring *r, unsigned int is_sc,
+ unsigned int n, enum rte_ring_queue_behavior behavior,
+ uint64_t *old_head, uint64_t *new_head,
+ uint32_t *entries)
+{
+ unsigned int max = n;
+ int success;
+
+ do {
+ /* Restore n as it may change every loop */
+ n = max;
+
+ *old_head = r->cons_64.head;
+
+ /* add rmb barrier to avoid load/load reorder in weak
+ * memory model. It is noop on x86
+ */
+ rte_smp_rmb();
+
+ /* The subtraction is done between two unsigned 64bits value
+ * (the result is always modulo 64 bits even if we have
+ * cons_head > prod_tail). So 'entries' is always between 0
+ * and size(ring)-1.
+ */
+ *entries = (r->prod_64.tail - *old_head);
+
+ /* Set the actual entries for dequeue */
+ if (n > *entries)
+ n = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : *entries;
+
+ if (unlikely(n == 0))
+ return 0;
+
+ *new_head = *old_head + n;
+ if (is_sc)
+ r->cons_64.head = *new_head, success = 1;
+ else
+ success = rte_atomic64_cmpset(&r->cons_64.head,
+ *old_head, *new_head);
+ } while (unlikely(success == 0));
+ return n;
+}
+
+#endif /* _RTE_RING_GENERIC_64_H_ */
--
2.13.6
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v2] doc: announce ring API change
2019-01-15 23:59 7% [dpdk-dev] [PATCH] doc: announce ring ABI and API changes Gage Eads
2019-01-16 0:34 7% ` Stephen Hemminger
@ 2019-01-18 15:28 3% ` Gage Eads
2019-01-18 15:31 3% ` [dpdk-dev] [PATCH v3] " Gage Eads
1 sibling, 1 reply; 200+ results
From: Gage Eads @ 2019-01-18 15:28 UTC (permalink / raw)
To: dev
Cc: olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev, stephen
In order to support the non-blocking ring[1], an API change (additional
argument to rte_ring_get_memsize()) is required in librte_ring. This commit
updates the deprecation notice to pave the way for its inclusion in
19.05.
[1] http://mails.dpdk.org/archives/dev/2019-January/123774.html
Signed-off-by: Gage Eads <gage.eads@intel.com>
---
v2:
- Drop the ABI change notice
doc/guides/rel_notes/deprecation.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d4aea4b46..5b74a2aa7 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -83,3 +83,9 @@ Deprecation Notices
- The size and layout of ``rte_cryptodev_qp_conf`` and syntax of
``rte_cryptodev_queue_pair_setup`` will change to to allow to use
two different mempools for crypto and device private sessions.
+
+* ring: two changes are planned for rte_ring in v19.05:
+
+ - rte_ring_get_memsize() will get a new ``flags`` parameter, so it can
+ calculate the memory required for rings that require more than 8B per entry
+ (such as the upcoming non-blocking ring).
--
2.13.6
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v3] doc: announce ring API change
2019-01-18 15:28 3% ` [dpdk-dev] [PATCH v2] doc: announce ring API change Gage Eads
@ 2019-01-18 15:31 3% ` Gage Eads
0 siblings, 0 replies; 200+ results
From: Gage Eads @ 2019-01-18 15:31 UTC (permalink / raw)
To: dev
Cc: olivier.matz, arybchenko, bruce.richardson, konstantin.ananyev, stephen
In order to support the non-blocking ring[1], an API change (additional
argument to rte_ring_get_memsize()) is required in librte_ring. This commit
updates the deprecation notice to pave the way for its inclusion in
19.05.
[1] http://mails.dpdk.org/archives/dev/2019-January/123774.html
Signed-off-by: Gage Eads <gage.eads@intel.com>
---
v3:
- "two changes are planned" -> "one change is planned"
v2:
- Drop the ABI change notice
doc/guides/rel_notes/deprecation.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d4aea4b46..91e048a6a 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -83,3 +83,9 @@ Deprecation Notices
- The size and layout of ``rte_cryptodev_qp_conf`` and syntax of
``rte_cryptodev_queue_pair_setup`` will change to to allow to use
two different mempools for crypto and device private sessions.
+
+* ring: one change is planned for rte_ring in v19.05:
+
+ - rte_ring_get_memsize() will get a new ``flags`` parameter, so it can
+ calculate the memory required for rings that require more than 8B per entry
+ (such as the upcoming non-blocking ring).
--
2.13.6
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH] service: fix parameter type
@ 2019-01-19 14:01 3% Nikhil Rao
2019-01-21 11:43 3% ` Van Haaren, Harry
0 siblings, 1 reply; 200+ results
From: Nikhil Rao @ 2019-01-19 14:01 UTC (permalink / raw)
To: harry.van.haaren; +Cc: dev, Nikhil Rao
The type of value parameter to rte_service_attr_get
should be uint64_t *, since the attributes
are of type uint64_t.
Fixes: 4d55194d76a4 ("service: add attribute get function")
Reviewed-by: Gage Eads <gage.eads@intel.com>
Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
---
lib/librte_eal/common/include/rte_service.h | 2 +-
lib/librte_eal/common/rte_service.c | 2 +-
test/test/test_service_cores.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
For 19.02, I assume this will require the ABI change announcement. I will
post it once this patch is acked.
diff --git a/lib/librte_eal/common/include/rte_service.h b/lib/librte_eal/common/include/rte_service.h
index 34b41af..670c89a 100644
--- a/lib/librte_eal/common/include/rte_service.h
+++ b/lib/librte_eal/common/include/rte_service.h
@@ -372,7 +372,7 @@ int32_t rte_service_run_iter_on_app_lcore(uint32_t id,
* -EINVAL Invalid id, attr_id or attr_value was NULL.
*/
int32_t rte_service_attr_get(uint32_t id, uint32_t attr_id,
- uint32_t *attr_value);
+ uint64_t *attr_value);
/**
* Reset all attribute values of a service.
diff --git a/lib/librte_eal/common/rte_service.c b/lib/librte_eal/common/rte_service.c
index 03fde97..5f75e5a 100644
--- a/lib/librte_eal/common/rte_service.c
+++ b/lib/librte_eal/common/rte_service.c
@@ -734,7 +734,7 @@ int32_t rte_service_run_iter_on_app_lcore(uint32_t id,
}
int32_t
-rte_service_attr_get(uint32_t id, uint32_t attr_id, uint32_t *attr_value)
+rte_service_attr_get(uint32_t id, uint32_t attr_id, uint64_t *attr_value)
{
struct rte_service_spec_impl *s;
SERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL);
diff --git a/test/test/test_service_cores.c b/test/test/test_service_cores.c
index ec31882..82bb2ce 100644
--- a/test/test/test_service_cores.c
+++ b/test/test/test_service_cores.c
@@ -259,7 +259,7 @@ static int32_t dummy_mt_safe_cb(void *args)
rte_service_set_stats_enable(id, 1);
uint32_t attr_id = UINT32_MAX;
- uint32_t attr_value = 0xdead;
+ uint64_t attr_value = 0xdead;
/* check error return values */
TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(id, attr_id,
&attr_value),
--
1.8.3.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] service: fix parameter type
2019-01-19 14:01 3% [dpdk-dev] [PATCH] service: fix parameter type Nikhil Rao
@ 2019-01-21 11:43 3% ` Van Haaren, Harry
0 siblings, 0 replies; 200+ results
From: Van Haaren, Harry @ 2019-01-21 11:43 UTC (permalink / raw)
To: Rao, Nikhil; +Cc: dev
> -----Original Message-----
> From: Rao, Nikhil
> Sent: Saturday, January 19, 2019 2:01 PM
> To: Van Haaren, Harry <harry.van.haaren@intel.com>
> Cc: dev@dpdk.org; Rao, Nikhil <nikhil.rao@intel.com>
> Subject: [PATCH] service: fix parameter type
>
> The type of value parameter to rte_service_attr_get
> should be uint64_t *, since the attributes
> are of type uint64_t.
>
> Fixes: 4d55194d76a4 ("service: add attribute get function")
>
> Reviewed-by: Gage Eads <gage.eads@intel.com>
> Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
Acked-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---
> lib/librte_eal/common/include/rte_service.h | 2 +-
> lib/librte_eal/common/rte_service.c | 2 +-
> test/test/test_service_cores.c | 2 +-
> 3 files changed, 3 insertions(+), 3 deletions(-)
>
> For 19.02, I assume this will require the ABI change announcement. I will
> post it once this patch is acked.
Correct - this breaks API and ABI, so certainly will need an announce.
Thanks for the fixup, -Harry
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] dev Digest, Vol 231, Issue 6
[not found] <mailman.14255.1548076743.7586.dev@dpdk.org>
@ 2019-01-21 13:23 0% ` Anudeep Kumar
0 siblings, 0 replies; 200+ results
From: Anudeep Kumar @ 2019-01-21 13:23 UTC (permalink / raw)
To: dev
Hi,
I am unable to run l3fwd in dpdk. Please provide steps to run.
Regards,
Anudeep
On Mon, Jan 21, 2019, 18:49 <dev-request@dpdk.org wrote:
> Send dev mailing list submissions to
> dev@dpdk.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://mails.dpdk.org/listinfo/dev
> or, via email, send a message with subject or body 'help' to
> dev-request@dpdk.org
>
> You can reach the person managing the list at
> dev-owner@dpdk.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of dev digest..."
>
>
> Today's Topics:
>
> 1. [PATCH v6 2/4] examples/ip_pipeline: support QinQ PPPoE encap
> (Nemanja Marjanovic)
> 2. [PATCH v6 1/4] pipeline: support QinQ PPPoE encap
> (Nemanja Marjanovic)
> 3. [PATCH v6 3/4] net/softnic: support QinQ PPPoE encap
> (Nemanja Marjanovic)
> 4. [PATCH v6 4/4] net: add PPPoE ethertypes (Nemanja Marjanovic)
> 5. Re: [PATCH] doc: add deprecation notice to remove rte meter
> color (Mohammad Abdul Awal)
> 6. Re: [PATCH] service: fix parameter type (Van Haaren, Harry)
> 7. Re: [PATCH] vhost: fix possible out of bound access for
> indirect descs (Maxime Coquelin)
> 8. Re: IXGBE, IOMMU DMAR DRHD handling fault issue (Hu, Xuekun)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Mon, 21 Jan 2019 11:11:22 +0000
> From: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
> To: dev@dpdk.org
> Cc: jasvinder.singh@intel.com, cristian.dumitrescu@intel.com, "Nemanja
> Marjanovic" <nemanja.marjanovic@intel.com>
> Subject: [dpdk-dev] [PATCH v6 2/4] examples/ip_pipeline: support QinQ
> PPPoE encap
> Message-ID: <20190121111124.16362-2-nemanja.marjanovic@intel.com>
>
> From: "Nemanja Marjanovic" <nemanja.marjanovic@intel.com>
>
> Add implementation of QinQ PPPoE packet encapsulation action.
>
> Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> ---
> v5:Removing footer from patch.
> v6:Added missing acks.
> ---
> examples/ip_pipeline/cli.c | 46 ++++++++++++++++++++++++++++++++++++--
> 1 file changed, 44 insertions(+), 2 deletions(-)
>
> diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
> index 910386282..dd05393ef 100644
> --- a/examples/ip_pipeline/cli.c
> +++ b/examples/ip_pipeline/cli.c
> @@ -1022,7 +1022,7 @@ static const char cmd_table_action_profile_help[] =
> " tc <n_tc>\n"
> " stats none | pkts | bytes | both]\n"
> " [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
> -" [encap ether | vlan | qinq | mpls | pppoe |\n"
> +" [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe \n"
> " vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]\n"
> " [nat src | dst\n"
> " proto udp | tcp]\n"
> @@ -1290,7 +1290,10 @@ cmd_table_action_profile(char **tokens,
>
> p.encap.encap_mask = 1LLU <<
> RTE_TABLE_ACTION_ENCAP_VXLAN;
> n_extra_tokens = 5;
> - } else {
> + } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0)
> + p.encap.encap_mask =
> + 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
> + else {
> snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
> return;
> }
> @@ -3090,6 +3093,7 @@ parse_match(char **tokens,
> * ether <da> <sa>
> * | vlan <da> <sa> <pcp> <dei> <vid>
> * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
> + * | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
> <session_id>
> * | mpls unicast | multicast
> * <da> <sa>
> * label0 <label> <tc> <ttl>
> @@ -3391,6 +3395,44 @@ parse_table_action_encap(char **tokens,
> return 1 + 9;
> }
>
> + /* qinq_pppoe */
> + if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
> + uint32_t svlan_pcp, svlan_dei, svlan_vid;
> + uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
> +
> + if ((n_tokens < 10) ||
> + parse_mac_addr(tokens[1],
> + &a->encap.qinq_pppoe.ether.da) ||
> + parse_mac_addr(tokens[2],
> + &a->encap.qinq_pppoe.ether.sa) ||
> + parser_read_uint32(&svlan_pcp, tokens[3]) ||
> + (svlan_pcp > 0x7) ||
> + parser_read_uint32(&svlan_dei, tokens[4]) ||
> + (svlan_dei > 0x1) ||
> + parser_read_uint32(&svlan_vid, tokens[5]) ||
> + (svlan_vid > 0xFFF) ||
> + parser_read_uint32(&cvlan_pcp, tokens[6]) ||
> + (cvlan_pcp > 0x7) ||
> + parser_read_uint32(&cvlan_dei, tokens[7]) ||
> + (cvlan_dei > 0x1) ||
> + parser_read_uint32(&cvlan_vid, tokens[8]) ||
> + (cvlan_vid > 0xFFF) ||
> +
> parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
> + tokens[9]))
> + return 0;
> +
> + a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
> + a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
> + a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
> + a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
> + a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
> + a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
> + a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
> + a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
> + return 1 + 10;
> +
> + }
> +
> /* mpls */
> if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
> uint32_t label, tc, ttl;
> --
> 2.17.1
>
>
>
> ------------------------------
>
> Message: 2
> Date: Mon, 21 Jan 2019 11:11:21 +0000
> From: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
> To: dev@dpdk.org
> Cc: jasvinder.singh@intel.com, cristian.dumitrescu@intel.com, "Nemanja
> Marjanovic" <nemanja.marjanovic@intel.com>
> Subject: [dpdk-dev] [PATCH v6 1/4] pipeline: support QinQ PPPoE encap
> Message-ID: <20190121111124.16362-1-nemanja.marjanovic@intel.com>
>
> From: "Nemanja Marjanovic" <nemanja.marjanovic@intel.com>
>
> Add support of QinQ PPPoE packet encapsulation action.
>
> Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> ---
> v5:Removing footer from patch.
> v6:Added missing acks.
> ---
> lib/librte_pipeline/rte_table_action.c | 61 ++++++++++++++++++++++++++
> lib/librte_pipeline/rte_table_action.h | 16 +++++++
> 2 files changed, 77 insertions(+)
>
> diff --git a/lib/librte_pipeline/rte_table_action.c
> b/lib/librte_pipeline/rte_table_action.c
> index 7c7c8dd82..466019934 100644
> --- a/lib/librte_pipeline/rte_table_action.c
> +++ b/lib/librte_pipeline/rte_table_action.c
> @@ -432,6 +432,7 @@ encap_valid(enum rte_table_action_encap_type encap)
> case RTE_TABLE_ACTION_ENCAP_MPLS:
> case RTE_TABLE_ACTION_ENCAP_PPPOE:
> case RTE_TABLE_ACTION_ENCAP_VXLAN:
> + case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
> return 1;
> default:
> return 0;
> @@ -532,6 +533,13 @@ struct encap_vxlan_ipv6_vlan_data {
> struct vxlan_hdr vxlan;
> } __attribute__((__packed__));
>
> +struct encap_qinq_pppoe_data {
> + struct ether_hdr ether;
> + struct vlan_hdr svlan;
> + struct vlan_hdr cvlan;
> + struct pppoe_ppp_hdr pppoe_ppp;
> +} __attribute__((__packed__));
> +
> static size_t
> encap_data_size(struct rte_table_action_encap_config *encap)
> {
> @@ -563,6 +571,9 @@ encap_data_size(struct rte_table_action_encap_config
> *encap)
> else
> return sizeof(struct
> encap_vxlan_ipv6_data);
>
> + case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
> + return sizeof(struct encap_qinq_pppoe_data);
> +
> default:
> return 0;
> }
> @@ -599,6 +610,9 @@ encap_apply_check(struct rte_table_action_encap_params
> *p,
> case RTE_TABLE_ACTION_ENCAP_VXLAN:
> return 0;
>
> + case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
> + return 0;
> +
> default:
> return -EINVAL;
> }
> @@ -676,6 +690,38 @@ encap_qinq_apply(void *data,
> return 0;
> }
>
> +static int
> +encap_qinq_pppoe_apply(void *data,
> + struct rte_table_action_encap_params *p)
> +{
> + struct encap_qinq_pppoe_data *d = data;
> +
> + /* Ethernet */
> + ether_addr_copy(&p->qinq.ether.da, &d->ether.d_addr);
> + ether_addr_copy(&p->qinq.ether.sa, &d->ether.s_addr);
> + d->ether.ether_type = rte_htons(ETHER_TYPE_VLAN);
> +
> + /* SVLAN */
> + d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp,
> + p->qinq.svlan.dei,
> + p->qinq.svlan.vid));
> + d->svlan.eth_proto = rte_htons(ETHER_TYPE_VLAN);
> +
> + /* CVLAN */
> + d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp,
> + p->qinq.cvlan.dei,
> + p->qinq.cvlan.vid));
> + d->cvlan.eth_proto = rte_htons(ETHER_TYPE_PPPOE_SESSION);
> +
> + /* PPPoE and PPP*/
> + d->pppoe_ppp.ver_type_code = rte_htons(0x1100);
> + d->pppoe_ppp.session_id =
> rte_htons(p->qinq_pppoe.pppoe.session_id);
> + d->pppoe_ppp.length = 0; /* not pre-computed */
> + d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP);
> +
> + return 0;
> +}
> +
> static int
> encap_mpls_apply(void *data,
> struct rte_table_action_encap_params *p)
> @@ -921,6 +967,9 @@ encap_apply(void *data,
> case RTE_TABLE_ACTION_ENCAP_VXLAN:
> return encap_vxlan_apply(data, p, cfg);
>
> + case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
> + return encap_qinq_pppoe_apply(data, p);
> +
> default:
> return -EINVAL;
> }
> @@ -1119,6 +1168,18 @@ pkt_work_encap(struct rte_mbuf *mbuf,
> break;
> }
>
> + case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
> + {
> + struct encap_qinq_pppoe_data *qinq_pppoe =
> + encap(ip, data, sizeof(struct
> encap_qinq_pppoe_data));
> + qinq_pppoe->pppoe_ppp.length = rte_htons(total_length + 2);
> + mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
> + sizeof(struct encap_qinq_pppoe_data));
> + mbuf->pkt_len = mbuf->data_len = total_length +
> + sizeof(struct encap_qinq_pppoe_data);
> + break;
> + }
> +
> case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN:
> {
> if (cfg->vxlan.ip_version)
> diff --git a/lib/librte_pipeline/rte_table_action.h
> b/lib/librte_pipeline/rte_table_action.h
> index c96061291..53d16af8a 100644
> --- a/lib/librte_pipeline/rte_table_action.h
> +++ b/lib/librte_pipeline/rte_table_action.h
> @@ -380,6 +380,9 @@ enum rte_table_action_encap_type {
> * Ether -> { Ether | VLAN | IP | UDP | VXLAN | Ether }
> */
> RTE_TABLE_ACTION_ENCAP_VXLAN,
> +
> + /** IP -> { Ether | S-VLAN | C-VLAN | PPPoE | PPP | IP } */
> + RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE,
> };
>
> /** Pre-computed Ethernet header fields for encapsulation action. */
> @@ -529,6 +532,16 @@ struct rte_table_action_encap_config {
> };
> };
>
> +/** QinQ_PPPoE encap paramaeters. */
> +struct rte_table_encap_ether_qinq_pppoe {
> +
> + /** Only valid when *type* is set to QinQ. */
> + struct rte_table_action_ether_hdr ether;
> + struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header.
> */
> + struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header.
> */
> + struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
> +};
> +
> /** Encap action parameters (per table rule). */
> struct rte_table_action_encap_params {
> /** Encapsulation type. */
> @@ -553,6 +566,9 @@ struct rte_table_action_encap_params {
>
> /** Only valid when *type* is set to VXLAN. */
> struct rte_table_action_encap_vxlan_params vxlan;
> +
> + /** Only valid when *type* is set to QinQ_PPPoE. */
> + struct rte_table_encap_ether_qinq_pppoe qinq_pppoe;
> };
> };
>
> --
> 2.17.1
>
>
>
> ------------------------------
>
> Message: 3
> Date: Mon, 21 Jan 2019 11:11:23 +0000
> From: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
> To: dev@dpdk.org
> Cc: jasvinder.singh@intel.com, cristian.dumitrescu@intel.com, "Nemanja
> Marjanovic" <nemanja.marjanovic@intel.com>
> Subject: [dpdk-dev] [PATCH v6 3/4] net/softnic: support QinQ PPPoE
> encap
> Message-ID: <20190121111124.16362-3-nemanja.marjanovic@intel.com>
>
> From: "Nemanja Marjanovic" <nemanja.marjanovic@intel.com>
>
> Add implementation of QinQ PPPoE packet encapsulation action.
>
> Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> ---
> v5:Removing footer from patch.
> v6:Added missing acks.
> ---
> drivers/net/softnic/rte_eth_softnic_cli.c | 44 ++++++++++++++++++++++-
> 1 file changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c
> b/drivers/net/softnic/rte_eth_softnic_cli.c
> index 57b623377..c15b57b5b 100644
> --- a/drivers/net/softnic/rte_eth_softnic_cli.c
> +++ b/drivers/net/softnic/rte_eth_softnic_cli.c
> @@ -1335,7 +1335,7 @@ cmd_port_in_action_profile(struct pmd_internals
> *softnic,
> * tc <n_tc>
> * stats none | pkts | bytes | both]
> * [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
> - * [encap ether | vlan | qinq | mpls | pppoe |
> + * [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe |
> * vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]
> * [nat src | dst
> * proto udp | tcp]
> @@ -1612,10 +1612,14 @@ cmd_table_action_profile(struct pmd_internals
> *softnic,
> p.encap.encap_mask = 1LLU <<
> RTE_TABLE_ACTION_ENCAP_VXLAN;
> n_extra_tokens = 5;
>
> + } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0) {
> + p.encap.encap_mask =
> + 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
> } else {
> snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
> return;
> }
> +
> p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
> t0 += 2 + n_extra_tokens;
> } /* encap */
> @@ -3353,6 +3357,7 @@ parse_match(char **tokens,
> * ether <da> <sa>
> * | vlan <da> <sa> <pcp> <dei> <vid>
> * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
> + * | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
> <session_id>
> * | mpls unicast | multicast
> * <da> <sa>
> * label0 <label> <tc> <ttl>
> @@ -3658,6 +3663,43 @@ parse_table_action_encap(char **tokens,
> return 1 + 9;
> }
>
> + /* qinq_pppoe */
> + if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
> + uint32_t svlan_pcp, svlan_dei, svlan_vid;
> + uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
> +
> + if (n_tokens < 10 ||
> + softnic_parse_mac_addr(tokens[1],
> + &a->encap.qinq_pppoe.ether.da) ||
> + softnic_parse_mac_addr(tokens[2],
> + &a->encap.qinq_pppoe.ether.sa) ||
> + softnic_parser_read_uint32(&svlan_pcp, tokens[3])
> ||
> + svlan_pcp > 0x7 ||
> + softnic_parser_read_uint32(&svlan_dei, tokens[4])
> ||
> + svlan_dei > 0x1 ||
> + softnic_parser_read_uint32(&svlan_vid, tokens[5])
> ||
> + svlan_vid > 0xFFF ||
> + softnic_parser_read_uint32(&cvlan_pcp, tokens[6])
> ||
> + cvlan_pcp > 0x7 ||
> + softnic_parser_read_uint32(&cvlan_dei, tokens[7])
> ||
> + cvlan_dei > 0x1 ||
> + softnic_parser_read_uint32(&cvlan_vid, tokens[8])
> ||
> + cvlan_vid > 0xFFF ||
> +
> softnic_parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
> + tokens[9]))
> + return 0;
> +
> + a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
> + a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
> + a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
> + a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
> + a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
> + a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
> + a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
> + a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
> + return 1 + 10;
> + }
> +
> /* mpls */
> if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
> uint32_t label, tc, ttl;
> --
> 2.17.1
>
>
>
> ------------------------------
>
> Message: 4
> Date: Mon, 21 Jan 2019 11:11:24 +0000
> From: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
> To: dev@dpdk.org
> Cc: jasvinder.singh@intel.com, cristian.dumitrescu@intel.com, "Nemanja
> Marjanovic" <nemanja.marjanovic@intel.com>
> Subject: [dpdk-dev] [PATCH v6 4/4] net: add PPPoE ethertypes
> Message-ID: <20190121111124.16362-4-nemanja.marjanovic@intel.com>
>
> From: "Nemanja Marjanovic" <nemanja.marjanovic@intel.com>
>
> Add PPPoE ethertypes in to rte_ether.h.
>
> Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> ---
> v5:Removing footer from patch.
> v6:Added missing acks.
> ---
> lib/librte_net/rte_ether.h | 2 ++
> lib/librte_pipeline/rte_table_action.c | 2 --
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index c2c5e249f..54822df75 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -301,6 +301,8 @@ struct vxlan_hdr {
> #define ETHER_TYPE_RARP 0x8035 /**< Reverse Arp Protocol. */
> #define ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */
> #define ETHER_TYPE_QINQ 0x88A8 /**< IEEE 802.1ad QinQ tagging. */
> +#define ETHER_TYPE_PPPOE_DISCOVERY 0x8863 /**< PPPoE Discovery Stage. */
> +#define ETHER_TYPE_PPPOE_SESSION 0x8864 /**< PPPoE Session Stage. */
> #define ETHER_TYPE_ETAG 0x893F /**< IEEE 802.1BR E-Tag. */
> #define ETHER_TYPE_1588 0x88F7 /**< IEEE 802.1AS 1588 Precise Time
> Protocol. */
> #define ETHER_TYPE_SLOW 0x8809 /**< Slow protocols (LACP and Marker). */
> diff --git a/lib/librte_pipeline/rte_table_action.c
> b/lib/librte_pipeline/rte_table_action.c
> index 466019934..ac8109f00 100644
> --- a/lib/librte_pipeline/rte_table_action.c
> +++ b/lib/librte_pipeline/rte_table_action.c
> @@ -485,8 +485,6 @@ struct encap_mpls_data {
> uint32_t mpls_count;
> } __attribute__((__packed__));
>
> -#define ETHER_TYPE_PPPOE_SESSION 0x8864
> -
> #define PPP_PROTOCOL_IP 0x0021
>
> struct pppoe_ppp_hdr {
> --
> 2.17.1
>
>
>
> ------------------------------
>
> Message: 5
> Date: Mon, 21 Jan 2019 11:39:09 +0000
> From: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
> To: Reshma Pattan <reshma.pattan@intel.com>, dev@dpdk.org
> Cc: jasvinder.singh@intel.com
> Subject: Re: [dpdk-dev] [PATCH] doc: add deprecation notice to remove
> rte meter color
> Message-ID: <398165c5-c5c3-dcc3-a9ef-d688f94db81c@intel.com>
> Content-Type: text/plain; charset=utf-8; format=flowed
>
>
> On 12/12/2018 16:38, Reshma Pattan wrote:
> > Added deprecation notice to replace rte_meter_color
> > with rte_color.
> >
> > Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
> > Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > ---
> > doc/guides/rel_notes/deprecation.rst | 5 +++++
> > 1 file changed, 5 insertions(+)
> >
> > diff --git a/doc/guides/rel_notes/deprecation.rst
> b/doc/guides/rel_notes/deprecation.rst
> > index b48486d36..bf1fdf369 100644
> > --- a/doc/guides/rel_notes/deprecation.rst
> > +++ b/doc/guides/rel_notes/deprecation.rst
> > @@ -105,3 +105,8 @@ Deprecation Notices
> > - ``rte_pdump_set_socket_dir`` will be removed;
> > - The parameter, ``path``, of ``rte_pdump_init`` will be removed;
> > - The enum ``rte_pdump_socktype`` will be removed.
> > +
> > +* meter: New ``rte_color`` definition will be added in 19.02 and that
> will
> > + replace ``enum rte_meter_color`` in meter library in 19.05. This will
> help
> > + to consolidate color definition, which is currently replicated in
> many places,
> > + such as: rte_meter.h, rte_mtr.h, rte_tm.h.
> Acked-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
>
>
> ------------------------------
>
> Message: 6
> Date: Mon, 21 Jan 2019 11:43:59 +0000
> From: "Van Haaren, Harry" <harry.van.haaren@intel.com>
> To: "Rao, Nikhil" <nikhil.rao@intel.com>
> Cc: "dev@dpdk.org" <dev@dpdk.org>
> Subject: Re: [dpdk-dev] [PATCH] service: fix parameter type
> Message-ID:
> <
> E923DB57A917B54B9182A2E928D00FA6757C579E@IRSMSX102.ger.corp.intel.com>
>
> Content-Type: text/plain; charset="us-ascii"
>
> > -----Original Message-----
> > From: Rao, Nikhil
> > Sent: Saturday, January 19, 2019 2:01 PM
> > To: Van Haaren, Harry <harry.van.haaren@intel.com>
> > Cc: dev@dpdk.org; Rao, Nikhil <nikhil.rao@intel.com>
> > Subject: [PATCH] service: fix parameter type
> >
> > The type of value parameter to rte_service_attr_get
> > should be uint64_t *, since the attributes
> > are of type uint64_t.
> >
> > Fixes: 4d55194d76a4 ("service: add attribute get function")
> >
> > Reviewed-by: Gage Eads <gage.eads@intel.com>
> > Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
>
> Acked-by: Harry van Haaren <harry.van.haaren@intel.com>
>
> > ---
> > lib/librte_eal/common/include/rte_service.h | 2 +-
> > lib/librte_eal/common/rte_service.c | 2 +-
> > test/test/test_service_cores.c | 2 +-
> > 3 files changed, 3 insertions(+), 3 deletions(-)
> >
> > For 19.02, I assume this will require the ABI change announcement. I will
> > post it once this patch is acked.
>
> Correct - this breaks API and ABI, so certainly will need an announce.
>
> Thanks for the fixup, -Harry
>
>
>
> ------------------------------
>
> Message: 7
> Date: Mon, 21 Jan 2019 13:43:55 +0100
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> To: Tiwei Bie <tiwei.bie@intel.com>, zhihong.wang@intel.com,
> dev@dpdk.org
> Cc: haiyue.wang@intel.com, stable@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH] vhost: fix possible out of bound
> access for indirect descs
> Message-ID: <1173420b-78cf-ba5b-c2f5-54ab47d0792f@redhat.com>
> Content-Type: text/plain; charset=utf-8; format=flowed
>
>
>
> On 1/21/19 9:12 AM, Tiwei Bie wrote:
> > Fix a possible out of bound access which may happen when handling
> > indirect descs in split ring.
> >
> > Fixes: 1be4ebb1c464 ("vhost: support indirect descriptor in mergeable
> Rx")
> > Cc: stable@dpdk.org
> >
> > Reported-by: Haiyue Wang <haiyue.wang@intel.com>
> > Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> > ---
> > lib/librte_vhost/virtio_net.c | 8 ++------
> > 1 file changed, 2 insertions(+), 6 deletions(-)
> >
>
>
> Applide to dpdk-next-virtio/master.
>
> Thanks,
> Maxime
>
>
>
> ------------------------------
>
> Message: 8
> Date: Mon, 21 Jan 2019 13:18:57 +0000
> From: "Hu, Xuekun" <xuekun.hu@intel.com>
> To: "Burakov, Anatoly" <anatoly.burakov@intel.com>, Ravi Kerur
> <rkerur@gmail.com>
> Cc: "dev@dpdk.org" <dev@dpdk.org>, "Ananyev, Konstantin"
> <konstantin.ananyev@intel.com>, "Lu, Wenzhuo" <
> wenzhuo.lu@intel.com>
> Subject: Re: [dpdk-dev] IXGBE, IOMMU DMAR DRHD handling fault issue
> Message-ID:
> <
> 88A92D351643BA4CB23E30315517062663547499@SHSMSX103.ccr.corp.intel.com>
>
> Content-Type: text/plain; charset="utf-8"
>
>
> > You might also want to look here:
> https://bugs.dpdk.org/show_bug.cgi?id=76
>
> > There are apparently issues with some kernel versions that will manifest
> themselves as problems with using VF devices with IOMMU in a VM.
>
> Thanks, Anatoly. By updating host kernel to 4.18, the issue is gone. ?
>
> End of dev Digest, Vol 231, Issue 6
> ***********************************
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring
2019-01-18 15:23 3% ` [dpdk-dev] [PATCH v3 " Gage Eads
2019-01-18 15:23 2% ` [dpdk-dev] [PATCH v3 1/5] ring: add 64-bit headtail structure Gage Eads
@ 2019-01-22 9:27 0% ` Ola Liljedahl
2019-01-22 10:15 0% ` Ola Liljedahl
` (2 more replies)
1 sibling, 3 replies; 200+ results
From: Ola Liljedahl @ 2019-01-22 9:27 UTC (permalink / raw)
To: gage.eads, dev
Cc: olivier.matz, stephen, bruce.richardson, arybchenko, konstantin.ananyev
On Fri, 2019-01-18 at 09:23 -0600, Gage Eads wrote:
> For some users, the rte ring's "non-preemptive" constraint is not
> acceptable;
> for example, if the application uses a mixture of pinned high-
> priority threads
> and multiplexed low-priority threads that share a mempool.
>
> This patchset introduces a non-blocking ring, on top of which a
> mempool can run.
> Crucially, the non-blocking algorithm relies on a 128-bit compare-
> and-swap, so
> it is currently limited to x86_64 machines. This is also an
> experimental API,
> so RING_F_NB users must build with the ALLOW_EXPERIMENTAL_API flag.
>
> The ring uses more compare-and-swap atomic operations than the
> regular rte ring:
> With no contention, an enqueue of n pointers uses (1 + 2n) CAS
> operations and a
> dequeue of n pointers uses 2. This algorithm has worse average-case
> performance
> than the regular rte ring (particularly a highly-contended ring with
> large bulk
> accesses), however:
> - For applications with preemptible pthreads, the regular rte ring's
> worst-case
> performance (i.e. one thread being preempted in the update_tail()
> critical
> section) is much worse than the non-blocking ring's.
> - Software caching can mitigate the average case performance for
> ring-based
> algorithms. For example, a non-blocking ring based mempool (a
> likely use case
> for this ring) with per-thread caching.
>
> The non-blocking ring is enabled via a new flag, RING_F_NB. For ease-
> of-use,
> existing ring enqueue/dequeue functions work with both "regular" and
> non-blocking rings.
>
> This patchset also adds non-blocking versions of ring_autotest and
> ring_perf_autotest, and a non-blocking ring based mempool.
>
> This patchset makes one API change; a deprecation notice will be
> posted in a
> separate commit.
>
> This patchset depends on the non-blocking stack patchset[1].
>
> [1] http://mails.dpdk.org/archives/dev/2019-January/123653.html
>
> v3:
> - Avoid the ABI break by putting 64-bit head and tail values in the
> same
> cacheline as struct rte_ring's prod and cons members.
> - Don't attempt to compile rte_atomic128_cmpset without
> ALLOW_EXPERIMENTAL_API, as this would break a large number of
> libraries.
> - Add a helpful warning to __rte_ring_do_nb_enqueue_mp() in case
> someone tries
> to use RING_F_NB without the ALLOW_EXPERIMENTAL_API flag.
> - Update the ring mempool to use experimental APIs
> - Clarify that RINB_F_NB is only limited to x86_64 currently;
> ARMv8.1-A builds
> can eventually support it with the CASP instruction.
ARMv8.0 should be able to implement a 128-bit atomic compare exchange
operation using LDXP/STXP.
From an ARM perspective, I want all atomic operations to take memory
ordering arguments (e.g. acquire, release). Not all usages of e.g.
atomic compare exchange require sequential consistency (which I think
what x86 cmpxchg instruction provides). DPDK functions should not be
modelled after x86 behaviour.
Lock-free 128-bit atomics implementations for ARM/AArch64 and x86-64
are available here:
https://github.com/ARM-software/progress64/blob/master/src/lockfree.h
>
> v2:
> - Merge separate docs commit into patch #5
> - Convert uintptr_t to size_t
> - Add a compile-time check for the size of size_t
> - Fix a space-after-typecast issue
> - Fix an unnecessary-parentheses checkpatch warning
> - Bump librte_ring's library version
>
> Gage Eads (5):
> ring: add 64-bit headtail structure
> ring: add a non-blocking implementation
> test_ring: add non-blocking ring autotest
> test_ring_perf: add non-blocking ring perf test
> mempool/ring: add non-blocking ring handlers
>
> doc/guides/prog_guide/env_abstraction_layer.rst | 2 +-
> drivers/mempool/ring/Makefile | 1 +
> drivers/mempool/ring/meson.build | 2 +
> drivers/mempool/ring/rte_mempool_ring.c | 58 ++-
> lib/librte_eventdev/rte_event_ring.h | 2 +-
> lib/librte_ring/Makefile | 3 +-
> lib/librte_ring/rte_ring.c | 72 ++-
> lib/librte_ring/rte_ring.h | 574
> ++++++++++++++++++++++--
> lib/librte_ring/rte_ring_generic_64.h | 152 +++++++
> lib/librte_ring/rte_ring_version.map | 7 +
> test/test/test_ring.c | 57 ++-
> test/test/test_ring_perf.c | 19 +-
> 12 files changed, 874 insertions(+), 75 deletions(-)
> create mode 100644 lib/librte_ring/rte_ring_generic_64.h
>
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] doc: announce ABI change for cryptodev config
2019-01-18 6:59 4% ` Shally Verma
@ 2019-01-22 9:31 4% ` Anoob Joseph
0 siblings, 0 replies; 200+ results
From: Anoob Joseph @ 2019-01-22 9:31 UTC (permalink / raw)
To: Trahe, Fiona, Akhil Goyal, De Lara Guarch, Pablo
Cc: Jerin Jacob Kollanukkaran, Narayana Prasad Raju Athreya,
Shally Verma, dev
Hi Fiona,
Any more comments on this?
@ Akhil, Pablo
Can you review this change and share your thoughts?
Thanks,
Anoob
> -----Original Message-----
> From: Shally Verma
> Sent: 18 January 2019 12:29
> To: Anoob Joseph <anoobj@marvell.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; Akhil Goyal <akhil.goyal@nxp.com>; De Lara Guarch,
> Pablo <pablo.de.lara.guarch@intel.com>
> Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Narayana Prasad Raju
> Athreya <pathreya@marvell.com>; dev@dpdk.org
> Subject: RE: [PATCH] doc: announce ABI change for cryptodev config
>
> HI Fiona, Anoob
>
> >-----Original Message-----
> >From: Anoob Joseph
> >Sent: 17 January 2019 19:17
> >To: Trahe, Fiona <fiona.trahe@intel.com>; Akhil Goyal
> ><akhil.goyal@nxp.com>; De Lara Guarch, Pablo
> ><pablo.de.lara.guarch@intel.com>
> >Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Narayana Prasad
> >Raju Athreya <pathreya@marvell.com>; Shally Verma
> ><shallyv@marvell.com>; dev@dpdk.org
> >Subject: RE: [PATCH] doc: announce ABI change for cryptodev config
> >
> >Hi Fiona,
> >
> >Please see inline.
> >
> >Thanks,
> >Anoob
> >
> >> -----Original Message-----
> >> From: Trahe, Fiona <fiona.trahe@intel.com>
> >> Sent: 17 January 2019 17:07
> >> To: Anoob Joseph <anoobj@marvell.com>; Akhil Goyal
> >> <akhil.goyal@nxp.com>; De Lara Guarch, Pablo
> >> <pablo.de.lara.guarch@intel.com>
> >> Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Narayana Prasad
> >> Raju Athreya <pathreya@marvell.com>; Shally Verma
> >> <shallyv@marvell.com>; dev@dpdk.org; Trahe, Fiona
> >> <fiona.trahe@intel.com>
> >> Subject: RE: [PATCH] doc: announce ABI change for cryptodev config
> >>
> >> Hi Joseph,
> >>
> >> > -----Original Message-----
> >> > From: Anoob Joseph [mailto:anoobj@marvell.com]
> >> > Sent: Thursday, January 17, 2019 9:40 AM
> >> > To: Akhil Goyal <akhil.goyal@nxp.com>; De Lara Guarch, Pablo
> >> > <pablo.de.lara.guarch@intel.com>; Trahe, Fiona
> >> > <fiona.trahe@intel.com>
> >> > Cc: Anoob Joseph <anoobj@marvell.com>; Jerin Jacob Kollanukkaran
> >> > <jerinj@marvell.com>; Narayana Prasad Raju Athreya
> >> > <pathreya@marvell.com>; Shally Verma <shallyv@marvell.com>;
> >> > dev@dpdk.org
> >> > Subject: [PATCH] doc: announce ABI change for cryptodev config
> >> >
> >> > Add new field ff_enable in rte_cryptodev_config. This enables
> >> > applications to control the features enabled on the crypto device.
> >> >
> >> > Proposed new layout:
> >> >
> >> > /** Crypto device configuration structure */ struct
> >> > rte_cryptodev_config {
> >> > int socket_id; /**< Socket to allocate resources on */
> >> > uint16_t nb_queue_pairs;
> >> > /**< Number of queue pairs to configure on device */
> >> > + uint64_t ff_enable;
> >> > + /**< Feature flags to be enabled on the device. Only the features set
> >> > + * on rte_cryptodev_info.feature_flags are allowed to be set.
> >> > + */
> >> > };
> >> >
> >> > For eth devices, rte_eth_conf.rx_mode.offloads and
> >> > rte_eth_conf.tx_mode.offloads fields are used by applications to
> >> > control the offloads enabled on the eth device. This proposal adds
> >> > a similar ability for the crypto device.
> >> [Fiona] I'm unfamiliar with eth config so can you explain a bit more
> >> how this works?
> >
> >[Anoob] For eth devices, application would first do
> >rte_eth_dev_info_get() and gets the capabilities. The device would
> >expose it's capabilities using dev_info.rx_offload_capa &
> dev_info.tx_offload_capa. The application can enable/disable these features
> while configuring the eth ports.
> >
> >From ipsec-secgw:
> >https://git.dpdk.org/dpdk/tree/examples/ipsec-secgw/ipsec-secgw.c#n1866
> >
> >if (frame_size) {
> > local_port_conf.rxmode.max_rx_pkt_len = frame_size;
> > local_port_conf.rxmode.offloads |=
> DEV_RX_OFFLOAD_JUMBO_FRAME;
> > }
> >
> ><snip>
> >
> >ret = rte_eth_dev_configure(portid, nb_rx_queue, nb_tx_queue,
> > &local_port_conf);
> >
> ><snip>
> >
> >This way application can choose to disable unwanted offloads.
> >
> >Port init in ipsec-secgw:
> >https://git.dpdk.org/dpdk/tree/examples/ipsec-secgw/ipsec-secgw.c#n1826
> >
> >> e.g. if a crypto device's info says it supports
> >> RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO
> >> RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING
> >> RTE_CRYPTODEV_FF_CPU_AESNI
> >> RTE_CRYPTODEV_FF_SECURITY
> >> RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT
> >> these things are all already enabled.
> >> Is the param a way to disable some of them?
> >
> >[Anoob] Yes. There are few other flags in addition to the above. Like
> RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO.
> >
> >> If so, it would be better to call it ff_disable.
> >
> >[Anoob] Calling it ff_enable is to make it similar to how it's done with eth
> devices. Either way should be fine.
> [Shally] keeping it as "ff_enable" will require application to set these flags to
> configure PMD. If we define it other way around, then it would be mean to mask
> out unwanted features which can be quite many.
> Though purpose can be achieved both ways but keeping it as "enable" looks
> more easy to use, readable and inline with how ethdev handle multi feature
> support.
> So I would prefer to keep it as "ff_enable"
>
> Thanks
> Shally
>
> >
> >> And to limit it to the subset of features that it makes sense to disable.
> >> i.e. why would an application disable chaining or any of the SGL
> >> flags? It would just add extra cycles in the PMD to error check on
> >> these cases, instead the appl can just not send such commands.
> >> And it doesn't make sense to disable AESNI or
> >> RTE_CRYPTODEV_FF_HW_ACCELERATED.
> >> Actually I can't see what an application would want to achieve by
> >> disabling any flag?
> >
> >[Anoob] Features like ASYMMETRIC or SECURITY is not required for every
> >application. SECURITY is added for eth devices also. But since the
> >feature can be disabled while configuring the port, applications are given a
> choice to disable it. That way apps like l2fwd doesn't enable SECURITY. With
> crypto this option is not available.
> >
> >If the unused offloads can be communicated to the PMD before initialization,
> the PMD will be allowed to optimize hardware usage.
> >Otherwise, supporting more features would affect performance, even if
> application is not making use of those features.
> >
> >Ex: test-crypto-perf doesn't use ASYM/SECURITY. Now adding these features
> would affect the performance of this app.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring
2019-01-22 9:27 0% ` [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring Ola Liljedahl
@ 2019-01-22 10:15 0% ` Ola Liljedahl
2019-01-22 19:15 0% ` Eads, Gage
2019-01-23 16:02 0% ` Jerin Jacob Kollanukkaran
2 siblings, 0 replies; 200+ results
From: Ola Liljedahl @ 2019-01-22 10:15 UTC (permalink / raw)
To: gage.eads, dev
Cc: olivier.matz, stephen, bruce.richardson, arybchenko, konstantin.ananyev
Sorry about the confidental footer. I tried to remove it using some Exhange
magic but it seems not to work with Evolution. I'll try some other way.
-- Ola
On Tue, 2019-01-22 at 09:27 +0000, Ola Liljedahl wrote:
> On Fri, 2019-01-18 at 09:23 -0600, Gage Eads wrote:
> >
> > For some users, the rte ring's "non-preemptive" constraint is not
> > acceptable;
> > for example, if the application uses a mixture of pinned high-
> > priority threads
> > and multiplexed low-priority threads that share a mempool.
> >
I. This patchset introduces a non-blocking ring, on top of which a
> > mempool can run.
> > Crucially, the non-blocking algorithm relies on a 128-bit compare-
> > and-swap, so
> > it is currently limited to x86_64 machines. This is also an
> > experimental API,
> > so RING_F_NB users must build with the ALLOW_EXPERIMENTAL_API flag.
> >
> > The ring uses more compare-and-swap atomic operations than the
> > regular rte ring:
> > With no contention, an enqueue of n pointers uses (1 + 2n) CAS
> > operations and a
> > dequeue of n pointers uses 2. This algorithm has worse average-case
> > performance
> > than the regular rte ring (particularly a highly-contended ring with
> > large bulk
> > accesses), however:
> > - For applications with preemptible pthreads, the regular rte ring's
> > worst-case
> > performance (i.e. one thread being preempted in the update_tail()
> > critical
> > section) is much worse than the non-blocking ring's.
> > - Software caching can mitigate the average case performance for
> > ring-based
> > algorithms. For example, a non-blocking ring based mempool (a
> > likely use case
> > for this ring) with per-thread caching.
> >
> > The non-blocking ring is enabled via a new flag, RING_F_NB. For ease-
> > of-use,
> > existing ring enqueue/dequeue functions work with both "regular" and
> > non-blocking rings.
> >
> > This patchset also adds non-blocking versions of ring_autotest and
> > ring_perf_autotest, and a non-blocking ring based mempool.
> >
> > This patchset makes one API change; a deprecation notice will be
> > posted in a
> > separate commit.
> >
> > This patchset depends on the non-blocking stack patchset[1].
> >
> > [1] http://mails.dpdk.org/archives/dev/2019-January/123653.html
> >
> > v3:
> > - Avoid the ABI break by putting 64-bit head and tail values in the
> > same
> > cacheline as struct rte_ring's prod and cons members.
> > - Don't attempt to compile rte_atomic128_cmpset without
> > ALLOW_EXPERIMENTAL_API, as this would break a large number of
> > libraries.
> > - Add a helpful warning to __rte_ring_do_nb_enqueue_mp() in case
> > someone tries
> > to use RING_F_NB without the ALLOW_EXPERIMENTAL_API flag.
> > - Update the ring mempool to use experimental APIs
> > - Clarify that RINB_F_NB is only limited to x86_64 currently;
> > ARMv8.1-A builds
> > can eventually support it with the CASP instruction.
> ARMv8.0 should be able to implement a 128-bit atomic compare exchange
> operation using LDXP/STXP.
>
> From an ARM perspective, I want all atomic operations to take memory
> ordering arguments (e.g. acquire, release). Not all usages of e.g.
> atomic compare exchange require sequential consistency (which I think
> what x86 cmpxchg instruction provides). DPDK functions should not be
> modelled after x86 behaviour.
>
> Lock-free 128-bit atomics implementations for ARM/AArch64 and x86-64
> are available here:
> https://github.com/ARM-software/progress64/blob/master/src/lockfree.h
>
> >
> >
> > v2:
> > - Merge separate docs commit into patch #5
> > - Convert uintptr_t to size_t
> > - Add a compile-time check for the size of size_t
> > - Fix a space-after-typecast issue
> > - Fix an unnecessary-parentheses checkpatch warning
> > - Bump librte_ring's library version
> >
> > Gage Eads (5):
> > ring: add 64-bit headtail structure
> > ring: add a non-blocking implementation
> > test_ring: add non-blocking ring autotest
> > test_ring_perf: add non-blocking ring perf test
> > mempool/ring: add non-blocking ring handlers
> >
> > doc/guides/prog_guide/env_abstraction_layer.rst | 2 +-
> > drivers/mempool/ring/Makefile | 1 +
> > drivers/mempool/ring/meson.build | 2 +
> > drivers/mempool/ring/rte_mempool_ring.c | 58 ++-
> > lib/librte_eventdev/rte_event_ring.h | 2 +-
> > lib/librte_ring/Makefile | 3 +-
> > lib/librte_ring/rte_ring.c | 72 ++-
> > lib/librte_ring/rte_ring.h | 574
> > ++++++++++++++++++++++--
> > lib/librte_ring/rte_ring_generic_64.h | 152 +++++++
> > lib/librte_ring/rte_ring_version.map | 7 +
> > test/test/test_ring.c | 57 ++-
> > test/test/test_ring_perf.c | 19 +-
> > 12 files changed, 874 insertions(+), 75 deletions(-)
> > create mode 100644 lib/librte_ring/rte_ring_generic_64.h
> >
> IMPORTANT NOTICE: The contents of this email and any attachments are
> confidential and may also be privileged. If you are not the intended
> recipient, please notify the sender immediately and do not disclose the
> contents to any other person, use it for any purpose, or store or copy the
> information in any medium. Thank you.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3 1/3] doc: clean ABI/API policy guide
2018-12-21 15:57 35% ` [dpdk-dev] [PATCH v2 " Ferruh Yigit
@ 2019-01-22 16:23 35% ` Ferruh Yigit
2019-01-22 16:23 17% ` [dpdk-dev] [PATCH v3 2/3] doc: make RTE_NEXT_ABI optional Ferruh Yigit
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Ferruh Yigit @ 2019-01-22 16:23 UTC (permalink / raw)
To: dev, John McNamara, Marko Kovacevic
Cc: Luca Boccassi, Kevin Traynor, Yongseok Koh, Neil Horman
The original document written from the point of ABI versioning but later
additions make document confusing, convert document into a ABI/API
policy documentation and organize the document in subsections:
- ABI/API Deprecation
- Experimental APIs
- Library versioning
- ABI versioning
Aim to clarify confusion between deprecation versioned ABI and overall
ABI/API deprecation, also ABI versioning and Library versioning by
organizing the sections.
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
Cc: Luca Boccassi <bluca@debian.org>
Cc: Kevin Traynor <ktraynor@redhat.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
---
doc/guides/contributing/versioning.rst | 132 +++++++++++++------------
1 file changed, 71 insertions(+), 61 deletions(-)
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 01b36247e..19af56cd2 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -1,33 +1,31 @@
.. SPDX-License-Identifier: BSD-3-Clause
Copyright 2018 The DPDK contributors
-Managing ABI updates
-====================
+DPDK ABI/API policy
+===================
Description
-----------
This document details some methods for handling ABI management in the DPDK.
-Note this document is not exhaustive, in that C library versioning is flexible
-allowing multiple methods to achieve various goals, but it will provide the user
-with some introductory methods
General Guidelines
------------------
#. Whenever possible, ABI should be preserved
-#. Libraries or APIs marked in ``experimental`` state may change without constraint.
+#. ABI/API may be changed with a deprecation process
+#. The modification of symbols can generally be managed with versioning
+#. Libraries or APIs marked in ``experimental`` state may change without constraint
#. New APIs will be marked as ``experimental`` for at least one release to allow
any issues found by users of the new API to be fixed quickly
#. The addition of symbols is generally not problematic
-#. The modification of symbols can generally be managed with versioning
#. The removal of symbols generally is an ABI break and requires bumping of the
LIBABIVER macro
#. Updates to the minimum hardware requirements, which drop support for hardware which
was previously supported, should be treated as an ABI change.
What is an ABI
---------------
+~~~~~~~~~~~~~~
An ABI (Application Binary Interface) is the set of runtime interfaces exposed
by a library. It is similar to an API (Application Programming Interface) but
@@ -39,9 +37,13 @@ Therefore, in the case of dynamic linking, it is critical that an ABI is
preserved, or (when modified), done in such a way that the application is unable
to behave improperly or in an unexpected fashion.
-The DPDK ABI policy
+
+ABI/API Deprecation
-------------------
+The DPDK ABI policy
+~~~~~~~~~~~~~~~~~~~
+
ABI versions are set at the time of major release labeling, and the ABI may
change multiple times, without warning, between the last release label and the
HEAD label of the git tree.
@@ -99,8 +101,36 @@ readability purposes should be avoided.
follow the relevant deprecation policy procedures as above: 3 acks and
announcement at least one release in advance.
+Examples of Deprecation Notices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+ to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+ in version 2.0. Backwards compatibility will be maintained for this function
+ until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+ performance reasons. Existing binary applications will have backwards
+ compatibility in release 2.0, while newly built binaries will need to
+ reference the new structure variant ``struct rte_foo2``. Compatibility will
+ be removed in release 2.2, and all applications will require updating and
+ rebuilding to the new structure at that time, which will be renamed to the
+ original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+ upcoming release 2.0 will not contain these changes, but release 2.1 will,
+ and no backwards compatibility is planned due to the extensive nature of
+ these changes. Binaries using this library built prior to version 2.1 will
+ require updating and recompilation.
+
+
Experimental APIs
-~~~~~~~~~~~~~~~~~
+-----------------
APIs marked as ``experimental`` are not considered part of the ABI and may
change without warning at any time. Since changes to APIs are most likely
@@ -130,35 +160,38 @@ is not required. Though, an API should remain in experimental state for at least
one release. Thereafter, normal process of posting patch for review to mailing
list can be followed.
-Examples of Deprecation Notices
--------------------------------
-The following are some examples of ABI deprecation notices which would be
-added to the Release Notes:
+Library versioning
+------------------
-* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
- to be replaced with the inline function ``rte_foo()``.
+Downstreams might want to provide different DPDK releases at the same time to
+support multiple consumers of DPDK linked against older and newer sonames.
-* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
- in version 2.0. Backwards compatibility will be maintained for this function
- until the release of version 2.1
+Also due to the interdependencies that DPDK libraries can have applications
+might end up with an executable space in which multiple versions of a library
+are mapped by ld.so.
-* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
- performance reasons. Existing binary applications will have backwards
- compatibility in release 2.0, while newly built binaries will need to
- reference the new structure variant ``struct rte_foo2``. Compatibility will
- be removed in release 2.2, and all applications will require updating and
- rebuilding to the new structure at that time, which will be renamed to the
- original ``struct rte_foo``.
+Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
+depending on LibA.
-* Significant ABI changes are planned for the ``librte_dostuff`` library. The
- upcoming release 2.0 will not contain these changes, but release 2.1 will,
- and no backwards compatibility is planned due to the extensive nature of
- these changes. Binaries using this library built prior to version 2.1 will
- require updating and recompilation.
+.. note::
+
+ Application
+ \-> LibA.old
+ \-> LibB.new -> LibA.new
+
+That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
+If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
+library - versions defined in the libraries ``LIBABIVER``.
+An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
+``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
+
+
+ABI versioning
+--------------
Versioning Macros
------------------
+~~~~~~~~~~~~~~~~~
When a symbol is exported from a library to provide an API, it also provides a
calling convention (ABI) that is embodied in its name, return type and
@@ -186,36 +219,11 @@ The macros exported are:
fully qualified function ``p``, so that if a symbol becomes versioned, it
can still be mapped back to the public symbol name.
-Setting a Major ABI version
----------------------------
-
-Downstreams might want to provide different DPDK releases at the same time to
-support multiple consumers of DPDK linked against older and newer sonames.
-
-Also due to the interdependencies that DPDK libraries can have applications
-might end up with an executable space in which multiple versions of a library
-are mapped by ld.so.
-
-Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
-depending on LibA.
-
-.. note::
-
- Application
- \-> LibA.old
- \-> LibB.new -> LibA.new
-
-That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
-If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
-library - versions defined in the libraries ``LIBABIVER``.
-An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
-``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
-
Examples of ABI Macro use
--------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^
Updating a public API
-~~~~~~~~~~~~~~~~~~~~~
+_____________________
Assume we have a function as follows
@@ -425,7 +433,7 @@ and a new DPDK_2.1 version, used by future built applications.
Deprecating part of a public API
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+________________________________
Lets assume that you've done the above update, and after a few releases have
passed you decide you would like to retire the old version of the function.
@@ -483,7 +491,7 @@ possibly incompatible library version:
+LIBABIVER := 2
Deprecating an entire ABI version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+_________________________________
While removing a symbol from and ABI may be useful, it is often more practical
to remove an entire version node at once. If a version node completely
@@ -532,6 +540,7 @@ Lastly, any VERSION_SYMBOL macros that point to the old version node should be
removed, taking care to keep, where need old code in place to support newer
versions of the symbol.
+
Running the ABI Validator
-------------------------
@@ -571,3 +580,4 @@ compile both tags) it will create compatibility reports in the
follows::
grep -lr Incompatible compat_reports/
+
--
2.17.2
^ permalink raw reply [relevance 35%]
* [dpdk-dev] [PATCH v3 2/3] doc: make RTE_NEXT_ABI optional
2019-01-22 16:23 35% ` [dpdk-dev] [PATCH v3 1/3] " Ferruh Yigit
@ 2019-01-22 16:23 17% ` Ferruh Yigit
2019-01-23 8:13 4% ` [dpdk-dev] [PATCH v3 1/3] doc: clean ABI/API policy guide Neil Horman
2019-01-24 18:10 35% ` [dpdk-dev] [PATCH v4 " Ferruh Yigit
2 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2019-01-22 16:23 UTC (permalink / raw)
To: dev, John McNamara, Marko Kovacevic
Cc: Luca Boccassi, Kevin Traynor, Yongseok Koh, Neil Horman
Initial process requires oncoming changes described in deprecation
notice should be implemented in a RTE_NEXT_ABI gated way.
This has been discussed in technical board, and since this can cause a
multiple #ifdef blocks in multiple locations of the code, can be
confusing specially for the modifications that requires data structure
changes. Anyway this was not happening in practice.
Making RTE_NEXT_ABI usage more optional based on techboard decision:
http://mails.dpdk.org/archives/dev/2019-January/123519.html
The intention with using RTE_NEXT_ABI was to provide more information
to the user about planned changes, and force developer to think more in
coding level. Since RTE_NEXT_ABI become optional, now the preferred way
to do this is, if possible, sending changes, described in deprecation
notice, as a separate patch and reference it in deprecation notice.
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
Cc: Luca Boccassi <bluca@debian.org>
Cc: Kevin Traynor <ktraynor@redhat.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
---
doc/guides/contributing/versioning.rst | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 19af56cd2..bfc27fbe0 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -73,19 +73,16 @@ being provided. The requirements for doing so are:
interest" be sought for each deprecation, for example: from NIC vendors,
CPU vendors, end-users, etc.
-#. The changes (including an alternative map file) must be gated with
- the ``RTE_NEXT_ABI`` option, and provided with a deprecation notice at the
- same time.
- It will become the default ABI in the next release.
+#. The changes (including an alternative map file) can be included with
+ deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
+ to provide more details about oncoming changes.
+ ``RTE_NEXT_ABI`` wrapper will be removed when it become the default ABI.
+ More preferred way to provide this information is sending the feature
+ as a separate patch and reference it in deprecation notice.
#. A full deprecation cycle, as explained above, must be made to offer
downstream consumers sufficient warning of the change.
-#. At the beginning of the next release cycle, every ``RTE_NEXT_ABI``
- conditions will be removed, the ``LIBABIVER`` variable in the makefile(s)
- where the ABI is changed will be incremented, and the map files will
- be updated.
-
Note that the above process for ABI deprecation should not be undertaken
lightly. ABI stability is extremely important for downstream consumers of the
DPDK, especially when distributed in shared object form. Every effort should
--
2.17.2
^ permalink raw reply [relevance 17%]
* Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width size
@ 2019-01-22 18:27 3% ` Eads, Gage
0 siblings, 0 replies; 200+ results
From: Eads, Gage @ 2019-01-22 18:27 UTC (permalink / raw)
To: Burakov, Anatoly, Richardson, Bruce
Cc: dev, olivier.matz, arybchenko, Ananyev, Konstantin
> -----Original Message-----
> From: Burakov, Anatoly
> Sent: Monday, January 21, 2019 8:15 AM
> To: Eads, Gage <gage.eads@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>
> Cc: dev@dpdk.org; olivier.matz@6wind.com; arybchenko@solarflare.com;
> Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width
> size
>
> On 11-Jan-19 7:27 PM, Eads, Gage wrote:
> >
> >
> >> -----Original Message-----
> >> From: Richardson, Bruce
> >> Sent: Friday, January 11, 2019 5:59 AM
> >> To: Burakov, Anatoly <anatoly.burakov@intel.com>
> >> Cc: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org;
> >> olivier.matz@6wind.com; arybchenko@solarflare.com; Ananyev,
> >> Konstantin <konstantin.ananyev@intel.com>
> >> Subject: Re: [dpdk-dev] [PATCH 1/6] ring: change head and tail to
> >> pointer-width size
> >>
> >> On Fri, Jan 11, 2019 at 11:30:24AM +0000, Burakov, Anatoly wrote:
> >>> On 11-Jan-19 10:58 AM, Bruce Richardson wrote:
> >>>> On Fri, Jan 11, 2019 at 10:40:19AM +0000, Burakov, Anatoly wrote:
> >>>>> <...>
> >>>>>
> >>>>>> + * Copyright(c) 2016-2019 Intel Corporation
> >>>>>> */
> >>>>>> /**
> >>>>>> @@ -88,7 +88,7 @@ rte_event_ring_enqueue_burst(struct
> >> rte_event_ring *r,
> >>>>>> const struct rte_event *events,
> >>>>>> unsigned int n, uint16_t *free_space)
> >>>>>> {
> >>>>>> - uint32_t prod_head, prod_next;
> >>>>>> + uintptr_t prod_head, prod_next;
> >>>>>
> >>>>> I would also question the use of uinptr_t. I think semnatically,
> >>>>> size_t is more appropriate.
> >>>>>
> >>>> Yes, it would, but I believe in this case they want to use the
> >>>> largest size of (unsigned)int where there exists an atomic for
> >>>> manipulating 2 of them simultaneously. [The largest size is to
> >>>> minimize any chance of an ABA issue occuring]. Therefore we need
> >>>> 32-bit values on 32-bit and 64-bit on 64, and I suspect the best
> >>>> way to guarantee this is to use pointer-sized values. If size_t is
> >>>> guaranteed across all OS's to have the same size as uintptr_t it
> >>>> could also be
> >> used, though.
> >>>>
> >>>> /Bruce
> >>>>
> >>>
> >>> Technically, size_t and uintptr_t are not guaranteed to match. In
> >>> practice, they won't match only on architectures that DPDK doesn't
> >>> intend to run on (such as 16-bit segmented archs, where size_t would
> >>> be 16-bit but uinptr_t would be 32-bit).
> >>>
> >>> In all the rest of DPDK code, we use size_t for this kind of thing.
> >>>
> >>
> >> Ok.
> >> If we do use size_t, I think we also need to add a compile-time check
> >> into the build too, to error out if sizeof(size_t) != sizeof(uintptr_t).
> >
> > Ok, I wasn't aware of the precedent of using size_t for this purpose. I'll change
> it and look into adding a static assert.
>
> RTE_BUILD_BUG_ON?
Appreciate the pointer, but with the changes needed to preserve ABI compatibility* this is no longer necessary.
*http://mails.dpdk.org/archives/dev/2019-January/123775.html
>
> >
> > Thanks,
> > Gage
> >
>
>
> --
> Thanks,
> Anatoly
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring
2019-01-22 9:27 0% ` [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring Ola Liljedahl
2019-01-22 10:15 0% ` Ola Liljedahl
@ 2019-01-22 19:15 0% ` Eads, Gage
2019-01-23 16:02 0% ` Jerin Jacob Kollanukkaran
2 siblings, 0 replies; 200+ results
From: Eads, Gage @ 2019-01-22 19:15 UTC (permalink / raw)
To: Ola Liljedahl, dev
Cc: olivier.matz, stephen, Richardson, Bruce, arybchenko, Ananyev,
Konstantin
> -----Original Message-----
> From: Ola Liljedahl [mailto:Ola.Liljedahl@arm.com]
> Sent: Tuesday, January 22, 2019 3:28 AM
> To: Eads, Gage <gage.eads@intel.com>; dev@dpdk.org
> Cc: olivier.matz@6wind.com; stephen@networkplumber.org; Richardson, Bruce
> <bruce.richardson@intel.com>; arybchenko@solarflare.com; Ananyev,
> Konstantin <konstantin.ananyev@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring
>
> On Fri, 2019-01-18 at 09:23 -0600, Gage Eads wrote:
> > For some users, the rte ring's "non-preemptive" constraint is not
> > acceptable; for example, if the application uses a mixture of pinned
> > high- priority threads and multiplexed low-priority threads that share
> > a mempool.
> >
> > This patchset introduces a non-blocking ring, on top of which a
> > mempool can run.
> > Crucially, the non-blocking algorithm relies on a 128-bit compare-
> > and-swap, so it is currently limited to x86_64 machines. This is also
> > an experimental API, so RING_F_NB users must build with the
> > ALLOW_EXPERIMENTAL_API flag.
> >
> > The ring uses more compare-and-swap atomic operations than the regular
> > rte ring:
> > With no contention, an enqueue of n pointers uses (1 + 2n) CAS
> > operations and a dequeue of n pointers uses 2. This algorithm has
> > worse average-case performance than the regular rte ring (particularly
> > a highly-contended ring with large bulk accesses), however:
> > - For applications with preemptible pthreads, the regular rte ring's
> > worst-case
> > performance (i.e. one thread being preempted in the update_tail()
> > critical
> > section) is much worse than the non-blocking ring's.
> > - Software caching can mitigate the average case performance for
> > ring-based
> > algorithms. For example, a non-blocking ring based mempool (a likely
> > use case
> > for this ring) with per-thread caching.
> >
> > The non-blocking ring is enabled via a new flag, RING_F_NB. For ease-
> > of-use, existing ring enqueue/dequeue functions work with both
> > "regular" and non-blocking rings.
> >
> > This patchset also adds non-blocking versions of ring_autotest and
> > ring_perf_autotest, and a non-blocking ring based mempool.
> >
> > This patchset makes one API change; a deprecation notice will be
> > posted in a separate commit.
> >
> > This patchset depends on the non-blocking stack patchset[1].
> >
> > [1] http://mails.dpdk.org/archives/dev/2019-January/123653.html
> >
> > v3:
> > - Avoid the ABI break by putting 64-bit head and tail values in the
> > same
> > cacheline as struct rte_ring's prod and cons members.
> > - Don't attempt to compile rte_atomic128_cmpset without
> > ALLOW_EXPERIMENTAL_API, as this would break a large number of
> > libraries.
> > - Add a helpful warning to __rte_ring_do_nb_enqueue_mp() in case
> > someone tries
> > to use RING_F_NB without the ALLOW_EXPERIMENTAL_API flag.
> > - Update the ring mempool to use experimental APIs
> > - Clarify that RINB_F_NB is only limited to x86_64 currently;
> > ARMv8.1-A builds
> > can eventually support it with the CASP instruction.
> ARMv8.0 should be able to implement a 128-bit atomic compare exchange
> operation using LDXP/STXP.
I see, I wasn't aware these instructions were available.
>
> From an ARM perspective, I want all atomic operations to take memory ordering
> arguments (e.g. acquire, release). Not all usages of e.g.
> atomic compare exchange require sequential consistency (which I think what
> x86 cmpxchg instruction provides). DPDK functions should not be modelled after
> x86 behaviour.
>
> Lock-free 128-bit atomics implementations for ARM/AArch64 and x86-64 are
> available here:
> https://github.com/ARM-software/progress64/blob/master/src/lockfree.h
>
Sure, I'll address this in the next patchset.
Thanks,
Gage
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 1/3] doc: clean ABI/API policy guide
2019-01-22 16:23 35% ` [dpdk-dev] [PATCH v3 1/3] " Ferruh Yigit
2019-01-22 16:23 17% ` [dpdk-dev] [PATCH v3 2/3] doc: make RTE_NEXT_ABI optional Ferruh Yigit
@ 2019-01-23 8:13 4% ` Neil Horman
2019-01-24 18:10 35% ` [dpdk-dev] [PATCH v4 " Ferruh Yigit
2 siblings, 0 replies; 200+ results
From: Neil Horman @ 2019-01-23 8:13 UTC (permalink / raw)
To: Ferruh Yigit
Cc: dev, John McNamara, Marko Kovacevic, Luca Boccassi,
Kevin Traynor, Yongseok Koh
On Tue, Jan 22, 2019 at 04:23:08PM +0000, Ferruh Yigit wrote:
> The original document written from the point of ABI versioning but later
> additions make document confusing, convert document into a ABI/API
> policy documentation and organize the document in subsections:
> - ABI/API Deprecation
> - Experimental APIs
> - Library versioning
> - ABI versioning
>
> Aim to clarify confusion between deprecation versioned ABI and overall
> ABI/API deprecation, also ABI versioning and Library versioning by
> organizing the sections.
>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
> Cc: Luca Boccassi <bluca@debian.org>
> Cc: Kevin Traynor <ktraynor@redhat.com>
> Cc: Yongseok Koh <yskoh@mellanox.com>
> Cc: Neil Horman <nhorman@tuxdriver.com>
> ---
> doc/guides/contributing/versioning.rst | 132 +++++++++++++------------
> 1 file changed, 71 insertions(+), 61 deletions(-)
>
> diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
> index 01b36247e..19af56cd2 100644
> --- a/doc/guides/contributing/versioning.rst
> +++ b/doc/guides/contributing/versioning.rst
> @@ -1,33 +1,31 @@
> .. SPDX-License-Identifier: BSD-3-Clause
> Copyright 2018 The DPDK contributors
>
> -Managing ABI updates
> -====================
> +DPDK ABI/API policy
> +===================
>
> Description
> -----------
>
> This document details some methods for handling ABI management in the DPDK.
> -Note this document is not exhaustive, in that C library versioning is flexible
> -allowing multiple methods to achieve various goals, but it will provide the user
> -with some introductory methods
>
> General Guidelines
> ------------------
>
> #. Whenever possible, ABI should be preserved
> -#. Libraries or APIs marked in ``experimental`` state may change without constraint.
> +#. ABI/API may be changed with a deprecation process
> +#. The modification of symbols can generally be managed with versioning
> +#. Libraries or APIs marked in ``experimental`` state may change without constraint
> #. New APIs will be marked as ``experimental`` for at least one release to allow
> any issues found by users of the new API to be fixed quickly
> #. The addition of symbols is generally not problematic
> -#. The modification of symbols can generally be managed with versioning
> #. The removal of symbols generally is an ABI break and requires bumping of the
> LIBABIVER macro
> #. Updates to the minimum hardware requirements, which drop support for hardware which
> was previously supported, should be treated as an ABI change.
>
> What is an ABI
> ---------------
> +~~~~~~~~~~~~~~
>
> An ABI (Application Binary Interface) is the set of runtime interfaces exposed
> by a library. It is similar to an API (Application Programming Interface) but
> @@ -39,9 +37,13 @@ Therefore, in the case of dynamic linking, it is critical that an ABI is
> preserved, or (when modified), done in such a way that the application is unable
> to behave improperly or in an unexpected fashion.
>
> -The DPDK ABI policy
> +
> +ABI/API Deprecation
> -------------------
>
> +The DPDK ABI policy
> +~~~~~~~~~~~~~~~~~~~
> +
> ABI versions are set at the time of major release labeling, and the ABI may
> change multiple times, without warning, between the last release label and the
> HEAD label of the git tree.
> @@ -99,8 +101,36 @@ readability purposes should be avoided.
> follow the relevant deprecation policy procedures as above: 3 acks and
> announcement at least one release in advance.
>
> +Examples of Deprecation Notices
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The following are some examples of ABI deprecation notices which would be
> +added to the Release Notes:
> +
> +* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
> + to be replaced with the inline function ``rte_foo()``.
> +
> +* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
> + in version 2.0. Backwards compatibility will be maintained for this function
> + until the release of version 2.1
> +
> +* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
> + performance reasons. Existing binary applications will have backwards
> + compatibility in release 2.0, while newly built binaries will need to
> + reference the new structure variant ``struct rte_foo2``. Compatibility will
> + be removed in release 2.2, and all applications will require updating and
> + rebuilding to the new structure at that time, which will be renamed to the
> + original ``struct rte_foo``.
> +
> +* Significant ABI changes are planned for the ``librte_dostuff`` library. The
> + upcoming release 2.0 will not contain these changes, but release 2.1 will,
> + and no backwards compatibility is planned due to the extensive nature of
> + these changes. Binaries using this library built prior to version 2.1 will
> + require updating and recompilation.
> +
> +
> Experimental APIs
> -~~~~~~~~~~~~~~~~~
> +-----------------
>
> APIs marked as ``experimental`` are not considered part of the ABI and may
> change without warning at any time. Since changes to APIs are most likely
> @@ -130,35 +160,38 @@ is not required. Though, an API should remain in experimental state for at least
> one release. Thereafter, normal process of posting patch for review to mailing
> list can be followed.
>
> -Examples of Deprecation Notices
> --------------------------------
>
> -The following are some examples of ABI deprecation notices which would be
> -added to the Release Notes:
> +Library versioning
> +------------------
>
> -* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
> - to be replaced with the inline function ``rte_foo()``.
> +Downstreams might want to provide different DPDK releases at the same time to
> +support multiple consumers of DPDK linked against older and newer sonames.
>
> -* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
> - in version 2.0. Backwards compatibility will be maintained for this function
> - until the release of version 2.1
> +Also due to the interdependencies that DPDK libraries can have applications
> +might end up with an executable space in which multiple versions of a library
> +are mapped by ld.so.
>
> -* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
> - performance reasons. Existing binary applications will have backwards
> - compatibility in release 2.0, while newly built binaries will need to
> - reference the new structure variant ``struct rte_foo2``. Compatibility will
> - be removed in release 2.2, and all applications will require updating and
> - rebuilding to the new structure at that time, which will be renamed to the
> - original ``struct rte_foo``.
> +Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
> +depending on LibA.
>
> -* Significant ABI changes are planned for the ``librte_dostuff`` library. The
> - upcoming release 2.0 will not contain these changes, but release 2.1 will,
> - and no backwards compatibility is planned due to the extensive nature of
> - these changes. Binaries using this library built prior to version 2.1 will
> - require updating and recompilation.
> +.. note::
> +
> + Application
> + \-> LibA.old
> + \-> LibB.new -> LibA.new
> +
> +That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
> +If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
> +library - versions defined in the libraries ``LIBABIVER``.
> +An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
> +``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
> +
> +
> +ABI versioning
> +--------------
>
> Versioning Macros
> ------------------
> +~~~~~~~~~~~~~~~~~
>
> When a symbol is exported from a library to provide an API, it also provides a
> calling convention (ABI) that is embodied in its name, return type and
> @@ -186,36 +219,11 @@ The macros exported are:
> fully qualified function ``p``, so that if a symbol becomes versioned, it
> can still be mapped back to the public symbol name.
>
> -Setting a Major ABI version
> ----------------------------
> -
> -Downstreams might want to provide different DPDK releases at the same time to
> -support multiple consumers of DPDK linked against older and newer sonames.
> -
> -Also due to the interdependencies that DPDK libraries can have applications
> -might end up with an executable space in which multiple versions of a library
> -are mapped by ld.so.
> -
> -Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
> -depending on LibA.
> -
> -.. note::
> -
> - Application
> - \-> LibA.old
> - \-> LibB.new -> LibA.new
> -
> -That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
> -If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
> -library - versions defined in the libraries ``LIBABIVER``.
> -An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
> -``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
> -
> Examples of ABI Macro use
> --------------------------
> +^^^^^^^^^^^^^^^^^^^^^^^^^
>
> Updating a public API
> -~~~~~~~~~~~~~~~~~~~~~
> +_____________________
>
> Assume we have a function as follows
>
> @@ -425,7 +433,7 @@ and a new DPDK_2.1 version, used by future built applications.
>
>
> Deprecating part of a public API
> -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +________________________________
>
> Lets assume that you've done the above update, and after a few releases have
> passed you decide you would like to retire the old version of the function.
> @@ -483,7 +491,7 @@ possibly incompatible library version:
> +LIBABIVER := 2
>
> Deprecating an entire ABI version
> -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +_________________________________
>
> While removing a symbol from and ABI may be useful, it is often more practical
> to remove an entire version node at once. If a version node completely
> @@ -532,6 +540,7 @@ Lastly, any VERSION_SYMBOL macros that point to the old version node should be
> removed, taking care to keep, where need old code in place to support newer
> versions of the symbol.
>
> +
> Running the ABI Validator
> -------------------------
>
> @@ -571,3 +580,4 @@ compile both tags) it will create compatibility reports in the
> follows::
>
> grep -lr Incompatible compat_reports/
> +
> --
> 2.17.2
>
>
Series
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring
2019-01-22 9:27 0% ` [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring Ola Liljedahl
2019-01-22 10:15 0% ` Ola Liljedahl
2019-01-22 19:15 0% ` Eads, Gage
@ 2019-01-23 16:02 0% ` Jerin Jacob Kollanukkaran
2019-01-23 16:29 0% ` Ola Liljedahl
2 siblings, 1 reply; 200+ results
From: Jerin Jacob Kollanukkaran @ 2019-01-23 16:02 UTC (permalink / raw)
To: Ola.Liljedahl, gage.eads, dev
Cc: olivier.matz, stephen, bruce.richardson, arybchenko, konstantin.ananyev
On Tue, 2019-01-22 at 09:27 +0000, Ola Liljedahl wrote:
> On Fri, 2019-01-18 at 09:23 -0600, Gage Eads wrote:
> > v3:
> > - Avoid the ABI break by putting 64-bit head and tail values in
> > the
> > same
> > cacheline as struct rte_ring's prod and cons members.
> > - Don't attempt to compile rte_atomic128_cmpset without
> > ALLOW_EXPERIMENTAL_API, as this would break a large number of
> > libraries.
> > - Add a helpful warning to __rte_ring_do_nb_enqueue_mp() in case
> > someone tries
> > to use RING_F_NB without the ALLOW_EXPERIMENTAL_API flag.
> > - Update the ring mempool to use experimental APIs
> > - Clarify that RINB_F_NB is only limited to x86_64 currently;
> > ARMv8.1-A builds
> > can eventually support it with the CASP instruction.
> ARMv8.0 should be able to implement a 128-bit atomic compare exchange
> operation using LDXP/STXP.
Just wondering what would the performance difference between CASP vs
LDXP/STXP on LSE supported machine?
I think, We can not detect the presese of LSE support in compile time.
Right?
The dynamic one will be costly like,
if (hwcaps & HWCAP_ATOMICS) {
casp
} else {
ldxp
stxp
}
> From an ARM perspective, I want all atomic operations to take memory
> ordering arguments (e.g. acquire, release). Not all usages of e.g.
+1
> atomic compare exchange require sequential consistency (which I think
> what x86 cmpxchg instruction provides). DPDK functions should not be
> modelled after x86 behaviour.
>
> Lock-free 128-bit atomics implementations for ARM/AArch64 and x86-64
> are available here:
> https://github.com/ARM-software/progress64/blob/master/src/lockfree.h
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring
2019-01-23 16:02 0% ` Jerin Jacob Kollanukkaran
@ 2019-01-23 16:29 0% ` Ola Liljedahl
0 siblings, 0 replies; 200+ results
From: Ola Liljedahl @ 2019-01-23 16:29 UTC (permalink / raw)
To: jerinj, gage.eads, dev
Cc: olivier.matz, stephen, nd, bruce.richardson, arybchenko,
konstantin.ananyev
On Wed, 2019-01-23 at 16:02 +0000, Jerin Jacob Kollanukkaran wrote:
> On Tue, 2019-01-22 at 09:27 +0000, Ola Liljedahl wrote:
> >
> > On Fri, 2019-01-18 at 09:23 -0600, Gage Eads wrote:
> > >
> > > v3:
> > > - Avoid the ABI break by putting 64-bit head and tail values in
> > > the
> > > same
> > > cacheline as struct rte_ring's prod and cons members.
> > > - Don't attempt to compile rte_atomic128_cmpset without
> > > ALLOW_EXPERIMENTAL_API, as this would break a large number of
> > > libraries.
> > > - Add a helpful warning to __rte_ring_do_nb_enqueue_mp() in case
> > > someone tries
> > > to use RING_F_NB without the ALLOW_EXPERIMENTAL_API flag.
> > > - Update the ring mempool to use experimental APIs
> > > - Clarify that RINB_F_NB is only limited to x86_64 currently;
> > > ARMv8.1-A builds
> > > can eventually support it with the CASP instruction.
> > ARMv8.0 should be able to implement a 128-bit atomic compare exchange
> > operation using LDXP/STXP.
> Just wondering what would the performance difference between CASP vs
> LDXP/STXP on LSE supported machine?
I think that is up to the microarchitecture. But one the ideas behind
introducing the LSE atomics was that they should be "better" than the equivalent
code using exclusives. I think non-conditional LDxxx and STxxx atomics could be
better than using exclusives while conditional atomics (CAS, CASP) might not be
so different (the reason has to do with cache coherency, a core can
speculatively snoop-unique the cache line which is targetted by an atomic
instruction but to what extent that provides a benefit could be depend on
whether the atomic actually performs a store or not).
>
> I think, We can not detect the presese of LSE support in compile time.
> Right?
Unfortunately, AFAIK GCC doesn't notify the source code that it is targetting
v8.1+ with LSE support. If there were intrinsics for (certain) LSE instructions
(e.g. those not generated by the compiler, e.g. STxxx and CASP), we could use
some corresponding preprocessor define to detect the presence of such intrinsics
(they exist for other intrinsics, e.g. __ARM_FEATURE_QRDMX for SQRDMLAH/SQRDMLSH
instructions and corresponding intrinsics).
I have tried to interest the Arm GCC developers in this but have not yet
succeeded. Perhaps if we have more use cases were atomics intrinsics would be
useful, we could convince them to add such intrinsics to the ACLE (ARM C
Language Extensions). But we will never get intrinsics for exclusives, they are
deemed unsafe for explicit use from C. Instead need to provide inline assembler
that contains the complete exclusives sequence. But in practice it seems to work
with using inline assembler for LDXR and STXR as I do in the lockfree code
linked below.
>
> The dynamic one will be costly like,
Do you think so? Shouldn't this branch be perfectly predictable? Once in a while
it will fall out of the branch history table but doesn't that mean the
application hasn't been executing this code for some time so not really
performance critical?
>
> if (hwcaps & HWCAP_ATOMICS) {
> casp
> } else {
> ldxp
> stxp
> }
>
> >
> > From an ARM perspective, I want all atomic operations to take memory
> > ordering arguments (e.g. acquire, release). Not all usages of e.g.
> +1
>
> >
> > atomic compare exchange require sequential consistency (which I think
> > what x86 cmpxchg instruction provides). DPDK functions should not be
> > modelled after x86 behaviour.
> >
> > Lock-free 128-bit atomics implementations for ARM/AArch64 and x86-64
> > are available here:
> > https://github.com/ARM-software/progress64/blob/master/src/lockfree.h
> >
--
Ola Liljedahl, Networking System Architect, Arm
Phone +46706866373, Skype ola.liljedahl
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] Introduce travis builds for github repositories
@ 2019-01-23 22:07 4% Michael Santana
2019-01-24 19:26 0% ` Honnappa Nagarahalli
0 siblings, 1 reply; 200+ results
From: Michael Santana @ 2019-01-23 22:07 UTC (permalink / raw)
To: dev; +Cc: Aaron Conole, Bruce Richardson, Thomas Monjalon, Ferruh Yigit
GitHub is a service used by developers to store repositories. GitHub
provides service integrations that allow 3rd party services to access
developer repositories and perform actions. One of these services is
Travis-CI, a simple continuous integration platform.
This is a simple initial implementation of a travis build for the DPDK
project. It doesn't require any changes from individual developers to
enable, but will allow those developers who opt-in to GitHub and the
travis service to get automatic builds for every push they make.
Additionally, the travis service will send an email to the test-report
list informing anyone interested in the automated build (including a
result).
Signed-off-by: Aaron Conole <aconole@redhat.com>
Signed-off-by: Michael Santana <msantana@redhat.com>
---
.ci/linux-build.sh | 34 +++++++++++++++++++++++++
.ci/linux-setup.sh | 3 +++
.travis.yml | 39 +++++++++++++++++++++++++++++
MAINTAINERS | 6 +++++
doc/guides/contributing/patches.rst | 3 +++
5 files changed, 85 insertions(+)
create mode 100755 .ci/linux-build.sh
create mode 100755 .ci/linux-setup.sh
create mode 100644 .travis.yml
diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh
new file mode 100755
index 0000000000..2cfaa05058
--- /dev/null
+++ b/.ci/linux-build.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+# check for whether we're clang or gcc
+# setup the right options depending on the environment variables
+# run the build
+
+# Just used for the 'classic' configuration system (ie: make)
+set_conf() {
+ c="$1/.config"
+ shift
+
+ if grep -q "$1" "$c"; then
+ sed -i "s:^$1=.*$:$1=$2:g" $c
+ else
+ echo $1=$2 >> "$c"
+ fi
+}
+
+
+if [ "${NINJABUILD}" == "1" ]; then
+ meson build
+ ninja -C build
+else
+ make config T=x86_64-native-linuxapp-${CC}
+ if [ "${SHARED}" == "1" ]; then
+ set_conf build CONFIG_RTE_BUILD_SHARED_LIB y
+ fi
+
+ if [ "${KERNEL}" == "1" ]; then
+ echo Unsupported kernel builds at the moment
+ fi
+
+ make all
+fi
diff --git a/.ci/linux-setup.sh b/.ci/linux-setup.sh
new file mode 100755
index 0000000000..6f9849cb94
--- /dev/null
+++ b/.ci/linux-setup.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+python3.5 -m pip install --upgrade meson --user
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..432d6c9c6c
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,39 @@
+language: c
+compiler:
+ - gcc
+ - clang
+
+os:
+ - linux
+
+addons:
+ apt:
+ sources:
+ - deadsnakes #source for python 3.5
+ - sourceline: 'ppa:mstipicevic/ninja-build-1-7-2'
+ packages:
+ - libnuma-dev
+ - linux-headers-$(uname -r)
+ - python3.5
+ - python3-pip
+ - ninja-build
+
+before_install: ./.ci/${TRAVIS_OS_NAME}-setup.sh
+
+sudo: false
+
+env:
+ - SHARED=1
+ - KERNEL=1
+ - NINJABUILD=1
+
+matrix:
+ include:
+ - compiler: clang
+
+script: ./.ci/${TRAVIS_OS_NAME}-build.sh
+
+notifications:
+ email:
+ recipients:
+ - test-report@dpdk.org
diff --git a/MAINTAINERS b/MAINTAINERS
index 66104405e5..14a7bf1284 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -119,6 +119,12 @@ F: config/rte_config.h
F: buildtools/gen-pmdinfo-cfile.sh
F: buildtools/symlink-drivers-solibs.sh
+Public CI
+M: Aaron Conole <aconole@redhat.com>
+M: Michael Santana <msantana@redhat.com>
+F: .travis.yml
+F: .ci/
+
ABI versioning
M: Neil Horman <nhorman@tuxdriver.com>
F: lib/librte_compat/
diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst
index a64bb03683..745a11a67a 100644
--- a/doc/guides/contributing/patches.rst
+++ b/doc/guides/contributing/patches.rst
@@ -32,6 +32,9 @@ The mailing list for DPDK development is `dev@dpdk.org <http://mails.dpdk.org/ar
Contributors will need to `register for the mailing list <http://mails.dpdk.org/listinfo/dev>`_ in order to submit patches.
It is also worth registering for the DPDK `Patchwork <http://patches.dpdk.org/project/dpdk/list/>`_
+If you are using the GitHub service, you can link your repository to the ``travis-ci.org`` build service. When you push
+patches to your repository, the travis service will automatically build your changes.
+
The development process requires some familiarity with the ``git`` version control system.
Refer to the `Pro Git Book <http://www.git-scm.com/book/>`_ for further information.
--
2.19.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v4 1/3] doc: clean ABI/API policy guide
2019-01-22 16:23 35% ` [dpdk-dev] [PATCH v3 1/3] " Ferruh Yigit
2019-01-22 16:23 17% ` [dpdk-dev] [PATCH v3 2/3] doc: make RTE_NEXT_ABI optional Ferruh Yigit
2019-01-23 8:13 4% ` [dpdk-dev] [PATCH v3 1/3] doc: clean ABI/API policy guide Neil Horman
@ 2019-01-24 18:10 35% ` Ferruh Yigit
2019-01-24 18:10 17% ` [dpdk-dev] [PATCH v4 2/3] doc: make RTE_NEXT_ABI optional Ferruh Yigit
2 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2019-01-24 18:10 UTC (permalink / raw)
To: dev, John McNamara, Marko Kovacevic
Cc: Luca Boccassi, Kevin Traynor, Yongseok Koh, Neil Horman
The original document written from the point of ABI versioning but later
additions make document confusing, convert document into a ABI/API
policy documentation and organize the document in subsections:
- ABI/API Deprecation
- Experimental APIs
- Library versioning
- ABI versioning
Aim to clarify confusion between deprecation versioned ABI and overall
ABI/API deprecation, also ABI versioning and Library versioning by
organizing the sections.
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
Cc: Luca Boccassi <bluca@debian.org>
Cc: Kevin Traynor <ktraynor@redhat.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
---
doc/guides/contributing/versioning.rst | 132 +++++++++++++------------
1 file changed, 71 insertions(+), 61 deletions(-)
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 01b36247e..19af56cd2 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -1,33 +1,31 @@
.. SPDX-License-Identifier: BSD-3-Clause
Copyright 2018 The DPDK contributors
-Managing ABI updates
-====================
+DPDK ABI/API policy
+===================
Description
-----------
This document details some methods for handling ABI management in the DPDK.
-Note this document is not exhaustive, in that C library versioning is flexible
-allowing multiple methods to achieve various goals, but it will provide the user
-with some introductory methods
General Guidelines
------------------
#. Whenever possible, ABI should be preserved
-#. Libraries or APIs marked in ``experimental`` state may change without constraint.
+#. ABI/API may be changed with a deprecation process
+#. The modification of symbols can generally be managed with versioning
+#. Libraries or APIs marked in ``experimental`` state may change without constraint
#. New APIs will be marked as ``experimental`` for at least one release to allow
any issues found by users of the new API to be fixed quickly
#. The addition of symbols is generally not problematic
-#. The modification of symbols can generally be managed with versioning
#. The removal of symbols generally is an ABI break and requires bumping of the
LIBABIVER macro
#. Updates to the minimum hardware requirements, which drop support for hardware which
was previously supported, should be treated as an ABI change.
What is an ABI
---------------
+~~~~~~~~~~~~~~
An ABI (Application Binary Interface) is the set of runtime interfaces exposed
by a library. It is similar to an API (Application Programming Interface) but
@@ -39,9 +37,13 @@ Therefore, in the case of dynamic linking, it is critical that an ABI is
preserved, or (when modified), done in such a way that the application is unable
to behave improperly or in an unexpected fashion.
-The DPDK ABI policy
+
+ABI/API Deprecation
-------------------
+The DPDK ABI policy
+~~~~~~~~~~~~~~~~~~~
+
ABI versions are set at the time of major release labeling, and the ABI may
change multiple times, without warning, between the last release label and the
HEAD label of the git tree.
@@ -99,8 +101,36 @@ readability purposes should be avoided.
follow the relevant deprecation policy procedures as above: 3 acks and
announcement at least one release in advance.
+Examples of Deprecation Notices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following are some examples of ABI deprecation notices which would be
+added to the Release Notes:
+
+* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
+ to be replaced with the inline function ``rte_foo()``.
+
+* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
+ in version 2.0. Backwards compatibility will be maintained for this function
+ until the release of version 2.1
+
+* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
+ performance reasons. Existing binary applications will have backwards
+ compatibility in release 2.0, while newly built binaries will need to
+ reference the new structure variant ``struct rte_foo2``. Compatibility will
+ be removed in release 2.2, and all applications will require updating and
+ rebuilding to the new structure at that time, which will be renamed to the
+ original ``struct rte_foo``.
+
+* Significant ABI changes are planned for the ``librte_dostuff`` library. The
+ upcoming release 2.0 will not contain these changes, but release 2.1 will,
+ and no backwards compatibility is planned due to the extensive nature of
+ these changes. Binaries using this library built prior to version 2.1 will
+ require updating and recompilation.
+
+
Experimental APIs
-~~~~~~~~~~~~~~~~~
+-----------------
APIs marked as ``experimental`` are not considered part of the ABI and may
change without warning at any time. Since changes to APIs are most likely
@@ -130,35 +160,38 @@ is not required. Though, an API should remain in experimental state for at least
one release. Thereafter, normal process of posting patch for review to mailing
list can be followed.
-Examples of Deprecation Notices
--------------------------------
-The following are some examples of ABI deprecation notices which would be
-added to the Release Notes:
+Library versioning
+------------------
-* The Macro ``#RTE_FOO`` is deprecated and will be removed with version 2.0,
- to be replaced with the inline function ``rte_foo()``.
+Downstreams might want to provide different DPDK releases at the same time to
+support multiple consumers of DPDK linked against older and newer sonames.
-* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
- in version 2.0. Backwards compatibility will be maintained for this function
- until the release of version 2.1
+Also due to the interdependencies that DPDK libraries can have applications
+might end up with an executable space in which multiple versions of a library
+are mapped by ld.so.
-* The members of ``struct rte_foo`` have been reorganized in release 2.0 for
- performance reasons. Existing binary applications will have backwards
- compatibility in release 2.0, while newly built binaries will need to
- reference the new structure variant ``struct rte_foo2``. Compatibility will
- be removed in release 2.2, and all applications will require updating and
- rebuilding to the new structure at that time, which will be renamed to the
- original ``struct rte_foo``.
+Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
+depending on LibA.
-* Significant ABI changes are planned for the ``librte_dostuff`` library. The
- upcoming release 2.0 will not contain these changes, but release 2.1 will,
- and no backwards compatibility is planned due to the extensive nature of
- these changes. Binaries using this library built prior to version 2.1 will
- require updating and recompilation.
+.. note::
+
+ Application
+ \-> LibA.old
+ \-> LibB.new -> LibA.new
+
+That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
+If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
+library - versions defined in the libraries ``LIBABIVER``.
+An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
+``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
+
+
+ABI versioning
+--------------
Versioning Macros
------------------
+~~~~~~~~~~~~~~~~~
When a symbol is exported from a library to provide an API, it also provides a
calling convention (ABI) that is embodied in its name, return type and
@@ -186,36 +219,11 @@ The macros exported are:
fully qualified function ``p``, so that if a symbol becomes versioned, it
can still be mapped back to the public symbol name.
-Setting a Major ABI version
----------------------------
-
-Downstreams might want to provide different DPDK releases at the same time to
-support multiple consumers of DPDK linked against older and newer sonames.
-
-Also due to the interdependencies that DPDK libraries can have applications
-might end up with an executable space in which multiple versions of a library
-are mapped by ld.so.
-
-Think of LibA that got an ABI bump and LibB that did not get an ABI bump but is
-depending on LibA.
-
-.. note::
-
- Application
- \-> LibA.old
- \-> LibB.new -> LibA.new
-
-That is a conflict which can be avoided by setting ``CONFIG_RTE_MAJOR_ABI``.
-If set, the value of ``CONFIG_RTE_MAJOR_ABI`` overwrites all - otherwise per
-library - versions defined in the libraries ``LIBABIVER``.
-An example might be ``CONFIG_RTE_MAJOR_ABI=16.11`` which will make all libraries
-``librte<?>.so.16.11`` instead of ``librte<?>.so.<LIBABIVER>``.
-
Examples of ABI Macro use
--------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^
Updating a public API
-~~~~~~~~~~~~~~~~~~~~~
+_____________________
Assume we have a function as follows
@@ -425,7 +433,7 @@ and a new DPDK_2.1 version, used by future built applications.
Deprecating part of a public API
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+________________________________
Lets assume that you've done the above update, and after a few releases have
passed you decide you would like to retire the old version of the function.
@@ -483,7 +491,7 @@ possibly incompatible library version:
+LIBABIVER := 2
Deprecating an entire ABI version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+_________________________________
While removing a symbol from and ABI may be useful, it is often more practical
to remove an entire version node at once. If a version node completely
@@ -532,6 +540,7 @@ Lastly, any VERSION_SYMBOL macros that point to the old version node should be
removed, taking care to keep, where need old code in place to support newer
versions of the symbol.
+
Running the ABI Validator
-------------------------
@@ -571,3 +580,4 @@ compile both tags) it will create compatibility reports in the
follows::
grep -lr Incompatible compat_reports/
+
--
2.17.2
^ permalink raw reply [relevance 35%]
* [dpdk-dev] [PATCH v4 2/3] doc: make RTE_NEXT_ABI optional
2019-01-24 18:10 35% ` [dpdk-dev] [PATCH v4 " Ferruh Yigit
@ 2019-01-24 18:10 17% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2019-01-24 18:10 UTC (permalink / raw)
To: dev, John McNamara, Marko Kovacevic
Cc: Luca Boccassi, Kevin Traynor, Yongseok Koh, Neil Horman
Initial process requires oncoming changes described in deprecation
notice should be implemented in a RTE_NEXT_ABI gated way.
This has been discussed in technical board, and since this can cause a
multiple #ifdef blocks in multiple locations of the code, can be
confusing specially for the modifications that requires data structure
changes. Anyway this was not happening in practice.
Making RTE_NEXT_ABI usage more optional based on techboard decision:
http://mails.dpdk.org/archives/dev/2019-January/123519.html
The intention with using RTE_NEXT_ABI was to provide more information
to the user about planned changes, and force developer to think more in
coding level. Since RTE_NEXT_ABI become optional, now the preferred way
to do this is, if possible, sending changes, described in deprecation
notice, as a separate patch and reference it in deprecation notice.
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
---
Cc: Luca Boccassi <bluca@debian.org>
Cc: Kevin Traynor <ktraynor@redhat.com>
Cc: Yongseok Koh <yskoh@mellanox.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
---
doc/guides/contributing/versioning.rst | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 19af56cd2..bfc27fbe0 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -73,19 +73,16 @@ being provided. The requirements for doing so are:
interest" be sought for each deprecation, for example: from NIC vendors,
CPU vendors, end-users, etc.
-#. The changes (including an alternative map file) must be gated with
- the ``RTE_NEXT_ABI`` option, and provided with a deprecation notice at the
- same time.
- It will become the default ABI in the next release.
+#. The changes (including an alternative map file) can be included with
+ deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
+ to provide more details about oncoming changes.
+ ``RTE_NEXT_ABI`` wrapper will be removed when it become the default ABI.
+ More preferred way to provide this information is sending the feature
+ as a separate patch and reference it in deprecation notice.
#. A full deprecation cycle, as explained above, must be made to offer
downstream consumers sufficient warning of the change.
-#. At the beginning of the next release cycle, every ``RTE_NEXT_ABI``
- conditions will be removed, the ``LIBABIVER`` variable in the makefile(s)
- where the ABI is changed will be incremented, and the map files will
- be updated.
-
Note that the above process for ABI deprecation should not be undertaken
lightly. ABI stability is extremely important for downstream consumers of the
DPDK, especially when distributed in shared object form. Every effort should
--
2.17.2
^ permalink raw reply [relevance 17%]
* Re: [dpdk-dev] [PATCH] Introduce travis builds for github repositories
2019-01-23 22:07 4% [dpdk-dev] [PATCH] Introduce travis builds for github repositories Michael Santana
@ 2019-01-24 19:26 0% ` Honnappa Nagarahalli
0 siblings, 0 replies; 200+ results
From: Honnappa Nagarahalli @ 2019-01-24 19:26 UTC (permalink / raw)
To: Michael Santana, dev
Cc: Aaron Conole, Bruce Richardson, thomas, Ferruh Yigit, nd,
Honnappa Nagarahalli, nd
>
> GitHub is a service used by developers to store repositories. GitHub
> provides service integrations that allow 3rd party services to access
> developer repositories and perform actions. One of these services is Travis-
> CI, a simple continuous integration platform.
>
> This is a simple initial implementation of a travis build for the DPDK project.
> It doesn't require any changes from individual developers to enable, but will
> allow those developers who opt-in to GitHub and the travis service to get
> automatic builds for every push they make.
>
> Additionally, the travis service will send an email to the test-report list
> informing anyone interested in the automated build (including a result).
>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
> Signed-off-by: Michael Santana <msantana@redhat.com>
> ---
> .ci/linux-build.sh | 34 +++++++++++++++++++++++++
> .ci/linux-setup.sh | 3 +++
> .travis.yml | 39 +++++++++++++++++++++++++++++
> MAINTAINERS | 6 +++++
> doc/guides/contributing/patches.rst | 3 +++
> 5 files changed, 85 insertions(+)
> create mode 100755 .ci/linux-build.sh
> create mode 100755 .ci/linux-setup.sh
> create mode 100644 .travis.yml
>
> diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh new file mode 100755 index
> 0000000000..2cfaa05058
> --- /dev/null
> +++ b/.ci/linux-build.sh
> @@ -0,0 +1,34 @@
> +#!/bin/bash
> +
> +# check for whether we're clang or gcc
> +# setup the right options depending on the environment variables # run
> +the build
> +
> +# Just used for the 'classic' configuration system (ie: make)
> +set_conf() {
> + c="$1/.config"
> + shift
> +
> + if grep -q "$1" "$c"; then
> + sed -i "s:^$1=.*$:$1=$2:g" $c
> + else
> + echo $1=$2 >> "$c"
> + fi
> +}
> +
> +
> +if [ "${NINJABUILD}" == "1" ]; then
> + meson build
> + ninja -C build
> +else
> + make config T=x86_64-native-linuxapp-${CC}
Adding Arm builds would be helpful.
> + if [ "${SHARED}" == "1" ]; then
> + set_conf build CONFIG_RTE_BUILD_SHARED_LIB y
> + fi
> +
> + if [ "${KERNEL}" == "1" ]; then
> + echo Unsupported kernel builds at the moment
> + fi
> +
> + make all
> +fi
> diff --git a/.ci/linux-setup.sh b/.ci/linux-setup.sh new file mode 100755 index
> 0000000000..6f9849cb94
> --- /dev/null
> +++ b/.ci/linux-setup.sh
> @@ -0,0 +1,3 @@
> +#!/bin/sh
> +
> +python3.5 -m pip install --upgrade meson --user
> diff --git a/.travis.yml b/.travis.yml
> new file mode 100644
> index 0000000000..432d6c9c6c
> --- /dev/null
> +++ b/.travis.yml
> @@ -0,0 +1,39 @@
> +language: c
> +compiler:
> + - gcc
> + - clang
> +
> +os:
> + - linux
> +
> +addons:
> + apt:
> + sources:
> + - deadsnakes #source for python 3.5
> + - sourceline: 'ppa:mstipicevic/ninja-build-1-7-2'
> + packages:
> + - libnuma-dev
> + - linux-headers-$(uname -r)
> + - python3.5
> + - python3-pip
> + - ninja-build
> +
> +before_install: ./.ci/${TRAVIS_OS_NAME}-setup.sh
> +
> +sudo: false
> +
> +env:
> + - SHARED=1
> + - KERNEL=1
> + - NINJABUILD=1
> +
> +matrix:
> + include:
> + - compiler: clang
> +
> +script: ./.ci/${TRAVIS_OS_NAME}-build.sh
> +
> +notifications:
> + email:
> + recipients:
> + - test-report@dpdk.org
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 66104405e5..14a7bf1284 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -119,6 +119,12 @@ F: config/rte_config.h
> F: buildtools/gen-pmdinfo-cfile.sh
> F: buildtools/symlink-drivers-solibs.sh
>
> +Public CI
> +M: Aaron Conole <aconole@redhat.com>
> +M: Michael Santana <msantana@redhat.com>
> +F: .travis.yml
> +F: .ci/
> +
> ABI versioning
> M: Neil Horman <nhorman@tuxdriver.com>
> F: lib/librte_compat/
> diff --git a/doc/guides/contributing/patches.rst
> b/doc/guides/contributing/patches.rst
> index a64bb03683..745a11a67a 100644
> --- a/doc/guides/contributing/patches.rst
> +++ b/doc/guides/contributing/patches.rst
> @@ -32,6 +32,9 @@ The mailing list for DPDK development is
> `dev@dpdk.org <http://mails.dpdk.org/ar Contributors will need to
> `register for the mailing list <http://mails.dpdk.org/listinfo/dev>`_ in order
> to submit patches.
> It is also worth registering for the DPDK `Patchwork
> <http://patches.dpdk.org/project/dpdk/list/>`_
>
> +If you are using the GitHub service, you can link your repository to
> +the ``travis-ci.org`` build service. When you push patches to your
> repository, the travis service will automatically build your changes.
> +
> The development process requires some familiarity with the ``git`` version
> control system.
> Refer to the `Pro Git Book <http://www.git-scm.com/book/>`_ for further
> information.
>
> --
> 2.19.1
^ permalink raw reply [relevance 0%]
Results 5001-5200 of ~18000 next (newer) | prev (older) | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2015-04-28 23:46 [dpdk-dev] [PATCH v8 0/6] Move common functions in EAL Ravi Kerur
2015-04-28 23:46 ` [dpdk-dev] [PATCH v8 1/6] Move common functions in eal_thread.c Ravi Kerur
2015-04-28 23:46 ` [dpdk-dev] [PATCH v8 2/6] Move common functions in eal.c Ravi Kerur
2018-12-18 1:42 0% ` Ferruh Yigit
2018-12-18 1:43 0% ` Ferruh Yigit
2015-08-19 20:46 [dpdk-dev] [PATCH v2] Move common functions in eal_thread.c Ravi Kerur
2018-12-19 21:09 0% ` Ferruh Yigit
2018-01-31 15:27 [dpdk-dev] [PATCH] doc: add kernel version deprecation notice Stephen Hemminger
2018-11-24 18:44 5% ` [dpdk-dev] [PATCH v2] doc: announce Linux support change Thomas Monjalon
2018-10-24 8:18 [dpdk-dev] [RFC 00/14] prefix network structures Olivier Matz
2018-12-20 21:59 3% ` Ferruh Yigit
2018-12-20 23:48 0% ` Stephen Hemminger
2018-12-21 14:38 0% ` Wiles, Keith
2018-12-21 15:14 0% ` Ferruh Yigit
2018-12-27 9:35 0% ` Olivier Matz
2018-11-01 4:54 [dpdk-dev] [PATCH 1/3] hash: deprecate lock ellision and read/write concurreny flags Honnappa Nagarahalli
2018-11-01 23:25 ` [dpdk-dev] [PATCH v2 0/4] " Honnappa Nagarahalli
2018-11-02 11:25 ` Bruce Richardson
2018-11-02 17:38 ` Honnappa Nagarahalli
2018-12-20 20:10 0% ` Yigit, Ferruh
2018-11-15 23:53 [dpdk-dev] [PATCH 1/9] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
2018-11-30 16:45 2% ` [dpdk-dev] [PATCH v2 0/9] ipsec: new library for IPsec data-path processing Konstantin Ananyev
2018-11-21 15:45 [dpdk-dev] [PATCH] doc: announce kvargs API change Thomas Monjalon
2018-11-23 13:17 0% ` Maxime Coquelin
2018-11-22 2:55 [dpdk-dev] [RFC] pdump: remove deprecated APIs Tiwei Bie
2018-12-03 2:58 6% ` [dpdk-dev] [PATCH] " Tiwei Bie
2018-12-13 17:15 0% ` Pattan, Reshma
2018-12-19 0:28 0% ` Thomas Monjalon
2018-11-22 12:09 [dpdk-dev] [PATCH v1 1/1] doc: announce ethdev ABI change for rte_eth_dev_info Ian Stokes
2018-11-22 12:11 4% ` Ferruh Yigit
2018-11-22 17:15 4% ` Thomas Monjalon
2018-11-24 17:37 4% ` Thomas Monjalon
2018-11-22 18:27 4% ` Ferruh Yigit
2018-11-23 8:08 4% ` Andrew Rybchenko
2018-11-23 11:33 1% [dpdk-dev] [PATCH] libs/power: add p-state driver compatibility Liang Ma
2018-12-10 16:08 0% ` Burakov, Anatoly
2018-12-14 11:13 1% ` [dpdk-dev] [PATCH v2] " Liang Ma
2018-12-14 12:20 0% ` Burakov, Anatoly
2018-12-14 13:11 1% ` [dpdk-dev] [PATCH v3] " Liang Ma
2018-12-19 3:18 0% ` Thomas Monjalon
2018-12-19 9:09 0% ` Hunt, David
2018-12-19 20:31 0% ` Thomas Monjalon
2018-12-20 9:25 0% ` Burakov, Anatoly
2018-12-20 9:33 0% ` Burakov, Anatoly
2018-12-20 10:10 0% ` Thomas Monjalon
2018-12-20 10:42 0% ` Luca Boccassi
2018-12-20 10:44 0% ` Thomas Monjalon
2018-12-20 10:54 0% ` Liang, Ma
2018-12-20 14:52 0% ` Hunt, David
2018-12-21 0:30 0% ` Thomas Monjalon
2018-12-21 0:33 0% ` Thomas Monjalon
2018-12-20 14:43 1% ` [dpdk-dev] [PATCH v4] " Liang Ma
2018-12-21 0:34 0% ` Thomas Monjalon
2018-11-23 16:54 [dpdk-dev] [PATCH] mbuf: implement generic format for sched field Jasvinder Singh
2018-11-26 11:37 ` Dumitrescu, Cristian
2018-11-29 10:42 3% ` Singh, Jasvinder
2018-12-04 17:39 0% ` Dumitrescu, Cristian
2018-12-05 12:22 0% ` Singh, Jasvinder
2018-12-07 14:31 5% ` [dpdk-dev] [PATCH v2 1/3] " Reshma Pattan
2018-12-11 19:02 0% ` Dumitrescu, Cristian
2018-12-13 18:08 ` [dpdk-dev] [PATCH v3 1/2] eal: add new rte color definition Reshma Pattan
2018-12-13 18:08 1% ` [dpdk-dev] [PATCH v3 2/2] mbuf: implement generic format for sched field Reshma Pattan
2018-12-14 22:52 0% ` Dumitrescu, Cristian
2018-12-18 15:40 ` [dpdk-dev] [PATCH v4 1/2] meter: add new rte color definition Reshma Pattan
2018-12-18 15:40 1% ` [dpdk-dev] [PATCH v4 2/2] mbuf: implement generic format for sched field Reshma Pattan
2018-12-19 15:34 ` [dpdk-dev] [PATCH v5 1/2] meter: add new rte color definition Reshma Pattan
2018-12-19 15:34 1% ` [dpdk-dev] [PATCH v5 2/2] mbuf: implement generic format for sched field Reshma Pattan
2018-12-19 15:42 ` [dpdk-dev] [PATCH v6 1/2] meter: add new rte color definition Reshma Pattan
2018-12-19 15:42 1% ` [dpdk-dev] [PATCH v6 2/2] mbuf: implement generic format for sched field Reshma Pattan
2018-12-19 18:14 0% ` Ananyev, Konstantin
2018-12-20 12:16 ` [dpdk-dev] [PATCH v7 1/2] meter: add new rte color definition Reshma Pattan
2018-12-20 12:16 1% ` [dpdk-dev] [PATCH v7 2/2] mbuf: implement generic format for sched field Reshma Pattan
2018-12-20 14:55 0% ` Rao, Nikhil
2019-01-15 22:37 3% ` Stephen Hemminger
2019-01-16 9:19 0% ` Pattan, Reshma
2019-01-16 9:33 0% ` Dumitrescu, Cristian
2019-01-16 10:09 0% ` Singh, Jasvinder
2019-01-15 23:11 4% ` Stephen Hemminger
2019-01-16 8:41 0% ` Thomas Monjalon
2018-11-26 10:51 4% [dpdk-dev] [PATCH v1] doc: update release notes for 18.11 John McNamara
2018-11-26 23:15 4% ` [dpdk-dev] [PATCH v2] " John McNamara
2018-11-26 17:55 2% [dpdk-dev] [PATCH] fix dpdk.org URLs Thomas Monjalon
2018-11-27 15:20 3% [dpdk-dev] [PATCH 0/3] lib/librte_meter: add RFC4115 trTCM meter support Eelco Chaudron
2018-11-27 15:21 7% ` [dpdk-dev] [PATCH 3/3] lib/librte_meter: update abi to include new rfc4115 function Eelco Chaudron
[not found] ` <CAJFAV8zUyBqEovvaChs3TO+Ah15T3davXPPkpDzzE2-fMQGD2g@mail.gmail.com>
2018-11-28 9:27 7% ` Eelco Chaudron
2018-11-28 10:09 9% ` Thomas Monjalon
2018-11-28 12:40 4% ` Eelco Chaudron
2018-11-28 12:51 4% ` Thomas Monjalon
2018-11-28 13:17 4% ` Eelco Chaudron
2018-11-28 9:52 [dpdk-dev] [RFC PATCH 0/3] Add rte_eth_read_clock API Tom Barbette
2018-11-28 9:52 ` [dpdk-dev] [RFC PATCH 2/3] mlx5: Implement support for read_clock Tom Barbette
2018-12-09 6:03 3% ` Shahaf Shuler
2018-11-28 10:44 9% [dpdk-dev] [PATCH] version: 19.02-rc0 Thomas Monjalon
2018-11-28 11:16 0% ` Ferruh Yigit
2018-11-28 12:45 0% ` Thomas Monjalon
2018-11-28 13:24 0% ` Ferruh Yigit
2018-11-28 13:35 0% ` Thomas Monjalon
2018-11-28 14:52 9% ` [dpdk-dev] [PATCH v2 1/2] " Thomas Monjalon
2018-11-28 14:52 18% ` [dpdk-dev] [PATCH v2 2/2] doc: improve release notes template Thomas Monjalon
2018-11-30 17:01 0% ` [dpdk-dev] [PATCH v2 1/2] version: 19.02-rc0 Ferruh Yigit
2018-11-29 5:05 1% [dpdk-dev] [PATCH] helloworld: Windows DPDK sample application is compiled and built using eal and kvargs libraries in order to add windows support in the mainline repository Pallavi Kadam
2018-11-29 5:54 [dpdk-dev] [PATCH] ethdev: support double precision RED queue weight Nikhil Rao
2018-11-29 6:12 3% ` Stephen Hemminger
2018-12-10 5:43 0% ` Rao, Nikhil
2018-12-10 16:01 0% ` Stephen Hemminger
2019-01-10 6:23 0% ` Rao, Nikhil
2018-11-29 23:35 [dpdk-dev] [PATCH 0/3] new software event timer adapter Erik Gabriel Carrillo
2018-12-07 17:52 4% ` [dpdk-dev] [PATCH v2 0/2] Timer library changes Erik Gabriel Carrillo
2018-12-07 17:52 ` [dpdk-dev] [PATCH v2 1/2] timer: allow timer management in shared memory Erik Gabriel Carrillo
2018-12-07 18:10 3% ` Stephen Hemminger
2018-12-07 19:21 4% ` Carrillo, Erik G
2018-12-13 22:26 4% ` [dpdk-dev] [PATCH v3 0/2] Timer library changes Erik Gabriel Carrillo
2018-12-19 3:35 0% ` Thomas Monjalon
2018-12-19 7:33 0% ` Mattias Rönnblom
2018-11-30 0:39 2% [dpdk-dev] [RFC PATCH] kvargs: add match count inside processing Thomas Monjalon
2018-11-30 16:45 [dpdk-dev] [PATCH v2 1/9] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
2018-12-06 15:38 2% ` [dpdk-dev] [PATCH v3 0/9] ipsec: new library for IPsec data-path processing Konstantin Ananyev
2018-12-03 13:01 [dpdk-dev] Marking symbols as experimental in the headers only David Marchand
2018-12-03 16:47 ` Neil Horman
2018-12-04 8:21 ` David Marchand
2018-12-04 15:14 4% ` Neil Horman
2018-12-04 20:48 0% ` David Marchand
2018-12-04 21:34 0% ` Richardson, Bruce
2018-12-05 12:21 0% ` Neil Horman
2018-12-04 12:22 4% [dpdk-dev] [PATCH 18.11] malloc: fix deadlock when using malloc stats Anatoly Burakov
2018-12-21 12:09 0% ` Thomas Monjalon
2018-12-21 12:12 0% ` Burakov, Anatoly
2018-12-21 12:26 4% ` [dpdk-dev] [PATCH 19.02 v2] " Anatoly Burakov
2018-12-21 13:35 0% ` Thomas Monjalon
2018-12-04 15:57 2% [dpdk-dev] [RFC] " Anatoly Burakov
2018-12-06 15:38 [dpdk-dev] [PATCH v3 1/9] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
2018-12-14 16:29 2% ` [dpdk-dev] [PATCH v4 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
2018-12-21 13:32 0% ` Akhil Goyal
2018-12-11 10:34 [dpdk-dev] [PATCH v2 0/2] lib/cryptodev: change qp conf and sym session Fan Zhang
2018-12-21 13:55 ` [dpdk-dev] [PATCH v3 0/2] cryptodev: " Fan Zhang
2018-12-21 13:55 1% ` [dpdk-dev] [PATCH v3 1/2] cryptodev: change queue pair configure structure Fan Zhang
2019-01-08 23:20 3% ` De Lara Guarch, Pablo
2019-01-09 11:30 0% ` Zhang, Roy Fan
2018-12-21 13:55 1% ` [dpdk-dev] [PATCH v3 2/2] cryptodev: change symmetric session structure Fan Zhang
2019-01-09 22:55 ` [dpdk-dev] [PATCH v4 00/12] cryptodev: change qp conf and sym session Fan Zhang
2019-01-09 22:55 3% ` [dpdk-dev] [PATCH v4 01/12] cryptodev: change queue pair configure structure Fan Zhang
2019-01-10 9:47 3% ` De Lara Guarch, Pablo
2019-01-10 11:24 0% ` De Lara Guarch, Pablo
2019-01-09 22:55 3% ` [dpdk-dev] [PATCH v4 02/12] cryptodev: add sym session mempool create Fan Zhang
2019-01-10 11:22 0% ` De Lara Guarch, Pablo
2019-01-09 22:56 3% ` [dpdk-dev] [PATCH v4 08/12] cryptodev: add sym session header size API Fan Zhang
2019-01-09 22:56 1% ` [dpdk-dev] [PATCH v4 09/12] cryptodev: update symmetric session structure Fan Zhang
2019-01-10 14:50 ` [dpdk-dev] [PATCH v5 00/12] cryptodev: change qp conf and sym session Fan Zhang
2019-01-10 14:50 3% ` [dpdk-dev] [PATCH v5 01/12] cryptodev: change queue pair configure structure Fan Zhang
2019-01-10 14:50 3% ` [dpdk-dev] [PATCH v5 02/12] cryptodev: add sym session mempool create Fan Zhang
2019-01-10 14:50 5% ` [dpdk-dev] [PATCH v5 09/12] cryptodev: update symmetric session structure Fan Zhang
2018-12-11 17:57 4% [dpdk-dev] [PATCH 1/6] bitmap: remove deprecated bsf64 function Anatoly Burakov
2018-12-11 17:57 4% ` [dpdk-dev] [PATCH 2/6] common: add bsf64 function similar to existing bsf32 Anatoly Burakov
2018-12-20 12:09 4% ` [dpdk-dev] [PATCH v2 1/4] bitmap: remove deprecated bsf64 function Anatoly Burakov
2018-12-20 12:09 4% ` [dpdk-dev] [PATCH v2 2/4] common: add bsf64 and bsf32_safe functions Anatoly Burakov
2018-12-13 11:43 [dpdk-dev] [PATCH v3 0/5] Allow using virtio-user without hugepages Anatoly Burakov
2018-12-11 16:43 ` [dpdk-dev] [PATCH v2 0/5] Allow using virtio " Anatoly Burakov
2018-11-13 17:54 ` [dpdk-dev] [PATCH 19.02 0/2] " Anatoly Burakov
2018-12-11 16:43 4% ` [dpdk-dev] [PATCH v2 1/5] mem: fix error code for segment fd API for external segs Anatoly Burakov
2018-12-11 16:43 4% ` [dpdk-dev] [PATCH v2 2/5] memalloc: check for memfd support in segment fd API Anatoly Burakov
2018-12-13 11:43 4% ` [dpdk-dev] [PATCH v3 1/5] mem: fix error code for segment fd API for external segs Anatoly Burakov
2018-12-13 11:43 4% ` [dpdk-dev] [PATCH v3 2/5] memalloc: check for memfd support in segment fd API Anatoly Burakov
2018-12-14 16:23 [dpdk-dev] [PATCH v4 01/10] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
2018-12-28 15:17 2% ` [dpdk-dev] [PATCH v5 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
2018-12-14 16:38 [dpdk-dev] [PATCH] eal: remove variable length array Jeff Shaw
2018-12-14 18:36 ` Mattias Rönnblom
2018-12-14 19:07 ` Jeff Shaw
2018-12-14 20:28 ` Mattias Rönnblom
2018-12-14 20:50 ` [dpdk-dev] [PATCH] eal: simplify RTE_PMD_DEBUG_TRACE Stephen Hemminger
2018-12-14 21:20 ` Jeff Shaw
2018-12-14 21:57 3% ` Stephen Hemminger
2018-12-18 1:25 1% [dpdk-dev] [RFC] kni: remove ethtool support Ferruh Yigit
2018-12-19 12:52 35% [dpdk-dev] [RFC 1/2] doc: clean ABI/API policy guide Ferruh Yigit
2018-12-20 8:02 4% ` Luca Boccassi
2018-12-20 8:03 8% ` Luca Boccassi
2018-12-21 15:57 35% ` [dpdk-dev] [PATCH v2 " Ferruh Yigit
2019-01-22 16:23 35% ` [dpdk-dev] [PATCH v3 1/3] " Ferruh Yigit
2019-01-22 16:23 17% ` [dpdk-dev] [PATCH v3 2/3] doc: make RTE_NEXT_ABI optional Ferruh Yigit
2019-01-23 8:13 4% ` [dpdk-dev] [PATCH v3 1/3] doc: clean ABI/API policy guide Neil Horman
2019-01-24 18:10 35% ` [dpdk-dev] [PATCH v4 " Ferruh Yigit
2019-01-24 18:10 17% ` [dpdk-dev] [PATCH v4 2/3] doc: make RTE_NEXT_ABI optional Ferruh Yigit
2018-12-23 9:58 [dpdk-dev] [PATCH] net/mlx5: modify-header support using Direct Verbs Dekel Peled
2018-12-25 11:38 3% ` Shahaf Shuler
2018-12-25 16:00 0% ` Dekel Peled
2018-12-27 4:13 [dpdk-dev] [PATCH v3 0/6] spinlock optimization and test case enhancements Gavin Hu
2018-12-27 4:13 ` [dpdk-dev] [PATCH v3 5/6] spinlock: reimplement with atomic one-way barrier builtins Gavin Hu
2018-12-27 7:42 ` [dpdk-dev] [EXT] " Jerin Jacob Kollanukkaran
2019-01-11 13:52 ` Gavin Hu (Arm Technology China)
2019-01-14 5:54 3% ` Honnappa Nagarahalli
2019-01-14 7:39 0% ` Jerin Jacob Kollanukkaran
2019-01-14 17:08 0% ` Gavin Hu (Arm Technology China)
2019-01-14 7:57 0% ` Gavin Hu (Arm Technology China)
2018-12-28 15:17 [dpdk-dev] [PATCH v5 01/10] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
2019-01-03 20:16 2% ` [dpdk-dev] [PATCH v6 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
2019-01-11 1:09 2% ` Xu, Yanjie
2019-01-03 20:16 ` [dpdk-dev] [PATCH v6 01/10] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
2019-01-04 0:25 3% ` Stephen Hemminger
2019-01-04 9:29 0% ` Ananyev, Konstantin
2019-01-09 23:41 4% ` Thomas Monjalon
2019-01-10 14:20 4% ` [dpdk-dev] [PATCH v7 00/10] ipsec: new library for IPsec data-path processing Konstantin Ananyev
2019-01-10 14:25 0% ` Thomas Monjalon
2019-01-10 14:40 0% ` De Lara Guarch, Pablo
2019-01-10 14:52 3% ` Ananyev, Konstantin
2019-01-10 14:54 0% ` Thomas Monjalon
2019-01-10 14:58 0% ` Ananyev, Konstantin
2019-01-10 15:00 0% ` Akhil Goyal
2019-01-10 15:09 0% ` Akhil Goyal
2019-01-10 14:51 0% ` Akhil Goyal
2019-01-10 14:20 5% ` [dpdk-dev] [PATCH v7 01/10] cryptodev: add opaque userdata pointer into crypto sym session Konstantin Ananyev
2019-01-10 21:06 4% ` [dpdk-dev] [PATCH v8 0/9] ipsec: new library for IPsec data-path processing Konstantin Ananyev
2019-01-10 21:06 5% ` [dpdk-dev] [PATCH v8 1/9] security: add opaque userdata pointer into security session Konstantin Ananyev
2019-01-10 14:20 9% ` [dpdk-dev] [PATCH v7 02/10] " Konstantin Ananyev
2019-01-10 11:11 [dpdk-dev] [PATCH] compat: merge compat library into EAL Bruce Richardson
2019-01-10 13:47 4% ` [dpdk-dev] [PATCH v2] " Bruce Richardson
2019-01-10 13:57 0% ` David Marchand
2019-01-10 14:01 0% ` Bruce Richardson
2019-01-10 13:38 2% [dpdk-dev] [PATCH] eal: fix strdup usages in internal config Anatoly Burakov
2019-01-14 14:18 0% ` Thomas Monjalon
2019-01-10 21:01 4% [dpdk-dev] [PATCH 0/6] Add non-blocking ring Gage Eads
2019-01-10 21:01 ` [dpdk-dev] [PATCH 1/6] ring: change head and tail to pointer-width size Gage Eads
2019-01-11 4:38 3% ` Stephen Hemminger
2019-01-11 19:07 3% ` Eads, Gage
2019-01-11 10:25 3% ` Burakov, Anatoly
2019-01-11 19:12 0% ` Eads, Gage
2019-01-11 19:55 3% ` Stephen Hemminger
2019-01-15 15:48 4% ` Eads, Gage
2019-01-11 10:40 ` Burakov, Anatoly
2019-01-11 10:58 ` Bruce Richardson
2019-01-11 11:30 ` Burakov, Anatoly
[not found] ` <20190111115851.GC3336@bricha3-MOBL.ger.corp.intel.com>
2019-01-11 19:27 ` Eads, Gage
2019-01-21 14:14 ` Burakov, Anatoly
2019-01-22 18:27 3% ` Eads, Gage
2019-01-15 23:52 3% ` [dpdk-dev] [PATCH v2 0/5] Add non-blocking ring Gage Eads
2019-01-16 0:26 3% ` Stephen Hemminger
2019-01-18 15:23 3% ` [dpdk-dev] [PATCH v3 " Gage Eads
2019-01-18 15:23 2% ` [dpdk-dev] [PATCH v3 1/5] ring: add 64-bit headtail structure Gage Eads
2019-01-22 9:27 0% ` [dpdk-dev] [PATCH v3 0/5] Add non-blocking ring Ola Liljedahl
2019-01-22 10:15 0% ` Ola Liljedahl
2019-01-22 19:15 0% ` Eads, Gage
2019-01-23 16:02 0% ` Jerin Jacob Kollanukkaran
2019-01-23 16:29 0% ` Ola Liljedahl
2019-01-14 5:20 4% [dpdk-dev] [PATCH 1/2] mbuf: remove deprecated macro Yongseok Koh
2019-01-15 23:59 7% [dpdk-dev] [PATCH] doc: announce ring ABI and API changes Gage Eads
2019-01-16 0:34 7% ` Stephen Hemminger
2019-01-16 18:21 8% ` Eads, Gage
2019-01-18 15:28 3% ` [dpdk-dev] [PATCH v2] doc: announce ring API change Gage Eads
2019-01-18 15:31 3% ` [dpdk-dev] [PATCH v3] " Gage Eads
2019-01-16 9:55 3% [dpdk-dev] DPDK techboard minutes of January 2 Thomas Monjalon
2019-01-16 11:45 5% [dpdk-dev] [PATCH] doc: increase minimal supported Linux version Thomas Monjalon
2019-01-17 9:39 4% [dpdk-dev] [PATCH] doc: announce ABI change for cryptodev config Anoob Joseph
2019-01-17 11:37 4% ` Trahe, Fiona
2019-01-17 13:47 4% ` Anoob Joseph
2019-01-18 6:59 4% ` Shally Verma
2019-01-22 9:31 4% ` Anoob Joseph
2019-01-19 14:01 3% [dpdk-dev] [PATCH] service: fix parameter type Nikhil Rao
2019-01-21 11:43 3% ` Van Haaren, Harry
[not found] <mailman.14255.1548076743.7586.dev@dpdk.org>
2019-01-21 13:23 0% ` [dpdk-dev] dev Digest, Vol 231, Issue 6 Anudeep Kumar
2019-01-23 22:07 4% [dpdk-dev] [PATCH] Introduce travis builds for github repositories Michael Santana
2019-01-24 19:26 0% ` Honnappa Nagarahalli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).