#include <rte_pci.h>
#include <rte_bus_pci.h>
#include <rte_ether.h>
-#include <rte_ethdev_driver.h>
-#include <rte_ethdev_pci.h>
+#include <ethdev_driver.h>
+#include <ethdev_pci.h>
#include <rte_memzone.h>
#include <rte_malloc.h>
#include <rte_memcpy.h>
#include <rte_tailq.h>
#include <rte_hash_crc.h>
#include <rte_bitmap.h>
+#include <rte_os_shim.h>
#include "i40e_logs.h"
#include "base/i40e_prototype.h"
#define ETH_I40E_FLOATING_VEB_LIST_ARG "floating_veb_list"
#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
#define I40E_TRANSLATE_INSET 0
#define I40E_TRANSLATE_REG 1
-#define I40E_INSET_IPV4_TOS_MASK 0x0009FF00UL
-#define I40E_INSET_IPv4_TTL_MASK 0x000D00FFUL
-#define I40E_INSET_IPV4_PROTO_MASK 0x000DFF00UL
-#define I40E_INSET_IPV6_TC_MASK 0x0009F00FUL
-#define I40E_INSET_IPV6_HOP_LIMIT_MASK 0x000CFF00UL
-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
+#define I40E_INSET_IPV4_TOS_MASK 0x0000FF00UL
+#define I40E_INSET_IPV4_TTL_MASK 0x000000FFUL
+#define I40E_INSET_IPV4_PROTO_MASK 0x0000FF00UL
+#define I40E_INSET_IPV6_TC_MASK 0x0000F00FUL
+#define I40E_INSET_IPV6_HOP_LIMIT_MASK 0x0000FF00UL
+#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000000FFUL
/* PCI offset for querying capability */
#define PCI_DEV_CAP_REG 0xA4
/* Bit mask of Extended Tag enable/disable */
#define PCI_DEV_CTRL_EXT_TAG_MASK (1 << PCI_DEV_CTRL_EXT_TAG_SHIFT)
+#define I40E_GLQF_PIT_IPV4_START 2
+#define I40E_GLQF_PIT_IPV4_COUNT 2
+#define I40E_GLQF_PIT_IPV6_START 4
+#define I40E_GLQF_PIT_IPV6_COUNT 2
+
+#define I40E_GLQF_PIT_SOURCE_OFF_GET(a) \
+ (((a) & I40E_GLQF_PIT_SOURCE_OFF_MASK) >> \
+ I40E_GLQF_PIT_SOURCE_OFF_SHIFT)
+
+#define I40E_GLQF_PIT_DEST_OFF_GET(a) \
+ (((a) & I40E_GLQF_PIT_DEST_OFF_MASK) >> \
+ I40E_GLQF_PIT_DEST_OFF_SHIFT)
+
+#define I40E_GLQF_PIT_FSIZE_GET(a) (((a) & I40E_GLQF_PIT_FSIZE_MASK) >> \
+ I40E_GLQF_PIT_FSIZE_SHIFT)
+
+#define I40E_GLQF_PIT_BUILD(off, mask) (((off) << 16) | (mask))
+#define I40E_FDIR_FIELD_OFFSET(a) ((a) >> 1)
+
static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev, void *init_params);
static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
static int i40e_dev_configure(struct rte_eth_dev *dev);
static int i40e_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
struct rte_eth_udp_tunnel *udp_tunnel);
static void i40e_filter_input_set_init(struct i40e_pf *pf);
-static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
- enum rte_filter_type filter_type,
- enum rte_filter_op filter_op,
- void *arg);
+static int i40e_dev_flow_ops_get(struct rte_eth_dev *dev,
+ const struct rte_flow_ops **ops);
static int i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
struct rte_eth_dcb_info *dcb_info);
static int i40e_dev_sync_phy_type(struct i40e_hw *hw);
static void i40e_configure_registers(struct i40e_hw *hw);
static void i40e_hw_init(struct rte_eth_dev *dev);
static int i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi);
-static enum i40e_status_code i40e_aq_del_mirror_rule(struct i40e_hw *hw,
- uint16_t seid,
- uint16_t rule_type,
- uint16_t *entries,
- uint16_t count,
- uint16_t rule_id);
-static int i40e_mirror_rule_set(struct rte_eth_dev *dev,
- struct rte_eth_mirror_conf *mirror_conf,
- uint8_t sw_id, uint8_t on);
-static int i40e_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t sw_id);
static int i40e_timesync_enable(struct rte_eth_dev *dev);
static int i40e_timesync_disable(struct rte_eth_dev *dev);
ETH_I40E_FLOATING_VEB_LIST_ARG,
ETH_I40E_SUPPORT_MULTI_DRIVER,
ETH_I40E_QUEUE_NUM_PER_VF_ARG,
- ETH_I40E_USE_LATEST_VEC,
ETH_I40E_VF_MSG_CFG,
NULL};
.rss_hash_conf_get = i40e_dev_rss_hash_conf_get,
.udp_tunnel_port_add = i40e_dev_udp_tunnel_port_add,
.udp_tunnel_port_del = i40e_dev_udp_tunnel_port_del,
- .filter_ctrl = i40e_dev_filter_ctrl,
+ .flow_ops_get = i40e_dev_flow_ops_get,
.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,
.timesync_disable = i40e_timesync_disable,
.timesync_read_rx_timestamp = i40e_timesync_read_rx_timestamp,
return retval;
}
+ if (eth_da.nb_representor_ports > 0 &&
+ eth_da.type != RTE_ETH_REPRESENTOR_VF) {
+ PMD_DRV_LOG(ERR, "unsupported representor type: %s\n",
+ pci_dev->device.devargs->args);
+ return -ENOTSUP;
+ }
+
retval = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
sizeof(struct i40e_adapter),
eth_dev_pci_specific_init, pci_dev,
uint32_t reg_val)
{
uint32_t ori_reg_val;
- struct rte_eth_dev *dev;
+ struct rte_eth_dev_data *dev_data =
+ ((struct i40e_adapter *)hw->back)->pf.dev_data;
+ struct rte_eth_dev *dev = &rte_eth_devices[dev_data->port_id];
ori_reg_val = i40e_read_rx_ctl(hw, reg_addr);
- dev = ((struct i40e_adapter *)hw->back)->eth_dev;
i40e_write_rx_ctl(hw, reg_addr, reg_val);
if (ori_reg_val != reg_val)
PMD_DRV_LOG(WARNING,
idx = strtoul(floating_veb_value, &end, 10);
if (errno || end == NULL)
return -1;
+ if (idx < 0)
+ return -1;
while (isblank(*end))
end++;
if (*end == '-') {
char fdir_hash_name[RTE_HASH_NAMESIZE];
uint32_t alloc = hw->func_caps.fd_filters_guaranteed;
uint32_t best = hw->func_caps.fd_filters_best_effort;
+ enum i40e_filter_pctype pctype;
struct rte_bitmap *bmp = NULL;
uint32_t bmp_size;
void *mem = NULL;
goto err_fdir_filter_array_alloc;
}
+ for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+ pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++)
+ pf->fdir.flow_count[pctype] = 0;
+
fdir_info->fdir_space_size = alloc + best;
fdir_info->fdir_actual_cnt = 0;
fdir_info->fdir_guarantee_total_space = alloc;
struct i40e_asq_cmd_details *cmd_details)
{
uint64_t ori_reg_val;
- struct rte_eth_dev *dev;
+ struct rte_eth_dev_data *dev_data =
+ ((struct i40e_adapter *)hw->back)->pf.dev_data;
+ struct rte_eth_dev *dev = &rte_eth_devices[dev_data->port_id];
int ret;
ret = i40e_aq_debug_read_register(hw, reg_addr, &ori_reg_val, NULL);
reg_addr);
return -EIO;
}
- dev = ((struct i40e_adapter *)hw->back)->eth_dev;
if (ori_reg_val != reg_val)
PMD_DRV_LOG(WARNING,
return i40e_aq_debug_write_register(hw, reg_addr, reg_val, cmd_details);
}
-static int
-i40e_parse_latest_vec_handler(__rte_unused const char *key,
- const char *value,
- void *opaque)
-{
- struct i40e_adapter *ad = opaque;
- int use_latest_vec;
-
- use_latest_vec = atoi(value);
-
- if (use_latest_vec != 0 && use_latest_vec != 1)
- PMD_DRV_LOG(WARNING, "Value should be 0 or 1, set it as 1!");
-
- ad->use_latest_vec = (uint8_t)use_latest_vec;
-
- return 0;
-}
-
-static int
-i40e_use_latest_vec(struct rte_eth_dev *dev)
-{
- struct i40e_adapter *ad =
- I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
- struct rte_kvargs *kvlist;
- int kvargs_count;
-
- ad->use_latest_vec = false;
-
- if (!dev->device->devargs)
- return 0;
-
- kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
- if (!kvlist)
- return -EINVAL;
-
- kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_USE_LATEST_VEC);
- if (!kvargs_count) {
- rte_kvargs_free(kvlist);
- return 0;
- }
-
- if (kvargs_count > 1)
- PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
- "the first invalid or last valid one is used !",
- ETH_I40E_USE_LATEST_VEC);
-
- if (rte_kvargs_process(kvlist, ETH_I40E_USE_LATEST_VEC,
- i40e_parse_latest_vec_handler, ad) < 0) {
- rte_kvargs_free(kvlist);
- return -EINVAL;
- }
-
- rte_kvargs_free(kvlist);
- return 0;
-}
-
static int
read_vf_msg_config(__rte_unused const char *key,
const char *value,
dev->dev_ops = &i40e_eth_dev_ops;
dev->rx_queue_count = i40e_dev_rx_queue_count;
- dev->rx_descriptor_done = i40e_dev_rx_descriptor_done;
dev->rx_descriptor_status = i40e_dev_rx_descriptor_status;
dev->tx_descriptor_status = i40e_dev_tx_descriptor_status;
dev->rx_pkt_burst = i40e_recv_pkts;
dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
pf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
- pf->adapter->eth_dev = dev;
pf->dev_data = dev->data;
hw->back = I40E_PF_TO_ADAPTER(pf);
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 */
- i40e_use_latest_vec(dev);
/* Make sure all is clean before doing PF reset */
i40e_clear_hw(hw);
*/
i40e_aq_set_mac_config(hw, I40E_FRAME_SIZE_MAX, TRUE, false, 0, NULL);
- /* initialize mirror rule list */
- TAILQ_INIT(&pf->mirror_list);
-
/* initialize RSS rule list */
TAILQ_INIT(&pf->rss_config_list);
return 0;
err_init_fdir_filter_list:
- rte_free(pf->tunnel.hash_table);
+ rte_hash_free(pf->tunnel.hash_table);
rte_free(pf->tunnel.hash_map);
err_init_tunnel_filter_list:
- rte_free(pf->ethertype.hash_table);
+ rte_hash_free(pf->ethertype.hash_table);
rte_free(pf->ethertype.hash_map);
err_init_ethtype_filter_list:
+ rte_intr_callback_unregister(intr_handle,
+ i40e_dev_interrupt_handler, dev);
rte_free(dev->data->mac_addrs);
dev->data->mac_addrs = NULL;
err_mac_alloc:
void
i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi)
{
- struct rte_eth_dev *dev = vsi->adapter->eth_dev;
+ struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(vsi);
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
int
i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx)
{
- struct rte_eth_dev *dev = vsi->adapter->eth_dev;
+ struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(vsi);
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
void
i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi)
{
- struct rte_eth_dev *dev = vsi->adapter->eth_dev;
+ struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(vsi);
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
void
i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
{
- struct rte_eth_dev *dev = vsi->adapter->eth_dev;
+ struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(vsi);
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
phy_conf.phy_type = is_up ? cpu_to_le32(phy_type_mask) : 0;
phy_conf.phy_type_ext = is_up ? (I40E_AQ_PHY_TYPE_EXT_25G_KR |
I40E_AQ_PHY_TYPE_EXT_25G_CR | I40E_AQ_PHY_TYPE_EXT_25G_SR |
- I40E_AQ_PHY_TYPE_EXT_25G_LR) : 0;
+ I40E_AQ_PHY_TYPE_EXT_25G_LR | I40E_AQ_PHY_TYPE_EXT_25G_AOC |
+ I40E_AQ_PHY_TYPE_EXT_25G_ACC) : 0;
phy_conf.fec_config = phy_ab.fec_cfg_curr_mod_ext_info;
phy_conf.eee_capability = phy_ab.eee_capability;
phy_conf.eeer = phy_ab.eeer_val;
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
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;
ret = i40e_dev_stop(dev);
- /* Remove all mirror rules */
- while ((p_mirror = TAILQ_FIRST(&pf->mirror_list))) {
- ret = i40e_aq_del_mirror_rule(hw,
- pf->main_vsi->veb->seid,
- p_mirror->rule_type,
- p_mirror->entries,
- p_mirror->num_entries,
- p_mirror->id);
- if (ret < 0)
- PMD_DRV_LOG(ERR, "failed to remove mirror rule: "
- "status = %d, aq_err = %d.", ret,
- hw->aq.asq_last_status);
-
- /* remove mirror software resource anyway */
- TAILQ_REMOVE(&pf->mirror_list, p_mirror, rules);
- rte_free(p_mirror);
- pf->nb_mirror_rule--;
- }
-
i40e_dev_free_queues(dev);
/* Disable interrupt */
((hw->nvm.version >> 4) & 0xff),
(hw->nvm.version & 0xf), hw->nvm.eetrack,
ver, build, patch);
+ if (ret < 0)
+ return -EINVAL;
ret += 1; /* add the size of '\0' */
- if (fw_size < (u32)ret)
+ if (fw_size < (size_t)ret)
return ret;
else
return 0;
u64 size,
u32 alignment)
{
+ static uint64_t i40e_dma_memzone_id;
const struct rte_memzone *mz = NULL;
char z_name[RTE_MEMZONE_NAMESIZE];
if (!mem)
return I40E_ERR_PARAM;
- snprintf(z_name, sizeof(z_name), "i40e_dma_%"PRIu64, rte_rand());
+ snprintf(z_name, sizeof(z_name), "i40e_dma_%" PRIu64,
+ __atomic_fetch_add(&i40e_dma_memzone_id, 1, __ATOMIC_RELAXED));
mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY,
RTE_MEMZONE_IOVA_CONTIG, alignment, RTE_PGSIZE_2M);
if (!mz)
/* VSI has child to attach, release child first */
if (vsi->veb) {
- TAILQ_FOREACH_SAFE(vsi_list, &vsi->veb->head, list, temp) {
+ RTE_TAILQ_FOREACH_SAFE(vsi_list, &vsi->veb->head, list, temp) {
if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
return -1;
}
}
if (vsi->floating_veb) {
- TAILQ_FOREACH_SAFE(vsi_list, &vsi->floating_veb->head, list, temp) {
+ RTE_TAILQ_FOREACH_SAFE(vsi_list, &vsi->floating_veb->head,
+ list, temp) {
if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
return -1;
}
/* Remove all macvlan filters of the VSI */
i40e_vsi_remove_all_macvlan_filter(vsi);
- TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp)
+ RTE_TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp)
rte_free(f);
if (vsi->type != I40E_VSI_MAIN &&
i = 0;
/* Remove all existing mac */
- TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) {
+ RTE_TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) {
mac_filter[i] = f->mac_info;
ret = i40e_vsi_delete_mac(vsi, &f->mac_info.mac_addr);
if (ret) {
break;
}
if (ret == I40E_SUCCESS)
- i40e_set_tx_function(container_of(pf, struct i40e_adapter, pf)
- ->eth_dev);
+ i40e_set_tx_function(&rte_eth_devices[pf->dev_data->port_id]);
return ret;
}
}
}
if (ret == I40E_SUCCESS)
- i40e_set_rx_function(container_of(pf, struct i40e_adapter, pf)
- ->eth_dev);
+ i40e_set_rx_function(&rte_eth_devices[pf->dev_data->port_id]);
return ret;
}
struct i40e_aqc_replace_cloud_filters_cmd filter_replace;
struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf;
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
+ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
enum i40e_status_code status = I40E_SUCCESS;
if (pf->support_multi_driver) {
struct i40e_aqc_replace_cloud_filters_cmd filter_replace;
struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf;
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
+ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
enum i40e_status_code status = I40E_SUCCESS;
if (pf->support_multi_driver) {
struct i40e_aqc_replace_cloud_filters_cmd filter_replace;
struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf;
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
+ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
enum i40e_status_code status = I40E_SUCCESS;
if (pf->support_multi_driver) {
struct i40e_aqc_replace_cloud_filters_cmd filter_replace;
struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf;
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
+ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
enum i40e_status_code status = I40E_SUCCESS;
if (pf->support_multi_driver) {
struct i40e_aqc_replace_cloud_filters_cmd filter_replace;
enum i40e_status_code status = I40E_SUCCESS;
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
+ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
if (pf->support_multi_driver) {
PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
struct i40e_aqc_replace_cloud_filters_cmd filter_replace;
enum i40e_status_code status = I40E_SUCCESS;
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
+ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
if (pf->support_multi_driver) {
PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
return val;
}
+static int
+i40e_get_inset_field_offset(struct i40e_hw *hw, uint32_t pit_reg_start,
+ uint32_t pit_reg_count, uint32_t hdr_off)
+{
+ const uint32_t pit_reg_end = pit_reg_start + pit_reg_count;
+ uint32_t field_off = I40E_FDIR_FIELD_OFFSET(hdr_off);
+ uint32_t i, reg_val, src_off, count;
+
+ for (i = pit_reg_start; i < pit_reg_end; i++) {
+ reg_val = i40e_read_rx_ctl(hw, I40E_GLQF_PIT(i));
+
+ src_off = I40E_GLQF_PIT_SOURCE_OFF_GET(reg_val);
+ count = I40E_GLQF_PIT_FSIZE_GET(reg_val);
+
+ if (src_off <= field_off && (src_off + count) > field_off)
+ break;
+ }
+
+ if (i >= pit_reg_end) {
+ PMD_DRV_LOG(ERR,
+ "Hardware GLQF_PIT configuration does not support this field mask");
+ return -1;
+ }
+
+ return I40E_GLQF_PIT_DEST_OFF_GET(reg_val) + field_off - src_off;
+}
+
int
-i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
+i40e_generate_inset_mask_reg(struct i40e_hw *hw, uint64_t inset,
+ uint32_t *mask, uint8_t nb_elem)
{
- uint8_t i, idx = 0;
- uint64_t inset_need_mask = inset;
+ static const uint64_t mask_inset[] = {
+ I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL,
+ I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT };
static const struct {
uint64_t inset;
uint32_t mask;
- } inset_mask_map[] = {
- {I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK},
- {I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0},
- {I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK},
- {I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK},
- {I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK},
- {I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0},
- {I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK},
- {I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK},
+ uint32_t offset;
+ } inset_mask_offset_map[] = {
+ { I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK,
+ offsetof(struct rte_ipv4_hdr, type_of_service) },
+
+ { I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK,
+ offsetof(struct rte_ipv4_hdr, next_proto_id) },
+
+ { I40E_INSET_IPV4_TTL, I40E_INSET_IPV4_TTL_MASK,
+ offsetof(struct rte_ipv4_hdr, time_to_live) },
+
+ { I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK,
+ offsetof(struct rte_ipv6_hdr, vtc_flow) },
+
+ { I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK,
+ offsetof(struct rte_ipv6_hdr, proto) },
+
+ { I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK,
+ offsetof(struct rte_ipv6_hdr, hop_limits) },
};
- if (!inset || !mask || !nb_elem)
+ uint32_t i;
+ int idx = 0;
+
+ assert(mask);
+ if (!inset)
return 0;
- for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
+ for (i = 0; i < RTE_DIM(mask_inset); i++) {
/* Clear the inset bit, if no MASK is required,
* for example proto + ttl
*/
- if ((inset & inset_mask_map[i].inset) ==
- inset_mask_map[i].inset && inset_mask_map[i].mask == 0)
- inset_need_mask &= ~inset_mask_map[i].inset;
- if (!inset_need_mask)
- return 0;
- }
- for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
- if ((inset_need_mask & inset_mask_map[i].inset) ==
- inset_mask_map[i].inset) {
- if (idx >= nb_elem) {
- PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
- return -EINVAL;
- }
- mask[idx] = inset_mask_map[i].mask;
- idx++;
+ if ((mask_inset[i] & inset) == mask_inset[i]) {
+ inset &= ~mask_inset[i];
+ if (!inset)
+ return 0;
+ }
+ }
+
+ for (i = 0; i < RTE_DIM(inset_mask_offset_map); i++) {
+ uint32_t pit_start, pit_count;
+ int offset;
+
+ if (!(inset_mask_offset_map[i].inset & inset))
+ continue;
+
+ if (inset_mask_offset_map[i].inset &
+ (I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+ I40E_INSET_IPV4_TTL)) {
+ pit_start = I40E_GLQF_PIT_IPV4_START;
+ pit_count = I40E_GLQF_PIT_IPV4_COUNT;
+ } else {
+ pit_start = I40E_GLQF_PIT_IPV6_START;
+ pit_count = I40E_GLQF_PIT_IPV6_COUNT;
}
+
+ offset = i40e_get_inset_field_offset(hw, pit_start, pit_count,
+ inset_mask_offset_map[i].offset);
+
+ if (offset < 0)
+ return -EINVAL;
+
+ if (idx >= nb_elem) {
+ PMD_DRV_LOG(ERR,
+ "Configuration of inset mask out of range %u",
+ nb_elem);
+ return -ERANGE;
+ }
+
+ mask[idx] = I40E_GLQF_PIT_BUILD((uint32_t)offset,
+ inset_mask_offset_map[i].mask);
+ idx++;
}
return idx;
i40e_check_write_global_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
{
uint32_t reg = i40e_read_rx_ctl(hw, addr);
- struct rte_eth_dev *dev;
+ struct rte_eth_dev_data *dev_data =
+ ((struct i40e_adapter *)hw->back)->pf.dev_data;
+ struct rte_eth_dev *dev = &rte_eth_devices[dev_data->port_id];
- dev = ((struct i40e_adapter *)hw->back)->eth_dev;
if (reg != val) {
i40e_write_rx_ctl(hw, addr, val);
PMD_DRV_LOG(WARNING,
input_set = i40e_get_default_input_set(pctype);
- num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+ num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg,
I40E_INSET_MASK_NUM_REG);
if (num < 0)
return;
inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
input_set |= pf->hash_input_set[pctype];
}
- num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+ num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg,
I40E_INSET_MASK_NUM_REG);
if (num < 0)
return -EINVAL;
}
static int
-i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
- enum rte_filter_type filter_type,
- enum rte_filter_op filter_op,
- void *arg)
+i40e_dev_flow_ops_get(struct rte_eth_dev *dev,
+ const struct rte_flow_ops **ops)
{
- int ret = 0;
-
if (dev == NULL)
return -EINVAL;
- switch (filter_type) {
- case RTE_ETH_FILTER_GENERIC:
- if (filter_op != RTE_ETH_FILTER_GET)
- return -EINVAL;
- *(const void **)arg = &i40e_flow_ops;
- break;
- default:
- PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
- filter_type);
- ret = -EINVAL;
- break;
- }
-
- return ret;
+ *ops = &i40e_flow_ops;
+ return 0;
}
/*
return 0;
}
-/**
- * i40e_aq_add_mirror_rule
- * @hw: pointer to the hardware structure
- * @seid: VEB seid to add mirror rule to
- * @dst_id: destination vsi seid
- * @entries: Buffer which contains the entities to be mirrored
- * @count: number of entities contained in the buffer
- * @rule_id:the rule_id of the rule to be added
- *
- * Add a mirror rule for a given veb.
- *
- **/
-static enum i40e_status_code
-i40e_aq_add_mirror_rule(struct i40e_hw *hw,
- uint16_t seid, uint16_t dst_id,
- uint16_t rule_type, uint16_t *entries,
- uint16_t count, uint16_t *rule_id)
-{
- struct i40e_aq_desc desc;
- struct i40e_aqc_add_delete_mirror_rule cmd;
- struct i40e_aqc_add_delete_mirror_rule_completion *resp =
- (struct i40e_aqc_add_delete_mirror_rule_completion *)
- &desc.params.raw;
- uint16_t buff_len;
- enum i40e_status_code status;
-
- i40e_fill_default_direct_cmd_desc(&desc,
- i40e_aqc_opc_add_mirror_rule);
- memset(&cmd, 0, sizeof(cmd));
-
- buff_len = sizeof(uint16_t) * count;
- desc.datalen = rte_cpu_to_le_16(buff_len);
- if (buff_len > 0)
- desc.flags |= rte_cpu_to_le_16(
- (uint16_t)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
- cmd.rule_type = rte_cpu_to_le_16(rule_type <<
- I40E_AQC_MIRROR_RULE_TYPE_SHIFT);
- cmd.num_entries = rte_cpu_to_le_16(count);
- cmd.seid = rte_cpu_to_le_16(seid);
- cmd.destination = rte_cpu_to_le_16(dst_id);
-
- rte_memcpy(&desc.params.raw, &cmd, sizeof(cmd));
- status = i40e_asq_send_command(hw, &desc, entries, buff_len, NULL);
- PMD_DRV_LOG(INFO,
- "i40e_aq_add_mirror_rule, aq_status %d, rule_id = %u mirror_rules_used = %u, mirror_rules_free = %u,",
- hw->aq.asq_last_status, resp->rule_id,
- resp->mirror_rules_used, resp->mirror_rules_free);
- *rule_id = rte_le_to_cpu_16(resp->rule_id);
-
- return status;
-}
-
-/**
- * i40e_aq_del_mirror_rule
- * @hw: pointer to the hardware structure
- * @seid: VEB seid to add mirror rule to
- * @entries: Buffer which contains the entities to be mirrored
- * @count: number of entities contained in the buffer
- * @rule_id:the rule_id of the rule to be delete
- *
- * Delete a mirror rule for a given veb.
- *
- **/
-static enum i40e_status_code
-i40e_aq_del_mirror_rule(struct i40e_hw *hw,
- uint16_t seid, uint16_t rule_type, uint16_t *entries,
- uint16_t count, uint16_t rule_id)
-{
- struct i40e_aq_desc desc;
- struct i40e_aqc_add_delete_mirror_rule cmd;
- uint16_t buff_len = 0;
- enum i40e_status_code status;
- void *buff = NULL;
-
- i40e_fill_default_direct_cmd_desc(&desc,
- i40e_aqc_opc_delete_mirror_rule);
- memset(&cmd, 0, sizeof(cmd));
- if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
- desc.flags |= rte_cpu_to_le_16((uint16_t)(I40E_AQ_FLAG_BUF |
- I40E_AQ_FLAG_RD));
- cmd.num_entries = count;
- buff_len = sizeof(uint16_t) * count;
- desc.datalen = rte_cpu_to_le_16(buff_len);
- buff = (void *)entries;
- } else
- /* rule id is filled in destination field for deleting mirror rule */
- cmd.destination = rte_cpu_to_le_16(rule_id);
-
- cmd.rule_type = rte_cpu_to_le_16(rule_type <<
- I40E_AQC_MIRROR_RULE_TYPE_SHIFT);
- cmd.seid = rte_cpu_to_le_16(seid);
-
- rte_memcpy(&desc.params.raw, &cmd, sizeof(cmd));
- status = i40e_asq_send_command(hw, &desc, buff, buff_len, NULL);
-
- return status;
-}
-
-/**
- * i40e_mirror_rule_set
- * @dev: pointer to the hardware structure
- * @mirror_conf: mirror rule info
- * @sw_id: mirror rule's sw_id
- * @on: enable/disable
- *
- * set a mirror rule.
- *
- **/
-static int
-i40e_mirror_rule_set(struct rte_eth_dev *dev,
- struct rte_eth_mirror_conf *mirror_conf,
- uint8_t sw_id, uint8_t on)
-{
- 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_mirror_rule *it, *mirr_rule = NULL;
- struct i40e_mirror_rule *parent = NULL;
- uint16_t seid, dst_seid, rule_id;
- uint16_t i, j = 0;
- int ret;
-
- PMD_DRV_LOG(DEBUG, "i40e_mirror_rule_set: sw_id = %d.", sw_id);
-
- if (pf->main_vsi->veb == NULL || pf->vfs == NULL) {
- PMD_DRV_LOG(ERR,
- "mirror rule can not be configured without veb or vfs.");
- return -ENOSYS;
- }
- if (pf->nb_mirror_rule > I40E_MAX_MIRROR_RULES) {
- PMD_DRV_LOG(ERR, "mirror table is full.");
- return -ENOSPC;
- }
- if (mirror_conf->dst_pool > pf->vf_num) {
- PMD_DRV_LOG(ERR, "invalid destination pool %u.",
- mirror_conf->dst_pool);
- return -EINVAL;
- }
-
- seid = pf->main_vsi->veb->seid;
-
- TAILQ_FOREACH(it, &pf->mirror_list, rules) {
- if (sw_id <= it->index) {
- mirr_rule = it;
- break;
- }
- parent = it;
- }
- if (mirr_rule && sw_id == mirr_rule->index) {
- if (on) {
- PMD_DRV_LOG(ERR, "mirror rule exists.");
- return -EEXIST;
- } else {
- ret = i40e_aq_del_mirror_rule(hw, seid,
- mirr_rule->rule_type,
- mirr_rule->entries,
- mirr_rule->num_entries, mirr_rule->id);
- if (ret < 0) {
- PMD_DRV_LOG(ERR,
- "failed to remove mirror rule: ret = %d, aq_err = %d.",
- ret, hw->aq.asq_last_status);
- return -ENOSYS;
- }
- TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules);
- rte_free(mirr_rule);
- pf->nb_mirror_rule--;
- return 0;
- }
- } else if (!on) {
- PMD_DRV_LOG(ERR, "mirror rule doesn't exist.");
- return -ENOENT;
- }
-
- mirr_rule = rte_zmalloc("i40e_mirror_rule",
- sizeof(struct i40e_mirror_rule) , 0);
- if (!mirr_rule) {
- PMD_DRV_LOG(ERR, "failed to allocate memory");
- return I40E_ERR_NO_MEMORY;
- }
- switch (mirror_conf->rule_type) {
- case ETH_MIRROR_VLAN:
- for (i = 0, j = 0; i < ETH_MIRROR_MAX_VLANS; i++) {
- if (mirror_conf->vlan.vlan_mask & (1ULL << i)) {
- mirr_rule->entries[j] =
- mirror_conf->vlan.vlan_id[i];
- j++;
- }
- }
- if (j == 0) {
- PMD_DRV_LOG(ERR, "vlan is not specified.");
- rte_free(mirr_rule);
- return -EINVAL;
- }
- mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_VLAN;
- break;
- case ETH_MIRROR_VIRTUAL_POOL_UP:
- case ETH_MIRROR_VIRTUAL_POOL_DOWN:
- /* check if the specified pool bit is out of range */
- if (mirror_conf->pool_mask > (uint64_t)(1ULL << (pf->vf_num + 1))) {
- PMD_DRV_LOG(ERR, "pool mask is out of range.");
- rte_free(mirr_rule);
- return -EINVAL;
- }
- for (i = 0, j = 0; i < pf->vf_num; i++) {
- if (mirror_conf->pool_mask & (1ULL << i)) {
- mirr_rule->entries[j] = pf->vfs[i].vsi->seid;
- j++;
- }
- }
- if (mirror_conf->pool_mask & (1ULL << pf->vf_num)) {
- /* add pf vsi to entries */
- mirr_rule->entries[j] = pf->main_vsi_seid;
- j++;
- }
- if (j == 0) {
- PMD_DRV_LOG(ERR, "pool is not specified.");
- rte_free(mirr_rule);
- return -EINVAL;
- }
- /* egress and ingress in aq commands means from switch but not port */
- mirr_rule->rule_type =
- (mirror_conf->rule_type == ETH_MIRROR_VIRTUAL_POOL_UP) ?
- I40E_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS :
- I40E_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS;
- break;
- case ETH_MIRROR_UPLINK_PORT:
- /* egress and ingress in aq commands means from switch but not port*/
- mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS;
- break;
- case ETH_MIRROR_DOWNLINK_PORT:
- mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS;
- break;
- default:
- PMD_DRV_LOG(ERR, "unsupported mirror type %d.",
- mirror_conf->rule_type);
- rte_free(mirr_rule);
- return -EINVAL;
- }
-
- /* If the dst_pool is equal to vf_num, consider it as PF */
- if (mirror_conf->dst_pool == pf->vf_num)
- dst_seid = pf->main_vsi_seid;
- else
- dst_seid = pf->vfs[mirror_conf->dst_pool].vsi->seid;
-
- ret = i40e_aq_add_mirror_rule(hw, seid, dst_seid,
- mirr_rule->rule_type, mirr_rule->entries,
- j, &rule_id);
- if (ret < 0) {
- PMD_DRV_LOG(ERR,
- "failed to add mirror rule: ret = %d, aq_err = %d.",
- ret, hw->aq.asq_last_status);
- rte_free(mirr_rule);
- return -ENOSYS;
- }
-
- mirr_rule->index = sw_id;
- mirr_rule->num_entries = j;
- mirr_rule->id = rule_id;
- mirr_rule->dst_vsi_seid = dst_seid;
-
- if (parent)
- TAILQ_INSERT_AFTER(&pf->mirror_list, parent, mirr_rule, rules);
- else
- TAILQ_INSERT_HEAD(&pf->mirror_list, mirr_rule, rules);
-
- pf->nb_mirror_rule++;
- return 0;
-}
-
-/**
- * i40e_mirror_rule_reset
- * @dev: pointer to the device
- * @sw_id: mirror rule's sw_id
- *
- * reset a mirror rule.
- *
- **/
-static int
-i40e_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t sw_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);
- struct i40e_mirror_rule *it, *mirr_rule = NULL;
- uint16_t seid;
- int ret;
-
- PMD_DRV_LOG(DEBUG, "i40e_mirror_rule_reset: sw_id = %d.", sw_id);
-
- seid = pf->main_vsi->veb->seid;
-
- TAILQ_FOREACH(it, &pf->mirror_list, rules) {
- if (sw_id == it->index) {
- mirr_rule = it;
- break;
- }
- }
- if (mirr_rule) {
- ret = i40e_aq_del_mirror_rule(hw, seid,
- mirr_rule->rule_type,
- mirr_rule->entries,
- mirr_rule->num_entries, mirr_rule->id);
- if (ret < 0) {
- PMD_DRV_LOG(ERR,
- "failed to remove mirror rule: status = %d, aq_err = %d.",
- ret, hw->aq.asq_last_status);
- return -ENOSYS;
- }
- TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules);
- rte_free(mirr_rule);
- pf->nb_mirror_rule--;
- } else {
- PMD_DRV_LOG(ERR, "mirror rule doesn't exist.");
- return -ENOENT;
- }
- return 0;
-}
-
static uint64_t
i40e_read_systime_cyclecounter(struct rte_eth_dev *dev)
{
uint32_t value = 0;
uint32_t i;
- if (!info || !info->length || !info->data)
- return -EINVAL;
-
if (hw->phy.link_info.module_type[0] == I40E_MODULE_TYPE_SFP)
is_sfp = true;
return -EBUSY;
}
- if (frame_size > RTE_ETHER_MAX_LEN)
+ if (frame_size > I40E_ETH_MAX_LEN)
dev_data->dev_conf.rxmode.offloads |=
DEV_RX_OFFLOAD_JUMBO_FRAME;
else
struct i40e_aqc_replace_cloud_filters_cmd filter_replace;
struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf;
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
+ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id];
if (pf->support_multi_driver) {
PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
return ret;
}
-RTE_LOG_REGISTER(i40e_logtype_init, pmd.net.i40e.init, NOTICE);
-RTE_LOG_REGISTER(i40e_logtype_driver, pmd.net.i40e.driver, NOTICE);
-#ifdef RTE_LIBRTE_I40E_DEBUG_RX
-RTE_LOG_REGISTER(i40e_logtype_rx, pmd.net.i40e.rx, DEBUG);
-#endif
-#ifdef RTE_LIBRTE_I40E_DEBUG_TX
-RTE_LOG_REGISTER(i40e_logtype_tx, pmd.net.i40e.tx, DEBUG);
+RTE_LOG_REGISTER_SUFFIX(i40e_logtype_init, init, NOTICE);
+RTE_LOG_REGISTER_SUFFIX(i40e_logtype_driver, driver, NOTICE);
+#ifdef RTE_ETHDEV_DEBUG_RX
+RTE_LOG_REGISTER_SUFFIX(i40e_logtype_rx, rx, DEBUG);
#endif
-#ifdef RTE_LIBRTE_I40E_DEBUG_TX_FREE
-RTE_LOG_REGISTER(i40e_logtype_tx_free, pmd.net.i40e.tx_free, DEBUG);
+#ifdef RTE_ETHDEV_DEBUG_TX
+RTE_LOG_REGISTER_SUFFIX(i40e_logtype_tx, tx, DEBUG);
#endif
RTE_PMD_REGISTER_PARAM_STRING(net_i40e,
ETH_I40E_FLOATING_VEB_ARG "=1"
ETH_I40E_FLOATING_VEB_LIST_ARG "=<string>"
ETH_I40E_QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16"
- ETH_I40E_SUPPORT_MULTI_DRIVER "=1"
- ETH_I40E_USE_LATEST_VEC "=0|1");
+ ETH_I40E_SUPPORT_MULTI_DRIVER "=1");