From patchwork Wed Jun 2 09:58:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 93789 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0782BA0524; Wed, 2 Jun 2021 11:58:55 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id DD4B8410E1; Wed, 2 Jun 2021 11:58:54 +0200 (CEST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id A7C86410E0 for ; Wed, 2 Jun 2021 11:58:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1622627933; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bVXse72thaudOt56LqRwaH31hc3Q/ogOXea1Dym4xJk=; b=R6ecfMSG474PzsxYDnZ0+x8rKBios86PbSTA9C8G6oCGgaZrrh4ljCTWaECEaSuTIOFyEk PQDo2Wj6uGavgsCip7MEUBZwno9f+0vjOD4hHDI63ne2gUAiupCVSqYPEfl2/AQqp/Kp4s okmmlSOfknwqzqgIHNunUFRudhxvueg= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-226-JSaRJz69PDObvSsuwScuEw-1; Wed, 02 Jun 2021 05:58:51 -0400 X-MC-Unique: JSaRJz69PDObvSsuwScuEw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C7FB1107ACC7; Wed, 2 Jun 2021 09:58:50 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.193.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2327C5944D; Wed, 2 Jun 2021 09:58:48 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Qiming Yang , Qi Zhang Date: Wed, 2 Jun 2021 11:58:35 +0200 Message-Id: <20210602095836.24901-2-david.marchand@redhat.com> In-Reply-To: <20210602095836.24901-1-david.marchand@redhat.com> References: <20210602095836.24901-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david.marchand@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH 1/2] net/ice: factorize firmware loading X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Both "normal" and "dcf" inits have their copy of some firmware loading code. The DSN query is moved in specific parts for the "normal" and "dcf" init. A common helper ice_load_pkg is then introduced and takes an adapter pointer as its main input. This helper takes care of finding the right firmware file and loading it. The adapter active_pkg_type field is set by this helper. The ice_access macro is removed from the osdep.h header: osdep.h should only hosts wrappers for base driver code. Signed-off-by: David Marchand --- drivers/net/ice/base/ice_osdep.h | 6 -- drivers/net/ice/ice_dcf_parent.c | 97 ++----------------- drivers/net/ice/ice_ethdev.c | 161 +++++++++++++++---------------- drivers/net/ice/ice_ethdev.h | 3 +- 4 files changed, 88 insertions(+), 179 deletions(-) diff --git a/drivers/net/ice/base/ice_osdep.h b/drivers/net/ice/base/ice_osdep.h index 878c5597d4..78093adb00 100644 --- a/drivers/net/ice/base/ice_osdep.h +++ b/drivers/net/ice/base/ice_osdep.h @@ -74,12 +74,6 @@ typedef uint64_t s64; #define min(a, b) RTE_MIN(a, b) #define max(a, b) RTE_MAX(a, b) -#ifdef RTE_EXEC_ENV_WINDOWS -#define ice_access _access -#else -#define ice_access access -#endif - #define FIELD_SIZEOF(t, f) RTE_SIZEOF_FIELD(t, f) #define ARRAY_SIZE(arr) RTE_DIM(arr) diff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c index 1d7aa8bc87..a30cfefaaf 100644 --- a/drivers/net/ice/ice_dcf_parent.c +++ b/drivers/net/ice/ice_dcf_parent.c @@ -298,13 +298,14 @@ static void ice_dcf_uninit_parent_hw(struct ice_hw *hw) } static int -ice_dcf_request_pkg_name(struct ice_hw *hw, char *pkg_name) +ice_dcf_load_pkg(struct ice_adapter *adapter) { struct ice_dcf_adapter *dcf_adapter = - container_of(hw, struct ice_dcf_adapter, parent.hw); + container_of(&adapter->hw, struct ice_dcf_adapter, parent.hw); struct virtchnl_pkg_info pkg_info; struct dcf_virtchnl_cmd vc_cmd; - uint64_t dsn; + bool use_dsn; + uint64_t dsn = 0; vc_cmd.v_op = VIRTCHNL_OP_DCF_GET_PKG_INFO; vc_cmd.req_msglen = 0; @@ -312,90 +313,11 @@ ice_dcf_request_pkg_name(struct ice_hw *hw, char *pkg_name) vc_cmd.rsp_buflen = sizeof(pkg_info); vc_cmd.rsp_msgbuf = (uint8_t *)&pkg_info; - if (ice_dcf_execute_virtchnl_cmd(&dcf_adapter->real_hw, &vc_cmd)) - goto pkg_file_direct; + use_dsn = ice_dcf_execute_virtchnl_cmd(&dcf_adapter->real_hw, &vc_cmd) == 0; + if (use_dsn) + rte_memcpy(&dsn, pkg_info.dsn, sizeof(dsn)); - rte_memcpy(&dsn, pkg_info.dsn, sizeof(dsn)); - - snprintf(pkg_name, ICE_MAX_PKG_FILENAME_SIZE, - ICE_PKG_FILE_SEARCH_PATH_UPDATES "ice-%016llx.pkg", - (unsigned long long)dsn); - if (!ice_access(pkg_name, 0)) - return 0; - - snprintf(pkg_name, ICE_MAX_PKG_FILENAME_SIZE, - ICE_PKG_FILE_SEARCH_PATH_DEFAULT "ice-%016llx.pkg", - (unsigned long long)dsn); - if (!ice_access(pkg_name, 0)) - return 0; - -pkg_file_direct: - snprintf(pkg_name, - ICE_MAX_PKG_FILENAME_SIZE, "%s", ICE_PKG_FILE_UPDATES); - if (!ice_access(pkg_name, 0)) - return 0; - - snprintf(pkg_name, - ICE_MAX_PKG_FILENAME_SIZE, "%s", ICE_PKG_FILE_DEFAULT); - if (!ice_access(pkg_name, 0)) - return 0; - - return -1; -} - -static int -ice_dcf_load_pkg(struct ice_hw *hw) -{ - char pkg_name[ICE_MAX_PKG_FILENAME_SIZE]; - uint8_t *pkg_buf; - uint32_t buf_len; - struct stat st; - FILE *fp; - int err; - - if (ice_dcf_request_pkg_name(hw, pkg_name)) { - PMD_INIT_LOG(ERR, "Failed to locate the package file"); - return -ENOENT; - } - - PMD_INIT_LOG(DEBUG, "DDP package name: %s", pkg_name); - - err = stat(pkg_name, &st); - if (err) { - PMD_INIT_LOG(ERR, "Failed to get file status"); - return err; - } - - buf_len = st.st_size; - pkg_buf = rte_malloc(NULL, buf_len, 0); - if (!pkg_buf) { - PMD_INIT_LOG(ERR, "failed to allocate buffer of size %u for package", - buf_len); - return -1; - } - - fp = fopen(pkg_name, "rb"); - if (!fp) { - PMD_INIT_LOG(ERR, "failed to open file: %s", pkg_name); - err = -1; - goto ret; - } - - err = fread(pkg_buf, buf_len, 1, fp); - fclose(fp); - if (err != 1) { - PMD_INIT_LOG(ERR, "failed to read package data"); - err = -1; - goto ret; - } - - err = ice_copy_and_init_pkg(hw, pkg_buf, buf_len); - if (err) - PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d", err); - -ret: - rte_free(pkg_buf); - return err; + return ice_load_pkg(adapter, use_dsn, dsn); } int @@ -436,13 +358,12 @@ ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev) return err; } - err = ice_dcf_load_pkg(parent_hw); + err = ice_dcf_load_pkg(parent_adapter); if (err) { PMD_INIT_LOG(ERR, "failed to load package with error %d", err); goto uninit_hw; } - parent_adapter->active_pkg_type = ice_load_pkg_type(parent_hw); parent_adapter->pf.main_vsi->idx = hw->num_vfs; ice_dcf_update_pf_vsi_map(parent_hw, diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index 5fd5f99b6f..05ccc41d95 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -1649,57 +1649,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. - */ -#ifndef RTE_EXEC_ENV_WINDOWS -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) { - if (rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4) < 0) { - PMD_INIT_LOG(ERR, "Failed to read pci config space\n"); - return -1; - } - if (rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8) < 0) { - PMD_INIT_LOG(ERR, "Failed to read pci config space\n"); - return -1; - } - 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 (!ice_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 (!ice_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 (!ice_access(pkg_file, 0)) - return 0; - strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE); - return 0; -} -#endif - -enum ice_pkg_type +static enum ice_pkg_type ice_load_pkg_type(struct ice_hw *hw) { enum ice_pkg_type package_type; @@ -1723,37 +1673,62 @@ ice_load_pkg_type(struct ice_hw *hw) return package_type; } -#ifndef RTE_EXEC_ENV_WINDOWS -static int ice_load_pkg(struct rte_eth_dev *dev) +#ifdef RTE_EXEC_ENV_WINDOWS +#define ice_access _access +#else +#define ice_access access +#endif + +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]; int err; - uint8_t *buf; + uint8_t *buf = NULL; 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); - err = ice_pkg_file_search_path(pci_dev, pkg_file); - if (err) { + if (!use_dsn) + goto no_dsn; + + 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); + if (!ice_access(strcat(pkg_file, opt_ddp_filename), 0)) + goto load_fw; + + strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT, + ICE_MAX_PKG_FILENAME_SIZE); + if (!ice_access(strcat(pkg_file, opt_ddp_filename), 0)) + goto load_fw; + +no_dsn: + strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE); + if (!ice_access(pkg_file, 0)) + goto load_fw; + strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE); + if (ice_access(pkg_file, 0)) { PMD_INIT_LOG(ERR, "failed to search file path\n"); - return err; + return -1; } +load_fw: file = fopen(pkg_file, "rb"); if (!file) { PMD_INIT_LOG(ERR, "failed to open file: %s\n", pkg_file); return -1; } + PMD_INIT_LOG(DEBUG, "DDP package name: %s", pkg_file); + err = stat(pkg_file, &fstat); if (err) { PMD_INIT_LOG(ERR, "failed to get file stats\n"); - fclose(file); - return err; + goto out; } buf_len = fstat.st_size; @@ -1762,44 +1737,33 @@ static int ice_load_pkg(struct rte_eth_dev *dev) if (!buf) { PMD_INIT_LOG(ERR, "failed to allocate buf of size %d for package\n", buf_len); - fclose(file); - return -1; + err = -1; + goto out; } 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; + goto out; } - 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; + goto out; } /* store the loaded pkg type info */ - ad->active_pkg_type = ice_load_pkg_type(hw); + adapter->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: +out: + fclose(file); rte_free(buf); return err; } -#endif + +#undef ice_access static void ice_base_queue_get(struct ice_pf *pf) @@ -2030,6 +1994,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; @@ -2081,7 +2051,30 @@ ice_dev_init(struct rte_eth_dev *dev) } #ifndef RTE_EXEC_ENV_WINDOWS - ret = ice_load_pkg(dev); + 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," diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index 2a8a8169d5..1997f9296f 100644 --- a/drivers/net/ice/ice_ethdev.h +++ b/drivers/net/ice/ice_ethdev.h @@ -531,7 +531,8 @@ struct ice_vsi_vlan_pvid_info { #define ICE_PF_TO_ETH_DEV(pf) \ (((struct ice_pf *)pf)->adapter->eth_dev) -enum ice_pkg_type ice_load_pkg_type(struct ice_hw *hw); +int +ice_load_pkg(struct ice_adapter *adapter, bool use_dsn, uint64_t dsn); struct ice_vsi * ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type); int From patchwork Wed Jun 2 09:58:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 93790 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 22984A0524; Wed, 2 Jun 2021 11:59:14 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0F68440E50; Wed, 2 Jun 2021 11:59:14 +0200 (CEST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mails.dpdk.org (Postfix) with ESMTP id D839740689 for ; Wed, 2 Jun 2021 11:59:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1622627952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LSrSXMszDdFLxvGIDeElIiVPml9HrP9T3tTwh7KXd4c=; b=gV2m/cU4xFl3rTsWgVKNaBI5tbcdpwZnUfCTsMsKrmPZniAt7Ty9x2sNEBSLiXKPmKJl91 MUvi5VxGT4dk6WdUP7J0zOIHAKzOYT46+iCJNT6roEqG++t54g/cI07kLWPDLjOzPp3W3G UI7OSbC59Bc11iVIu+zrkQtTd5KG2fU= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-573-pZRuKEUINz2cZzMfgrfvEw-1; Wed, 02 Jun 2021 05:59:05 -0400 X-MC-Unique: pZRuKEUINz2cZzMfgrfvEw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5C6BC80293E; Wed, 2 Jun 2021 09:59:02 +0000 (UTC) Received: from dmarchan.remote.csb (unknown [10.40.193.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7E36A5944D; Wed, 2 Jun 2021 09:58:56 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Aaron Conole , Michael Santana , Bruce Richardson , Rasesh Mody , Shahed Shaikh , Qiming Yang , Qi Zhang , Heinrich Kuhn , Devendra Singh Rawat , Igor Russkikh , Ray Kinsella , Neil Horman , Dmitry Kozlyuk , Narcisa Ana Maria Vasile , Dmitry Malloy , Pallavi Kadam Date: Wed, 2 Jun 2021 11:58:36 +0200 Message-Id: <20210602095836.24901-3-david.marchand@redhat.com> In-Reply-To: <20210602095836.24901-1-david.marchand@redhat.com> References: <20210602095836.24901-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david.marchand@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH 2/2] eal: handle compressed firmwares X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Introduce an internal firmware loading helper to remove code duplication in our drivers and handle xz compressed firmwares by calling libarchive. This helper tries to look for .xz suffixes so that drivers are not aware the firmwares have been compressed. libarchive is set as an optional dependency: without libarchive, a runtime warning is emitted so that users know there is a compressed firmware. Windows implementation is left as an empty stub. Signed-off-by: David Marchand Reviewed-by: Igor Russkikh --- .github/workflows/build.yml | 1 + .travis.yml | 1 + config/meson.build | 9 +++ drivers/net/bnx2x/bnx2x.c | 35 ++++------- drivers/net/ice/ice_ethdev.c | 60 ++++--------------- drivers/net/nfp/nfp_net.c | 57 ++++-------------- drivers/net/qede/qede_main.c | 44 ++++++-------- lib/eal/include/rte_firmware.h | 35 +++++++++++ lib/eal/unix/eal_firmware.c | 106 +++++++++++++++++++++++++++++++++ lib/eal/unix/meson.build | 1 + lib/eal/version.map | 2 + lib/eal/windows/eal.c | 9 +++ 12 files changed, 218 insertions(+), 142 deletions(-) create mode 100644 lib/eal/include/rte_firmware.h create mode 100644 lib/eal/unix/eal_firmware.c diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7c4d6dcdbf..7dac20ddeb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,6 +93,7 @@ jobs: run: sudo apt install -y ccache libnuma-dev python3-setuptools python3-wheel python3-pip python3-pyelftools ninja-build libbsd-dev libpcap-dev libibverbs-dev libcrypto++-dev libfdt-dev libjansson-dev + libarchive-dev - name: Install libabigail build dependencies if no cache is available if: env.ABI_CHECKS == 'true' && steps.libabigail-cache.outputs.cache-hit != 'true' run: sudo apt install -y autoconf automake libtool pkg-config libxml2-dev diff --git a/.travis.yml b/.travis.yml index 5b702cc9bb..23067d9e3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ addons: packages: &required_packages - [libnuma-dev, python3-setuptools, python3-wheel, python3-pip, python3-pyelftools, ninja-build] - [libbsd-dev, libpcap-dev, libibverbs-dev, libcrypto++-dev, libfdt-dev, libjansson-dev] + - [libarchive-dev] _aarch64_packages: &aarch64_packages - *required_packages diff --git a/config/meson.build b/config/meson.build index 017bb2efbb..337daa2719 100644 --- a/config/meson.build +++ b/config/meson.build @@ -166,6 +166,15 @@ if fdt_dep.found() and cc.has_header('fdt.h') dpdk_extra_ldflags += '-lfdt' endif +has_libarchive = 0 +archive_dep = cc.find_library('libarchive', required: false) +if archive_dep.found() and cc.has_header('archive.h') + dpdk_conf.set10('RTE_HAS_LIBARCHIVE', true) + has_libarchive = 1 + add_project_link_arguments('-larchive', language: 'c') + dpdk_extra_ldflags += '-larchive' +endif + libexecinfo = cc.find_library('libexecinfo', required: false) if libexecinfo.found() and cc.has_header('execinfo.h') add_project_link_arguments('-lexecinfo', language: 'c') diff --git a/drivers/net/bnx2x/bnx2x.c b/drivers/net/bnx2x/bnx2x.c index 654878d9de..60292753e2 100644 --- a/drivers/net/bnx2x/bnx2x.c +++ b/drivers/net/bnx2x/bnx2x.c @@ -26,7 +26,9 @@ #include #include #include + #include +#include #include #define BNX2X_PMD_VER_PREFIX "BNX2X PMD" @@ -9655,44 +9657,33 @@ static void bnx2x_init_rte(struct bnx2x_softc *sc) void bnx2x_load_firmware(struct bnx2x_softc *sc) { const char *fwname; - int f; - struct stat st; + void *buf; + size_t bufsz; fwname = sc->devinfo.device_id == CHIP_NUM_57711 ? FW_NAME_57711 : FW_NAME_57810; - f = open(fwname, O_RDONLY); - if (f < 0) { + if (rte_firmware_read(fwname, &buf, &bufsz) != 0) { PMD_DRV_LOG(NOTICE, sc, "Can't open firmware file"); return; } - if (fstat(f, &st) < 0) { - PMD_DRV_LOG(NOTICE, sc, "Can't stat firmware file"); - close(f); - return; - } - - sc->firmware = rte_zmalloc("bnx2x_fw", st.st_size, RTE_CACHE_LINE_SIZE); + sc->firmware = rte_zmalloc("bnx2x_fw", bufsz, RTE_CACHE_LINE_SIZE); if (!sc->firmware) { PMD_DRV_LOG(NOTICE, sc, "Can't allocate memory for firmware"); - close(f); - return; + goto out; } - if (read(f, sc->firmware, st.st_size) != st.st_size) { - PMD_DRV_LOG(NOTICE, sc, "Can't read firmware data"); - close(f); - return; - } - close(f); - - sc->fw_len = st.st_size; + sc->fw_len = bufsz; if (sc->fw_len < FW_HEADER_LEN) { PMD_DRV_LOG(NOTICE, sc, "Invalid fw size: %" PRIu64, sc->fw_len); - return; + goto out; } + + memcpy(sc->firmware, buf, sc->fw_len); PMD_DRV_LOG(DEBUG, sc, "fw_len = %" PRIu64, sc->fw_len); +out: + free(buf); } static void diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index 05ccc41d95..6bb8c76ab3 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -10,6 +10,7 @@ #include #include +#include #include #include "base/ice_sched.h" @@ -1673,22 +1674,14 @@ ice_load_pkg_type(struct ice_hw *hw) return package_type; } -#ifdef RTE_EXEC_ENV_WINDOWS -#define ice_access _access -#else -#define ice_access access -#endif - int ice_load_pkg(struct ice_adapter *adapter, bool use_dsn, uint64_t dsn) { 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 = NULL; - int buf_len; - FILE *file; - struct stat fstat; if (!use_dsn) goto no_dsn; @@ -1698,57 +1691,31 @@ int ice_load_pkg(struct ice_adapter *adapter, bool use_dsn, uint64_t dsn) "ice-%016" PRIx64 ".pkg", dsn); strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_UPDATES, ICE_MAX_PKG_FILENAME_SIZE); - if (!ice_access(strcat(pkg_file, opt_ddp_filename), 0)) + strcat(pkg_file, opt_ddp_filename); + if (rte_firmware_read(pkg_file, &buf, &bufsz) == 0) goto load_fw; strncpy(pkg_file, ICE_PKG_FILE_SEARCH_PATH_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE); - if (!ice_access(strcat(pkg_file, opt_ddp_filename), 0)) + strcat(pkg_file, opt_ddp_filename); + if (rte_firmware_read(pkg_file, &buf, &bufsz) == 0) goto load_fw; no_dsn: strncpy(pkg_file, ICE_PKG_FILE_UPDATES, ICE_MAX_PKG_FILENAME_SIZE); - if (!ice_access(pkg_file, 0)) + if (rte_firmware_read(pkg_file, &buf, &bufsz) == 0) goto load_fw; + strncpy(pkg_file, ICE_PKG_FILE_DEFAULT, ICE_MAX_PKG_FILENAME_SIZE); - if (ice_access(pkg_file, 0)) { + if (rte_firmware_read(pkg_file, &buf, &bufsz) < 0) { PMD_INIT_LOG(ERR, "failed to search file path\n"); return -1; } load_fw: - file = fopen(pkg_file, "rb"); - if (!file) { - PMD_INIT_LOG(ERR, "failed to open file: %s\n", pkg_file); - return -1; - } - PMD_INIT_LOG(DEBUG, "DDP package name: %s", pkg_file); - err = stat(pkg_file, &fstat); - if (err) { - PMD_INIT_LOG(ERR, "failed to get file stats\n"); - goto out; - } - - 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); - err = -1; - goto out; - } - - err = fread(buf, buf_len, 1, file); - if (err != 1) { - PMD_INIT_LOG(ERR, "failed to read package data\n"); - err = -1; - goto out; - } - - 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 out; @@ -1758,13 +1725,10 @@ int ice_load_pkg(struct ice_adapter *adapter, bool use_dsn, uint64_t dsn) adapter->active_pkg_type = ice_load_pkg_type(hw); out: - fclose(file); - rte_free(buf); + free(buf); return err; } -#undef ice_access - static void ice_base_queue_get(struct ice_pf *pf) { diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c index 2ee88fbfc7..879da7ef59 100644 --- a/drivers/net/nfp/nfp_net.c +++ b/drivers/net/nfp/nfp_net.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "nfpcore/nfp_cpp.h" #include "nfpcore/nfp_nffw.h" @@ -3366,12 +3367,10 @@ static int nfp_fw_upload(struct rte_pci_device *dev, struct nfp_nsp *nsp, char *card) { struct nfp_cpp *cpp = nsp->cpp; - int fw_f; - char *fw_buf; + void *fw_buf; char fw_name[125]; char serial[40]; - struct stat file_stat; - off_t fsize, bytes; + size_t fsize; /* Looking for firmware file in order of priority */ @@ -3384,66 +3383,34 @@ nfp_fw_upload(struct rte_pci_device *dev, struct nfp_nsp *nsp, char *card) snprintf(fw_name, sizeof(fw_name), "%s/%s.nffw", DEFAULT_FW_PATH, serial); - PMD_DRV_LOG(DEBUG, "Trying with fw file: %s", fw_name); - fw_f = open(fw_name, O_RDONLY); - if (fw_f >= 0) - goto read_fw; + if (rte_firmware_read(fw_name, &fw_buf, &fsize) == 0) + goto load_fw; /* Then try the PCI name */ snprintf(fw_name, sizeof(fw_name), "%s/pci-%s.nffw", DEFAULT_FW_PATH, dev->device.name); - PMD_DRV_LOG(DEBUG, "Trying with fw file: %s", fw_name); - fw_f = open(fw_name, O_RDONLY); - if (fw_f >= 0) - goto read_fw; + if (rte_firmware_read(fw_name, &fw_buf, &fsize) == 0) + goto load_fw; /* Finally try the card type and media */ snprintf(fw_name, sizeof(fw_name), "%s/%s", DEFAULT_FW_PATH, card); PMD_DRV_LOG(DEBUG, "Trying with fw file: %s", fw_name); - fw_f = open(fw_name, O_RDONLY); - if (fw_f < 0) { + if (rte_firmware_read(fw_name, &fw_buf, &fsize) < 0) { PMD_DRV_LOG(INFO, "Firmware file %s not found.", fw_name); return -ENOENT; } -read_fw: - if (fstat(fw_f, &file_stat) < 0) { - PMD_DRV_LOG(INFO, "Firmware file %s size is unknown", fw_name); - close(fw_f); - return -ENOENT; - } - - fsize = file_stat.st_size; - PMD_DRV_LOG(INFO, "Firmware file found at %s with size: %" PRIu64 "", - fw_name, (uint64_t)fsize); - - fw_buf = malloc((size_t)fsize); - if (!fw_buf) { - PMD_DRV_LOG(INFO, "malloc failed for fw buffer"); - close(fw_f); - return -ENOMEM; - } - memset(fw_buf, 0, fsize); - - bytes = read(fw_f, fw_buf, fsize); - if (bytes != fsize) { - PMD_DRV_LOG(INFO, "Reading fw to buffer failed." - "Just %" PRIu64 " of %" PRIu64 " bytes read", - (uint64_t)bytes, (uint64_t)fsize); - free(fw_buf); - close(fw_f); - return -EIO; - } +load_fw: + PMD_DRV_LOG(INFO, "Firmware file found at %s with size: %zu", + fw_name, fsize); PMD_DRV_LOG(INFO, "Uploading the firmware ..."); - nfp_nsp_load_fw(nsp, fw_buf, bytes); + nfp_nsp_load_fw(nsp, fw_buf, fsize); PMD_DRV_LOG(INFO, "Done"); free(fw_buf); - close(fw_f); - return 0; } diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c index caa9d1d4f6..347e407b1b 100644 --- a/drivers/net/qede/qede_main.c +++ b/drivers/net/qede/qede_main.c @@ -6,6 +6,7 @@ #include #include +#include #include #include "qede_ethdev.h" @@ -127,51 +128,40 @@ static void qed_free_stream_mem(struct ecore_dev *edev) #ifdef CONFIG_ECORE_BINARY_FW static int qed_load_firmware_data(struct ecore_dev *edev) { - int fd; - struct stat st; const char *fw = RTE_LIBRTE_QEDE_FW; + void *buf; + size_t bufsz; + int ret; if (strcmp(fw, "") == 0) strcpy(qede_fw_file, QEDE_DEFAULT_FIRMWARE); else strcpy(qede_fw_file, fw); - fd = open(qede_fw_file, O_RDONLY); - if (fd < 0) { - DP_ERR(edev, "Can't open firmware file\n"); - return -ENOENT; - } - - if (fstat(fd, &st) < 0) { - DP_ERR(edev, "Can't stat firmware file\n"); - close(fd); + if (rte_firmware_read(qede_fw_file, &buf, &bufsz) < 0) { + DP_ERR(edev, "Can't read firmware data: %s\n", qede_fw_file); return -1; } - edev->firmware = rte_zmalloc("qede_fw", st.st_size, - RTE_CACHE_LINE_SIZE); + edev->firmware = rte_zmalloc("qede_fw", bufsz, RTE_CACHE_LINE_SIZE); if (!edev->firmware) { DP_ERR(edev, "Can't allocate memory for firmware\n"); - close(fd); - return -ENOMEM; - } - - if (read(fd, edev->firmware, st.st_size) != st.st_size) { - DP_ERR(edev, "Can't read firmware data\n"); - close(fd); - return -1; + ret = -ENOMEM; + goto out; } - edev->fw_len = st.st_size; + memcpy(edev->firmware, buf, bufsz); + edev->fw_len = bufsz; if (edev->fw_len < 104) { DP_ERR(edev, "Invalid fw size: %" PRIu64 "\n", edev->fw_len); - close(fd); - return -EINVAL; + ret = -EINVAL; + goto out; } - - close(fd); - return 0; + ret = 0; +out: + free(buf); + return ret; } #endif diff --git a/lib/eal/include/rte_firmware.h b/lib/eal/include/rte_firmware.h new file mode 100644 index 0000000000..d2a7bc8083 --- /dev/null +++ b/lib/eal/include/rte_firmware.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Red Hat, Inc. + */ + +#ifndef __RTE_FIRMWARE_H__ +#define __RTE_FIRMWARE_H__ + +#include + +#include + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Load a firmware in a dynamically allocated buffer, dealing with compressed + * files if libarchive is available. + * + * @param name + * Firmware filename to load. + * @param buf + * Buffer allocated by this function. If this function succeeds, the + * caller is responsible for freeing the buffer. + * @param bufsz + * Size of the data in the buffer. + * + * @return + * 0 if successful. + * Negative otherwise, buf and bufsize contents are invalid. + */ +__rte_internal +int +rte_firmware_read(const char *name, void **buf, size_t *bufsz); + +#endif diff --git a/lib/eal/unix/eal_firmware.c b/lib/eal/unix/eal_firmware.c new file mode 100644 index 0000000000..ea66fecfe9 --- /dev/null +++ b/lib/eal/unix/eal_firmware.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Red Hat, Inc. + */ + +#ifdef RTE_HAS_LIBARCHIVE +#include +#endif +#include +#include +#include +#include + +#include +#include +#include + +static int +firmware_read(const char *name, void **buf, size_t *bufsz) +{ + const size_t blocksize = 4096; + int ret = -1; + int err; +#ifdef RTE_HAS_LIBARCHIVE + struct archive_entry *entry; + struct archive *a; +#else + int fd; +#endif + + *buf = NULL; + *bufsz = 0; + +#ifdef RTE_HAS_LIBARCHIVE + a = archive_read_new(); + if (a == NULL || archive_read_support_format_raw(a) != ARCHIVE_OK || + archive_read_support_filter_xz(a) != ARCHIVE_OK || + archive_read_open_filename(a, name, blocksize) != ARCHIVE_OK || + archive_read_next_header(a, &entry) != ARCHIVE_OK) + goto out; +#else + fd = open(name, O_RDONLY); + if (fd < 0) + goto out; +#endif + + do { + void *tmp; + + tmp = realloc(*buf, *bufsz + blocksize); + if (tmp == NULL) { + free(*buf); + *buf = NULL; + *bufsz = 0; + break; + } + *buf = tmp; + +#ifdef RTE_HAS_LIBARCHIVE + err = archive_read_data(a, RTE_PTR_ADD(*buf, *bufsz), blocksize); +#else + err = read(fd, RTE_PTR_ADD(*buf, *bufsz), blocksize); +#endif + if (err < 0) { + free(*buf); + *buf = NULL; + *bufsz = 0; + break; + } + *bufsz += err; + + } while (err != 0); + + if (*buf != NULL) + ret = 0; +out: +#ifdef RTE_HAS_LIBARCHIVE + if (a != NULL) + archive_read_free(a); +#else + if (fd >= 0) + close(fd); +#endif + return ret; +} + +int +rte_firmware_read(const char *name, void **buf, size_t *bufsz) +{ + char path[PATH_MAX]; + int ret; + + ret = firmware_read(name, buf, bufsz); + if (ret < 0) { + snprintf(path, sizeof(path), "%s.xz", name); + path[PATH_MAX - 1] = '\0'; +#ifndef RTE_HAS_LIBARCHIVE + if (access(path, F_OK) == 0) { + RTE_LOG(WARNING, EAL, "libarchive not available, %s cannot be decompressed\n", + path); + } +#else + ret = firmware_read(path, buf, bufsz); +#endif + } + return ret; +} diff --git a/lib/eal/unix/meson.build b/lib/eal/unix/meson.build index dc711b4240..e3ecd3e956 100644 --- a/lib/eal/unix/meson.build +++ b/lib/eal/unix/meson.build @@ -5,5 +5,6 @@ sources += files( 'eal_file.c', 'eal_unix_memory.c', 'eal_unix_timer.c', + 'eal_firmware.c', 'rte_thread.c', ) diff --git a/lib/eal/version.map b/lib/eal/version.map index fe5c3dac98..020c058e5f 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -423,11 +423,13 @@ EXPERIMENTAL { rte_version_release; # WINDOWS_NO_EXPORT rte_version_suffix; # WINDOWS_NO_EXPORT rte_version_year; # WINDOWS_NO_EXPORT + }; INTERNAL { global: + rte_firmware_read; rte_mem_lock; rte_mem_map; rte_mem_page_size; diff --git a/lib/eal/windows/eal.c b/lib/eal/windows/eal.c index 28c787c0b0..938ace92f5 100644 --- a/lib/eal/windows/eal.c +++ b/lib/eal/windows/eal.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "eal_hugepages.h" #include "eal_trace.h" @@ -463,3 +464,11 @@ rte_vfio_container_dma_unmap(__rte_unused int container_fd, { return -1; } + +int +rte_firmware_read(__rte_unused const char *name, + __rte_unused void **buf, + __rte_unused size_t *bufsz) +{ + return -1; +}