summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/intel/Kconfig9
-rw-r--r--drivers/net/ethernet/intel/i40e/Makefile1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h14
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c60
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_configfs.c354
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c6
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c227
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_nvm.c9
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c42
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c68
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h2
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_common.c44
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.c16
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c2
14 files changed, 284 insertions, 570 deletions
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
index 7216a53..f4ff465 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -303,15 +303,6 @@ config I40E_FCOE
If unsure, say N.
-config I40E_CONFIGFS_FS
- bool "Config File System Support (configfs)"
- default n
- depends on I40E && CONFIGFS_FS && !(I40E=y && CONFIGFS_FS=m)
- ---help---
- Provides support for the configfs file system for additional
- driver configuration. Say Y here if you want to use the
- configuration file system in the driver.
-
config I40EVF
tristate "Intel(R) XL710 X710 Virtual Function Ethernet support"
depends on PCI_MSI
diff --git a/drivers/net/ethernet/intel/i40e/Makefile b/drivers/net/ethernet/intel/i40e/Makefile
index 023e452..b4729ba 100644
--- a/drivers/net/ethernet/intel/i40e/Makefile
+++ b/drivers/net/ethernet/intel/i40e/Makefile
@@ -37,7 +37,6 @@ i40e-objs := i40e_main.o \
i40e_hmc.o \
i40e_lan_hmc.o \
i40e_nvm.o \
- i40e_configfs.o \
i40e_debugfs.o \
i40e_diag.o \
i40e_txrx.o \
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index ce3fbb8..7ce8e60 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -175,6 +175,7 @@ struct i40e_lump_tracking {
#define I40E_FDIR_MAX_RAW_PACKET_SIZE 512
#define I40E_FDIR_BUFFER_FULL_MARGIN 10
#define I40E_FDIR_BUFFER_HEAD_ROOM 32
+#define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4)
enum i40e_fd_stat_idx {
I40E_FD_STAT_ATR,
@@ -276,7 +277,7 @@ struct i40e_pf {
enum i40e_interrupt_policy int_policy;
u16 rx_itr_default;
u16 tx_itr_default;
- u16 msg_enable;
+ u32 msg_enable;
char int_name[I40E_INT_NAME_STR_LEN];
u16 adminq_work_limit; /* num of admin receive queue desc to process */
unsigned long service_timer_period;
@@ -636,9 +637,10 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
int i40e_add_del_fdir(struct i40e_vsi *vsi,
struct i40e_fdir_filter *input, bool add);
void i40e_fdir_check_and_reenable(struct i40e_pf *pf);
-int i40e_get_current_fd_count(struct i40e_pf *pf);
-int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf);
-int i40e_get_current_atr_cnt(struct i40e_pf *pf);
+u32 i40e_get_current_fd_count(struct i40e_pf *pf);
+u32 i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf);
+u32 i40e_get_current_atr_cnt(struct i40e_pf *pf);
+u32 i40e_get_global_fd_count(struct i40e_pf *pf);
bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features);
void i40e_set_ethtool_ops(struct net_device *netdev);
struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
@@ -747,10 +749,6 @@ int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr);
void i40e_ptp_init(struct i40e_pf *pf);
void i40e_ptp_stop(struct i40e_pf *pf);
int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi);
-#if IS_ENABLED(CONFIG_I40E_CONFIGFS_FS)
-int i40e_configfs_init(void);
-void i40e_configfs_exit(void);
-#endif /* CONFIG_I40E_CONFIGFS_FS */
i40e_status i40e_get_npar_bw_setting(struct i40e_pf *pf);
i40e_status i40e_set_npar_bw_setting(struct i40e_pf *pf);
i40e_status i40e_commit_npar_bw_setting(struct i40e_pf *pf);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 10f9451..fb78bdd 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -85,9 +85,8 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
{
struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
u16 len = le16_to_cpu(aq_desc->datalen);
- u8 *aq_buffer = (u8 *)buffer;
- u32 data[4];
- u32 i = 0;
+ u8 *buf = (u8 *)buffer;
+ u16 i = 0;
if ((!(mask & hw->debug_mask)) || (desc == NULL))
return;
@@ -109,29 +108,30 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
le32_to_cpu(aq_desc->params.external.addr_low));
if ((buffer != NULL) && (aq_desc->datalen != 0)) {
- memset(data, 0, sizeof(data));
i40e_debug(hw, mask, "AQ CMD Buffer:\n");
if (buf_len < len)
len = buf_len;
- for (i = 0; i < len; i++) {
- data[((i % 16) / 4)] |=
- ((u32)aq_buffer[i]) << (8 * (i % 4));
- if ((i % 16) == 15) {
- i40e_debug(hw, mask,
- "\t0x%04X %08X %08X %08X %08X\n",
- i - 15, le32_to_cpu(data[0]),
- le32_to_cpu(data[1]),
- le32_to_cpu(data[2]),
- le32_to_cpu(data[3]));
- memset(data, 0, sizeof(data));
- }
+ /* write the full 16-byte chunks */
+ for (i = 0; i < (len - 16); i += 16)
+ i40e_debug(hw, mask,
+ "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
+ i, buf[i], buf[i + 1], buf[i + 2],
+ buf[i + 3], buf[i + 4], buf[i + 5],
+ buf[i + 6], buf[i + 7], buf[i + 8],
+ buf[i + 9], buf[i + 10], buf[i + 11],
+ buf[i + 12], buf[i + 13], buf[i + 14],
+ buf[i + 15]);
+ /* write whatever's left over without overrunning the buffer */
+ if (i < len) {
+ char d_buf[80];
+ int j = 0;
+
+ memset(d_buf, 0, sizeof(d_buf));
+ j += sprintf(d_buf, "\t0x%04X ", i);
+ while (i < len)
+ j += sprintf(&d_buf[j], " %02X", buf[i++]);
+ i40e_debug(hw, mask, "%s\n", d_buf);
}
- if ((i % 16) != 0)
- i40e_debug(hw, mask, "\t0x%04X %08X %08X %08X %08X\n",
- i - (i % 16), le32_to_cpu(data[0]),
- le32_to_cpu(data[1]),
- le32_to_cpu(data[2]),
- le32_to_cpu(data[3]));
}
}
@@ -2126,7 +2126,7 @@ i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
* Read the register using the admin queue commands
**/
i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
- u32 reg_addr, u64 *reg_val,
+ u32 reg_addr, u64 *reg_val,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
@@ -2137,17 +2137,15 @@ i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
if (reg_val == NULL)
return I40E_ERR_PARAM;
- i40e_fill_default_direct_cmd_desc(&desc,
- i40e_aqc_opc_debug_read_reg);
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg);
cmd_resp->address = cpu_to_le32(reg_addr);
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
if (!status) {
- *reg_val = ((u64)cmd_resp->value_high << 32) |
- (u64)cmd_resp->value_low;
- *reg_val = le64_to_cpu(*reg_val);
+ *reg_val = ((u64)le32_to_cpu(cmd_resp->value_high) << 32) |
+ (u64)le32_to_cpu(cmd_resp->value_low);
}
return status;
@@ -3409,9 +3407,9 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
* is not passed then only register at 'reg_addr0' is read.
*
**/
-i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
- u32 reg_addr0, u32 *reg_val0,
- u32 reg_addr1, u32 *reg_val1)
+static i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
+ u32 reg_addr0, u32 *reg_val0,
+ u32 reg_addr1, u32 *reg_val1)
{
struct i40e_aq_desc desc;
struct i40e_aqc_alternate_write *cmd_resp =
diff --git a/drivers/net/ethernet/intel/i40e/i40e_configfs.c b/drivers/net/ethernet/intel/i40e/i40e_configfs.c
deleted file mode 100644
index d3cdfc2..0000000
--- a/drivers/net/ethernet/intel/i40e/i40e_configfs.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*******************************************************************************
- *
- * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * The full GNU General Public License is included in this distribution in
- * the file called "COPYING".
- *
- * 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/configfs.h>
-#include "i40e.h"
-
-#if IS_ENABLED(CONFIG_I40E_CONFIGFS_FS)
-
-/**
- * configfs structure for i40e
- *
- * This file adds code for configfs support for the i40e driver. This sets
- * up a filesystem under /sys/kernel/config in which configuration changes
- * can be made for the driver's netdevs.
- *
- * The initialization in this code creates the "i40e" entry in the configfs
- * system. After that, the user needs to use mkdir to create configurations
- * for specific netdev ports; for example "mkdir eth3". This code will verify
- * that such a netdev exists and that it is owned by i40e.
- *
- **/
-
-struct i40e_cfgfs_vsi {
- struct config_item item;
- struct i40e_vsi *vsi;
-};
-
-static inline struct i40e_cfgfs_vsi *to_i40e_cfgfs_vsi(struct config_item *item)
-{
- return item ? container_of(item, struct i40e_cfgfs_vsi, item) : NULL;
-}
-
-static struct configfs_attribute i40e_cfgfs_vsi_attr_min_bw = {
- .ca_owner = THIS_MODULE,
- .ca_name = "min_bw",
- .ca_mode = S_IRUGO | S_IWUSR,
-};
-
-static struct configfs_attribute i40e_cfgfs_vsi_attr_max_bw = {
- .ca_owner = THIS_MODULE,
- .ca_name = "max_bw",
- .ca_mode = S_IRUGO | S_IWUSR,
-};
-
-static struct configfs_attribute i40e_cfgfs_vsi_attr_commit = {
- .ca_owner = THIS_MODULE,
- .ca_name = "commit",
- .ca_mode = S_IRUGO | S_IWUSR,
-};
-
-static struct configfs_attribute i40e_cfgfs_vsi_attr_port_count = {
- .ca_owner = THIS_MODULE,
- .ca_name = "ports",
- .ca_mode = S_IRUGO | S_IWUSR,
-};
-
-static struct configfs_attribute i40e_cfgfs_vsi_attr_part_count = {
- .ca_owner = THIS_MODULE,
- .ca_name = "partitions",
- .ca_mode = S_IRUGO | S_IWUSR,
-};
-
-static struct configfs_attribute *i40e_cfgfs_vsi_attrs[] = {
- &i40e_cfgfs_vsi_attr_min_bw,
- &i40e_cfgfs_vsi_attr_max_bw,
- &i40e_cfgfs_vsi_attr_commit,
- &i40e_cfgfs_vsi_attr_port_count,
- &i40e_cfgfs_vsi_attr_part_count,
- NULL,
-};
-
-/**
- * i40e_cfgfs_vsi_attr_show - Show a VSI's NPAR BW partition info
- * @item: A pointer back to the configfs item created on driver load
- * @attr: A pointer to this item's configuration attribute
- * @page: A pointer to the output buffer
- **/
-static ssize_t i40e_cfgfs_vsi_attr_show(struct config_item *item,
- struct configfs_attribute *attr,
- char *page)
-{
- struct i40e_cfgfs_vsi *i40e_cfgfs_vsi = to_i40e_cfgfs_vsi(item);
- struct i40e_pf *pf = i40e_cfgfs_vsi->vsi->back;
- ssize_t count;
-
- if (i40e_cfgfs_vsi->vsi != pf->vsi[pf->lan_vsi])
- return 0;
-
- if (strncmp(attr->ca_name, "min_bw", 6) == 0)
- count = sprintf(page, "%s %s %d%%\n",
- i40e_cfgfs_vsi->vsi->netdev->name,
- (pf->npar_min_bw & I40E_ALT_BW_RELATIVE_MASK) ?
- "Relative Min BW" : "Absolute Min BW",
- pf->npar_min_bw & I40E_ALT_BW_VALUE_MASK);
- else if (strncmp(attr->ca_name, "max_bw", 6) == 0)
- count = sprintf(page, "%s %s %d%%\n",
- i40e_cfgfs_vsi->vsi->netdev->name,
- (pf->npar_max_bw & I40E_ALT_BW_RELATIVE_MASK) ?
- "Relative Max BW" : "Absolute Max BW",
- pf->npar_max_bw & I40E_ALT_BW_VALUE_MASK);
- else if (strncmp(attr->ca_name, "ports", 5) == 0)
- count = sprintf(page, "%d\n",
- pf->hw.num_ports);
- else if (strncmp(attr->ca_name, "partitions", 10) == 0)
- count = sprintf(page, "%d\n",
- pf->hw.num_partitions);
- else
- return 0;
-
- return count;
-}
-
-/**
- * i40e_cfgfs_vsi_attr_store - Show a VSI's NPAR BW partition info
- * @item: A pointer back to the configfs item created on driver load
- * @attr: A pointer to this item's configuration attribute
- * @page: A pointer to the user input buffer holding the user input values
- **/
-static ssize_t i40e_cfgfs_vsi_attr_store(struct config_item *item,
- struct configfs_attribute *attr,
- const char *page, size_t count)
-{
- struct i40e_cfgfs_vsi *i40e_cfgfs_vsi = to_i40e_cfgfs_vsi(item);
- struct i40e_pf *pf = i40e_cfgfs_vsi->vsi->back;
- char *p = (char *)page;
- int rc;
- unsigned long tmp;
-
- if (i40e_cfgfs_vsi->vsi != pf->vsi[pf->lan_vsi])
- return 0;
-
- if (!p || (*p && (*p == '\n')))
- return -EINVAL;
-
- rc = kstrtoul(p, 10, &tmp);
- if (rc)
- return rc;
- if (tmp > 100)
- return -ERANGE;
-
- if (strncmp(attr->ca_name, "min_bw", 6) == 0) {
- if (tmp > (pf->npar_max_bw & I40E_ALT_BW_VALUE_MASK))
- return -ERANGE;
- /* Preserve the valid and relative BW bits - the rest is
- * don't care.
- */
- pf->npar_min_bw &= (I40E_ALT_BW_RELATIVE_MASK |
- I40E_ALT_BW_VALID_MASK);
- pf->npar_min_bw |= (tmp & I40E_ALT_BW_VALUE_MASK);
- i40e_set_npar_bw_setting(pf);
- } else if (strncmp(attr->ca_name, "max_bw", 6) == 0) {
- if (tmp < 1 ||
- tmp < (pf->npar_min_bw & I40E_ALT_BW_VALUE_MASK))
- return -ERANGE;
- /* Preserve the valid and relative BW bits - the rest is
- * don't care.
- */
- pf->npar_max_bw &= (I40E_ALT_BW_RELATIVE_MASK |
- I40E_ALT_BW_VALID_MASK);
- pf->npar_max_bw |= (tmp & I40E_ALT_BW_VALUE_MASK);
- i40e_set_npar_bw_setting(pf);
- } else if (strncmp(attr->ca_name, "commit", 6) == 0 && tmp == 1) {
- if (i40e_commit_npar_bw_setting(pf))
- return -EIO;
- }
-
- return count;
-}
-
-/**
- * i40e_cfgfs_vsi_release - Free up the configuration item memory
- * @item: A pointer back to the configfs item created on driver load
- **/
-static void i40e_cfgfs_vsi_release(struct config_item *item)
-{
- kfree(to_i40e_cfgfs_vsi(item));
-}
-
-static struct configfs_item_operations i40e_cfgfs_vsi_item_ops = {
- .release = i40e_cfgfs_vsi_release,
- .show_attribute = i40e_cfgfs_vsi_attr_show,
- .store_attribute = i40e_cfgfs_vsi_attr_store,
-};
-
-static struct config_item_type i40e_cfgfs_vsi_type = {
- .ct_item_ops = &i40e_cfgfs_vsi_item_ops,
- .ct_attrs = i40e_cfgfs_vsi_attrs,
- .ct_owner = THIS_MODULE,
-};
-
-struct i40e_cfgfs_group {
- struct config_group group;
-};
-
-/**
- * to_i40e_cfgfs_group - Get the group pointer from the config item
- * @item: A pointer back to the configfs item created on driver load
- **/
-static inline struct i40e_cfgfs_group *
-to_i40e_cfgfs_group(struct config_item *item)
-{
- return item ? container_of(to_config_group(item),
- struct i40e_cfgfs_group, group) : NULL;
-}
-
-/**
- * i40e_cfgfs_group_make_item - Create the configfs item with group container
- * @group: A pointer to our configfs group
- * @name: A pointer to the nume of the device we're looking for
- **/
-static struct config_item *
-i40e_cfgfs_group_make_item(struct config_group *group, const char *name)
-{
- struct i40e_cfgfs_vsi *i40e_cfgfs_vsi;
- struct net_device *netdev;
- struct i40e_netdev_priv *np;
-
- read_lock(&dev_base_lock);
- netdev = first_net_device(&init_net);
- while (netdev) {
- if (strncmp(netdev->name, name, sizeof(netdev->name)) == 0)
- break;
- netdev = next_net_device(netdev);
- }
- read_unlock(&dev_base_lock);
-
- if (!netdev)
- return ERR_PTR(-ENODEV);
-
- /* is this netdev owned by i40e? */
- if (netdev->netdev_ops->ndo_open != i40e_open)
- return ERR_PTR(-EACCES);
-
- i40e_cfgfs_vsi = kzalloc(sizeof(*i40e_cfgfs_vsi), GFP_KERNEL);
- if (!i40e_cfgfs_vsi)
- return ERR_PTR(-ENOMEM);
-
- np = netdev_priv(netdev);
- i40e_cfgfs_vsi->vsi = np->vsi;
- config_item_init_type_name(&i40e_cfgfs_vsi->item, name,
- &i40e_cfgfs_vsi_type);
-
- return &i40e_cfgfs_vsi->item;
-}
-
-static struct configfs_attribute i40e_cfgfs_group_attr_description = {
- .ca_owner = THIS_MODULE,
- .ca_name = "description",
- .ca_mode = S_IRUGO,
-};
-
-static struct configfs_attribute *i40e_cfgfs_group_attrs[] = {
- &i40e_cfgfs_group_attr_description,
- NULL,
-};
-
-static ssize_t i40e_cfgfs_group_attr_show(struct config_item *item,
- struct configfs_attribute *attr,
- char *page)
-{
- return sprintf(page,
-"i40e\n"
-"\n"
-"This subsystem allows the modification of network port configurations.\n"
-"To start, use the name of the network port to be configured in a 'mkdir'\n"
-"command, e.g. 'mkdir eth3'.\n");
-}
-
-static void i40e_cfgfs_group_release(struct config_item *item)
-{
- kfree(to_i40e_cfgfs_group(item));
-}
-
-static struct configfs_item_operations i40e_cfgfs_group_item_ops = {
- .release = i40e_cfgfs_group_release,
- .show_attribute = i40e_cfgfs_group_attr_show,
-};
-
-/* Note that, since no extra work is required on ->drop_item(),
- * no ->drop_item() is provided.
- */
-static struct configfs_group_operations i40e_cfgfs_group_ops = {
- .make_item = i40e_cfgfs_group_make_item,
-};
-
-static struct config_item_type i40e_cfgfs_group_type = {
- .ct_item_ops = &i40e_cfgfs_group_item_ops,
- .ct_group_ops = &i40e_cfgfs_group_ops,
- .ct_attrs = i40e_cfgfs_group_attrs,
- .ct_owner = THIS_MODULE,
-};
-
-static struct configfs_subsystem i40e_cfgfs_group_subsys = {
- .su_group = {
- .cg_item = {
- .ci_namebuf = "i40e",
- .ci_type = &i40e_cfgfs_group_type,
- },
- },
-};
-
-/**
- * i40e_configfs_init - Initialize configfs support for our driver
- **/
-int i40e_configfs_init(void)
-{
- int ret;
- struct configfs_subsystem *subsys;
-
- subsys = &i40e_cfgfs_group_subsys;
-
- config_group_init(&subsys->su_group);
- mutex_init(&subsys->su_mutex);
- ret = configfs_register_subsystem(subsys);
- if (ret) {
- pr_err("Error %d while registering configfs subsystem %s\n",
- ret, subsys->su_group.cg_item.ci_namebuf);
- return ret;
- }
-
- return 0;
-}
-
-/**
- * i40e_configfs_init - Bail out - unregister configfs subsystem and release
- **/
-void i40e_configfs_exit(void)
-{
- configfs_unregister_subsystem(&i40e_cfgfs_group_subsys);
-}
-#endif /* IS_ENABLED(CONFIG_I40E_CONFIGFS_FS) */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index e045de1..01c811c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1224,7 +1224,7 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_TEST:
return I40E_TEST_LEN;
case ETH_SS_STATS:
- if (vsi == pf->vsi[pf->lan_vsi]) {
+ if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1) {
int len = I40E_PF_STATS_LEN(netdev);
if (pf->lan_veb != I40E_NO_VEB)
@@ -1297,7 +1297,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
i += 2;
}
rcu_read_unlock();
- if (vsi != pf->vsi[pf->lan_vsi])
+ if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
return;
if (pf->lan_veb != I40E_NO_VEB) {
@@ -1370,7 +1370,7 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
p += ETH_GSTRING_LEN;
}
- if (vsi != pf->vsi[pf->lan_vsi])
+ if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
return;
if (pf->lan_veb != I40E_NO_VEB) {
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 0937cf3..4bed881 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -39,7 +39,7 @@ static const char i40e_driver_string[] =
#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 2
-#define DRV_VERSION_BUILD 11
+#define DRV_VERSION_BUILD 12
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
@@ -1541,7 +1541,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
vsi->tc_config.tc_info[i].qoffset = offset;
vsi->tc_config.tc_info[i].qcount = qcount;
- /* find the power-of-2 of the number of queue pairs */
+ /* find the next higher power-of-2 of num queue pairs */
num_qps = qcount;
pow = 0;
while (num_qps && ((1 << pow) < qcount)) {
@@ -5345,9 +5345,9 @@ static void i40e_service_event_complete(struct i40e_pf *pf)
* i40e_get_cur_guaranteed_fd_count - Get the consumed guaranteed FD filters
* @pf: board private structure
**/
-int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf)
+u32 i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf)
{
- int val, fcnt_prog;
+ u32 val, fcnt_prog;
val = rd32(&pf->hw, I40E_PFQF_FDSTAT);
fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK);
@@ -5355,12 +5355,13 @@ int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf)
}
/**
- * i40e_get_current_fd_count - Get the count of total FD filters programmed
+ * i40e_get_current_fd_count - Get total FD filters programmed for this PF
* @pf: board private structure
**/
-int i40e_get_current_fd_count(struct i40e_pf *pf)
+u32 i40e_get_current_fd_count(struct i40e_pf *pf)
{
- int val, fcnt_prog;
+ u32 val, fcnt_prog;
+
val = rd32(&pf->hw, I40E_PFQF_FDSTAT);
fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK) +
((val & I40E_PFQF_FDSTAT_BEST_CNT_MASK) >>
@@ -5369,6 +5370,21 @@ int i40e_get_current_fd_count(struct i40e_pf *pf)
}
/**
+ * i40e_get_global_fd_count - Get total FD filters programmed on device
+ * @pf: board private structure
+ **/
+u32 i40e_get_global_fd_count(struct i40e_pf *pf)
+{
+ u32 val, fcnt_prog;
+
+ val = rd32(&pf->hw, I40E_GLQF_FDCNT_0);
+ fcnt_prog = (val & I40E_GLQF_FDCNT_0_GUARANT_CNT_MASK) +
+ ((val & I40E_GLQF_FDCNT_0_BESTCNT_MASK) >>
+ I40E_GLQF_FDCNT_0_BESTCNT_SHIFT);
+ return fcnt_prog;
+}
+
+/**
* i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled
* @pf: board private structure
**/
@@ -5382,7 +5398,7 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
/* Check if, FD SB or ATR was auto disabled and if there is enough room
* to re-enable
*/
- fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf);
+ fcnt_prog = i40e_get_global_fd_count(pf);
fcnt_avail = pf->fdir_pf_filter_count;
if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) ||
(pf->fd_add_err == 0) ||
@@ -5404,13 +5420,17 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
}
#define I40E_MIN_FD_FLUSH_INTERVAL 10
+#define I40E_MIN_FD_FLUSH_SB_ATR_UNSTABLE 30
/**
* i40e_fdir_flush_and_replay - Function to flush all FD filters and replay SB
* @pf: board private structure
**/
static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
{
+ unsigned long min_flush_time;
int flush_wait_retry = 50;
+ bool disable_atr = false;
+ int fd_room;
int reg;
if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED)))
@@ -5418,9 +5438,20 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
if (time_after(jiffies, pf->fd_flush_timestamp +
(I40E_MIN_FD_FLUSH_INTERVAL * HZ))) {
- set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
+ /* If the flush is happening too quick and we have mostly
+ * SB rules we should not re-enable ATR for some time.
+ */
+ min_flush_time = pf->fd_flush_timestamp
+ + (I40E_MIN_FD_FLUSH_SB_ATR_UNSTABLE * HZ);
+ fd_room = pf->fdir_pf_filter_count - pf->fdir_pf_active_filters;
+
+ if (!(time_after(jiffies, min_flush_time)) &&
+ (fd_room < I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR)) {
+ dev_info(&pf->pdev->dev, "ATR disabled, not enough FD filter space.\n");
+ disable_atr = true;
+ }
+
pf->fd_flush_timestamp = jiffies;
- pf->auto_disable_flags |= I40E_FLAG_FD_SB_ENABLED;
pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED;
/* flush all filters */
wr32(&pf->hw, I40E_PFQF_CTL_1,
@@ -5440,10 +5471,8 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
} else {
/* replay sideband filters */
i40e_fdir_filter_restore(pf->vsi[pf->lan_vsi]);
-
- pf->flags |= I40E_FLAG_FD_ATR_ENABLED;
- pf->auto_disable_flags &= ~I40E_FLAG_FD_ATR_ENABLED;
- pf->auto_disable_flags &= ~I40E_FLAG_FD_SB_ENABLED;
+ if (!disable_atr)
+ pf->flags |= I40E_FLAG_FD_ATR_ENABLED;
clear_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
dev_info(&pf->pdev->dev, "FD Filter table flushed and FD-SB replayed.\n");
}
@@ -5454,7 +5483,7 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
* i40e_get_current_atr_count - Get the count of total FD ATR filters programmed
* @pf: board private structure
**/
-int i40e_get_current_atr_cnt(struct i40e_pf *pf)
+u32 i40e_get_current_atr_cnt(struct i40e_pf *pf)
{
return i40e_get_current_fd_count(pf) - pf->fdir_pf_active_filters;
}
@@ -5480,9 +5509,7 @@ static void i40e_fdir_reinit_subtask(struct i40e_pf *pf)
if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED)))
return;
- if ((pf->fd_add_err >= I40E_MAX_FD_PROGRAM_ERROR) &&
- (i40e_get_current_atr_cnt(pf) >= pf->fd_atr_cnt) &&
- (i40e_get_current_atr_cnt(pf) > pf->fdir_pf_filter_count))
+ if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state))
i40e_fdir_flush_and_replay(pf);
i40e_fdir_check_and_reenable(pf);
@@ -5913,6 +5940,74 @@ static void i40e_verify_eeprom(struct i40e_pf *pf)
}
/**
+ * i40e_enable_pf_switch_lb
+ * @pf: pointer to the pf structure
+ *
+ * enable switch loop back or die - no point in a return value
+ **/
+static void i40e_enable_pf_switch_lb(struct i40e_pf *pf)
+{
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ struct i40e_vsi_context ctxt;
+ int aq_ret;
+
+ ctxt.seid = pf->main_vsi_seid;
+ ctxt.pf_num = pf->hw.pf_id;
+ ctxt.vf_num = 0;
+ aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+ "%s couldn't get pf vsi config, err %d, aq_err %d\n",
+ __func__, aq_ret, pf->hw.aq.asq_last_status);
+ return;
+ }
+ ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+ ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+ ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
+
+ aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+ "%s: update vsi switch failed, aq_err=%d\n",
+ __func__, vsi->back->hw.aq.asq_last_status);
+ }
+}
+
+/**
+ * i40e_disable_pf_switch_lb
+ * @pf: pointer to the pf structure
+ *
+ * disable switch loop back or die - no point in a return value
+ **/
+static void i40e_disable_pf_switch_lb(struct i40e_pf *pf)
+{
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ struct i40e_vsi_context ctxt;
+ int aq_ret;
+
+ ctxt.seid = pf->main_vsi_seid;
+ ctxt.pf_num = pf->hw.pf_id;
+ ctxt.vf_num = 0;
+ aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+ "%s couldn't get pf vsi config, err %d, aq_err %d\n",
+ __func__, aq_ret, pf->hw.aq.asq_last_status);
+ return;
+ }
+ ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+ ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+ ctxt.info.switch_id &= ~cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
+
+ aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+ if (aq_ret) {
+ dev_info(&pf->pdev->dev,
+ "%s: update vsi switch failed, aq_err=%d\n",
+ __func__, vsi->back->hw.aq.asq_last_status);
+ }
+}
+
+/**
* i40e_config_bridge_mode - Configure the HW bridge mode
* @veb: pointer to the bridge instance
*
@@ -6940,7 +7035,7 @@ static int i40e_reserve_msix_vectors(struct i40e_pf *pf, int vectors)
static int i40e_init_msix(struct i40e_pf *pf)
{
struct i40e_hw *hw = &pf->hw;
- int other_vecs = 0;
+ int vectors_left;
int v_budget, i;
int v_actual;
@@ -6964,25 +7059,62 @@ static int i40e_init_msix(struct i40e_pf *pf)
* If we can't get what we want, we'll simplify to nearly nothing
* and try again. If that still fails, we punt.
*/
- pf->num_lan_msix = min_t(int, num_online_cpus(),
- hw->func_caps.num_msix_vectors);
- pf->num_vmdq_msix = pf->num_vmdq_qps;
- other_vecs = 1;
- other_vecs += (pf->num_vmdq_vsis * pf->num_vmdq_msix);
- if (pf->flags & I40E_FLAG_FD_SB_ENABLED)
- other_vecs++;
-
- /* Scale down if necessary, and the rings will share vectors */
- pf->num_lan_msix = min_t(int, pf->num_lan_msix,
- (hw->func_caps.num_msix_vectors - other_vecs));
- v_budget = pf->num_lan_msix + other_vecs;
+ vectors_left = hw->func_caps.num_msix_vectors;
+ v_budget = 0;
+
+ /* reserve one vector for miscellaneous handler */
+ if (vectors_left) {
+ v_budget++;
+ vectors_left--;
+ }
+
+ /* reserve vectors for the main PF traffic queues */
+ pf->num_lan_msix = min_t(int, num_online_cpus(), vectors_left);
+ vectors_left -= pf->num_lan_msix;
+ v_budget += pf->num_lan_msix;
+
+ /* reserve one vector for sideband flow director */
+ if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
+ if (vectors_left) {
+ v_budget++;
+ vectors_left--;
+ } else {
+ pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
+ }
+ }
#ifdef I40E_FCOE
+ /* can we reserve enough for FCoE? */
if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
- pf->num_fcoe_msix = pf->num_fcoe_qps;
+ if (!vectors_left)
+ pf->num_fcoe_msix = 0;
+ else if (vectors_left >= pf->num_fcoe_qps)
+ pf->num_fcoe_msix = pf->num_fcoe_qps;
+ else
+ pf->num_fcoe_msix = 1;
v_budget += pf->num_fcoe_msix;
+ vectors_left -= pf->num_fcoe_msix;
}
+
#endif
+ /* any vectors left over go for VMDq support */
+ if (pf->flags & I40E_FLAG_VMDQ_ENABLED) {
+ int vmdq_vecs_wanted = pf->num_vmdq_vsis * pf->num_vmdq_qps;
+ int vmdq_vecs = min_t(int, vectors_left, vmdq_vecs_wanted);
+
+ /* if we're short on vectors for what's desired, we limit
+ * the queues per vmdq. If this is still more than are
+ * available, the user will need to change the number of
+ * queues/vectors used by the PF later with the ethtool
+ * channels command
+ */
+ if (vmdq_vecs < vmdq_vecs_wanted)
+ pf->num_vmdq_qps = 1;
+ pf->num_vmdq_msix = pf->num_vmdq_qps;
+
+ v_budget += vmdq_vecs;
+ vectors_left -= vmdq_vecs;
+ }
pf->msix_entries = kcalloc(v_budget, sizeof(struct msix_entry),
GFP_KERNEL);
@@ -7028,6 +7160,8 @@ static int i40e_init_msix(struct i40e_pf *pf)
/* Scale vector usage down */
pf->num_vmdq_msix = 1; /* force VMDqs to only one vector */
pf->num_vmdq_vsis = 1;
+ pf->num_vmdq_qps = 1;
+ pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
/* partition out the remaining vectors */
switch (vec) {
@@ -7053,10 +7187,8 @@ static int i40e_init_msix(struct i40e_pf *pf)
vec--;
}
#endif
- pf->num_lan_msix = min_t(int, (vec / 2),
- pf->num_lan_qps);
- pf->num_vmdq_vsis = min_t(int, (vec - pf->num_lan_msix),
- I40E_DEFAULT_NUM_VMDQ_VSI);
+ /* give the rest to the PF */
+ pf->num_lan_msix = min_t(int, vec, pf->num_lan_qps);
break;
}
}
@@ -7266,13 +7398,10 @@ static int i40e_config_rss(struct i40e_pf *pf)
/* Check capability and Set table size and register per hw expectation*/
reg_val = rd32(hw, I40E_PFQF_CTL_0);
- if (hw->func_caps.rss_table_size == 512) {
+ if (pf->rss_table_size == 512)
reg_val |= I40E_PFQF_CTL_0_HASHLUTSIZE_512;
- pf->rss_table_size = 512;
- } else {
- pf->rss_table_size = 128;
+ else
reg_val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_512;
- }
wr32(hw, I40E_PFQF_CTL_0, reg_val);
/* Populate the LUT with max no. of queues in round robin fashion */
@@ -7923,7 +8052,7 @@ static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
}
#endif /* HAVE_BRIDGE_ATTRIBS */
-const struct net_device_ops i40e_netdev_ops = {
+static const struct net_device_ops i40e_netdev_ops = {
.ndo_open = i40e_open,
.ndo_stop = i40e_close,
.ndo_start_xmit = i40e_lan_xmit_frame,
@@ -9242,14 +9371,6 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
pf->fc_autoneg_status = ((pf->hw.phy.link_info.an_info &
I40E_AQ_AN_COMPLETED) ? true : false);
- /* fill in link information and enable LSE reporting */
- i40e_aq_get_link_info(&pf->hw, true, NULL, NULL);
- i40e_link_event(pf);
-
- /* Initialize user-specific link properties */
- pf->fc_autoneg_status = ((pf->hw.phy.link_info.an_info &
- I40E_AQ_AN_COMPLETED) ? true : false);
-
i40e_ptp_init(pf);
return ret;
@@ -10166,9 +10287,6 @@ static int __init i40e_init_module(void)
i40e_driver_string, i40e_driver_version_str);
pr_info("%s: %s\n", i40e_driver_name, i40e_copyright);
-#if IS_ENABLED(CONFIG_I40E_CONFIGFS_FS)
- i40e_configfs_init();
-#endif /* CONFIG_I40E_CONFIGFS_FS */
i40e_dbg_init();
return pci_register_driver(&i40e_driver);
}
@@ -10184,8 +10302,5 @@ static void __exit i40e_exit_module(void)
{
pci_unregister_driver(&i40e_driver);
i40e_dbg_exit();
-#if IS_ENABLED(CONFIG_I40E_CONFIGFS_FS)
- i40e_configfs_exit();
-#endif /* CONFIG_I40E_CONFIGFS_FS */
}
module_exit(i40e_exit_module);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 039018a..e49acd2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -171,8 +171,8 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
*
* Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
**/
-i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
- u16 *data)
+static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
+ u16 *data)
{
i40e_status ret_code = I40E_ERR_TIMEOUT;
u32 sr_reg;
@@ -200,7 +200,6 @@ i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
*data = (u16)((sr_reg &
I40E_GLNVM_SRDATA_RDDATA_MASK)
>> I40E_GLNVM_SRDATA_RDDATA_SHIFT);
- *data = le16_to_cpu(*data);
}
}
if (ret_code)
@@ -237,8 +236,8 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
* method. The buffer read is preceded by the NVM ownership take
* and followed by the release.
**/
-i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
- u16 *words, u16 *data)
+static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
+ u16 *words, u16 *data)
{
i40e_status ret_code = 0;
u16 index, word;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index d4b4aa7..f5a50b9 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -228,7 +228,7 @@ static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi,
"PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n",
fd_data->pctype, fd_data->fd_id, ret);
err = true;
- } else {
+ } else if (I40E_DEBUG_FD & pf->hw.debug_mask) {
if (add)
dev_info(&pf->pdev->dev,
"Filter OK for PCTYPE %d loc = %d\n",
@@ -303,7 +303,7 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
"PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n",
fd_data->pctype, fd_data->fd_id, ret);
err = true;
- } else {
+ } else if (I40E_DEBUG_FD & pf->hw.debug_mask) {
if (add)
dev_info(&pf->pdev->dev, "Filter OK for PCTYPE %d loc = %d)\n",
fd_data->pctype, fd_data->fd_id);
@@ -376,7 +376,7 @@ static int i40e_add_del_fdir_ipv4(struct i40e_vsi *vsi,
"PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n",
fd_data->pctype, fd_data->fd_id, ret);
err = true;
- } else {
+ } else if (I40E_DEBUG_FD & pf->hw.debug_mask) {
if (add)
dev_info(&pf->pdev->dev,
"Filter OK for PCTYPE %d loc = %d\n",
@@ -471,12 +471,27 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
dev_warn(&pdev->dev, "ntuple filter loc = %d, could not be added\n",
rx_desc->wb.qword0.hi_dword.fd_id);
+ /* Check if the programming error is for ATR.
+ * If so, auto disable ATR and set a state for
+ * flush in progress. Next time we come here if flush is in
+ * progress do nothing, once flush is complete the state will
+ * be cleared.
+ */
+ if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state))
+ return;
+
pf->fd_add_err++;
/* store the current atr filter count */
pf->fd_atr_cnt = i40e_get_current_atr_cnt(pf);
+ if ((rx_desc->wb.qword0.hi_dword.fd_id == 0) &&
+ (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) {
+ pf->auto_disable_flags |= I40E_FLAG_FD_ATR_ENABLED;
+ set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
+ }
+
/* filter programming failed most likely due to table full */
- fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf);
+ fcnt_prog = i40e_get_global_fd_count(pf);
fcnt_avail = pf->fdir_pf_filter_count;
/* If ATR is running fcnt_prog can quickly change,
* if we are very close to full, it makes sense to disable
@@ -755,6 +770,8 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
tx_desc = I40E_TX_DESC(tx_ring, 0);
}
+ prefetch(tx_desc);
+
/* update budget accounting */
budget--;
} while (likely(budget));
@@ -1044,7 +1061,7 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
for (i = 0; i < rx_ring->count; i++) {
rx_bi = &rx_ring->rx_bi[i];
rx_bi->dma = 0;
- rx_bi->hdr_buf = 0;
+ rx_bi->hdr_buf = NULL;
}
}
}
@@ -1926,6 +1943,9 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
if (!(pf->flags & I40E_FLAG_FD_ATR_ENABLED))
return;
+ if ((pf->auto_disable_flags & I40E_FLAG_FD_ATR_ENABLED))
+ return;
+
/* if sampling is disabled do nothing */
if (!tx_ring->atr_sample_rate)
return;
@@ -2198,8 +2218,16 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
struct iphdr *this_ip_hdr;
u32 network_hdr_len;
u8 l4_hdr = 0;
+ u32 l4_tunnel = 0;
if (skb->encapsulation) {
+ switch (ip_hdr(skb)->protocol) {
+ case IPPROTO_UDP:
+ l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING;
+ break;
+ default:
+ return;
+ }
network_hdr_len = skb_inner_network_header_len(skb);
this_ip_hdr = inner_ip_hdr(skb);
this_ipv6_hdr = inner_ipv6_hdr(skb);
@@ -2222,8 +2250,8 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
/* Now set the ctx descriptor fields */
*cd_tunneling |= (skb_network_header_len(skb) >> 2) <<
- I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |
- I40E_TXD_CTX_UDP_TUNNELING |
+ I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |
+ l4_tunnel |
((skb_inner_network_offset(skb) -
skb_transport_offset(skb)) >> 1) <<
I40E_TXD_CTX_QW0_NATLEN_SHIFT;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 1d8b94d..7cc635e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -710,74 +710,6 @@ complete_reset:
}
/**
- * i40e_enable_pf_switch_lb
- * @pf: pointer to the pf structure
- *
- * enable switch loop back or die - no point in a return value
- **/
-void i40e_enable_pf_switch_lb(struct i40e_pf *pf)
-{
- struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
- struct i40e_vsi_context ctxt;
- int aq_ret;
-
- ctxt.seid = pf->main_vsi_seid;
- ctxt.pf_num = pf->hw.pf_id;
- ctxt.vf_num = 0;
- aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
- if (aq_ret) {
- dev_info(&pf->pdev->dev,
- "%s couldn't get pf vsi config, err %d, aq_err %d\n",
- __func__, aq_ret, pf->hw.aq.asq_last_status);
- return;
- }
- ctxt.flags = I40E_AQ_VSI_TYPE_PF;
- ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
- ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
-
- aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
- if (aq_ret) {
- dev_info(&pf->pdev->dev,
- "%s: update vsi switch failed, aq_err=%d\n",
- __func__, vsi->back->hw.aq.asq_last_status);
- }
-}
-
-/**
- * i40e_disable_pf_switch_lb
- * @pf: pointer to the pf structure
- *
- * disable switch loop back or die - no point in a return value
- **/
-void i40e_disable_pf_switch_lb(struct i40e_pf *pf)
-{
- struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
- struct i40e_vsi_context ctxt;
- int aq_ret;
-
- ctxt.seid = pf->main_vsi_seid;
- ctxt.pf_num = pf->hw.pf_id;
- ctxt.vf_num = 0;
- aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
- if (aq_ret) {
- dev_info(&pf->pdev->dev,
- "%s couldn't get pf vsi config, err %d, aq_err %d\n",
- __func__, aq_ret, pf->hw.aq.asq_last_status);
- return;
- }
- ctxt.flags = I40E_AQ_VSI_TYPE_PF;
- ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
- ctxt.info.switch_id &= ~cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
-
- aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
- if (aq_ret) {
- dev_info(&pf->pdev->dev,
- "%s: update vsi switch failed, aq_err=%d\n",
- __func__, vsi->back->hw.aq.asq_last_status);
- }
-}
-
-/**
* i40e_free_vfs
* @pf: pointer to the pf structure
*
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
index ef777a6..21db113 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
@@ -126,7 +126,5 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable);
void i40e_vc_notify_link_state(struct i40e_pf *pf);
void i40e_vc_notify_reset(struct i40e_pf *pf);
-void i40e_enable_pf_switch_lb(struct i40e_pf *pf);
-void i40e_disable_pf_switch_lb(struct i40e_pf *pf);
#endif /* _I40E_VIRTCHNL_PF_H_ */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_common.c b/drivers/net/ethernet/intel/i40evf/i40e_common.c
index 0335b3f..f07b9ff 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_common.c
@@ -85,9 +85,8 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
{
struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
u16 len = le16_to_cpu(aq_desc->datalen);
- u8 *aq_buffer = (u8 *)buffer;
- u32 data[4];
- u32 i = 0;
+ u8 *buf = (u8 *)buffer;
+ u16 i = 0;
if ((!(mask & hw->debug_mask)) || (desc == NULL))
return;
@@ -109,29 +108,30 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
le32_to_cpu(aq_desc->params.external.addr_low));
if ((buffer != NULL) && (aq_desc->datalen != 0)) {
- memset(data, 0, sizeof(data));
i40e_debug(hw, mask, "AQ CMD Buffer:\n");
if (buf_len < len)
len = buf_len;
- for (i = 0; i < len; i++) {
- data[((i % 16) / 4)] |=
- ((u32)aq_buffer[i]) << (8 * (i % 4));
- if ((i % 16) == 15) {
- i40e_debug(hw, mask,
- "\t0x%04X %08X %08X %08X %08X\n",
- i - 15, le32_to_cpu(data[0]),
- le32_to_cpu(data[1]),
- le32_to_cpu(data[2]),
- le32_to_cpu(data[3]));
- memset(data, 0, sizeof(data));
- }
+ /* write the full 16-byte chunks */
+ for (i = 0; i < (len - 16); i += 16)
+ i40e_debug(hw, mask,
+ "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
+ i, buf[i], buf[i + 1], buf[i + 2],
+ buf[i + 3], buf[i + 4], buf[i + 5],
+ buf[i + 6], buf[i + 7], buf[i + 8],
+ buf[i + 9], buf[i + 10], buf[i + 11],
+ buf[i + 12], buf[i + 13], buf[i + 14],
+ buf[i + 15]);
+ /* write whatever's left over without overrunning the buffer */
+ if (i < len) {
+ char d_buf[80];
+ int j = 0;
+
+ memset(d_buf, 0, sizeof(d_buf));
+ j += sprintf(d_buf, "\t0x%04X ", i);
+ while (i < len)
+ j += sprintf(&d_buf[j], " %02X", buf[i++]);
+ i40e_debug(hw, mask, "%s\n", d_buf);
}
- if ((i % 16) != 0)
- i40e_debug(hw, mask, "\t0x%04X %08X %08X %08X %08X\n",
- i - (i % 16), le32_to_cpu(data[0]),
- le32_to_cpu(data[1]),
- le32_to_cpu(data[2]),
- le32_to_cpu(data[3]));
}
}
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index fe13ad2..d9f3db5 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -289,6 +289,8 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
tx_desc = I40E_TX_DESC(tx_ring, 0);
}
+ prefetch(tx_desc);
+
/* update budget accounting */
budget--;
} while (likely(budget));
@@ -542,7 +544,7 @@ void i40evf_clean_rx_ring(struct i40e_ring *rx_ring)
for (i = 0; i < rx_ring->count; i++) {
rx_bi = &rx_ring->rx_bi[i];
rx_bi->dma = 0;
- rx_bi->hdr_buf = 0;
+ rx_bi->hdr_buf = NULL;
}
}
}
@@ -1461,8 +1463,16 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
struct iphdr *this_ip_hdr;
u32 network_hdr_len;
u8 l4_hdr = 0;
+ u32 l4_tunnel = 0;
if (skb->encapsulation) {
+ switch (ip_hdr(skb)->protocol) {
+ case IPPROTO_UDP:
+ l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING;
+ break;
+ default:
+ return;
+ }
network_hdr_len = skb_inner_network_header_len(skb);
this_ip_hdr = inner_ip_hdr(skb);
this_ipv6_hdr = inner_ipv6_hdr(skb);
@@ -1485,8 +1495,8 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
/* Now set the ctx descriptor fields */
*cd_tunneling |= (skb_network_header_len(skb) >> 2) <<
- I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |
- I40E_TXD_CTX_UDP_TUNNELING |
+ I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |
+ l4_tunnel |
((skb_inner_network_offset(skb) -
skb_transport_offset(skb)) >> 1) <<
I40E_TXD_CTX_QW0_NATLEN_SHIFT;
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 3d53bb4..8537416 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -36,7 +36,7 @@ char i40evf_driver_name[] = "i40evf";
static const char i40evf_driver_string[] =
"Intel(R) XL710/X710 Virtual Function Network Driver";
-#define DRV_VERSION "1.2.5"
+#define DRV_VERSION "1.2.6"
const char i40evf_driver_version[] = DRV_VERSION;
static const char i40evf_copyright[] =
"Copyright (c) 2013 - 2014 Intel Corporation.";