DPDK patches and discussions
 help / color / mirror / Atom feed
From: Chaoyong He <chaoyong.he@corigine.com>
To: dev@dpdk.org
Cc: oss-drivers@corigine.com, Chaoyong He <chaoyong.he@corigine.com>,
	Long Wu <long.wu@corigine.com>,
	Peng Zhang <peng.zhang@corigine.com>
Subject: [PATCH 3/3] net/nfp: support load firmware from flash
Date: Tue,  3 Sep 2024 13:52:39 +0800	[thread overview]
Message-ID: <20240903055239.2642656-4-chaoyong.he@corigine.com> (raw)
In-Reply-To: <20240903055239.2642656-1-chaoyong.he@corigine.com>

Add the logic to support load firmware from flash, also do some refactor
to the related logic at the same time.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 drivers/net/nfp/nfp_ethdev.c | 233 ++++++++++++++++++++++++++++++-----
 1 file changed, 202 insertions(+), 31 deletions(-)

diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index db12914afe..b35e40a7d0 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -1323,16 +1323,30 @@ nfp_fw_check_change(struct nfp_cpp *cpp,
 
 static int
 nfp_fw_reload(struct nfp_nsp *nsp,
-		char *fw_name)
+		char *fw_name,
+		int reset)
 {
 	int err;
+	bool reset_flag;
+
+	reset_flag = (reset == NFP_NSP_DRV_RESET_ALWAYS) ||
+			(reset == NFP_NSP_DRV_RESET_DISK);
+
+	if (reset_flag) {
+		err = nfp_nsp_device_soft_reset(nsp);
+		if (err != 0) {
+			PMD_DRV_LOG(ERR, "NFP firmware soft reset failed");
+			return err;
+		}
+	}
 
-	nfp_nsp_device_soft_reset(nsp);
 	err = nfp_fw_upload(nsp, fw_name);
-	if (err != 0)
+	if (err != 0) {
 		PMD_DRV_LOG(ERR, "NFP firmware load failed");
+		return err;
+	}
 
-	return err;
+	return 0;
 }
 
 static bool
@@ -1398,11 +1412,27 @@ nfp_fw_skip_load(const struct nfp_dev_info *dev_info,
 
 	return false;
 }
+
 static int
-nfp_fw_reload_for_single_pf(struct nfp_nsp *nsp,
+nfp_fw_reload_from_flash(struct nfp_nsp *nsp)
+{
+	int ret;
+
+	ret = nfp_nsp_load_stored_fw(nsp);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Load firmware from flash failed.");
+		return -EACCES;
+	}
+
+	return 0;
+}
+
+static int
+nfp_fw_reload_for_single_pf_from_disk(struct nfp_nsp *nsp,
 		char *fw_name,
 		struct nfp_cpp *cpp,
-		bool force_reload_fw)
+		bool force_reload_fw,
+		int reset)
 {
 	int ret;
 	bool fw_changed = true;
@@ -1416,7 +1446,7 @@ nfp_fw_reload_for_single_pf(struct nfp_nsp *nsp,
 	if (!fw_changed)
 		return 0;
 
-	ret = nfp_fw_reload(nsp, fw_name);
+	ret = nfp_fw_reload(nsp, fw_name, reset);
 	if (ret != 0)
 		return ret;
 
@@ -1424,18 +1454,81 @@ nfp_fw_reload_for_single_pf(struct nfp_nsp *nsp,
 }
 
 static int
-nfp_fw_reload_for_multi_pf(struct nfp_nsp *nsp,
+nfp_fw_reload_for_single_pf(struct nfp_nsp *nsp,
+		char *fw_name,
+		struct nfp_cpp *cpp,
+		bool force_reload_fw,
+		int reset,
+		int policy)
+{
+	int ret;
+
+	if (policy == NFP_NSP_APP_FW_LOAD_FLASH && nfp_nsp_has_stored_fw_load(nsp)) {
+		ret = nfp_fw_reload_from_flash(nsp);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "Load single PF firmware from flash failed.");
+			return ret;
+		}
+	} else if (fw_name[0] != 0) {
+		ret = nfp_fw_reload_for_single_pf_from_disk(nsp, fw_name, cpp,
+				force_reload_fw, reset);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "Load single PF firmware from disk failed.");
+			return ret;
+		}
+	} else {
+		PMD_DRV_LOG(ERR, "Not load firmware, please update flash or recofigure card.");
+		return -ENODATA;
+	}
+
+	return 0;
+}
+
+static int
+nfp_fw_reload_for_multi_pf_from_disk(struct nfp_nsp *nsp,
 		char *fw_name,
 		struct nfp_cpp *cpp,
 		const struct nfp_dev_info *dev_info,
 		struct nfp_multi_pf *multi_pf,
-		bool force_reload_fw)
+		bool force_reload_fw,
+		int reset)
 {
 	int err;
 	bool fw_changed = true;
 	bool skip_load_fw = false;
 	bool reload_fw = force_reload_fw;
 
+	if (nfp_nsp_has_fw_loaded(nsp) && nfp_nsp_fw_loaded(nsp) && !reload_fw) {
+		err = nfp_fw_check_change(cpp, fw_name, &fw_changed);
+		if (err != 0)
+			return err;
+	}
+
+	if (!fw_changed || reload_fw)
+		skip_load_fw = nfp_fw_skip_load(dev_info, multi_pf, &reload_fw);
+
+	if (skip_load_fw && !reload_fw)
+		return 0;
+
+	err = nfp_fw_reload(nsp, fw_name, reset);
+	if (err != 0)
+		return err;
+
+	return 0;
+}
+
+static int
+nfp_fw_reload_for_multi_pf(struct nfp_nsp *nsp,
+		char *fw_name,
+		struct nfp_cpp *cpp,
+		const struct nfp_dev_info *dev_info,
+		struct nfp_multi_pf *multi_pf,
+		bool force_reload_fw,
+		int reset,
+		int policy)
+{
+	int err;
+
 	err = nfp_net_keepalive_init(cpp, multi_pf);
 	if (err != 0) {
 		PMD_DRV_LOG(ERR, "NFP init beat failed");
@@ -1448,21 +1541,24 @@ nfp_fw_reload_for_multi_pf(struct nfp_nsp *nsp,
 		goto keepalive_uninit;
 	}
 
-	if (nfp_nsp_has_fw_loaded(nsp) && nfp_nsp_fw_loaded(nsp) && !reload_fw) {
-		err = nfp_fw_check_change(cpp, fw_name, &fw_changed);
-		if (err != 0)
+	if (policy == NFP_NSP_APP_FW_LOAD_FLASH && nfp_nsp_has_stored_fw_load(nsp)) {
+		err = nfp_fw_reload_from_flash(nsp);
+		if (err != 0) {
+			PMD_DRV_LOG(ERR, "Load multi PF firmware from flash failed.");
 			goto keepalive_stop;
-	}
-
-	if (!fw_changed || reload_fw)
-		skip_load_fw = nfp_fw_skip_load(dev_info, multi_pf, &reload_fw);
-
-	if (skip_load_fw && !reload_fw)
-		return 0;
-
-	err = nfp_fw_reload(nsp, fw_name);
-	if (err != 0)
+		}
+	} else if (fw_name[0] != 0) {
+		err = nfp_fw_reload_for_multi_pf_from_disk(nsp, fw_name, cpp,
+				dev_info, multi_pf, force_reload_fw, reset);
+		if (err != 0) {
+			PMD_DRV_LOG(ERR, "Load multi PF firmware from disk failed.");
+			goto keepalive_stop;
+		}
+	} else {
+		PMD_DRV_LOG(ERR, "Not load firmware, please update flash or recofigure card.");
+		err = -ENODATA;
 		goto keepalive_stop;
+	}
 
 	nfp_net_keepalive_clear_others(dev_info, multi_pf);
 
@@ -1476,6 +1572,57 @@ nfp_fw_reload_for_multi_pf(struct nfp_nsp *nsp,
 	return err;
 }
 
+static int
+nfp_strtol(const char *buf,
+		int base,
+		long *value)
+{
+	long val;
+	char *tmp;
+
+	if (value == NULL)
+		return -EINVAL;
+
+	val = strtol(buf, &tmp, base);
+	if (tmp == NULL || *tmp != 0)
+		return -EINVAL;
+
+	*value = val;
+
+	return 0;
+}
+
+static int
+nfp_fw_policy_value_get(struct nfp_nsp *nsp,
+		const char *key,
+		const char *default_val,
+		int max_val,
+		int *value)
+{
+	int ret;
+	int64_t val;
+	char buf[64];
+
+	snprintf(buf, sizeof(buf), "%s", key);
+	ret = nfp_nsp_hwinfo_lookup_optional(nsp, buf, sizeof(buf), default_val);
+	if (ret != 0)
+		return ret;
+
+	ret = nfp_strtol(buf, 0, &val);
+	if (ret != 0 || val < 0 || val > max_val) {
+		PMD_DRV_LOG(WARNING, "Invalid value '%s' from '%s', ignoring",
+				buf, key);
+		/* Fall back to the default value */
+		ret = nfp_strtol(default_val, 0, &val);
+		if (ret != 0)
+			return ret;
+	}
+
+	*value = val;
+
+	return 0;
+}
+
 static int
 nfp_fw_setup(struct rte_pci_device *dev,
 		struct nfp_cpp *cpp,
@@ -1486,27 +1633,51 @@ nfp_fw_setup(struct rte_pci_device *dev,
 		bool force_reload_fw)
 {
 	int err;
+	int reset;
+	int policy;
 	char fw_name[125];
 	struct nfp_nsp *nsp;
 
-	err = nfp_fw_get_name(dev, cpp, nfp_eth_table, hwinfo, fw_name, sizeof(fw_name));
-	if (err != 0) {
-		PMD_DRV_LOG(ERR, "Can't find suitable firmware.");
-		return err;
-	}
-
 	nsp = nfp_nsp_open(cpp);
 	if (nsp == NULL) {
 		PMD_DRV_LOG(ERR, "NFP error when obtaining NSP handle");
 		return -EIO;
 	}
 
+	err = nfp_fw_policy_value_get(nsp, "abi_drv_reset",
+			NFP_NSP_DRV_RESET_DEFAULT, NFP_NSP_DRV_RESET_NEVER,
+			&reset);
+	if (err != 0) {
+		PMD_DRV_LOG(ERR, "Get 'abi_drv_reset' from HWinfo failed.");
+		goto close_nsp;
+	}
+
+	err = nfp_fw_policy_value_get(nsp, "app_fw_from_flash",
+			NFP_NSP_APP_FW_LOAD_DEFAULT, NFP_NSP_APP_FW_LOAD_PREF,
+			&policy);
+	if (err != 0) {
+		PMD_DRV_LOG(ERR, "Get 'app_fw_from_flash' from HWinfo failed.");
+		goto close_nsp;
+	}
+
+	fw_name[0] = 0;
+	if (policy != NFP_NSP_APP_FW_LOAD_FLASH) {
+		err = nfp_fw_get_name(dev, cpp, nfp_eth_table, hwinfo, fw_name,
+				sizeof(fw_name));
+		if (err != 0) {
+			PMD_DRV_LOG(ERR, "Can't find suitable firmware.");
+			goto close_nsp;
+		}
+	}
+
 	if (multi_pf->enabled)
-		err = nfp_fw_reload_for_multi_pf(nsp, fw_name, cpp, dev_info, multi_pf,
-				force_reload_fw);
+		err = nfp_fw_reload_for_multi_pf(nsp, fw_name, cpp, dev_info,
+				multi_pf, force_reload_fw, reset, policy);
 	else
-		err = nfp_fw_reload_for_single_pf(nsp, fw_name, cpp, force_reload_fw);
+		err = nfp_fw_reload_for_single_pf(nsp, fw_name, cpp,
+				force_reload_fw, reset, policy);
 
+close_nsp:
 	nfp_nsp_close(nsp);
 	return err;
 }
-- 
2.39.1


  parent reply	other threads:[~2024-09-03  5:53 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-03  5:52 [PATCH 0/3] " Chaoyong He
2024-09-03  5:52 ` [PATCH 1/3] net/nfp: fix potential problem on certain version BSP Chaoyong He
2024-09-03  5:52 ` [PATCH 2/3] net/nfp: add two APIs of the NSP module Chaoyong He
2024-09-03  5:52 ` Chaoyong He [this message]
2024-10-04  6:15 ` [PATCH 0/3] support load firmware from flash Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240903055239.2642656-4-chaoyong.he@corigine.com \
    --to=chaoyong.he@corigine.com \
    --cc=dev@dpdk.org \
    --cc=long.wu@corigine.com \
    --cc=oss-drivers@corigine.com \
    --cc=peng.zhang@corigine.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).