#include <rte_memcpy.h>
#include <rte_alarm.h>
#include <rte_dev.h>
-#include <rte_eth_ctrl.h>
#include <rte_tailq.h>
#include <rte_hash_crc.h>
#define ETH_I40E_SUPPORT_MULTI_DRIVER "support-multi-driver"
#define ETH_I40E_QUEUE_NUM_PER_VF_ARG "queue-num-per-vf"
#define ETH_I40E_USE_LATEST_VEC "use-latest-supported-vec"
+#define ETH_I40E_VF_MSG_CFG "vf_msg_cfg"
#define I40E_CLEAR_PXE_WAIT_MS 200
static void i40e_dev_stop(struct rte_eth_dev *dev);
static void i40e_dev_close(struct rte_eth_dev *dev);
static int i40e_dev_reset(struct rte_eth_dev *dev);
-static void i40e_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void i40e_dev_promiscuous_disable(struct rte_eth_dev *dev);
-static void i40e_dev_allmulticast_enable(struct rte_eth_dev *dev);
-static void i40e_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static int i40e_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int i40e_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int i40e_dev_allmulticast_enable(struct rte_eth_dev *dev);
+static int i40e_dev_allmulticast_disable(struct rte_eth_dev *dev);
static int i40e_dev_set_link_up(struct rte_eth_dev *dev);
static int i40e_dev_set_link_down(struct rte_eth_dev *dev);
static int i40e_dev_stats_get(struct rte_eth_dev *dev,
static int i40e_dev_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
unsigned limit);
-static void i40e_dev_stats_reset(struct rte_eth_dev *dev);
-static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev,
- uint16_t queue_id,
- uint8_t stat_idx,
- uint8_t is_rx);
+static int i40e_dev_stats_reset(struct rte_eth_dev *dev);
static int i40e_fw_version_get(struct rte_eth_dev *dev,
char *fw_version, size_t fw_size);
-static void i40e_dev_info_get(struct rte_eth_dev *dev,
- struct rte_eth_dev_info *dev_info);
+static int i40e_dev_info_get(struct rte_eth_dev *dev,
+ struct rte_eth_dev_info *dev_info);
static int i40e_vlan_filter_set(struct rte_eth_dev *dev,
uint16_t vlan_id,
int on);
static int i40e_priority_flow_ctrl_set(struct rte_eth_dev *dev,
struct rte_eth_pfc_conf *pfc_conf);
static int i40e_macaddr_add(struct rte_eth_dev *dev,
- struct ether_addr *mac_addr,
+ struct rte_ether_addr *mac_addr,
uint32_t index,
uint32_t pool);
static void i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index);
struct rte_dev_eeprom_info *info);
static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
- struct ether_addr *mac_addr);
+ struct rte_ether_addr *mac_addr);
static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
int i40e_logtype_init;
int i40e_logtype_driver;
+#ifdef RTE_LIBRTE_I40E_DEBUG_RX
+int i40e_logtype_rx;
+#endif
+#ifdef RTE_LIBRTE_I40E_DEBUG_TX
+int i40e_logtype_tx;
+#endif
+#ifdef RTE_LIBRTE_I40E_DEBUG_TX_FREE
+int i40e_logtype_tx_free;
+#endif
static const char *const valid_keys[] = {
ETH_I40E_FLOATING_VEB_ARG,
ETH_I40E_SUPPORT_MULTI_DRIVER,
ETH_I40E_QUEUE_NUM_PER_VF_ARG,
ETH_I40E_USE_LATEST_VEC,
+ ETH_I40E_VF_MSG_CFG,
NULL};
static const struct rte_pci_id pci_id_i40e_map[] = {
{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_1G_BASE_T_X722) },
{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_X722) },
{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_I_X722) },
+ { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X710_N3000) },
+ { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_XXV710_N3000) },
+ { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_BC) },
{ .vendor_id = 0, /* sentinel */ },
};
.xstats_get_names = i40e_dev_xstats_get_names,
.stats_reset = i40e_dev_stats_reset,
.xstats_reset = i40e_dev_stats_reset,
- .queue_stats_mapping_set = i40e_dev_queue_stats_mapping_set,
.fw_version_get = i40e_fw_version_get,
.dev_infos_get = i40e_dev_info_get,
.dev_supported_ptypes_get = i40e_dev_supported_ptypes_get,
.filter_ctrl = i40e_dev_filter_ctrl,
.rxq_info_get = i40e_rxq_info_get,
.txq_info_get = i40e_txq_info_get,
+ .rx_burst_mode_get = i40e_rx_burst_mode_get,
+ .tx_burst_mode_get = i40e_tx_burst_mode_get,
.mirror_rule_set = i40e_mirror_rule_set,
.mirror_rule_reset = i40e_mirror_rule_reset,
.timesync_enable = i40e_timesync_enable,
{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
- {"rx_dropped", offsetof(struct i40e_eth_stats, rx_discards)},
+ {"rx_dropped_packets", offsetof(struct i40e_eth_stats, rx_discards)},
{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
rx_unknown_protocol)},
{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)},
{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)},
{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)},
- {"tx_dropped", offsetof(struct i40e_eth_stats, tx_discards)},
+ {"tx_dropped_packets", offsetof(struct i40e_eth_stats, tx_discards)},
};
#define I40E_NB_ETH_XSTATS (sizeof(rte_i40e_stats_strings) / \
ethdev = rte_eth_dev_allocated(pci_dev->device.name);
if (!ethdev)
- return -ENODEV;
-
+ return 0;
if (ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
- return rte_eth_dev_destroy(ethdev, i40e_vf_representor_uninit);
+ return rte_eth_dev_pci_generic_remove(pci_dev,
+ i40e_vf_representor_uninit);
else
- return rte_eth_dev_destroy(ethdev, eth_i40e_dev_uninit);
+ return rte_eth_dev_pci_generic_remove(pci_dev,
+ eth_i40e_dev_uninit);
}
static struct rte_pci_driver rte_i40e_pmd = {
.id_table = pci_id_i40e_map,
- .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
- RTE_PCI_DRV_IOVA_AS_VA,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = eth_i40e_pci_probe,
.remove = eth_i40e_pci_remove,
};
const char *value,
void *opaque)
{
- struct i40e_adapter *ad;
+ struct i40e_adapter *ad = opaque;
int use_latest_vec;
- ad = (struct i40e_adapter *)opaque;
-
use_latest_vec = atoi(value);
if (use_latest_vec != 0 && use_latest_vec != 1)
return 0;
}
+static int
+read_vf_msg_config(__rte_unused const char *key,
+ const char *value,
+ void *opaque)
+{
+ struct i40e_vf_msg_cfg *cfg = opaque;
+
+ if (sscanf(value, "%u@%u:%u", &cfg->max_msg, &cfg->period,
+ &cfg->ignore_second) != 3) {
+ memset(cfg, 0, sizeof(*cfg));
+ PMD_DRV_LOG(ERR, "format error! example: "
+ "%s=60@120:180", ETH_I40E_VF_MSG_CFG);
+ return -EINVAL;
+ }
+
+ /*
+ * If the message validation function been enabled, the 'period'
+ * and 'ignore_second' must greater than 0.
+ */
+ if (cfg->max_msg && (!cfg->period || !cfg->ignore_second)) {
+ memset(cfg, 0, sizeof(*cfg));
+ PMD_DRV_LOG(ERR, "%s error! the second and third"
+ " number must be greater than 0!",
+ ETH_I40E_VF_MSG_CFG);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+i40e_parse_vf_msg_config(struct rte_eth_dev *dev,
+ struct i40e_vf_msg_cfg *msg_cfg)
+{
+ struct rte_kvargs *kvlist;
+ int kvargs_count;
+ int ret = 0;
+
+ memset(msg_cfg, 0, sizeof(*msg_cfg));
+
+ if (!dev->device->devargs)
+ return ret;
+
+ kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
+ if (!kvlist)
+ return -EINVAL;
+
+ kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_VF_MSG_CFG);
+ if (!kvargs_count)
+ goto free_end;
+
+ if (kvargs_count > 1) {
+ PMD_DRV_LOG(ERR, "More than one argument \"%s\"!",
+ ETH_I40E_VF_MSG_CFG);
+ ret = -EINVAL;
+ goto free_end;
+ }
+
+ if (rte_kvargs_process(kvlist, ETH_I40E_VF_MSG_CFG,
+ read_vf_msg_config, msg_cfg) < 0)
+ ret = -EINVAL;
+
+free_end:
+ rte_kvargs_free(kvlist);
+ return ret;
+}
+
#define I40E_ALARM_INTERVAL 50000 /* us */
static int
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_vsi *vsi;
int ret;
- uint32_t len;
+ uint32_t len, val;
uint8_t aq_fail = 0;
PMD_INIT_FUNC_TRACE();
hw->bus.device = pci_dev->addr.devid;
hw->bus.func = pci_dev->addr.function;
hw->adapter_stopped = 0;
+ hw->adapter_closed = 0;
+
+ /* Init switch device pointer */
+ hw->switch_dev = NULL;
/*
* Switch Tag value should not be identical to either the First Tag
*/
hw->switch_tag = 0xffff;
+ val = I40E_READ_REG(hw, I40E_GL_FWSTS);
+ if (val & I40E_GL_FWSTS_FWS1B_MASK) {
+ PMD_INIT_LOG(ERR, "\nERROR: "
+ "Firmware recovery mode detected. Limiting functionality.\n"
+ "Refer to the Intel(R) Ethernet Adapters and Devices "
+ "User Guide for details on firmware recovery mode.");
+ return -EIO;
+ }
+
+ i40e_parse_vf_msg_config(dev, &pf->vf_msg_cfg);
/* Check if need to support multi-driver */
i40e_support_multi_driver(dev);
/* Check if users want the latest supported vec path */
PMD_INIT_LOG(ERR, "Failed to init adminq: %d", ret);
return -EIO;
}
+ /* Firmware of SFP x722 does not support adminq option */
+ if (hw->device_id == I40E_DEV_ID_SFP_X722)
+ hw->flags &= ~I40E_HW_FLAG_802_1AD_CAPABLE;
+
PMD_INIT_LOG(INFO, "FW %d.%d API %d.%d NVM %02d.%02d.%02d eetrack %04x",
hw->aq.fw_maj_ver, hw->aq.fw_min_ver,
hw->aq.api_maj_ver, hw->aq.api_min_ver,
goto err_get_mac_addr;
}
/* Copy the permanent MAC address */
- ether_addr_copy((struct ether_addr *) hw->mac.addr,
- (struct ether_addr *) hw->mac.perm_addr);
+ rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,
+ (struct rte_ether_addr *)hw->mac.perm_addr);
/* Disable flow control */
hw->fc.requested_mode = I40E_FC_NONE;
/* Set the global registers with default ether type value */
if (!pf->support_multi_driver) {
ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER,
- ETHER_TYPE_VLAN);
+ RTE_ETHER_TYPE_VLAN);
if (ret != I40E_SUCCESS) {
PMD_INIT_LOG(ERR,
"Failed to set the default outer "
goto err_setup_pf_switch;
}
- /* reset all stats of the device, including pf and main vsi */
- i40e_dev_stats_reset(dev);
-
vsi = pf->main_vsi;
/* Disable double vlan by default */
}
if (!vsi->max_macaddrs)
- len = ETHER_ADDR_LEN;
+ len = RTE_ETHER_ADDR_LEN;
else
- len = ETHER_ADDR_LEN * vsi->max_macaddrs;
+ len = RTE_ETHER_ADDR_LEN * vsi->max_macaddrs;
/* Should be after VSI initialized */
dev->data->mac_addrs = rte_zmalloc("i40e", len, 0);
"Failed to allocated memory for storing mac address");
goto err_mac_alloc;
}
- ether_addr_copy((struct ether_addr *)hw->mac.perm_addr,
+ rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr,
&dev->data->mac_addrs[0]);
+ /* Pass the information to the rte_eth_dev_close() that it should also
+ * release the private port resources.
+ */
+ dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
+
/* Init dcb to sw mode by default */
ret = i40e_dcb_init_configure(dev, TRUE);
if (ret != I40E_SUCCESS) {
memset(&pf->rss_info, 0,
sizeof(struct i40e_rte_flow_rss_conf));
+ /* reset all stats of the device, including pf and main vsi */
+ i40e_dev_stats_reset(dev);
+
return 0;
err_init_fdir_filter_list:
rte_free(pf->ethertype.hash_map);
err_init_ethtype_filter_list:
rte_free(dev->data->mac_addrs);
+ dev->data->mac_addrs = NULL;
err_mac_alloc:
i40e_vsi_release(pf->main_vsi);
err_setup_pf_switch:
static int
eth_i40e_dev_uninit(struct rte_eth_dev *dev)
{
- struct i40e_pf *pf;
- struct rte_pci_device *pci_dev;
- struct rte_intr_handle *intr_handle;
struct i40e_hw *hw;
- struct i40e_filter_control_settings settings;
- struct rte_flow *p_flow;
- int ret;
- uint8_t aq_fail = 0;
- int retries = 0;
PMD_INIT_FUNC_TRACE();
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
- pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- pci_dev = RTE_ETH_DEV_TO_PCI(dev);
- intr_handle = &pci_dev->intr_handle;
- ret = rte_eth_switch_domain_free(pf->switch_domain_id);
- if (ret)
- PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);
-
- if (hw->adapter_stopped == 0)
+ if (hw->adapter_closed == 0)
i40e_dev_close(dev);
- dev->dev_ops = NULL;
- dev->rx_pkt_burst = NULL;
- dev->tx_pkt_burst = NULL;
-
- /* Clear PXE mode */
- i40e_clear_pxe_mode(hw);
-
- /* Unconfigure filter control */
- memset(&settings, 0, sizeof(settings));
- ret = i40e_set_filter_control(hw, &settings);
- if (ret)
- PMD_INIT_LOG(WARNING, "setup_pf_filter_control failed: %d",
- ret);
-
- /* Disable flow control */
- hw->fc.requested_mode = I40E_FC_NONE;
- i40e_set_fc(hw, &aq_fail, TRUE);
-
- /* uninitialize pf host driver */
- i40e_pf_host_uninit(dev);
-
- /* disable uio intr before callback unregister */
- rte_intr_disable(intr_handle);
-
- /* unregister callback func to eal lib */
- do {
- ret = rte_intr_callback_unregister(intr_handle,
- i40e_dev_interrupt_handler, dev);
- if (ret >= 0) {
- break;
- } else if (ret != -EAGAIN) {
- PMD_INIT_LOG(ERR,
- "intr callback unregister failed: %d",
- ret);
- return ret;
- }
- i40e_msec_delay(500);
- } while (retries++ < 5);
-
- i40e_rm_ethtype_filter_list(pf);
- i40e_rm_tunnel_filter_list(pf);
- i40e_rm_fdir_filter_list(pf);
-
- /* Remove all flows */
- while ((p_flow = TAILQ_FIRST(&pf->flow_list))) {
- TAILQ_REMOVE(&pf->flow_list, p_flow, node);
- rte_free(p_flow);
- }
-
- /* Remove all Traffic Manager configuration */
- i40e_tm_conf_uninit(dev);
-
return 0;
}
ad->tx_simple_allowed = true;
ad->tx_vec_allowed = true;
+ if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
+ dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH;
+
/* Only legacy filter API needs the following fdir config. So when the
* legacy filter API is deprecated, the following codes should also be
* removed.
pf->tm_conf.committed = false;
hw->adapter_stopped = 1;
+
+ pf->adapter->rss_reta_updated = 0;
}
static void
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_mirror_rule *p_mirror;
+ struct i40e_filter_control_settings settings;
+ struct rte_flow *p_flow;
uint32_t reg;
int i;
int ret;
+ uint8_t aq_fail = 0;
+ int retries = 0;
PMD_INIT_FUNC_TRACE();
+ ret = rte_eth_switch_domain_free(pf->switch_domain_id);
+ if (ret)
+ PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);
+
+
i40e_dev_stop(dev);
/* Remove all mirror rules */
I40E_WRITE_REG(hw, I40E_PFGEN_CTRL,
(reg | I40E_PFGEN_CTRL_PFSWR_MASK));
I40E_WRITE_FLUSH(hw);
+
+ dev->dev_ops = NULL;
+ dev->rx_pkt_burst = NULL;
+ dev->tx_pkt_burst = NULL;
+
+ /* Clear PXE mode */
+ i40e_clear_pxe_mode(hw);
+
+ /* Unconfigure filter control */
+ memset(&settings, 0, sizeof(settings));
+ ret = i40e_set_filter_control(hw, &settings);
+ if (ret)
+ PMD_INIT_LOG(WARNING, "setup_pf_filter_control failed: %d",
+ ret);
+
+ /* Disable flow control */
+ hw->fc.requested_mode = I40E_FC_NONE;
+ i40e_set_fc(hw, &aq_fail, TRUE);
+
+ /* uninitialize pf host driver */
+ i40e_pf_host_uninit(dev);
+
+ do {
+ ret = rte_intr_callback_unregister(intr_handle,
+ i40e_dev_interrupt_handler, dev);
+ if (ret >= 0 || ret == -ENOENT) {
+ break;
+ } else if (ret != -EAGAIN) {
+ PMD_INIT_LOG(ERR,
+ "intr callback unregister failed: %d",
+ ret);
+ }
+ i40e_msec_delay(500);
+ } while (retries++ < 5);
+
+ i40e_rm_ethtype_filter_list(pf);
+ i40e_rm_tunnel_filter_list(pf);
+ i40e_rm_fdir_filter_list(pf);
+
+ /* Remove all flows */
+ while ((p_flow = TAILQ_FIRST(&pf->flow_list))) {
+ TAILQ_REMOVE(&pf->flow_list, p_flow, node);
+ rte_free(p_flow);
+ }
+
+ /* Remove all Traffic Manager configuration */
+ i40e_tm_conf_uninit(dev);
+
+ hw->adapter_closed = 1;
}
/*
return ret;
}
-static void
+static int
i40e_dev_promiscuous_enable(struct rte_eth_dev *dev)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
true, NULL, true);
- if (status != I40E_SUCCESS)
+ if (status != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to enable unicast promiscuous");
+ return -EAGAIN;
+ }
status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
TRUE, NULL);
- if (status != I40E_SUCCESS)
+ if (status != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to enable multicast promiscuous");
+ /* Rollback unicast promiscuous mode */
+ i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
+ false, NULL, true);
+ return -EAGAIN;
+ }
+ return 0;
}
-static void
+static int
i40e_dev_promiscuous_disable(struct rte_eth_dev *dev)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
false, NULL, true);
- if (status != I40E_SUCCESS)
+ if (status != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to disable unicast promiscuous");
+ return -EAGAIN;
+ }
/* must remain in all_multicast mode */
if (dev->data->all_multicast == 1)
- return;
+ return 0;
status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
false, NULL);
- if (status != I40E_SUCCESS)
+ if (status != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to disable multicast promiscuous");
+ /* Rollback unicast promiscuous mode */
+ i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
+ true, NULL, true);
+ return -EAGAIN;
+ }
+
+ return 0;
}
-static void
+static int
i40e_dev_allmulticast_enable(struct rte_eth_dev *dev)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
int ret;
ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, TRUE, NULL);
- if (ret != I40E_SUCCESS)
+ if (ret != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to enable multicast promiscuous");
+ return -EAGAIN;
+ }
+
+ return 0;
}
-static void
+static int
i40e_dev_allmulticast_disable(struct rte_eth_dev *dev)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
int ret;
if (dev->data->promiscuous == 1)
- return; /* must remain in all_multicast mode */
+ return 0; /* must remain in all_multicast mode */
ret = i40e_aq_set_vsi_multicast_promiscuous(hw,
vsi->seid, FALSE, NULL);
- if (ret != I40E_SUCCESS)
+ if (ret != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to disable multicast promiscuous");
+ return -EAGAIN;
+ }
+
+ return 0;
}
/*
#define I40E_PRTMAC_MACC 0x001E24E0
#define I40E_REG_MACC_25GB 0x00020000
#define I40E_REG_SPEED_MASK 0x38000000
-#define I40E_REG_SPEED_100MB 0x00000000
-#define I40E_REG_SPEED_1GB 0x08000000
-#define I40E_REG_SPEED_10GB 0x10000000
-#define I40E_REG_SPEED_20GB 0x20000000
-#define I40E_REG_SPEED_25_40GB 0x18000000
+#define I40E_REG_SPEED_0 0x00000000
+#define I40E_REG_SPEED_1 0x08000000
+#define I40E_REG_SPEED_2 0x10000000
+#define I40E_REG_SPEED_3 0x18000000
+#define I40E_REG_SPEED_4 0x20000000
uint32_t link_speed;
uint32_t reg_val;
/* Parse the link status */
switch (link_speed) {
- case I40E_REG_SPEED_100MB:
+ case I40E_REG_SPEED_0:
link->link_speed = ETH_SPEED_NUM_100M;
break;
- case I40E_REG_SPEED_1GB:
+ case I40E_REG_SPEED_1:
link->link_speed = ETH_SPEED_NUM_1G;
break;
- case I40E_REG_SPEED_10GB:
- link->link_speed = ETH_SPEED_NUM_10G;
- break;
- case I40E_REG_SPEED_20GB:
- link->link_speed = ETH_SPEED_NUM_20G;
+ case I40E_REG_SPEED_2:
+ if (hw->mac.type == I40E_MAC_X722)
+ link->link_speed = ETH_SPEED_NUM_2_5G;
+ else
+ link->link_speed = ETH_SPEED_NUM_10G;
break;
- case I40E_REG_SPEED_25_40GB:
- reg_val = I40E_READ_REG(hw, I40E_PRTMAC_MACC);
+ case I40E_REG_SPEED_3:
+ if (hw->mac.type == I40E_MAC_X722) {
+ link->link_speed = ETH_SPEED_NUM_5G;
+ } else {
+ reg_val = I40E_READ_REG(hw, I40E_PRTMAC_MACC);
- if (reg_val & I40E_REG_MACC_25GB)
- link->link_speed = ETH_SPEED_NUM_25G;
+ if (reg_val & I40E_REG_MACC_25GB)
+ link->link_speed = ETH_SPEED_NUM_25G;
+ else
+ link->link_speed = ETH_SPEED_NUM_40G;
+ }
+ break;
+ case I40E_REG_SPEED_4:
+ if (hw->mac.type == I40E_MAC_X722)
+ link->link_speed = ETH_SPEED_NUM_10G;
else
- link->link_speed = ETH_SPEED_NUM_40G;
-
+ link->link_speed = ETH_SPEED_NUM_20G;
break;
default:
PMD_DRV_LOG(ERR, "Unknown link speed info %u", link_speed);
status = i40e_aq_get_link_info(hw, enable_lse,
&link_status, NULL);
if (unlikely(status != I40E_SUCCESS)) {
- link->link_speed = ETH_SPEED_NUM_100M;
+ link->link_speed = ETH_SPEED_NUM_NONE;
link->link_duplex = ETH_LINK_FULL_DUPLEX;
PMD_DRV_LOG(ERR, "Failed to get link info");
return;
link->link_speed = ETH_SPEED_NUM_40G;
break;
default:
- link->link_speed = ETH_SPEED_NUM_100M;
+ link->link_speed = ETH_SPEED_NUM_NONE;
break;
}
}
else
update_link_aq(hw, &link, enable_lse, wait_to_complete);
+ if (hw->switch_dev)
+ rte_eth_linkstatus_get(hw->switch_dev, &link);
+
ret = rte_eth_linkstatus_set(dev, &link);
i40e_notify_all_vfs_link_status(dev);
&nes->rx_broadcast);
/* exclude CRC bytes */
nes->rx_bytes -= (nes->rx_unicast + nes->rx_multicast +
- nes->rx_broadcast) * ETHER_CRC_LEN;
+ nes->rx_broadcast) * RTE_ETHER_CRC_LEN;
i40e_stat_update_32(hw, I40E_GLV_RDPC(idx), vsi->offset_loaded,
&oes->rx_discards, &nes->rx_discards);
/* exclude CRC size */
pf->internal_stats.rx_bytes -= (pf->internal_stats.rx_unicast +
pf->internal_stats.rx_multicast +
- pf->internal_stats.rx_broadcast) * ETHER_CRC_LEN;
+ pf->internal_stats.rx_broadcast) * RTE_ETHER_CRC_LEN;
/* Get statistics of struct i40e_eth_stats */
i40e_stat_update_48(hw, I40E_GLPRT_GORCH(hw->port),
pf->offset_loaded, &os->eth.rx_broadcast,
&ns->eth.rx_broadcast);
/* Workaround: CRC size should not be included in byte statistics,
- * so subtract ETHER_CRC_LEN from the byte counter for each rx packet.
+ * so subtract RTE_ETHER_CRC_LEN from the byte counter for each rx
+ * packet.
*/
ns->eth.rx_bytes -= (ns->eth.rx_unicast + ns->eth.rx_multicast +
- ns->eth.rx_broadcast) * ETHER_CRC_LEN;
+ ns->eth.rx_broadcast) * RTE_ETHER_CRC_LEN;
/* exclude internal rx bytes
* Workaround: it is possible I40E_GLV_GORCH[H/L] is updated before
pf->offset_loaded, &os->eth.tx_broadcast,
&ns->eth.tx_broadcast);
ns->eth.tx_bytes -= (ns->eth.tx_unicast + ns->eth.tx_multicast +
- ns->eth.tx_broadcast) * ETHER_CRC_LEN;
+ ns->eth.tx_broadcast) * RTE_ETHER_CRC_LEN;
/* exclude internal tx bytes
* Workaround: it is possible I40E_GLV_GOTCH[H/L] is updated before
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
+ struct i40e_vsi *vsi;
unsigned i;
/* call read registers - updates values, now write them to struct */
i40e_read_stats_registers(pf, hw);
- stats->ipackets = ns->eth.rx_unicast +
- ns->eth.rx_multicast +
- ns->eth.rx_broadcast -
- ns->eth.rx_discards -
+ stats->ipackets = pf->main_vsi->eth_stats.rx_unicast +
+ pf->main_vsi->eth_stats.rx_multicast +
+ pf->main_vsi->eth_stats.rx_broadcast -
pf->main_vsi->eth_stats.rx_discards;
stats->opackets = ns->eth.tx_unicast +
ns->eth.tx_multicast +
ns->eth.tx_broadcast;
- stats->ibytes = ns->eth.rx_bytes;
+ stats->ibytes = pf->main_vsi->eth_stats.rx_bytes;
stats->obytes = ns->eth.tx_bytes;
stats->oerrors = ns->eth.tx_errors +
pf->main_vsi->eth_stats.tx_errors;
ns->rx_length_errors + ns->rx_undersize +
ns->rx_oversize + ns->rx_fragments + ns->rx_jabber;
+ if (pf->vfs) {
+ for (i = 0; i < pf->vf_num; i++) {
+ vsi = pf->vfs[i].vsi;
+ i40e_update_vsi_stats(vsi);
+
+ stats->ipackets += (vsi->eth_stats.rx_unicast +
+ vsi->eth_stats.rx_multicast +
+ vsi->eth_stats.rx_broadcast -
+ vsi->eth_stats.rx_discards);
+ stats->ibytes += vsi->eth_stats.rx_bytes;
+ stats->oerrors += vsi->eth_stats.tx_errors;
+ stats->imissed += vsi->eth_stats.rx_discards;
+ }
+ }
+
PMD_DRV_LOG(DEBUG, "***************** PF stats start *******************");
PMD_DRV_LOG(DEBUG, "rx_bytes: %"PRIu64"", ns->eth.rx_bytes);
PMD_DRV_LOG(DEBUG, "rx_unicast: %"PRIu64"", ns->eth.rx_unicast);
}
/* Reset the statistics */
-static void
+static int
i40e_dev_stats_reset(struct rte_eth_dev *dev)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
/* read the stats, reading current register values into offset */
i40e_read_stats_registers(pf, hw);
+
+ return 0;
}
static uint32_t
/* Get stats from i40e_eth_stats struct */
for (i = 0; i < I40E_NB_ETH_XSTATS; i++) {
- snprintf(xstats_names[count].name,
- sizeof(xstats_names[count].name),
- "%s", rte_i40e_stats_strings[i].name);
+ strlcpy(xstats_names[count].name,
+ rte_i40e_stats_strings[i].name,
+ sizeof(xstats_names[count].name));
count++;
}
/* Get individiual stats from i40e_hw_port struct */
for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
- snprintf(xstats_names[count].name,
- sizeof(xstats_names[count].name),
- "%s", rte_i40e_hw_port_strings[i].name);
+ strlcpy(xstats_names[count].name,
+ rte_i40e_hw_port_strings[i].name,
+ sizeof(xstats_names[count].name));
count++;
}
return count;
}
-static int
-i40e_dev_queue_stats_mapping_set(__rte_unused struct rte_eth_dev *dev,
- __rte_unused uint16_t queue_id,
- __rte_unused uint8_t stat_idx,
- __rte_unused uint8_t is_rx)
-{
- PMD_INIT_FUNC_TRACE();
-
- return -ENOSYS;
-}
-
static int
i40e_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
{
return 0;
}
-static void
+/*
+ * When using NVM 6.01(for X710 XL710 XXV710)/3.33(for X722) or later,
+ * the Rx data path does not hang if the FW LLDP is stopped.
+ * return true if lldp need to stop
+ * return false if we cannot disable the LLDP to avoid Rx data path blocking.
+ */
+static bool
+i40e_need_stop_lldp(struct rte_eth_dev *dev)
+{
+ double nvm_ver;
+ char ver_str[64] = {0};
+ struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ i40e_fw_version_get(dev, ver_str, 64);
+ nvm_ver = atof(ver_str);
+ if ((hw->mac.type == I40E_MAC_X722 ||
+ hw->mac.type == I40E_MAC_X722_VF) &&
+ ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(3.33 * 1000)))
+ return true;
+ else if ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(6.01 * 1000))
+ return true;
+
+ return false;
+}
+
+static int
i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
dev_info->max_mac_addrs = vsi->max_macaddrs;
dev_info->max_vfs = pci_dev->max_vfs;
+ dev_info->max_mtu = dev_info->max_rx_pktlen - I40E_ETH_OVERHEAD;
+ dev_info->min_mtu = RTE_ETHER_MIN_MTU;
dev_info->rx_queue_offload_capa = 0;
dev_info->rx_offload_capa =
DEV_RX_OFFLOAD_VLAN_STRIP |
DEV_RX_OFFLOAD_SCATTER |
DEV_RX_OFFLOAD_VLAN_EXTEND |
DEV_RX_OFFLOAD_VLAN_FILTER |
- DEV_RX_OFFLOAD_JUMBO_FRAME;
+ DEV_RX_OFFLOAD_JUMBO_FRAME |
+ DEV_RX_OFFLOAD_RSS_HASH;
dev_info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
dev_info->tx_offload_capa =
}
dev_info->default_rxportconf.burst_size = 32;
dev_info->default_txportconf.burst_size = 32;
+
+ return 0;
}
static int
struct i40e_vsi *vsi = pf->main_vsi;
struct rte_eth_rxmode *rxmode;
+ if (mask & ETH_QINQ_STRIP_MASK) {
+ PMD_DRV_LOG(ERR, "Strip qinq is not supported.");
+ return -ENOTSUP;
+ }
+
rxmode = &dev->data->dev_conf.rxmode;
if (mask & ETH_VLAN_FILTER_MASK) {
if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
i40e_vsi_config_double_vlan(vsi, TRUE);
/* Set global registers with default ethertype. */
i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER,
- ETHER_TYPE_VLAN);
+ RTE_ETHER_TYPE_VLAN);
i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER,
- ETHER_TYPE_VLAN);
+ RTE_ETHER_TYPE_VLAN);
}
else
i40e_vsi_config_double_vlan(vsi, FALSE);
/* Add a MAC address, and update filters */
static int
i40e_macaddr_add(struct rte_eth_dev *dev,
- struct ether_addr *mac_addr,
+ struct rte_ether_addr *mac_addr,
__rte_unused uint32_t index,
uint32_t pool)
{
return -EINVAL;
}
- rte_memcpy(&mac_filter.mac_addr, mac_addr, ETHER_ADDR_LEN);
+ rte_memcpy(&mac_filter.mac_addr, mac_addr, RTE_ETHER_ADDR_LEN);
if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
mac_filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
else
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_vsi *vsi;
struct rte_eth_dev_data *data = dev->data;
- struct ether_addr *macaddr;
+ struct rte_ether_addr *macaddr;
int ret;
uint32_t i;
uint64_t pool_sel;
{
struct i40e_hw *hw;
struct i40e_mac_filter_info mac_filter;
- struct ether_addr old_mac;
- struct ether_addr *new_mac;
+ struct rte_ether_addr old_mac;
+ struct rte_ether_addr *new_mac;
struct i40e_pf_vf *vf = NULL;
uint16_t vf_id;
int ret;
new_mac = &filter->mac_addr;
- if (is_zero_ether_addr(new_mac)) {
+ if (rte_is_zero_ether_addr(new_mac)) {
PMD_DRV_LOG(ERR, "Invalid ethernet address.");
return -EINVAL;
}
}
vf = &pf->vfs[vf_id];
- if (add && is_same_ether_addr(new_mac, &(pf->dev_addr))) {
+ if (add && rte_is_same_ether_addr(new_mac, &pf->dev_addr)) {
PMD_DRV_LOG(INFO, "Ignore adding permanent MAC address.");
return -EINVAL;
}
if (add) {
- rte_memcpy(&old_mac, hw->mac.addr, ETHER_ADDR_LEN);
+ rte_memcpy(&old_mac, hw->mac.addr, RTE_ETHER_ADDR_LEN);
rte_memcpy(hw->mac.addr, new_mac->addr_bytes,
- ETHER_ADDR_LEN);
+ RTE_ETHER_ADDR_LEN);
rte_memcpy(&mac_filter.mac_addr, &filter->mac_addr,
- ETHER_ADDR_LEN);
+ RTE_ETHER_ADDR_LEN);
mac_filter.filter_type = filter->filter_type;
ret = i40e_vsi_add_mac(vf->vsi, &mac_filter);
PMD_DRV_LOG(ERR, "Failed to add MAC filter.");
return -1;
}
- ether_addr_copy(new_mac, &pf->dev_addr);
+ rte_ether_addr_copy(new_mac, &pf->dev_addr);
} else {
rte_memcpy(hw->mac.addr, hw->mac.perm_addr,
- ETHER_ADDR_LEN);
+ RTE_ETHER_ADDR_LEN);
ret = i40e_vsi_delete_mac(vf->vsi, &filter->mac_addr);
if (ret != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to delete MAC filter.");
}
/* Clear device address as it has been removed */
- if (is_same_ether_addr(&(pf->dev_addr), new_mac))
- memset(&pf->dev_addr, 0, sizeof(struct ether_addr));
+ if (rte_is_same_ether_addr(&pf->dev_addr, new_mac))
+ memset(&pf->dev_addr, 0, sizeof(struct rte_ether_addr));
}
return 0;
return -EINVAL;
if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
- ret = i40e_aq_get_rss_lut(hw, vsi->vsi_id, TRUE,
+ ret = i40e_aq_get_rss_lut(hw, vsi->vsi_id,
+ vsi->type != I40E_VSI_SRIOV,
lut, lut_size);
if (ret) {
PMD_DRV_LOG(ERR, "Failed to get RSS lookup table");
hw = I40E_VSI_TO_HW(vsi);
if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
- ret = i40e_aq_set_rss_lut(hw, vsi->vsi_id, TRUE,
+ ret = i40e_aq_set_rss_lut(hw, vsi->vsi_id,
+ vsi->type != I40E_VSI_SRIOV,
lut, lut_size);
if (ret) {
PMD_DRV_LOG(ERR, "Failed to set RSS lookup table");
}
ret = i40e_set_rss_lut(pf->main_vsi, lut, reta_size);
+ pf->adapter->rss_reta_updated = 1;
+
out:
rte_free(lut);
ret = i40e_aq_remove_macvlan(hw, vsi->seid, &def_filter, 1, NULL);
if (ret != I40E_SUCCESS) {
struct i40e_mac_filter *f;
- struct ether_addr *mac;
+ struct rte_ether_addr *mac;
PMD_DRV_LOG(DEBUG,
"Cannot remove the default macvlan filter");
return ret;
}
rte_memcpy(&filter.mac_addr,
- (struct ether_addr *)(hw->mac.perm_addr), ETH_ADDR_LEN);
+ (struct rte_ether_addr *)(hw->mac.perm_addr), ETH_ADDR_LEN);
filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
return i40e_vsi_add_mac(vsi, &filter);
}
struct i40e_mac_filter_info filter;
int ret;
struct i40e_vsi_context ctxt;
- struct ether_addr broadcast =
+ struct rte_ether_addr broadcast =
{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
}
/* MAC/VLAN configuration */
- rte_memcpy(&filter.mac_addr, &broadcast, ETHER_ADDR_LEN);
+ rte_memcpy(&filter.mac_addr, &broadcast, RTE_ETHER_ADDR_LEN);
filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
ret = i40e_vsi_add_mac(vsi, &filter);
/* Find out specific MAC filter */
static struct i40e_mac_filter *
i40e_find_mac_filter(struct i40e_vsi *vsi,
- struct ether_addr *macaddr)
+ struct rte_ether_addr *macaddr)
{
struct i40e_mac_filter *f;
TAILQ_FOREACH(f, &vsi->mac_list, next) {
- if (is_same_ether_addr(macaddr, &f->mac_info.mac_addr))
+ if (rte_is_same_ether_addr(macaddr, &f->mac_info.mac_addr))
return f;
}
int
i40e_find_all_vlan_for_mac(struct i40e_vsi *vsi,
struct i40e_macvlan_filter *mv_f,
- int num, struct ether_addr *addr)
+ int num, struct rte_ether_addr *addr)
{
int i;
uint32_t j, k;
int mac_num;
int ret = I40E_SUCCESS;
- if (!vsi || vlan > ETHER_MAX_VLAN_ID)
+ if (!vsi || vlan > RTE_ETHER_MAX_VLAN_ID)
return I40E_ERR_PARAM;
/* If it's already set, just return */
* Vlan 0 is the generic filter for untagged packets
* and can't be removed.
*/
- if (!vsi || vlan == 0 || vlan > ETHER_MAX_VLAN_ID)
+ if (!vsi || vlan == 0 || vlan > RTE_ETHER_MAX_VLAN_ID)
return I40E_ERR_PARAM;
/* If can't find it, just return */
}
int
-i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
+i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct rte_ether_addr *addr)
{
struct i40e_mac_filter *f;
struct i40e_macvlan_filter *mv_f;
int ret;
if (!key || !key_len)
- return -EINVAL;
+ return 0;
if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
ret = i40e_aq_get_rss_key(hw, vsi->vsi_id,
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint64_t hena;
+ int ret;
+
+ if (!rss_conf)
+ return -EINVAL;
- i40e_get_rss_key(pf->main_vsi, rss_conf->rss_key,
+ ret = i40e_get_rss_key(pf->main_vsi, rss_conf->rss_key,
&rss_conf->rss_key_len);
+ if (ret)
+ return ret;
hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
struct i40e_aqc_cloud_filters_element_bb *cld_filter,
struct i40e_tunnel_filter *tunnel_filter)
{
- ether_addr_copy((struct ether_addr *)&cld_filter->element.outer_mac,
- (struct ether_addr *)&tunnel_filter->input.outer_mac);
- ether_addr_copy((struct ether_addr *)&cld_filter->element.inner_mac,
- (struct ether_addr *)&tunnel_filter->input.inner_mac);
+ rte_ether_addr_copy((struct rte_ether_addr *)
+ &cld_filter->element.outer_mac,
+ (struct rte_ether_addr *)&tunnel_filter->input.outer_mac);
+ rte_ether_addr_copy((struct rte_ether_addr *)
+ &cld_filter->element.inner_mac,
+ (struct rte_ether_addr *)&tunnel_filter->input.inner_mac);
tunnel_filter->input.inner_vlan = cld_filter->element.inner_vlan;
if ((rte_le_to_cpu_16(cld_filter->element.flags) &
I40E_AQC_ADD_CLOUD_FLAGS_IPV6) ==
}
pfilter = cld_filter;
- ether_addr_copy(&tunnel_filter->outer_mac,
- (struct ether_addr *)&pfilter->element.outer_mac);
- ether_addr_copy(&tunnel_filter->inner_mac,
- (struct ether_addr *)&pfilter->element.inner_mac);
+ rte_ether_addr_copy(&tunnel_filter->outer_mac,
+ (struct rte_ether_addr *)&pfilter->element.outer_mac);
+ rte_ether_addr_copy(&tunnel_filter->inner_mac,
+ (struct rte_ether_addr *)&pfilter->element.inner_mac);
pfilter->element.inner_vlan =
rte_cpu_to_le_16(tunnel_filter->inner_vlan);
case RTE_TUNNEL_TYPE_IP_IN_GRE:
tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_IP;
break;
+ case RTE_TUNNEL_TYPE_VXLAN_GPE:
+ tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN_GPE;
+ break;
default:
/* Other tunnel types is not supported. */
PMD_DRV_LOG(ERR, "tunnel type is not supported.");
}
pfilter = cld_filter;
- ether_addr_copy(&tunnel_filter->outer_mac,
- (struct ether_addr *)&pfilter->element.outer_mac);
- ether_addr_copy(&tunnel_filter->inner_mac,
- (struct ether_addr *)&pfilter->element.inner_mac);
+ rte_ether_addr_copy(&tunnel_filter->outer_mac,
+ (struct rte_ether_addr *)&pfilter->element.outer_mac);
+ rte_ether_addr_copy(&tunnel_filter->inner_mac,
+ (struct rte_ether_addr *)&pfilter->element.inner_mac);
pfilter->element.inner_vlan =
rte_cpu_to_le_16(tunnel_filter->inner_vlan);
}
static int
-i40e_add_vxlan_port(struct i40e_pf *pf, uint16_t port)
+i40e_add_vxlan_port(struct i40e_pf *pf, uint16_t port, int udp_type)
{
int idx, ret;
- uint8_t filter_idx;
+ uint8_t filter_idx = 0;
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
idx = i40e_get_vxlan_port_idx(pf, port);
return -ENOSPC;
}
- ret = i40e_aq_add_udp_tunnel(hw, port, I40E_AQC_TUNNEL_TYPE_VXLAN,
+ ret = i40e_aq_add_udp_tunnel(hw, port, udp_type,
&filter_idx, NULL);
if (ret < 0) {
PMD_DRV_LOG(ERR, "Failed to add VXLAN UDP port %d", port);
switch (udp_tunnel->prot_type) {
case RTE_TUNNEL_TYPE_VXLAN:
- ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port);
+ ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port,
+ I40E_AQC_TUNNEL_TYPE_VXLAN);
+ break;
+ case RTE_TUNNEL_TYPE_VXLAN_GPE:
+ ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port,
+ I40E_AQC_TUNNEL_TYPE_VXLAN_GPE);
break;
-
case RTE_TUNNEL_TYPE_GENEVE:
case RTE_TUNNEL_TYPE_TEREDO:
PMD_DRV_LOG(ERR, "Tunnel type is not supported now.");
switch (udp_tunnel->prot_type) {
case RTE_TUNNEL_TYPE_VXLAN:
+ case RTE_TUNNEL_TYPE_VXLAN_GPE:
ret = i40e_del_vxlan_port(pf, udp_tunnel->udp_port);
break;
case RTE_TUNNEL_TYPE_GENEVE:
return -ENOTSUP;
}
- for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
- if (j == num)
- j = 0;
- lut = (lut << 8) | (j & ((0x1 <<
- hw->func_caps.rss_table_entry_width) - 1));
- if ((i & 3) == 3)
- I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut);
+ if (pf->adapter->rss_reta_updated == 0) {
+ for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
+ if (j == num)
+ j = 0;
+ lut = (lut << 8) | (j & ((0x1 <<
+ hw->func_caps.rss_table_entry_width) - 1));
+ if ((i & 3) == 3)
+ I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2),
+ rte_bswap32(lut));
+ }
}
rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf;
return -EINVAL;
}
- if (filter->inner_vlan > ETHER_MAX_VLAN_ID) {
+ if (filter->inner_vlan > RTE_ETHER_MAX_VLAN_ID) {
PMD_DRV_LOG(ERR, "Invalid inner VLAN ID");
return -EINVAL;
}
if ((filter->filter_type & ETH_TUNNEL_FILTER_OMAC) &&
- (is_zero_ether_addr(&filter->outer_mac))) {
+ (rte_is_zero_ether_addr(&filter->outer_mac))) {
PMD_DRV_LOG(ERR, "Cannot add NULL outer MAC address");
return -EINVAL;
}
if ((filter->filter_type & ETH_TUNNEL_FILTER_IMAC) &&
- (is_zero_ether_addr(&filter->inner_mac))) {
+ (rte_is_zero_ether_addr(&filter->inner_mac))) {
PMD_DRV_LOG(ERR, "Cannot add NULL inner MAC address");
return -EINVAL;
}
i40e_ethertype_filter_convert(const struct rte_eth_ethertype_filter *input,
struct i40e_ethertype_filter *filter)
{
- rte_memcpy(&filter->input.mac_addr, &input->mac_addr, ETHER_ADDR_LEN);
+ rte_memcpy(&filter->input.mac_addr, &input->mac_addr,
+ RTE_ETHER_ADDR_LEN);
filter->input.ether_type = input->ether_type;
filter->flags = input->flags;
filter->queue = input->queue;
PMD_DRV_LOG(ERR, "Invalid queue ID");
return -EINVAL;
}
- if (filter->ether_type == ETHER_TYPE_IPv4 ||
- filter->ether_type == ETHER_TYPE_IPv6) {
+ if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
+ filter->ether_type == RTE_ETHER_TYPE_IPV6) {
PMD_DRV_LOG(ERR,
"unsupported ether_type(0x%04x) in control packet filter.",
filter->ether_type);
return -EINVAL;
}
- if (filter->ether_type == ETHER_TYPE_VLAN)
+ if (filter->ether_type == RTE_ETHER_TYPE_VLAN)
PMD_DRV_LOG(WARNING,
"filter vlan ether_type in first tag is not supported.");
i40e_start_timecounters(struct rte_eth_dev *dev)
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct i40e_adapter *adapter =
- (struct i40e_adapter *)dev->data->dev_private;
+ struct i40e_adapter *adapter = dev->data->dev_private;
struct rte_eth_link link;
uint32_t tsync_inc_l;
uint32_t tsync_inc_h;
switch (link.link_speed) {
case ETH_SPEED_NUM_40G:
+ case ETH_SPEED_NUM_25G:
tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
break;
static int
i40e_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
{
- struct i40e_adapter *adapter =
- (struct i40e_adapter *)dev->data->dev_private;
+ struct i40e_adapter *adapter = dev->data->dev_private;
adapter->systime_tc.nsec += delta;
adapter->rx_tstamp_tc.nsec += delta;
i40e_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
{
uint64_t ns;
- struct i40e_adapter *adapter =
- (struct i40e_adapter *)dev->data->dev_private;
+ struct i40e_adapter *adapter = dev->data->dev_private;
ns = rte_timespec_to_ns(ts);
i40e_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
{
uint64_t ns, systime_cycles;
- struct i40e_adapter *adapter =
- (struct i40e_adapter *)dev->data->dev_private;
+ struct i40e_adapter *adapter = dev->data->dev_private;
systime_cycles = i40e_read_systime_cyclecounter(dev);
ns = rte_timecounter_update(&adapter->systime_tc, systime_cycles);
struct timespec *timestamp, uint32_t flags)
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct i40e_adapter *adapter =
- (struct i40e_adapter *)dev->data->dev_private;
-
+ struct i40e_adapter *adapter = dev->data->dev_private;
uint32_t sync_status;
uint32_t index = flags & 0x03;
uint64_t rx_tstamp_cycles;
struct timespec *timestamp)
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct i40e_adapter *adapter =
- (struct i40e_adapter *)dev->data->dev_private;
-
+ struct i40e_adapter *adapter = dev->data->dev_private;
uint32_t sync_status;
uint64_t tx_tstamp_cycles;
uint64_t ns;
* LLDP MIB change event.
*/
if (sw_dcb == TRUE) {
- /* When using NVM 6.01 or later, the RX data path does
- * not hang if the FW LLDP is stopped.
- */
- if (((hw->nvm.version >> 12) & 0xf) >= 6 &&
- ((hw->nvm.version >> 4) & 0xff) >= 1) {
+ if (i40e_need_stop_lldp(dev)) {
ret = i40e_aq_stop_lldp(hw, TRUE, NULL);
if (ret != I40E_SUCCESS)
PMD_INIT_LOG(DEBUG, "Failed to stop lldp");
I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
I40E_WRITE_FLUSH(hw);
- rte_intr_enable(&pci_dev->intr_handle);
+ rte_intr_ack(&pci_dev->intr_handle);
return 0;
}
return 0;
}
+/**
+ * This function is used to check if the register is valid.
+ * Below is the valid registers list for X722 only:
+ * 0x2b800--0x2bb00
+ * 0x38700--0x38a00
+ * 0x3d800--0x3db00
+ * 0x208e00--0x209000
+ * 0x20be00--0x20c000
+ * 0x263c00--0x264000
+ * 0x265c00--0x266000
+ */
+static inline int i40e_valid_regs(enum i40e_mac_type type, uint32_t reg_offset)
+{
+ if ((type != I40E_MAC_X722) &&
+ ((reg_offset >= 0x2b800 && reg_offset <= 0x2bb00) ||
+ (reg_offset >= 0x38700 && reg_offset <= 0x38a00) ||
+ (reg_offset >= 0x3d800 && reg_offset <= 0x3db00) ||
+ (reg_offset >= 0x208e00 && reg_offset <= 0x209000) ||
+ (reg_offset >= 0x20be00 && reg_offset <= 0x20c000) ||
+ (reg_offset >= 0x263c00 && reg_offset <= 0x264000) ||
+ (reg_offset >= 0x265c00 && reg_offset <= 0x266000)))
+ return 0;
+ else
+ return 1;
+}
+
static int i40e_get_regs(struct rte_eth_dev *dev,
struct rte_dev_reg_info *regs)
{
reg_offset = arr_idx * reg_info->stride1 +
arr_idx2 * reg_info->stride2;
reg_offset += reg_info->base_addr;
- ptr_data[reg_offset >> 2] =
- I40E_READ_REG(hw, reg_offset);
+ if (!i40e_valid_regs(hw->mac.type, reg_offset))
+ ptr_data[reg_offset >> 2] = 0;
+ else
+ ptr_data[reg_offset >> 2] =
+ I40E_READ_REG(hw, reg_offset);
}
}
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
bool is_sfp = false;
i40e_status status;
- uint8_t *data = info->data;
+ uint8_t *data;
uint32_t value = 0;
uint32_t i;
- if (!info || !info->length || !data)
+ if (!info || !info->length || !info->data)
return -EINVAL;
if (hw->phy.link_info.module_type[0] == I40E_MODULE_TYPE_SFP)
is_sfp = true;
+ data = info->data;
for (i = 0; i < info->length; i++) {
u32 offset = i + info->offset;
u32 addr = is_sfp ? I40E_I2C_EEPROM_DEV_ADDR : 0;
}
static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
- struct ether_addr *mac_addr)
+ struct rte_ether_addr *mac_addr)
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_mac_filter *f;
int ret;
- if (!is_valid_assigned_ether_addr(mac_addr)) {
+ if (!rte_is_valid_assigned_ether_addr(mac_addr)) {
PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
return -EINVAL;
}
TAILQ_FOREACH(f, &vsi->mac_list, next) {
- if (is_same_ether_addr(&pf->dev_addr, &f->mac_info.mac_addr))
+ if (rte_is_same_ether_addr(&pf->dev_addr,
+ &f->mac_info.mac_addr))
break;
}
int ret = 0;
/* check if mtu is within the allowed range */
- if ((mtu < ETHER_MIN_MTU) || (frame_size > I40E_FRAME_SIZE_MAX))
+ if (mtu < RTE_ETHER_MIN_MTU || frame_size > I40E_FRAME_SIZE_MAX)
return -EINVAL;
/* mtu setting is forbidden if port is start */
return -EBUSY;
}
- if (frame_size > ETHER_MAX_LEN)
+ if (frame_size > RTE_ETHER_MAX_LEN)
dev_data->dev_conf.rxmode.offloads |=
DEV_RX_OFFLOAD_JUMBO_FRAME;
else
vsi = vf->vsi;
}
memset(&cld_filter, 0, sizeof(cld_filter));
- ether_addr_copy((struct ether_addr *)&f->input.outer_mac,
- (struct ether_addr *)&cld_filter.element.outer_mac);
- ether_addr_copy((struct ether_addr *)&f->input.inner_mac,
- (struct ether_addr *)&cld_filter.element.inner_mac);
+ rte_ether_addr_copy((struct rte_ether_addr *)
+ &f->input.outer_mac,
+ (struct rte_ether_addr *)&cld_filter.element.outer_mac);
+ rte_ether_addr_copy((struct rte_ether_addr *)
+ &f->input.inner_mac,
+ (struct rte_ether_addr *)&cld_filter.element.inner_mac);
cld_filter.element.inner_vlan = f->input.inner_vlan;
cld_filter.element.flags = f->input.flags;
cld_filter.element.tenant_id = f->input.tenant_id;
i40e_rss_filter_restore(pf);
}
-static bool
+bool
is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
{
if (strcmp(dev->device->driver->name, drv->driver.name))
for (n = 0; n < proto_num; n++) {
if (proto[n].proto_id != proto_id)
continue;
- strcat(name, proto[n].name);
- strcat(name, "_");
+ strlcat(name, proto[n].name, sizeof(name));
+ strlcat(name, "_", sizeof(name));
break;
}
}
return -EINVAL;
if (!in->key && in->key_len)
return -EINVAL;
- if (in->key)
- out->conf.key = memcpy(out->key, in->key, in->key_len);
out->conf = (struct rte_flow_action_rss){
.func = in->func,
.level = in->level,
.queue = memcpy(out->queue, in->queue,
sizeof(*in->queue) * in->queue_num),
};
+ if (in->key)
+ out->conf.key = memcpy(out->key, in->key, in->key_len);
return 0;
}
return -EINVAL;
}
- if (rss_info->conf.queue_num)
- return -EINVAL;
-
/* If both VMDQ and RSS enabled, not all of PF queues are configured.
* It's necessary to calculate the actual PF queues that are configured.
*/
rss_conf.rss_key = (uint8_t *)rss_key_default;
rss_conf.rss_key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
sizeof(uint32_t);
+ PMD_DRV_LOG(INFO,
+ "No valid RSS key config for i40e, using default\n");
}
i40e_hw_rss_hash_set(pf, &rss_conf);
i40e_logtype_driver = rte_log_register("pmd.net.i40e.driver");
if (i40e_logtype_driver >= 0)
rte_log_set_level(i40e_logtype_driver, RTE_LOG_NOTICE);
+
+#ifdef RTE_LIBRTE_I40E_DEBUG_RX
+ i40e_logtype_rx = rte_log_register("pmd.net.i40e.rx");
+ if (i40e_logtype_rx >= 0)
+ rte_log_set_level(i40e_logtype_rx, RTE_LOG_DEBUG);
+#endif
+
+#ifdef RTE_LIBRTE_I40E_DEBUG_TX
+ i40e_logtype_tx = rte_log_register("pmd.net.i40e.tx");
+ if (i40e_logtype_tx >= 0)
+ rte_log_set_level(i40e_logtype_tx, RTE_LOG_DEBUG);
+#endif
+
+#ifdef RTE_LIBRTE_I40E_DEBUG_TX_FREE
+ i40e_logtype_tx_free = rte_log_register("pmd.net.i40e.tx_free");
+ if (i40e_logtype_tx_free >= 0)
+ rte_log_set_level(i40e_logtype_tx_free, RTE_LOG_DEBUG);
+#endif
}
RTE_PMD_REGISTER_PARAM_STRING(net_i40e,