#include "ice_rxtx.h"
#include "ice_switch_filter.h"
+/* devargs */
+#define ICE_SAFE_MODE_SUPPORT_ARG "safe-mode-support"
+#define ICE_PROTO_XTR_ARG "proto_xtr"
+
+static const char * const ice_valid_args[] = {
+ ICE_SAFE_MODE_SUPPORT_ARG,
+ ICE_PROTO_XTR_ARG,
+ NULL
+};
+
#define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
-#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg"
+
+/* DDP package search path */
+#define ICE_PKG_FILE_DEFAULT "/lib/firmware/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_UPDATES "/lib/firmware/updates/intel/ice/ddp/ice.pkg"
+#define ICE_PKG_FILE_SEARCH_PATH_DEFAULT "/lib/firmware/intel/ice/ddp/"
+#define ICE_PKG_FILE_SEARCH_PATH_UPDATES "/lib/firmware/updates/intel/ice/ddp/"
+
+#define ICE_OS_DEFAULT_PKG_NAME "ICE OS Default Package"
+#define ICE_COMMS_PKG_NAME "ICE COMMS Package"
+#define ICE_MAX_PKG_FILENAME_SIZE 256
int ice_logtype_init;
int ice_logtype_driver;
+#ifdef RTE_LIBRTE_ICE_DEBUG_RX
+int ice_logtype_rx;
+#endif
+#ifdef RTE_LIBRTE_ICE_DEBUG_TX
+int ice_logtype_tx;
+#endif
+#ifdef RTE_LIBRTE_ICE_DEBUG_TX_FREE
+int ice_logtype_tx_free;
+#endif
static int ice_dev_configure(struct rte_eth_dev *dev);
static int ice_dev_start(struct rte_eth_dev *dev);
static void ice_dev_stop(struct rte_eth_dev *dev);
static void ice_dev_close(struct rte_eth_dev *dev);
static int ice_dev_reset(struct rte_eth_dev *dev);
-static void ice_dev_info_get(struct rte_eth_dev *dev,
- struct rte_eth_dev_info *dev_info);
+static int ice_dev_info_get(struct rte_eth_dev *dev,
+ struct rte_eth_dev_info *dev_info);
static int ice_link_update(struct rte_eth_dev *dev,
int wait_to_complete);
static int ice_dev_set_link_up(struct rte_eth_dev *dev);
struct rte_eth_rss_conf *rss_conf);
static int ice_rss_hash_conf_get(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf);
-static void ice_promisc_enable(struct rte_eth_dev *dev);
-static void ice_promisc_disable(struct rte_eth_dev *dev);
-static void ice_allmulti_enable(struct rte_eth_dev *dev);
-static void ice_allmulti_disable(struct rte_eth_dev *dev);
+static int ice_promisc_enable(struct rte_eth_dev *dev);
+static int ice_promisc_disable(struct rte_eth_dev *dev);
+static int ice_allmulti_enable(struct rte_eth_dev *dev);
+static int ice_allmulti_disable(struct rte_eth_dev *dev);
static int ice_vlan_filter_set(struct rte_eth_dev *dev,
uint16_t vlan_id,
int on);
struct rte_dev_eeprom_info *eeprom);
static int ice_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
-static void ice_stats_reset(struct rte_eth_dev *dev);
+static int ice_stats_reset(struct rte_eth_dev *dev);
static int ice_xstats_get(struct rte_eth_dev *dev,
struct rte_eth_xstat *xstats, unsigned int n);
static int ice_xstats_get_names(struct rte_eth_dev *dev,
.vlan_pvid_set = ice_vlan_pvid_set,
.rxq_info_get = ice_rxq_info_get,
.txq_info_get = ice_txq_info_get,
+ .rx_burst_mode_get = ice_rx_burst_mode_get,
+ .tx_burst_mode_get = ice_tx_burst_mode_get,
.get_eeprom_length = ice_get_eeprom_length,
.get_eeprom = ice_get_eeprom,
.rx_queue_count = ice_rx_queue_count,
hw->mailboxq.sq_buf_size = ICE_MAILBOXQ_BUF_SZ;
}
+static int
+lookup_proto_xtr_type(const char *xtr_name)
+{
+ static struct {
+ const char *name;
+ enum proto_xtr_type type;
+ } xtr_type_map[] = {
+ { "vlan", PROTO_XTR_VLAN },
+ { "ipv4", PROTO_XTR_IPV4 },
+ { "ipv6", PROTO_XTR_IPV6 },
+ { "ipv6_flow", PROTO_XTR_IPV6_FLOW },
+ { "tcp", PROTO_XTR_TCP },
+ };
+ uint32_t i;
+
+ for (i = 0; i < RTE_DIM(xtr_type_map); i++) {
+ if (strcmp(xtr_name, xtr_type_map[i].name) == 0)
+ return xtr_type_map[i].type;
+ }
+
+ return -1;
+}
+
+/*
+ * Parse elem, the elem could be single number/range or '(' ')' group
+ * 1) A single number elem, it's just a simple digit. e.g. 9
+ * 2) A single range elem, two digits with a '-' between. e.g. 2-6
+ * 3) A group elem, combines multiple 1) or 2) with '( )'. e.g (0,2-4,6)
+ * Within group elem, '-' used for a range separator;
+ * ',' used for a single number.
+ */
+static int
+parse_queue_set(const char *input, int xtr_type, struct ice_devargs *devargs)
+{
+ const char *str = input;
+ char *end = NULL;
+ uint32_t min, max;
+ uint32_t idx;
+
+ while (isblank(*str))
+ str++;
+
+ if (!isdigit(*str) && *str != '(')
+ return -1;
+
+ /* process single number or single range of number */
+ if (*str != '(') {
+ errno = 0;
+ idx = strtoul(str, &end, 10);
+ if (errno || end == NULL || idx >= ICE_MAX_QUEUE_NUM)
+ return -1;
+
+ while (isblank(*end))
+ end++;
+
+ min = idx;
+ max = idx;
+
+ /* process single <number>-<number> */
+ if (*end == '-') {
+ end++;
+ while (isblank(*end))
+ end++;
+ if (!isdigit(*end))
+ return -1;
+
+ errno = 0;
+ idx = strtoul(end, &end, 10);
+ if (errno || end == NULL || idx >= ICE_MAX_QUEUE_NUM)
+ return -1;
+
+ max = idx;
+ while (isblank(*end))
+ end++;
+ }
+
+ if (*end != ':')
+ return -1;
+
+ for (idx = RTE_MIN(min, max);
+ idx <= RTE_MAX(min, max); idx++)
+ devargs->proto_xtr[idx] = xtr_type;
+
+ return 0;
+ }
+
+ /* process set within bracket */
+ str++;
+ while (isblank(*str))
+ str++;
+ if (*str == '\0')
+ return -1;
+
+ min = ICE_MAX_QUEUE_NUM;
+ do {
+ /* go ahead to the first digit */
+ while (isblank(*str))
+ str++;
+ if (!isdigit(*str))
+ return -1;
+
+ /* get the digit value */
+ errno = 0;
+ idx = strtoul(str, &end, 10);
+ if (errno || end == NULL || idx >= ICE_MAX_QUEUE_NUM)
+ return -1;
+
+ /* go ahead to separator '-',',' and ')' */
+ while (isblank(*end))
+ end++;
+ if (*end == '-') {
+ if (min == ICE_MAX_QUEUE_NUM)
+ min = idx;
+ else /* avoid continuous '-' */
+ return -1;
+ } else if (*end == ',' || *end == ')') {
+ max = idx;
+ if (min == ICE_MAX_QUEUE_NUM)
+ min = idx;
+
+ for (idx = RTE_MIN(min, max);
+ idx <= RTE_MAX(min, max); idx++)
+ devargs->proto_xtr[idx] = xtr_type;
+
+ min = ICE_MAX_QUEUE_NUM;
+ } else {
+ return -1;
+ }
+
+ str = end + 1;
+ } while (*end != ')' && *end != '\0');
+
+ return 0;
+}
+
+static int
+parse_queue_proto_xtr(const char *queues, struct ice_devargs *devargs)
+{
+ const char *queue_start;
+ uint32_t idx;
+ int xtr_type;
+ char xtr_name[32];
+
+ while (isblank(*queues))
+ queues++;
+
+ if (*queues != '[') {
+ xtr_type = lookup_proto_xtr_type(queues);
+ if (xtr_type < 0)
+ return -1;
+
+ memset(devargs->proto_xtr, xtr_type,
+ sizeof(devargs->proto_xtr));
+
+ return 0;
+ }
+
+ queues++;
+ do {
+ while (isblank(*queues))
+ queues++;
+ if (*queues == '\0')
+ return -1;
+
+ queue_start = queues;
+
+ /* go across a complete bracket */
+ if (*queue_start == '(') {
+ queues += strcspn(queues, ")");
+ if (*queues != ')')
+ return -1;
+ }
+
+ /* scan the separator ':' */
+ queues += strcspn(queues, ":");
+ if (*queues++ != ':')
+ return -1;
+ while (isblank(*queues))
+ queues++;
+
+ for (idx = 0; ; idx++) {
+ if (isblank(queues[idx]) ||
+ queues[idx] == ',' ||
+ queues[idx] == ']' ||
+ queues[idx] == '\0')
+ break;
+
+ if (idx > sizeof(xtr_name) - 2)
+ return -1;
+
+ xtr_name[idx] = queues[idx];
+ }
+ xtr_name[idx] = '\0';
+ xtr_type = lookup_proto_xtr_type(xtr_name);
+ if (xtr_type < 0)
+ return -1;
+
+ queues += idx;
+
+ while (isblank(*queues) || *queues == ',' || *queues == ']')
+ queues++;
+
+ if (parse_queue_set(queue_start, xtr_type, devargs) < 0)
+ return -1;
+ } while (*queues != '\0');
+
+ return 0;
+}
+
+static int
+handle_proto_xtr_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_queue_proto_xtr(value, devargs) < 0) {
+ PMD_DRV_LOG(ERR,
+ "The protocol extraction parameter is wrong : '%s'",
+ value);
+ return -1;
+ }
+
+ return 0;
+}
+
+static bool
+ice_proto_xtr_support(struct ice_hw *hw)
+{
+#define FLX_REG(val, fld, idx) \
+ (((val) & GLFLXP_RXDID_FLX_WRD_##idx##_##fld##_M) >> \
+ GLFLXP_RXDID_FLX_WRD_##idx##_##fld##_S)
+ static struct {
+ uint32_t rxdid;
+ uint16_t protid_0;
+ uint16_t protid_1;
+ } xtr_sets[] = {
+ { ICE_RXDID_COMMS_AUX_VLAN, ICE_PROT_EVLAN_O, ICE_PROT_VLAN_O },
+ { ICE_RXDID_COMMS_AUX_IPV4, ICE_PROT_IPV4_OF_OR_S,
+ ICE_PROT_IPV4_OF_OR_S },
+ { ICE_RXDID_COMMS_AUX_IPV6, ICE_PROT_IPV6_OF_OR_S,
+ ICE_PROT_IPV6_OF_OR_S },
+ { ICE_RXDID_COMMS_AUX_IPV6_FLOW, ICE_PROT_IPV6_OF_OR_S,
+ ICE_PROT_IPV6_OF_OR_S },
+ { ICE_RXDID_COMMS_AUX_TCP, ICE_PROT_TCP_IL, ICE_PROT_ID_INVAL },
+ };
+ uint32_t i;
+
+ for (i = 0; i < RTE_DIM(xtr_sets); i++) {
+ uint32_t rxdid = xtr_sets[i].rxdid;
+ uint32_t v;
+
+ if (xtr_sets[i].protid_0 != ICE_PROT_ID_INVAL) {
+ v = ICE_READ_REG(hw, GLFLXP_RXDID_FLX_WRD_4(rxdid));
+
+ if (FLX_REG(v, PROT_MDID, 4) != xtr_sets[i].protid_0 ||
+ FLX_REG(v, RXDID_OPCODE, 4) != ICE_RX_OPC_EXTRACT)
+ return false;
+ }
+
+ if (xtr_sets[i].protid_1 != ICE_PROT_ID_INVAL) {
+ v = ICE_READ_REG(hw, GLFLXP_RXDID_FLX_WRD_5(rxdid));
+
+ if (FLX_REG(v, PROT_MDID, 5) != xtr_sets[i].protid_1 ||
+ FLX_REG(v, RXDID_OPCODE, 5) != ICE_RX_OPC_EXTRACT)
+ return false;
+ }
+ }
+
+ return true;
+}
+
static int
ice_res_pool_init(struct ice_res_pool_info *pool, uint32_t base,
uint32_t num)
static int
ice_pf_sw_init(struct rte_eth_dev *dev)
{
+ struct ice_adapter *ad =
+ ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_hw *hw = ICE_PF_TO_HW(pf);
pf->lan_nb_qps = pf->lan_nb_qp_max;
+ if (ice_proto_xtr_support(hw))
+ pf->proto_xtr = rte_zmalloc(NULL, pf->lan_nb_qps, 0);
+
+ if (pf->proto_xtr != NULL)
+ rte_memcpy(pf->proto_xtr, ad->devargs.proto_xtr,
+ RTE_MIN((size_t)pf->lan_nb_qps,
+ sizeof(ad->devargs.proto_xtr)));
+ else
+ PMD_DRV_LOG(NOTICE, "Protocol extraction is disabled");
+
return 0;
}
return 0;
}
+/* PCIe configuration space setting */
+#define PCI_CFG_SPACE_SIZE 256
+#define PCI_CFG_SPACE_EXP_SIZE 4096
+#define PCI_EXT_CAP_ID(header) (int)((header) & 0x0000ffff)
+#define PCI_EXT_CAP_NEXT(header) (((header) >> 20) & 0xffc)
+#define PCI_EXT_CAP_ID_DSN 0x03
+
+static int
+ice_pci_find_next_ext_capability(struct rte_pci_device *dev, int cap)
+{
+ uint32_t header;
+ int ttl;
+ int pos = PCI_CFG_SPACE_SIZE;
+
+ /* minimum 8 bytes per capability */
+ ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+ if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+ PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+ return -1;
+ }
+
+ /*
+ * If we have no capabilities, this is indicated by cap ID,
+ * cap version and next pointer all being 0.
+ */
+ if (header == 0)
+ return 0;
+
+ while (ttl-- > 0) {
+ if (PCI_EXT_CAP_ID(header) == cap)
+ return pos;
+
+ pos = PCI_EXT_CAP_NEXT(header);
+
+ if (pos < PCI_CFG_SPACE_SIZE)
+ break;
+
+ if (rte_pci_read_config(dev, &header, 4, pos) < 0) {
+ PMD_INIT_LOG(ERR, "ice error reading extended capabilities\n");
+ return -1;
+ }
+ }
+
+ 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)
+{
+ int 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 = ice_pci_find_next_ext_capability(pci_dev, 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;
+}
+
+static enum ice_pkg_type
+ice_load_pkg_type(struct ice_hw *hw)
+{
+ enum ice_pkg_type package_type;
+
+ /* store the activated package type (OS default or Comms) */
+ if (!strncmp((char *)hw->active_pkg_name, ICE_OS_DEFAULT_PKG_NAME,
+ ICE_PKG_NAME_SIZE))
+ package_type = ICE_PKG_TYPE_OS_DEFAULT;
+ else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME,
+ ICE_PKG_NAME_SIZE))
+ package_type = ICE_PKG_TYPE_COMMS;
+ else
+ package_type = ICE_PKG_TYPE_UNKNOWN;
+
+ PMD_INIT_LOG(NOTICE, "Active package is: %d.%d.%d.%d, %s",
+ hw->active_pkg_ver.major, hw->active_pkg_ver.minor,
+ hw->active_pkg_ver.update, hw->active_pkg_ver.draft,
+ hw->active_pkg_name);
+
+ return package_type;
+}
+
static int ice_load_pkg(struct rte_eth_dev *dev)
{
struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- const char *pkg_file = ICE_DFLT_PKG_FILE;
+ char pkg_file[ICE_MAX_PKG_FILENAME_SIZE];
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);
file = fopen(pkg_file, "rb");
if (!file) {
PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err);
goto fail_exit;
}
+
+ /* 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);
}
}
+static int
+parse_bool(const char *key, const char *value, void *args)
+{
+ int *i = (int *)args;
+ char *end;
+ int num;
+
+ num = strtoul(value, &end, 10);
+
+ if (num != 0 && num != 1) {
+ PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
+ "value must be 0 or 1",
+ value, key);
+ return -1;
+ }
+
+ *i = num;
+ return 0;
+}
+
+static int ice_parse_devargs(struct rte_eth_dev *dev)
+{
+ struct ice_adapter *ad =
+ ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct rte_devargs *devargs = dev->device->devargs;
+ struct rte_kvargs *kvlist;
+ int ret;
+
+ if (devargs == NULL)
+ return 0;
+
+ kvlist = rte_kvargs_parse(devargs->args, ice_valid_args);
+ if (kvlist == NULL) {
+ PMD_INIT_LOG(ERR, "Invalid kvargs key\n");
+ return -EINVAL;
+ }
+
+ memset(ad->devargs.proto_xtr, PROTO_XTR_NONE,
+ sizeof(ad->devargs.proto_xtr));
+
+ ret = rte_kvargs_process(kvlist, ICE_PROTO_XTR_ARG,
+ &handle_proto_xtr_arg, &ad->devargs);
+ if (ret)
+ goto bail;
+
+ ret = rte_kvargs_process(kvlist, ICE_SAFE_MODE_SUPPORT_ARG,
+ &parse_bool, &ad->devargs.safe_mode_support);
+
+bail:
+ rte_kvargs_free(kvlist);
+ return ret;
+}
+
+/* Forward LLDP packets to default VSI by set switch rules */
+static int
+ice_vsi_config_sw_lldp(struct ice_vsi *vsi, bool on)
+{
+ struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
+ struct ice_fltr_list_entry *s_list_itr = NULL;
+ struct LIST_HEAD_TYPE list_head;
+ int ret = 0;
+
+ INIT_LIST_HEAD(&list_head);
+
+ s_list_itr = (struct ice_fltr_list_entry *)
+ ice_malloc(hw, sizeof(*s_list_itr));
+ if (!s_list_itr)
+ return -ENOMEM;
+ s_list_itr->fltr_info.lkup_type = ICE_SW_LKUP_ETHERTYPE;
+ s_list_itr->fltr_info.vsi_handle = vsi->idx;
+ s_list_itr->fltr_info.l_data.ethertype_mac.ethertype =
+ RTE_ETHER_TYPE_LLDP;
+ s_list_itr->fltr_info.fltr_act = ICE_FWD_TO_VSI;
+ s_list_itr->fltr_info.flag = ICE_FLTR_RX;
+ s_list_itr->fltr_info.src_id = ICE_SRC_ID_LPORT;
+ LIST_ADD(&s_list_itr->list_entry, &list_head);
+ if (on)
+ ret = ice_add_eth_mac(hw, &list_head);
+ else
+ ret = ice_remove_eth_mac(hw, &list_head);
+
+ rte_free(s_list_itr);
+ return ret;
+}
+
static int
ice_dev_init(struct rte_eth_dev *dev)
{
dev->tx_pkt_burst = ice_xmit_pkts;
dev->tx_pkt_prepare = ice_prep_pkts;
+ /* for secondary processes, we don't initialise any further as primary
+ * has already done this work.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ ice_set_rx_function(dev);
+ ice_set_tx_function(dev);
+ return 0;
+ }
+
ice_set_default_ptype_table(dev);
pci_dev = RTE_DEV_TO_PCI(dev->device);
intr_handle = &pci_dev->intr_handle;
hw->bus.device = pci_dev->addr.devid;
hw->bus.func = pci_dev->addr.function;
+ ret = ice_parse_devargs(dev);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to parse devargs");
+ return -EINVAL;
+ }
+
ice_init_controlq_parameter(hw);
ret = ice_init_hw(hw);
ret = ice_load_pkg(dev);
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;
+ }
+
PMD_INIT_LOG(WARNING, "Failed to load the DDP package,"
- "Entering Safe Mode");
+ "Entering Safe Mode");
ad->is_safe_mode = 1;
}
goto err_init_mac;
}
+ /* 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;
+
ret = ice_res_pool_init(&pf->msix_pool, 1,
hw->func_caps.common_cap.num_msix_vectors - 1);
if (ret) {
ret = ice_aq_stop_lldp(hw, TRUE, FALSE, NULL);
if (ret != ICE_SUCCESS)
PMD_INIT_LOG(DEBUG, "lldp has already stopped\n");
-
+ ret = ice_init_dcb(hw, TRUE);
+ if (ret != ICE_SUCCESS)
+ PMD_INIT_LOG(DEBUG, "Failed to init DCB\n");
+ /* Forward LLDP packets to default VSI */
+ ret = ice_vsi_config_sw_lldp(vsi, TRUE);
+ if (ret != ICE_SUCCESS)
+ PMD_INIT_LOG(DEBUG, "Failed to cfg lldp\n");
/* register callback func to eal lib */
rte_intr_callback_register(intr_handle,
ice_interrupt_handler, dev);
ice_sched_cleanup_all(hw);
rte_free(hw->port_info);
ice_shutdown_all_ctrlq(hw);
+ rte_free(pf->proto_xtr);
return ret;
}
{
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_hw *hw = ICE_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 rte_flow *p_flow;
/* Since stop will make link down, then the link event will be
* triggered, disable the irq firstly to avoid the port_infoe etc
rte_free(hw->port_info);
hw->port_info = NULL;
ice_shutdown_all_ctrlq(hw);
-}
-
-static int
-ice_dev_uninit(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 ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
- struct rte_flow *p_flow;
-
- ice_dev_close(dev);
+ rte_free(pf->proto_xtr);
+ pf->proto_xtr = NULL;
dev->dev_ops = NULL;
dev->rx_pkt_burst = NULL;
ice_free_switch_filter_rule(p_flow->rule);
rte_free(p_flow);
}
+}
+
+static int
+ice_dev_uninit(struct rte_eth_dev *dev)
+{
+ ice_dev_close(dev);
return 0;
}
static int
-ice_dev_configure(__rte_unused struct rte_eth_dev *dev)
+ice_dev_configure(struct rte_eth_dev *dev)
{
struct ice_adapter *ad =
ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
/* configure RSS for IPv4 with input set IPv4 src/dst */
ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV4,
- ICE_FLOW_SEG_HDR_IPV4);
+ ICE_FLOW_SEG_HDR_IPV4, 0);
if (ret)
PMD_DRV_LOG(ERR, "%s IPV4 rss flow fail %d", __func__, ret);
/* configure RSS for IPv6 with input set IPv6 src/dst */
ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV6,
- ICE_FLOW_SEG_HDR_IPV6);
+ ICE_FLOW_SEG_HDR_IPV6, 0);
if (ret)
PMD_DRV_LOG(ERR, "%s IPV6 rss flow fail %d", __func__, ret);
/* configure RSS for tcp6 with input set IPv6 src/dst, TCP src/dst */
ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV6,
- ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV6);
+ ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV6, 0);
if (ret)
PMD_DRV_LOG(ERR, "%s TCP_IPV6 rss flow fail %d", __func__, ret);
/* configure RSS for udp6 with input set IPv6 src/dst, UDP src/dst */
ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV6,
- ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6);
+ ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6, 0);
if (ret)
PMD_DRV_LOG(ERR, "%s UDP_IPV6 rss flow fail %d", __func__, ret);
/* configure RSS for sctp6 with input set IPv6 src/dst */
ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV6,
- ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV6);
+ ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV6, 0);
if (ret)
PMD_DRV_LOG(ERR, "%s SCTP_IPV6 rss flow fail %d",
__func__, ret);
/* configure RSS for tcp4 with input set IP src/dst, TCP src/dst */
ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV4,
- ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4);
+ ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4, 0);
if (ret)
PMD_DRV_LOG(ERR, "%s TCP_IPV4 rss flow fail %d", __func__, ret);
/* configure RSS for udp4 with input set IP src/dst, UDP src/dst */
ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV4,
- ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4);
+ ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4, 0);
if (ret)
PMD_DRV_LOG(ERR, "%s UDP_IPV4 rss flow fail %d", __func__, ret);
/* configure RSS for sctp4 with input set IP src/dst */
ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV4,
- ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4);
+ ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4, 0);
if (ret)
PMD_DRV_LOG(ERR, "%s SCTP_IPV4 rss flow fail %d",
__func__, ret);
return 0;
}
-static void
+static int
ice_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
dev_info->default_txportconf.nb_queues = 1;
dev_info->default_rxportconf.ring_size = ICE_BUF_SIZE_MIN;
dev_info->default_txportconf.ring_size = ICE_BUF_SIZE_MIN;
+
+ return 0;
}
static inline int
return 0;
}
-static void
+static int
ice_promisc_enable(struct rte_eth_dev *dev)
{
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_vsi *vsi = pf->main_vsi;
enum ice_status status;
uint8_t pmask;
+ int ret = 0;
pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX |
ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX;
status = ice_set_vsi_promisc(hw, vsi->idx, pmask, 0);
- if (status == ICE_ERR_ALREADY_EXISTS)
+ switch (status) {
+ case ICE_ERR_ALREADY_EXISTS:
PMD_DRV_LOG(DEBUG, "Promisc mode has already been enabled");
- else if (status != ICE_SUCCESS)
+ case ICE_SUCCESS:
+ break;
+ default:
PMD_DRV_LOG(ERR, "Failed to enable promisc, err=%d", status);
+ ret = -EAGAIN;
+ }
+
+ return ret;
}
-static void
+static int
ice_promisc_disable(struct rte_eth_dev *dev)
{
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_vsi *vsi = pf->main_vsi;
enum ice_status status;
uint8_t pmask;
+ int ret = 0;
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)
+ if (status != ICE_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to clear promisc, err=%d", status);
+ ret = -EAGAIN;
+ }
+
+ return ret;
}
-static void
+static int
ice_allmulti_enable(struct rte_eth_dev *dev)
{
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_vsi *vsi = pf->main_vsi;
enum ice_status status;
uint8_t pmask;
+ int ret = 0;
pmask = ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX;
status = ice_set_vsi_promisc(hw, vsi->idx, pmask, 0);
- if (status != ICE_SUCCESS)
+
+ switch (status) {
+ case ICE_ERR_ALREADY_EXISTS:
+ PMD_DRV_LOG(DEBUG, "Allmulti has already been enabled");
+ case ICE_SUCCESS:
+ break;
+ default:
PMD_DRV_LOG(ERR, "Failed to enable allmulti, err=%d", status);
+ ret = -EAGAIN;
+ }
+
+ return ret;
}
-static void
+static int
ice_allmulti_disable(struct rte_eth_dev *dev)
{
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct ice_vsi *vsi = pf->main_vsi;
enum ice_status status;
uint8_t pmask;
+ int ret = 0;
if (dev->data->promiscuous == 1)
- return; /* must remain in all_multicast mode */
+ return 0; /* must remain in all_multicast mode */
pmask = ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX;
status = ice_clear_vsi_promisc(hw, vsi->idx, pmask, 0);
- if (status != ICE_SUCCESS)
+ if (status != ICE_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to clear allmulti, err=%d", status);
+ ret = -EAGAIN;
+ }
+
+ return ret;
}
static int ice_rx_queue_intr_enable(struct rte_eth_dev *dev,
}
/* Reset the statistics */
-static void
+static int
ice_stats_reset(struct rte_eth_dev *dev)
{
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
/* read the stats, reading current register values into offset */
ice_read_stats_registers(pf, hw);
+
+ return 0;
}
static uint32_t
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_PROTO_XTR_ARG "=[queue:]<vlan|ipv4|ipv6|ipv6_flow|tcp>"
+ ICE_SAFE_MODE_SUPPORT_ARG "=<0|1>");
RTE_INIT(ice_init_log)
{
ice_logtype_driver = rte_log_register("pmd.net.ice.driver");
if (ice_logtype_driver >= 0)
rte_log_set_level(ice_logtype_driver, RTE_LOG_NOTICE);
+
+#ifdef RTE_LIBRTE_ICE_DEBUG_RX
+ ice_logtype_rx = rte_log_register("pmd.net.ice.rx");
+ if (ice_logtype_rx >= 0)
+ rte_log_set_level(ice_logtype_rx, RTE_LOG_DEBUG);
+#endif
+
+#ifdef RTE_LIBRTE_ICE_DEBUG_TX
+ ice_logtype_tx = rte_log_register("pmd.net.ice.tx");
+ if (ice_logtype_tx >= 0)
+ rte_log_set_level(ice_logtype_tx, RTE_LOG_DEBUG);
+#endif
+
+#ifdef RTE_LIBRTE_ICE_DEBUG_TX_FREE
+ ice_logtype_tx_free = rte_log_register("pmd.net.ice.tx_free");
+ if (ice_logtype_tx_free >= 0)
+ rte_log_set_level(ice_logtype_tx_free, RTE_LOG_DEBUG);
+#endif
}