drivers/net: update Rx RSS hash offload capabilities
[dpdk.git] / drivers / net / i40e / i40e_ethdev.c
index f4d778e..27d2c0e 100644 (file)
@@ -44,6 +44,7 @@
 #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
 
@@ -223,10 +224,10 @@ static int i40e_dev_start(struct rte_eth_dev *dev);
 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,
@@ -236,15 +237,11 @@ static int i40e_dev_xstats_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);
@@ -403,6 +400,15 @@ static void i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev);
 
 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,
@@ -410,6 +416,7 @@ static const char *const valid_keys[] = {
        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[] = {
@@ -457,7 +464,6 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
        .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,
@@ -496,6 +502,8 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
        .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,
@@ -526,13 +534,13 @@ static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = {
        {"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) / \
@@ -701,8 +709,7 @@ static int eth_i40e_pci_remove(struct rte_pci_device *pci_dev)
 
 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,
 };
@@ -1211,11 +1218,9 @@ i40e_parse_latest_vec_handler(__rte_unused const char *key,
                                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)
@@ -1264,6 +1269,73 @@ i40e_use_latest_vec(struct rte_eth_dev *dev)
        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
@@ -1336,6 +1408,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
                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 */
@@ -1365,6 +1438,10 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
                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,
@@ -1524,6 +1601,11 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
        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) {
@@ -1602,6 +1684,7 @@ err_init_tunnel_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:
@@ -1692,85 +1775,18 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 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_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;
 }
 
@@ -1796,6 +1812,8 @@ i40e_dev_configure(struct rte_eth_dev *dev)
        ad->tx_simple_allowed = true;
        ad->tx_vec_allowed = true;
 
+       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.
@@ -2468,12 +2486,21 @@ i40e_dev_close(struct rte_eth_dev *dev)
        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 */
@@ -2538,6 +2565,53 @@ i40e_dev_close(struct rte_eth_dev *dev)
                        (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) {
+                       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;
 }
 
@@ -2567,7 +2641,7 @@ i40e_dev_reset(struct rte_eth_dev *dev)
        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);
@@ -2577,17 +2651,25 @@ i40e_dev_promiscuous_enable(struct rte_eth_dev *dev)
 
        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);
@@ -2597,20 +2679,29 @@ i40e_dev_promiscuous_disable(struct rte_eth_dev *dev)
 
        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);
@@ -2619,11 +2710,15 @@ i40e_dev_allmulticast_enable(struct rte_eth_dev *dev)
        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);
@@ -2632,12 +2727,16 @@ i40e_dev_allmulticast_disable(struct rte_eth_dev *dev)
        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;
 }
 
 /*
@@ -2746,7 +2845,7 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
                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;
@@ -2780,7 +2879,7 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
                link->link_speed = ETH_SPEED_NUM_40G;
                break;
        default:
-               link->link_speed = ETH_SPEED_NUM_100M;
+               link->link_speed = ETH_SPEED_NUM_NONE;
                break;
        }
 }
@@ -3299,7 +3398,7 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 }
 
 /* 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);
@@ -3312,6 +3411,8 @@ i40e_dev_stats_reset(struct rte_eth_dev *dev)
 
        /* read the stats, reading current register values into offset */
        i40e_read_stats_registers(pf, hw);
+
+       return 0;
 }
 
 static uint32_t
@@ -3433,17 +3534,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
        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)
 {
@@ -3497,7 +3587,7 @@ i40e_need_stop_lldp(struct rte_eth_dev *dev)
        return false;
 }
 
-static void
+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);
@@ -3525,7 +3615,8 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                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 =
@@ -3634,6 +3725,8 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        }
        dev_info->default_rxportconf.burst_size = 32;
        dev_info->default_txportconf.burst_size = 32;
+
+       return 0;
 }
 
 static int
@@ -3757,6 +3850,11 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
        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)
@@ -8390,7 +8488,7 @@ static int
 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);
@@ -9997,8 +10095,8 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
                PMD_DRV_LOG(ERR, "Invalid queue ID");
                return -EINVAL;
        }
-       if (filter->ether_type == RTE_ETHER_TYPE_IPv4 ||
-               filter->ether_type == RTE_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);
@@ -10843,8 +10941,7 @@ static void
 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;
@@ -10896,8 +10993,7 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 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;
@@ -10910,8 +11006,7 @@ static int
 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);
 
@@ -10927,8 +11022,7 @@ static int
 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);
@@ -11004,9 +11098,7 @@ i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
                                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;
@@ -11028,9 +11120,7 @@ i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
                                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;
@@ -11671,7 +11761,7 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
                               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;
 }
@@ -12142,7 +12232,7 @@ i40e_filter_restore(struct i40e_pf *pf)
        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))
@@ -12791,6 +12881,24 @@ RTE_INIT(i40e_init_log)
        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,