ethdev: fix max Rx packet length
[dpdk.git] / drivers / net / ice / ice_ethdev.c
index 8999d44..878b3b1 100644 (file)
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include <rte_tailq.h>
+
+#include "eal_firmware.h"
+
 #include "base/ice_sched.h"
 #include "base/ice_flow.h"
 #include "base/ice_dcb.h"
 #include "base/ice_common.h"
+#include "base/ice_ptp_hw.h"
 
 #include "rte_pmd_ice.h"
 #include "ice_ethdev.h"
 #define ICE_SAFE_MODE_SUPPORT_ARG "safe-mode-support"
 #define ICE_PIPELINE_MODE_SUPPORT_ARG  "pipeline-mode-support"
 #define ICE_PROTO_XTR_ARG         "proto_xtr"
+#define ICE_HW_DEBUG_MASK_ARG     "hw_debug_mask"
+#define ICE_ONE_PPS_OUT_ARG       "pps_out"
+#define ICE_RX_LOW_LATENCY_ARG    "rx_low_latency"
+
+#define ICE_CYCLECOUNTER_MASK  0xffffffffffffffffULL
+
+uint64_t ice_timestamp_dynflag;
+int ice_timestamp_dynfield_offset = -1;
 
 static const char * const ice_valid_args[] = {
        ICE_SAFE_MODE_SUPPORT_ARG,
        ICE_PIPELINE_MODE_SUPPORT_ARG,
        ICE_PROTO_XTR_ARG,
+       ICE_HW_DEBUG_MASK_ARG,
+       ICE_ONE_PPS_OUT_ARG,
+       ICE_RX_LOW_LATENCY_ARG,
        NULL
 };
 
+#define PPS_OUT_DELAY_NS  1
+
 static const struct rte_mbuf_dynfield ice_proto_xtr_metadata_param = {
        .name = "intel_pmd_dynfield_proto_xtr_metadata",
        .size = sizeof(uint32_t),
@@ -129,14 +147,24 @@ static int ice_xstats_get(struct rte_eth_dev *dev,
 static int ice_xstats_get_names(struct rte_eth_dev *dev,
                                struct rte_eth_xstat_name *xstats_names,
                                unsigned int limit);
-static int ice_dev_filter_ctrl(struct rte_eth_dev *dev,
-                       enum rte_filter_type filter_type,
-                       enum rte_filter_op filter_op,
-                       void *arg);
+static int ice_dev_flow_ops_get(struct rte_eth_dev *dev,
+                               const struct rte_flow_ops **ops);
 static int ice_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
                        struct rte_eth_udp_tunnel *udp_tunnel);
 static int ice_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
                        struct rte_eth_udp_tunnel *udp_tunnel);
+static int ice_timesync_enable(struct rte_eth_dev *dev);
+static int ice_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
+                                         struct timespec *timestamp,
+                                         uint32_t flags);
+static int ice_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
+                                         struct timespec *timestamp);
+static int ice_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta);
+static int ice_timesync_read_time(struct rte_eth_dev *dev,
+                                 struct timespec *timestamp);
+static int ice_timesync_write_time(struct rte_eth_dev *dev,
+                                  const struct timespec *timestamp);
+static int ice_timesync_disable(struct rte_eth_dev *dev);
 
 static const struct rte_pci_id pci_id_ice_map[] = {
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823L_BACKPLANE) },
@@ -180,9 +208,9 @@ static const struct eth_dev_ops ice_eth_dev_ops = {
        .tx_queue_start               = ice_tx_queue_start,
        .tx_queue_stop                = ice_tx_queue_stop,
        .rx_queue_setup               = ice_rx_queue_setup,
-       .rx_queue_release             = ice_rx_queue_release,
+       .rx_queue_release             = ice_dev_rx_queue_release,
        .tx_queue_setup               = ice_tx_queue_setup,
-       .tx_queue_release             = ice_tx_queue_release,
+       .tx_queue_release             = ice_dev_tx_queue_release,
        .dev_infos_get                = ice_dev_info_get,
        .dev_supported_ptypes_get     = ice_dev_supported_ptypes_get,
        .link_update                  = ice_link_update,
@@ -215,11 +243,18 @@ static const struct eth_dev_ops ice_eth_dev_ops = {
        .xstats_get                   = ice_xstats_get,
        .xstats_get_names             = ice_xstats_get_names,
        .xstats_reset                 = ice_stats_reset,
-       .filter_ctrl                  = ice_dev_filter_ctrl,
+       .flow_ops_get                 = ice_dev_flow_ops_get,
        .udp_tunnel_port_add          = ice_dev_udp_tunnel_port_add,
        .udp_tunnel_port_del          = ice_dev_udp_tunnel_port_del,
        .tx_done_cleanup              = ice_tx_done_cleanup,
        .get_monitor_addr             = ice_get_monitor_addr,
+       .timesync_enable              = ice_timesync_enable,
+       .timesync_read_rx_timestamp   = ice_timesync_read_rx_timestamp,
+       .timesync_read_tx_timestamp   = ice_timesync_read_tx_timestamp,
+       .timesync_adjust_time         = ice_timesync_adjust_time,
+       .timesync_read_time           = ice_timesync_read_time,
+       .timesync_write_time          = ice_timesync_write_time,
+       .timesync_disable             = ice_timesync_disable,
 };
 
 /* store statistics names and its offset in stats structure */
@@ -809,7 +844,7 @@ ice_init_mac_address(struct rte_eth_dev *dev)
                (struct rte_ether_addr *)hw->port_info[0].mac.perm_addr);
 
        dev->data->mac_addrs =
-               rte_zmalloc(NULL, sizeof(struct rte_ether_addr), 0);
+               rte_zmalloc(NULL, sizeof(struct rte_ether_addr) * ICE_NUM_MACADDR_MAX, 0);
        if (!dev->data->mac_addrs) {
                PMD_INIT_LOG(ERR,
                             "Failed to allocate memory to store mac address");
@@ -1094,12 +1129,13 @@ ice_remove_all_mac_vlan_filters(struct ice_vsi *vsi)
 {
        struct ice_mac_filter *m_f;
        struct ice_vlan_filter *v_f;
+       void *temp;
        int ret = 0;
 
        if (!vsi || !vsi->mac_num)
                return -EINVAL;
 
-       TAILQ_FOREACH(m_f, &vsi->mac_list, next) {
+       RTE_TAILQ_FOREACH_SAFE(m_f, &vsi->mac_list, next, temp) {
                ret = ice_remove_mac_filter(vsi, &m_f->mac_info.mac_addr);
                if (ret != ICE_SUCCESS) {
                        ret = -EINVAL;
@@ -1110,7 +1146,7 @@ ice_remove_all_mac_vlan_filters(struct ice_vsi *vsi)
        if (vsi->vlan_num == 0)
                return 0;
 
-       TAILQ_FOREACH(v_f, &vsi->vlan_list, next) {
+       RTE_TAILQ_FOREACH_SAFE(v_f, &vsi->vlan_list, next, temp) {
                ret = ice_remove_vlan_filter(vsi, &v_f->vlan_info.vlan);
                if (ret != ICE_SUCCESS) {
                        ret = -EINVAL;
@@ -1648,49 +1684,7 @@ ice_pf_setup(struct ice_pf *pf)
        return 0;
 }
 
-/*
- * Extract device serial number from PCIe Configuration Space and
- * determine the pkg file path according to the DSN.
- */
-static int
-ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file)
-{
-       off_t pos;
-       char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
-       uint32_t dsn_low, dsn_high;
-       memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
-
-       pos = rte_pci_find_ext_capability(pci_dev, RTE_PCI_EXT_CAP_ID_DSN);
-
-       if (pos) {
-               rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4);
-               rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8);
-               snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
-                        "ice-%08x%08x.pkg", dsn_high, dsn_low);
-       } else {
-               PMD_INIT_LOG(ERR, "Failed to read device serial number\n");
-               goto fail_dsn;
-       }
-
-       strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
-               ICE_MAX_PKG_FILENAME_SIZE);
-       if (!access(strcat(pkg_file, opt_ddp_filename), 0))
-               return 0;
-
-       strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
-               ICE_MAX_PKG_FILENAME_SIZE);
-       if (!access(strcat(pkg_file, opt_ddp_filename), 0))
-               return 0;
-
-fail_dsn:
-       strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
-       if (!access(pkg_file, 0))
-               return 0;
-       strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
-       return 0;
-}
-
-enum ice_pkg_type
+static enum ice_pkg_type
 ice_load_pkg_type(struct ice_hw *hw)
 {
        enum ice_pkg_type package_type;
@@ -1714,75 +1708,58 @@ ice_load_pkg_type(struct ice_hw *hw)
        return package_type;
 }
 
-static int ice_load_pkg(struct rte_eth_dev *dev)
+int ice_load_pkg(struct ice_adapter *adapter, bool use_dsn, uint64_t dsn)
 {
-       struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ice_hw *hw = &adapter->hw;
        char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
+       char opt_ddp_filename[ICE_MAX_PKG_FILENAME_SIZE];
+       void *buf;
+       size_t bufsz;
        int err;
-       uint8_t *buf;
-       int buf_len;
-       FILE *file;
-       struct stat fstat;
-       struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
-       struct ice_adapter *ad =
-               ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 
-       ice_pkg_file_search_path(pci_dev, pkg_file);
+       if (!use_dsn)
+               goto no_dsn;
 
-       file = fopen(pkg_file, "rb");
-       if (!file)  {
-               PMD_INIT_LOG(ERR, "failed to open file: %s\n", pkg_file);
-               return -1;
-       }
+       memset(opt_ddp_filename, 0, ICE_MAX_PKG_FILENAME_SIZE);
+       snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE,
+               "ice-%016" PRIx64 ".pkg", dsn);
+       strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES,
+               ICE_MAX_PKG_FILENAME_SIZE);
+       strcat(pkg_file, opt_ddp_filename);
+       if (rte_firmware_read(pkg_file, &buf, &bufsz) == 0)
+               goto load_fw;
 
-       err = stat(pkg_file, &fstat);
-       if (err) {
-               PMD_INIT_LOG(ERR, "failed to get file stats\n");
-               fclose(file);
-               return err;
-       }
+       strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT,
+               ICE_MAX_PKG_FILENAME_SIZE);
+       strcat(pkg_file, opt_ddp_filename);
+       if (rte_firmware_read(pkg_file, &buf, &bufsz) == 0)
+               goto load_fw;
 
-       buf_len = fstat.st_size;
-       buf = rte_malloc(NULL, buf_len, 0);
+no_dsn:
+       strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE);
+       if (rte_firmware_read(pkg_file, &buf, &bufsz) == 0)
+               goto load_fw;
 
-       if (!buf) {
-               PMD_INIT_LOG(ERR, "failed to allocate buf of size %d for package\n",
-                               buf_len);
-               fclose(file);
+       strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE);
+       if (rte_firmware_read(pkg_file, &buf, &bufsz) < 0) {
+               PMD_INIT_LOG(ERR, "failed to search file path\n");
                return -1;
        }
 
-       err = fread(buf, buf_len, 1, file);
-       if (err != 1) {
-               PMD_INIT_LOG(ERR, "failed to read package data\n");
-               fclose(file);
-               err = -1;
-               goto fail_exit;
-       }
+load_fw:
+       PMD_INIT_LOG(DEBUG, "DDP package name: %s", pkg_file);
 
-       fclose(file);
-
-       err = ice_copy_and_init_pkg(hw, buf, buf_len);
+       err = ice_copy_and_init_pkg(hw, buf, bufsz);
        if (err) {
                PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
-               goto fail_exit;
+               goto out;
        }
 
        /* store the loaded pkg type info */
-       ad->active_pkg_type = ice_load_pkg_type(hw);
-
-       err = ice_init_hw_tbls(hw);
-       if (err) {
-               PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err);
-               goto fail_init_tbls;
-       }
-
-       return 0;
+       adapter->active_pkg_type = ice_load_pkg_type(hw);
 
-fail_init_tbls:
-       rte_free(hw->pkg_copy);
-fail_exit:
-       rte_free(buf);
+out:
+       free(buf);
        return err;
 }
 
@@ -1821,6 +1798,144 @@ parse_bool(const char *key, const char *value, void *args)
        return 0;
 }
 
+static int
+parse_u64(const char *key, const char *value, void *args)
+{
+       u64 *num = (u64 *)args;
+       u64 tmp;
+
+       errno = 0;
+       tmp = strtoull(value, NULL, 16);
+       if (errno) {
+               PMD_DRV_LOG(WARNING, "%s: \"%s\" is not a valid u64",
+                           key, value);
+               return -1;
+       }
+
+       *num = tmp;
+
+       return 0;
+}
+
+static int
+lookup_pps_type(const char *pps_name)
+{
+       static struct {
+               const char *name;
+               enum pps_type type;
+       } pps_type_map[] = {
+               { "pin",  PPS_PIN  },
+       };
+
+       uint32_t i;
+
+       for (i = 0; i < RTE_DIM(pps_type_map); i++) {
+               if (strcmp(pps_name, pps_type_map[i].name) == 0)
+                       return pps_type_map[i].type;
+       }
+
+       return -1;
+}
+
+static int
+parse_pin_set(const char *input, int pps_type, struct ice_devargs *devargs)
+{
+       const char *str = input;
+       char *end = NULL;
+       uint32_t idx;
+
+       while (isblank(*str))
+               str++;
+
+       if (!isdigit(*str))
+               return -1;
+
+       if (pps_type == PPS_PIN) {
+               idx = strtoul(str, &end, 10);
+               if (end == NULL || idx >= ICE_MAX_PIN_NUM)
+                       return -1;
+               while (isblank(*end))
+                       end++;
+               if (*end != ']')
+                       return -1;
+
+               devargs->pin_idx = idx;
+               devargs->pps_out_ena = 1;
+
+               return 0;
+       }
+
+       return -1;
+}
+
+static int
+parse_pps_out_parameter(const char *pins, struct ice_devargs *devargs)
+{
+       const char *pin_start;
+       uint32_t idx;
+       int pps_type;
+       char pps_name[32];
+
+       while (isblank(*pins))
+               pins++;
+
+       pins++;
+       while (isblank(*pins))
+               pins++;
+       if (*pins == '\0')
+               return -1;
+
+       for (idx = 0; ; idx++) {
+               if (isblank(pins[idx]) ||
+                   pins[idx] == ':' ||
+                   pins[idx] == '\0')
+                       break;
+
+               pps_name[idx] = pins[idx];
+       }
+       pps_name[idx] = '\0';
+       pps_type = lookup_pps_type(pps_name);
+       if (pps_type < 0)
+               return -1;
+
+       pins += idx;
+
+       pins += strcspn(pins, ":");
+       if (*pins++ != ':')
+               return -1;
+       while (isblank(*pins))
+               pins++;
+
+       pin_start = pins;
+
+       while (isblank(*pins))
+               pins++;
+
+       if (parse_pin_set(pin_start, pps_type, devargs) < 0)
+               return -1;
+
+       return 0;
+}
+
+static int
+handle_pps_out_arg(__rte_unused const char *key, const char *value,
+                  void *extra_args)
+{
+       struct ice_devargs *devargs = extra_args;
+
+       if (value == NULL || extra_args == NULL)
+               return -EINVAL;
+
+       if (parse_pps_out_parameter(value, devargs) < 0) {
+               PMD_DRV_LOG(ERR,
+                           "The GPIO pin parameter is wrong : '%s'",
+                           value);
+               return -1;
+       }
+
+       return 0;
+}
+
 static int ice_parse_devargs(struct rte_eth_dev *dev)
 {
        struct ice_adapter *ad =
@@ -1857,6 +1972,19 @@ static int ice_parse_devargs(struct rte_eth_dev *dev)
        if (ret)
                goto bail;
 
+       ret = rte_kvargs_process(kvlist, ICE_HW_DEBUG_MASK_ARG,
+                                &parse_u64, &ad->hw.debug_mask);
+       if (ret)
+               goto bail;
+
+       ret = rte_kvargs_process(kvlist, ICE_ONE_PPS_OUT_ARG,
+                                &handle_pps_out_arg, &ad->devargs);
+       if (ret)
+               goto bail;
+
+       ret = rte_kvargs_process(kvlist, ICE_RX_LOW_LATENCY_ARG,
+                                &parse_bool, &ad->devargs.rx_low_latency);
+
 bail:
        rte_kvargs_free(kvlist);
        return ret;
@@ -2015,6 +2143,12 @@ ice_dev_init(struct rte_eth_dev *dev)
                ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
        struct ice_vsi *vsi;
        int ret;
+#ifndef RTE_EXEC_ENV_WINDOWS
+       off_t pos;
+       uint32_t dsn_low, dsn_high;
+       uint64_t dsn;
+       bool use_dsn;
+#endif
 
        dev->dev_ops = &ice_eth_dev_ops;
        dev->rx_queue_count = ice_rx_queue_count;
@@ -2040,7 +2174,6 @@ ice_dev_init(struct rte_eth_dev *dev)
        intr_handle = &pci_dev->intr_handle;
 
        pf->adapter = ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
-       pf->adapter->eth_dev = dev;
        pf->dev_data = dev->data;
        hw->back = pf->adapter;
        hw->hw_addr = (uint8_t *)pci_dev->mem_resource[0].addr;
@@ -2065,18 +2198,43 @@ ice_dev_init(struct rte_eth_dev *dev)
                return -EINVAL;
        }
 
-       ret = ice_load_pkg(dev);
+#ifndef RTE_EXEC_ENV_WINDOWS
+       use_dsn = false;
+       dsn = 0;
+       pos = rte_pci_find_ext_capability(pci_dev, RTE_PCI_EXT_CAP_ID_DSN);
+       if (pos) {
+               if (rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4) < 0 ||
+                               rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8) < 0) {
+                       PMD_INIT_LOG(ERR, "Failed to read pci config space\n");
+               } else {
+                       use_dsn = true;
+                       dsn = (uint64_t)dsn_high << 32 | dsn_low;
+               }
+       } else {
+               PMD_INIT_LOG(ERR, "Failed to read device serial number\n");
+       }
+
+       ret = ice_load_pkg(pf->adapter, use_dsn, dsn);
+       if (ret == 0) {
+               ret = ice_init_hw_tbls(hw);
+               if (ret) {
+                       PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", ret);
+                       rte_free(hw->pkg_copy);
+               }
+       }
+
        if (ret) {
                if (ad->devargs.safe_mode_support == 0) {
                        PMD_INIT_LOG(ERR, "Failed to load the DDP package,"
                                        "Use safe-mode-support=1 to enter Safe Mode");
-                       return ret;
+                       goto err_init_fw;
                }
 
                PMD_INIT_LOG(WARNING, "Failed to load the DDP package,"
                                        "Entering Safe Mode");
                ad->is_safe_mode = 1;
        }
+#endif
 
        PMD_INIT_LOG(INFO, "FW %d.%d.%05d API %d.%d",
                     hw->fw_maj_ver, hw->fw_min_ver, hw->fw_build,
@@ -2139,30 +2297,37 @@ ice_dev_init(struct rte_eth_dev *dev)
                ret = ice_flow_init(ad);
                if (ret) {
                        PMD_INIT_LOG(ERR, "Failed to initialize flow");
-                       return ret;
+                       goto err_flow_init;
                }
        }
 
        ret = ice_reset_fxp_resource(hw);
        if (ret) {
                PMD_INIT_LOG(ERR, "Failed to reset fxp resource");
-               return ret;
+               goto err_flow_init;
        }
 
        pf->supported_rxdid = ice_get_supported_rxdid(hw);
 
        return 0;
 
+err_flow_init:
+       ice_flow_uninit(ad);
+       rte_intr_disable(intr_handle);
+       ice_pf_disable_irq0(hw);
+       rte_intr_callback_unregister(intr_handle,
+                                    ice_interrupt_handler, dev);
 err_pf_setup:
        ice_res_pool_destroy(&pf->msix_pool);
 err_msix_pool_init:
        rte_free(dev->data->mac_addrs);
        dev->data->mac_addrs = NULL;
 err_init_mac:
-       ice_sched_cleanup_all(hw);
-       rte_free(hw->port_info);
-       ice_shutdown_all_ctrlq(hw);
        rte_free(pf->proto_xtr);
+#ifndef RTE_EXEC_ENV_WINDOWS
+err_init_fw:
+#endif
+       ice_deinit_hw(hw);
 
        return ret;
 }
@@ -2201,7 +2366,7 @@ ice_release_vsi(struct ice_vsi *vsi)
 void
 ice_vsi_disable_queues_intr(struct ice_vsi *vsi)
 {
-       struct rte_eth_dev *dev = vsi->adapter->eth_dev;
+       struct rte_eth_dev *dev = &rte_eth_devices[vsi->adapter->pf.dev_data->port_id];
        struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
@@ -2279,6 +2444,9 @@ ice_dev_close(struct rte_eth_dev *dev)
        struct ice_adapter *ad =
                ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
        int ret;
+       uint32_t val;
+       uint8_t timer = hw->func_caps.ts_func_info.tmr_index_owned;
+       uint32_t pin_idx = ad->devargs.pin_idx;
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return 0;
@@ -2308,6 +2476,16 @@ ice_dev_close(struct rte_eth_dev *dev)
        rte_free(pf->proto_xtr);
        pf->proto_xtr = NULL;
 
+       if (ad->devargs.pps_out_ena) {
+               ICE_WRITE_REG(hw, GLTSYN_AUX_OUT(pin_idx, timer), 0);
+               ICE_WRITE_REG(hw, GLTSYN_CLKO(pin_idx, timer), 0);
+               ICE_WRITE_REG(hw, GLTSYN_TGT_L(pin_idx, timer), 0);
+               ICE_WRITE_REG(hw, GLTSYN_TGT_H(pin_idx, timer), 0);
+
+               val = GLGEN_GPIO_CTL_PIN_DIR_M;
+               ICE_WRITE_REG(hw, GLGEN_GPIO_CTL(pin_idx), val);
+       }
+
        /* disable uio intr before callback unregister */
        rte_intr_disable(intr_handle);
 
@@ -2338,7 +2516,7 @@ hash_cfg_reset(struct ice_rss_hash_cfg *cfg)
        cfg->hash_flds = 0;
        cfg->addl_hdrs = 0;
        cfg->symm = 0;
-       cfg->hdr_type = ICE_RSS_ANY_HEADERS;
+       cfg->hdr_type = ICE_RSS_OUTER_HEADERS;
 }
 
 static int
@@ -2823,7 +3001,7 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
                            __func__, ret);
 
        cfg.symm = 0;
-       cfg.hdr_type = ICE_RSS_ANY_HEADERS;
+       cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
        /* Configure RSS for IPv4 with src/dst addr as input set */
        if (rss_hf & ETH_RSS_IPV4) {
                cfg.addl_hdrs = ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
@@ -2911,23 +3089,9 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
        }
 
        if (rss_hf & ETH_RSS_IPV4) {
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER;
-               cfg.hash_flds = ICE_FLOW_HASH_IPV4;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_IPV4 rss flow fail %d",
-                                   __func__, ret);
-
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_IPV4 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4 rss flow fail %d",
-                                   __func__, ret);
-
                cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_IPV4 |
                                ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_FLOW_HASH_IPV4;
                ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV4 rss flow fail %d",
@@ -2935,23 +3099,9 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
        }
 
        if (rss_hf & ETH_RSS_IPV6) {
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER;
-               cfg.hash_flds = ICE_FLOW_HASH_IPV6;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_IPV6 rss flow fail %d",
-                                   __func__, ret);
-
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_IPV6 |
-                               ICE_FLOW_SEG_HDR_IPV_OTHER;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6 rss flow fail %d",
-                                   __func__, ret);
-
                cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_IPV6 |
                                ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_FLOW_HASH_IPV6;
                ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV6 rss flow fail %d",
@@ -2959,23 +3109,9 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
        }
 
        if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) {
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
-               cfg.hash_flds = ICE_HASH_UDP_IPV4;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_IPV4_UDP rss flow fail %d",
-                                   __func__, ret);
-
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4_UDP rss flow fail %d",
-                                   __func__, ret);
-
                cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_UDP |
                                ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_UDP_IPV4;
                ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV4_UDP rss flow fail %d",
@@ -2983,23 +3119,9 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
        }
 
        if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) {
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
-               cfg.hash_flds = ICE_HASH_UDP_IPV6;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_IPV6_UDP rss flow fail %d",
-                                   __func__, ret);
-
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_UDP |
-                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6_UDP rss flow fail %d",
-                                   __func__, ret);
-
                cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_UDP |
                                ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_UDP_IPV6;
                ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV6_UDP rss flow fail %d",
@@ -3007,23 +3129,9 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
        }
 
        if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) {
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
-               cfg.hash_flds = ICE_HASH_TCP_IPV4;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_IPV4_TCP rss flow fail %d",
-                                   __func__, ret);
-
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4_TCP rss flow fail %d",
-                                   __func__, ret);
-
                cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_TCP |
                                ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_TCP_IPV4;
                ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV4_TCP rss flow fail %d",
@@ -3031,23 +3139,9 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
        }
 
        if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) {
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
-               cfg.hash_flds = ICE_HASH_TCP_IPV6;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_IPV6_TCP rss flow fail %d",
-                                   __func__, ret);
-
-               cfg.addl_hdrs = ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_TCP |
-                               ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
-               ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
-               if (ret)
-                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6_TCP rss flow fail %d",
-                                   __func__, ret);
-
                cfg.addl_hdrs = ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_TCP |
                                ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER;
+               cfg.hash_flds = ICE_HASH_TCP_IPV6;
                ret = ice_add_rss_cfg_wrap(pf, vsi->idx, &cfg);
                if (ret)
                        PMD_DRV_LOG(ERR, "%s PPPoE_IPV6_TCP rss flow fail %d",
@@ -3057,11 +3151,36 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
        pf->rss_hf = rss_hf & ICE_RSS_HF_ALL;
 }
 
+static void
+ice_get_default_rss_key(uint8_t *rss_key, uint32_t rss_key_size)
+{
+       static struct ice_aqc_get_set_rss_keys default_key;
+       static bool default_key_done;
+       uint8_t *key = (uint8_t *)&default_key;
+       size_t i;
+
+       if (rss_key_size > sizeof(default_key)) {
+               PMD_DRV_LOG(WARNING,
+                           "requested size %u is larger than default %zu, "
+                           "only %zu bytes are gotten for key\n",
+                           rss_key_size, sizeof(default_key),
+                           sizeof(default_key));
+       }
+
+       if (!default_key_done) {
+               /* Calculate the default hash key */
+               for (i = 0; i < sizeof(default_key); i++)
+                       key[i] = (uint8_t)rte_rand();
+               default_key_done = true;
+       }
+       rte_memcpy(rss_key, key, RTE_MIN(rss_key_size, sizeof(default_key)));
+}
+
 static int ice_init_rss(struct ice_pf *pf)
 {
        struct ice_hw *hw = ICE_PF_TO_HW(pf);
        struct ice_vsi *vsi = pf->main_vsi;
-       struct rte_eth_dev *dev = pf->adapter->eth_dev;
+       struct rte_eth_dev_data *dev_data = pf->dev_data;
        struct ice_aq_get_set_rss_lut_params lut_params;
        struct rte_eth_rss_conf *rss_conf;
        struct ice_aqc_get_set_rss_keys key;
@@ -3070,8 +3189,8 @@ static int ice_init_rss(struct ice_pf *pf)
        bool is_safe_mode = pf->adapter->is_safe_mode;
        uint32_t reg;
 
-       rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
-       nb_q = dev->data->nb_rx_queues;
+       rss_conf = &dev_data->dev_conf.rx_adv_conf.rss_conf;
+       nb_q = dev_data->nb_rx_queues;
        vsi->rss_key_size = ICE_AQC_GET_SET_RSS_KEY_DATA_RSS_KEY_SIZE;
        vsi->rss_lut_size = pf->hash_lut_size;
 
@@ -3105,15 +3224,13 @@ static int ice_init_rss(struct ice_pf *pf)
                }
        }
        /* configure RSS key */
-       if (!rss_conf->rss_key) {
-               /* Calculate the default hash key */
-               for (i = 0; i <= vsi->rss_key_size; i++)
-                       vsi->rss_key[i] = (uint8_t)rte_rand();
-       } else {
+       if (!rss_conf->rss_key)
+               ice_get_default_rss_key(vsi->rss_key, vsi->rss_key_size);
+       else
                rte_memcpy(vsi->rss_key, rss_conf->rss_key,
                           RTE_MIN(rss_conf->rss_key_len,
                                   vsi->rss_key_size));
-       }
+
        rte_memcpy(key.standard_rss_key, vsi->rss_key, vsi->rss_key_size);
        ret = ice_aq_set_rss_key(hw, vsi->idx, &key);
        if (ret)
@@ -3184,8 +3301,9 @@ __vsi_queues_bind_intr(struct ice_vsi *vsi, uint16_t msix_vect,
 {
        struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
        uint32_t val, val_tx;
-       int i;
+       int rx_low_latency, i;
 
+       rx_low_latency = vsi->adapter->devargs.rx_low_latency;
        for (i = 0; i < nb_queue; i++) {
                /*do actual bind*/
                val = (msix_vect & QINT_RQCTL_MSIX_INDX_M) |
@@ -3195,8 +3313,21 @@ __vsi_queues_bind_intr(struct ice_vsi *vsi, uint16_t msix_vect,
 
                PMD_DRV_LOG(INFO, "queue %d is binding to vect %d",
                            base_queue + i, msix_vect);
+
                /* set ITR0 value */
-               ICE_WRITE_REG(hw, GLINT_ITR(0, msix_vect), 0x2);
+               if (rx_low_latency) {
+                       /**
+                        * Empirical configuration for optimal real time
+                        * latency reduced interrupt throttling to 2us
+                        */
+                       ICE_WRITE_REG(hw, GLINT_ITR(0, msix_vect), 0x1);
+                       ICE_WRITE_REG(hw, QRX_ITR(base_queue + i),
+                                     QRX_ITR_NO_EXPR_M);
+               } else {
+                       ICE_WRITE_REG(hw, GLINT_ITR(0, msix_vect), 0x2);
+                       ICE_WRITE_REG(hw, QRX_ITR(base_queue + i), 0);
+               }
+
                ICE_WRITE_REG(hw, QINT_RQCTL(base_queue + i), val);
                ICE_WRITE_REG(hw, QINT_TQCTL(base_queue + i), val_tx);
        }
@@ -3205,7 +3336,7 @@ __vsi_queues_bind_intr(struct ice_vsi *vsi, uint16_t msix_vect,
 void
 ice_vsi_queues_bind_intr(struct ice_vsi *vsi)
 {
-       struct rte_eth_dev *dev = vsi->adapter->eth_dev;
+       struct rte_eth_dev *dev = &rte_eth_devices[vsi->adapter->pf.dev_data->port_id];
        struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
@@ -3258,7 +3389,7 @@ ice_vsi_queues_bind_intr(struct ice_vsi *vsi)
 void
 ice_vsi_enable_queues_intr(struct ice_vsi *vsi)
 {
-       struct rte_eth_dev *dev = vsi->adapter->eth_dev;
+       struct rte_eth_dev *dev = &rte_eth_devices[vsi->adapter->pf.dev_data->port_id];
        struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
@@ -3351,6 +3482,49 @@ ice_get_init_link_status(struct rte_eth_dev *dev)
                pf->init_link_up = true;
 }
 
+static int
+ice_pps_out_cfg(struct ice_hw *hw, int idx, int timer)
+{
+       uint64_t current_time, start_time;
+       uint32_t hi, lo, lo2, func, val;
+
+       lo = ICE_READ_REG(hw, GLTSYN_TIME_L(timer));
+       hi = ICE_READ_REG(hw, GLTSYN_TIME_H(timer));
+       lo2 = ICE_READ_REG(hw, GLTSYN_TIME_L(timer));
+
+       if (lo2 < lo) {
+               lo = ICE_READ_REG(hw, GLTSYN_TIME_L(timer));
+               hi = ICE_READ_REG(hw, GLTSYN_TIME_H(timer));
+       }
+
+       current_time = ((uint64_t)hi << 32) | lo;
+
+       start_time = (current_time + NSEC_PER_SEC) /
+                       NSEC_PER_SEC * NSEC_PER_SEC;
+       start_time = start_time - PPS_OUT_DELAY_NS;
+
+       func = 8 + idx + timer * 4;
+       val = GLGEN_GPIO_CTL_PIN_DIR_M |
+               ((func << GLGEN_GPIO_CTL_PIN_FUNC_S) &
+               GLGEN_GPIO_CTL_PIN_FUNC_M);
+
+       /* Write clkout with half of period value */
+       ICE_WRITE_REG(hw, GLTSYN_CLKO(idx, timer), NSEC_PER_SEC / 2);
+
+       /* Write TARGET time register */
+       ICE_WRITE_REG(hw, GLTSYN_TGT_L(idx, timer), start_time & 0xffffffff);
+       ICE_WRITE_REG(hw, GLTSYN_TGT_H(idx, timer), start_time >> 32);
+
+       /* Write AUX_OUT register */
+       ICE_WRITE_REG(hw, GLTSYN_AUX_OUT(idx, timer),
+                     GLTSYN_AUX_OUT_0_OUT_ENA_M | GLTSYN_AUX_OUT_0_OUTMOD_M);
+
+       /* Write GPIO CTL register */
+       ICE_WRITE_REG(hw, GLGEN_GPIO_CTL(idx), val);
+
+       return 0;
+}
+
 static int
 ice_dev_start(struct rte_eth_dev *dev)
 {
@@ -3358,10 +3532,14 @@ ice_dev_start(struct rte_eth_dev *dev)
        struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct ice_vsi *vsi = pf->main_vsi;
+       struct ice_adapter *ad =
+                       ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
        uint16_t nb_rxq = 0;
        uint16_t nb_txq, i;
        uint16_t max_frame_size;
        int mask, ret;
+       uint8_t timer = hw->func_caps.ts_func_info.tmr_index_owned;
+       uint32_t pin_idx = ad->devargs.pin_idx;
 
        /* program Tx queues' context in hardware */
        for (nb_txq = 0; nb_txq < data->nb_tx_queues; nb_txq++) {
@@ -3425,13 +3603,21 @@ ice_dev_start(struct rte_eth_dev *dev)
        pf->adapter_stopped = false;
 
        /* Set the max frame size to default value*/
-       max_frame_size = pf->dev_data->dev_conf.rxmode.max_rx_pkt_len ?
-               pf->dev_data->dev_conf.rxmode.max_rx_pkt_len :
+       max_frame_size = pf->dev_data->mtu ?
+               pf->dev_data->mtu + ICE_ETH_OVERHEAD :
                ICE_FRAME_SIZE_MAX;
 
        /* Set the max frame size to HW*/
        ice_aq_set_mac_cfg(hw, max_frame_size, NULL);
 
+       if (ad->devargs.pps_out_ena) {
+               ret = ice_pps_out_cfg(hw, pin_idx, timer);
+               if (ret) {
+                       PMD_DRV_LOG(ERR, "Fail to configure 1pps out");
+                       goto rx_err;
+               }
+       }
+
        return 0;
 
        /* stop the started queues if failed to start all queues */
@@ -3509,7 +3695,8 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                        DEV_RX_OFFLOAD_QINQ_STRIP |
                        DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
                        DEV_RX_OFFLOAD_VLAN_EXTEND |
-                       DEV_RX_OFFLOAD_RSS_HASH;
+                       DEV_RX_OFFLOAD_RSS_HASH |
+                       DEV_RX_OFFLOAD_TIMESTAMP;
                dev_info->tx_offload_capa |=
                        DEV_TX_OFFLOAD_QINQ_INSERT |
                        DEV_TX_OFFLOAD_IPV4_CKSUM |
@@ -3522,7 +3709,7 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        }
 
        dev_info->rx_queue_offload_capa = 0;
-       dev_info->tx_queue_offload_capa = 0;
+       dev_info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
 
        dev_info->reta_size = pf->hash_lut_size;
        dev_info->hash_key_size = (VSIQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t);
@@ -3805,14 +3992,10 @@ ice_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
                return -EBUSY;
        }
 
-       if (frame_size > ICE_ETH_MAX_LEN)
-               dev_data->dev_conf.rxmode.offloads |=
-                       DEV_RX_OFFLOAD_JUMBO_FRAME;
+       if (mtu > RTE_ETHER_MTU)
+               dev_data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
        else
-               dev_data->dev_conf.rxmode.offloads &=
-                       ~DEV_RX_OFFLOAD_JUMBO_FRAME;
-
-       dev_data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+               dev_data->dev_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
 
        return 0;
 }
@@ -4447,8 +4630,10 @@ ice_rss_hash_update(struct rte_eth_dev *dev,
        if (status)
                return status;
 
-       if (rss_conf->rss_hf == 0)
+       if (rss_conf->rss_hf == 0) {
+               pf->rss_hf = 0;
                return 0;
+       }
 
        /* RSS hash configuration */
        ice_rss_hash_set(pf, rss_conf->rss_hf);
@@ -4507,8 +4692,11 @@ ice_promisc_disable(struct rte_eth_dev *dev)
        uint8_t pmask;
        int ret = 0;
 
-       pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX |
-               ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX;
+       if (dev->data->all_multicast == 1)
+               pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX;
+       else
+               pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX |
+                       ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX;
 
        status = ice_clear_vsi_promisc(hw, vsi->idx, pmask, 0);
        if (status != ICE_SUCCESS) {
@@ -4624,10 +4812,12 @@ ice_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
                        hw->flash.nvm.minor,
                        hw->flash.nvm.eetrack,
                        ver, build, patch);
+       if (ret < 0)
+               return -EINVAL;
 
        /* add the size of '\0' */
        ret += 1;
-       if (fw_size < (u32)ret)
+       if (fw_size < (size_t)ret)
                return ret;
        else
                return 0;
@@ -5255,30 +5445,14 @@ static int ice_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
 }
 
 static int
-ice_dev_filter_ctrl(struct rte_eth_dev *dev,
-                    enum rte_filter_type filter_type,
-                    enum rte_filter_op filter_op,
-                    void *arg)
+ice_dev_flow_ops_get(struct rte_eth_dev *dev,
+                    const struct rte_flow_ops **ops)
 {
-       int ret = 0;
-
        if (!dev)
                return -EINVAL;
 
-       switch (filter_type) {
-       case RTE_ETH_FILTER_GENERIC:
-               if (filter_op != RTE_ETH_FILTER_GET)
-                       return -EINVAL;
-               *(const void **)arg = &ice_flow_ops;
-               break;
-       default:
-               PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
-                                       filter_type);
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
+       *ops = &ice_flow_ops;
+       return 0;
 }
 
 /* Add UDP tunneling port */
@@ -5329,6 +5503,184 @@ ice_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
        return ret;
 }
 
+static int
+ice_timesync_enable(struct rte_eth_dev *dev)
+{
+       struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ice_adapter *ad =
+                       ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+       int ret;
+
+       if (dev->data->dev_started && !(dev->data->dev_conf.rxmode.offloads &
+           DEV_RX_OFFLOAD_TIMESTAMP)) {
+               PMD_DRV_LOG(ERR, "Rx timestamp offload not configured");
+               return -1;
+       }
+
+       if (hw->func_caps.ts_func_info.src_tmr_owned) {
+               ret = ice_ptp_init_phc(hw);
+               if (ret) {
+                       PMD_DRV_LOG(ERR, "Failed to initialize PHC");
+                       return -1;
+               }
+
+               ret = ice_ptp_write_incval(hw, ICE_PTP_NOMINAL_INCVAL_E810);
+               if (ret) {
+                       PMD_DRV_LOG(ERR,
+                               "Failed to write PHC increment time value");
+                       return -1;
+               }
+       }
+
+       /* Initialize cycle counters for system time/RX/TX timestamp */
+       memset(&ad->systime_tc, 0, sizeof(struct rte_timecounter));
+       memset(&ad->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
+       memset(&ad->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
+
+       ad->systime_tc.cc_mask = ICE_CYCLECOUNTER_MASK;
+       ad->systime_tc.cc_shift = 0;
+       ad->systime_tc.nsec_mask = 0;
+
+       ad->rx_tstamp_tc.cc_mask = ICE_CYCLECOUNTER_MASK;
+       ad->rx_tstamp_tc.cc_shift = 0;
+       ad->rx_tstamp_tc.nsec_mask = 0;
+
+       ad->tx_tstamp_tc.cc_mask = ICE_CYCLECOUNTER_MASK;
+       ad->tx_tstamp_tc.cc_shift = 0;
+       ad->tx_tstamp_tc.nsec_mask = 0;
+
+       ad->ptp_ena = 1;
+
+       return 0;
+}
+
+static int
+ice_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
+                              struct timespec *timestamp, uint32_t flags)
+{
+       struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ice_adapter *ad =
+                       ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+       struct ice_rx_queue *rxq;
+       uint32_t ts_high;
+       uint64_t ts_ns, ns;
+
+       rxq = dev->data->rx_queues[flags];
+
+       ts_high = rxq->time_high;
+       ts_ns = ice_tstamp_convert_32b_64b(hw, ts_high);
+       ns = rte_timecounter_update(&ad->rx_tstamp_tc, ts_ns);
+       *timestamp = rte_ns_to_timespec(ns);
+
+       return 0;
+}
+
+static int
+ice_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
+                              struct timespec *timestamp)
+{
+       struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ice_adapter *ad =
+                       ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+       uint8_t lport;
+       uint64_t ts_ns, ns, tstamp;
+       const uint64_t mask = 0xFFFFFFFF;
+       int ret;
+
+       lport = hw->port_info->lport;
+
+       ret = ice_read_phy_tstamp(hw, lport, 0, &tstamp);
+       if (ret) {
+               PMD_DRV_LOG(ERR, "Failed to read phy timestamp");
+               return -1;
+       }
+
+       ts_ns = ice_tstamp_convert_32b_64b(hw, (tstamp >> 8) & mask);
+       ns = rte_timecounter_update(&ad->tx_tstamp_tc, ts_ns);
+       *timestamp = rte_ns_to_timespec(ns);
+
+       return 0;
+}
+
+static int
+ice_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
+{
+       struct ice_adapter *ad =
+                       ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+       ad->systime_tc.nsec += delta;
+       ad->rx_tstamp_tc.nsec += delta;
+       ad->tx_tstamp_tc.nsec += delta;
+
+       return 0;
+}
+
+static int
+ice_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
+{
+       struct ice_adapter *ad =
+                       ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+       uint64_t ns;
+
+       ns = rte_timespec_to_ns(ts);
+
+       ad->systime_tc.nsec = ns;
+       ad->rx_tstamp_tc.nsec = ns;
+       ad->tx_tstamp_tc.nsec = ns;
+
+       return 0;
+}
+
+static int
+ice_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
+{
+       struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ice_adapter *ad =
+                       ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+       uint32_t hi, lo, lo2;
+       uint64_t time, ns;
+
+       lo = ICE_READ_REG(hw, GLTSYN_TIME_L(0));
+       hi = ICE_READ_REG(hw, GLTSYN_TIME_H(0));
+       lo2 = ICE_READ_REG(hw, GLTSYN_TIME_L(0));
+
+       if (lo2 < lo) {
+               lo = ICE_READ_REG(hw, GLTSYN_TIME_L(0));
+               hi = ICE_READ_REG(hw, GLTSYN_TIME_H(0));
+       }
+
+       time = ((uint64_t)hi << 32) | lo;
+       ns = rte_timecounter_update(&ad->systime_tc, time);
+       *ts = rte_ns_to_timespec(ns);
+
+       return 0;
+}
+
+static int
+ice_timesync_disable(struct rte_eth_dev *dev)
+{
+       struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ice_adapter *ad =
+                       ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+       uint64_t val;
+       uint8_t lport;
+
+       lport = hw->port_info->lport;
+
+       ice_clear_phy_tstamp(hw, lport, 0);
+
+       val = ICE_READ_REG(hw, GLTSYN_ENA(0));
+       val &= ~GLTSYN_ENA_TSYN_ENA_M;
+       ICE_WRITE_REG(hw, GLTSYN_ENA(0), val);
+
+       ICE_WRITE_REG(hw, GLTSYN_INCVAL_L(0), 0);
+       ICE_WRITE_REG(hw, GLTSYN_INCVAL_H(0), 0);
+
+       ad->ptp_ena = 0;
+
+       return 0;
+}
+
 static int
 ice_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
              struct rte_pci_device *pci_dev)
@@ -5360,18 +5712,17 @@ RTE_PMD_REGISTER_PCI(net_ice, rte_ice_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_ice, pci_id_ice_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_ice, "* igb_uio | uio_pci_generic | vfio-pci");
 RTE_PMD_REGISTER_PARAM_STRING(net_ice,
+                             ICE_HW_DEBUG_MASK_ARG "=0xXXX"
                              ICE_PROTO_XTR_ARG "=[queue:]<vlan|ipv4|ipv6|ipv6_flow|tcp|ip_offset>"
                              ICE_SAFE_MODE_SUPPORT_ARG "=<0|1>"
-                             ICE_PIPELINE_MODE_SUPPORT_ARG "=<0|1>");
+                             ICE_PIPELINE_MODE_SUPPORT_ARG "=<0|1>"
+                             ICE_RX_LOW_LATENCY_ARG "=<0|1>");
 
-RTE_LOG_REGISTER(ice_logtype_init, pmd.net.ice.init, NOTICE);
-RTE_LOG_REGISTER(ice_logtype_driver, pmd.net.ice.driver, NOTICE);
-#ifdef RTE_LIBRTE_ICE_DEBUG_RX
-RTE_LOG_REGISTER(ice_logtype_rx, pmd.net.ice.rx, DEBUG);
-#endif
-#ifdef RTE_LIBRTE_ICE_DEBUG_TX
-RTE_LOG_REGISTER(ice_logtype_tx, pmd.net.ice.tx, DEBUG);
+RTE_LOG_REGISTER_SUFFIX(ice_logtype_init, init, NOTICE);
+RTE_LOG_REGISTER_SUFFIX(ice_logtype_driver, driver, NOTICE);
+#ifdef RTE_ETHDEV_DEBUG_RX
+RTE_LOG_REGISTER_SUFFIX(ice_logtype_rx, rx, DEBUG);
 #endif
-#ifdef RTE_LIBRTE_ICE_DEBUG_TX_FREE
-RTE_LOG_REGISTER(ice_logtype_tx_free, pmd.net.ice.tx_free, DEBUG);
+#ifdef RTE_ETHDEV_DEBUG_TX
+RTE_LOG_REGISTER_SUFFIX(ice_logtype_tx, tx, DEBUG);
 #endif