+ 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
+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);
+ 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, "failed to open file: %s\n", pkg_file);
+ return -1;
+ }
+
+ err = stat(pkg_file, &fstat);
+ if (err) {
+ PMD_INIT_LOG(ERR, "failed to get file stats\n");
+ fclose(file);
+ return err;
+ }
+
+ buf_len = fstat.st_size;
+ buf = rte_malloc(NULL, buf_len, 0);
+
+ if (!buf) {
+ PMD_INIT_LOG(ERR, "failed to allocate buf of size %d for package\n",
+ buf_len);
+ fclose(file);
+ 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;
+ }
+
+ fclose(file);
+
+ err = ice_copy_and_init_pkg(hw, buf, buf_len);
+ if (err) {
+ 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);
+ goto fail_init_tbls;
+ }
+
+ return 0;
+
+fail_init_tbls:
+ rte_free(hw->pkg_copy);
+fail_exit:
+ rte_free(buf);
+ return err;
+}
+
+static void
+ice_base_queue_get(struct ice_pf *pf)
+{
+ uint32_t reg;
+ struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+ reg = ICE_READ_REG(hw, PFLAN_RX_QALLOC);
+ if (reg & PFLAN_RX_QALLOC_VALID_M) {
+ pf->base_queue = reg & PFLAN_RX_QALLOC_FIRSTQ_M;
+ } else {
+ PMD_INIT_LOG(WARNING, "Failed to get Rx base queue"
+ " index");
+ }
+}
+
+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;
+ }
+
+ ad->devargs.proto_xtr_dflt = PROTO_XTR_NONE;
+ 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);
+ if (ret)
+ goto bail;
+
+ ret = rte_kvargs_process(kvlist, ICE_PIPELINE_MODE_SUPPORT_ARG,
+ &parse_bool, &ad->devargs.pipe_mode_support);
+ if (ret)
+ goto bail;
+
+ ret = rte_kvargs_process(kvlist, ICE_FLOW_MARK_SUPPORT_ARG,
+ &parse_bool, &ad->devargs.flow_mark_support);
+ if (ret)
+ goto bail;
+
+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 enum ice_status
+ice_get_hw_res(struct ice_hw *hw, uint16_t res_type,
+ uint16_t num, uint16_t desc_id,
+ uint16_t *prof_buf, uint16_t *num_prof)
+{
+ struct ice_aqc_get_allocd_res_desc_resp *resp_buf;
+ int ret;
+ uint16_t buf_len;
+ bool res_shared = 1;
+ struct ice_aq_desc aq_desc;
+ struct ice_sq_cd *cd = NULL;
+ struct ice_aqc_get_allocd_res_desc *cmd =
+ &aq_desc.params.get_res_desc;
+
+ buf_len = sizeof(resp_buf->elem) * num;
+ resp_buf = ice_malloc(hw, buf_len);
+ if (!resp_buf)
+ return -ENOMEM;
+
+ ice_fill_dflt_direct_cmd_desc(&aq_desc,
+ ice_aqc_opc_get_allocd_res_desc);
+
+ cmd->ops.cmd.res = CPU_TO_LE16(((res_type << ICE_AQC_RES_TYPE_S) &
+ ICE_AQC_RES_TYPE_M) | (res_shared ?
+ ICE_AQC_RES_TYPE_FLAG_SHARED : 0));
+ cmd->ops.cmd.first_desc = CPU_TO_LE16(desc_id);
+
+ ret = ice_aq_send_cmd(hw, &aq_desc, resp_buf, buf_len, cd);
+ if (!ret)
+ *num_prof = LE16_TO_CPU(cmd->ops.resp.num_desc);
+ else
+ goto exit;
+
+ ice_memcpy(prof_buf, resp_buf->elem, sizeof(resp_buf->elem) *
+ (*num_prof), ICE_NONDMA_TO_NONDMA);
+
+exit:
+ rte_free(resp_buf);
+ return ret;
+}
+static int
+ice_cleanup_resource(struct ice_hw *hw, uint16_t res_type)
+{
+ int ret;
+ uint16_t prof_id;
+ uint16_t prof_buf[ICE_MAX_RES_DESC_NUM];
+ uint16_t first_desc = 1;
+ uint16_t num_prof = 0;
+
+ ret = ice_get_hw_res(hw, res_type, ICE_MAX_RES_DESC_NUM,
+ first_desc, prof_buf, &num_prof);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to get fxp resource");
+ return ret;
+ }
+
+ for (prof_id = 0; prof_id < num_prof; prof_id++) {
+ ret = ice_free_hw_res(hw, res_type, 1, &prof_buf[prof_id]);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to free fxp resource");
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int
+ice_reset_fxp_resource(struct ice_hw *hw)
+{
+ int ret;
+
+ ret = ice_cleanup_resource(hw, ICE_AQC_RES_TYPE_FD_PROF_BLDR_PROFID);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to clearup fdir resource");
+ return ret;
+ }
+
+ ret = ice_cleanup_resource(hw, ICE_AQC_RES_TYPE_HASH_PROF_BLDR_PROFID);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to clearup rss resource");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void
+ice_rss_ctx_init(struct ice_pf *pf)
+{
+ ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4);
+ ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6);
+
+ ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_udp);
+ ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_udp);
+
+ ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv4_tcp);
+ ICE_HASH_CFG_RESET(&pf->gtpu_hash_ctx.ipv6_tcp);
+}
+
+static int
+ice_dev_init(struct rte_eth_dev *dev)
+{
+ struct rte_pci_device *pci_dev;
+ struct rte_intr_handle *intr_handle;
+ 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_adapter *ad =
+ ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct ice_vsi *vsi;
+ int ret;
+
+ dev->dev_ops = &ice_eth_dev_ops;
+ dev->rx_pkt_burst = ice_recv_pkts;
+ 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;
+
+ 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;
+ hw->vendor_id = pci_dev->id.vendor_id;
+ hw->device_id = pci_dev->id.device_id;
+ hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
+ hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
+ 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);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to initialize HW");
+ return -EINVAL;
+ }
+
+ 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");
+ ad->is_safe_mode = 1;
+ }
+
+ PMD_INIT_LOG(INFO, "FW %d.%d.%05d API %d.%d",
+ hw->fw_maj_ver, hw->fw_min_ver, hw->fw_build,
+ hw->api_maj_ver, hw->api_min_ver);
+
+ ice_pf_sw_init(dev);
+ ret = ice_init_mac_address(dev);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to initialize mac address");
+ 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) {
+ PMD_INIT_LOG(ERR, "Failed to init MSIX pool");
+ goto err_msix_pool_init;
+ }
+
+ ret = ice_pf_setup(pf);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to setup PF");
+ goto err_pf_setup;
+ }
+
+ ret = ice_send_driver_ver(hw);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to send driver version");
+ goto err_pf_setup;
+ }
+
+ vsi = pf->main_vsi;
+
+ /* Disable double vlan by default */
+ ice_vsi_config_double_vlan(vsi, false);
+
+ 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);