* [PATCH 2/3] net/nfp: add two APIs of the NSP module
2024-09-03 5:52 [PATCH 0/3] support load firmware from flash 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 ` Chaoyong He
2024-09-03 5:52 ` [PATCH 3/3] net/nfp: support load firmware from flash Chaoyong He
2024-10-04 6:15 ` [PATCH 0/3] " Ferruh Yigit
3 siblings, 0 replies; 5+ messages in thread
From: Chaoyong He @ 2024-09-03 5:52 UTC (permalink / raw)
To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang
Add two APIs of the NSP module, also modify the logic to use the
argument to control the log switch for NSP command.
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/nfpcore/nfp_nsp.c | 86 ++++++++++++++++++++++++++++++-
drivers/net/nfp/nfpcore/nfp_nsp.h | 15 ++++++
2 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/drivers/net/nfp/nfpcore/nfp_nsp.c b/drivers/net/nfp/nfpcore/nfp_nsp.c
index 7dfb472723..2ac39b10b5 100644
--- a/drivers/net/nfp/nfpcore/nfp_nsp.c
+++ b/drivers/net/nfp/nfpcore/nfp_nsp.c
@@ -60,6 +60,8 @@
#define NFP_FW_LOAD_RET_MAJOR GENMASK_ULL(15, 8)
#define NFP_FW_LOAD_RET_MINOR GENMASK_ULL(23, 16)
+#define NFP_HWINFO_LOOKUP_SIZE GENMASK_ULL(11, 0)
+
enum nfp_nsp_cmd {
SPCODE_NOOP = 0, /* No operation */
SPCODE_SOFT_RESET = 1, /* Soft reset the NFP */
@@ -477,7 +479,9 @@ nfp_nsp_command_buf_def(struct nfp_nsp *nsp,
FIELD_PREP(NSP_BUFFER_ADDRESS, cpp_buf);
ret = nfp_nsp_command_real(nsp, &arg->arg);
if (ret < 0) {
- PMD_DRV_LOG(ERR, "NSP command failed");
+ if (!arg->arg.error_quiet)
+ PMD_DRV_LOG(ERR, "NSP command failed");
+
return ret;
}
@@ -755,3 +759,83 @@ nfp_nsp_read_media(struct nfp_nsp *state,
return nfp_nsp_command_buf(state, &media);
}
+
+int
+nfp_nsp_load_stored_fw(struct nfp_nsp *state)
+{
+ int ret;
+ struct nfp_nsp_command_buf_arg fw_stored = {
+ {
+ .code = SPCODE_FW_STORED,
+ .error_cb = nfp_nsp_load_fw_extended_msg,
+ },
+ };
+
+ ret = nfp_nsp_command_buf(state, &fw_stored);
+ if (ret < 0)
+ return ret;
+
+ nfp_nsp_load_fw_extended_msg(state, ret);
+
+ return 0;
+}
+
+static int
+nfp_nsp_hwinfo_lookup_real(struct nfp_nsp *state,
+ void *buf,
+ size_t size,
+ bool optional)
+{
+ struct nfp_nsp_command_buf_arg hwinfo_lookup = {
+ {
+ .code = SPCODE_HWINFO_LOOKUP,
+ .option = size,
+ .error_quiet = optional,
+ },
+ .in_buf = buf,
+ .in_size = size,
+ .out_buf = buf,
+ .out_size = size,
+ };
+
+ return nfp_nsp_command_buf(state, &hwinfo_lookup);
+}
+
+int
+nfp_nsp_hwinfo_lookup_optional(struct nfp_nsp *state,
+ void *buf,
+ size_t size,
+ const char *default_val)
+{
+ int ret;
+ size_t min_size;
+
+ if (strnlen(default_val, size) == size) {
+ PMD_DRV_LOG(ERR, "NSP HWinfo default value not NULL terminated");
+ return -EINVAL;
+ }
+
+ if (!nfp_nsp_has_hwinfo_lookup(state))
+ goto default_return;
+
+ min_size = RTE_MIN(size, NFP_HWINFO_LOOKUP_SIZE);
+ ret = nfp_nsp_hwinfo_lookup_real(state, buf, min_size, true);
+ if (ret != 0) {
+ if (ret == -ENOENT)
+ goto default_return;
+
+ PMD_DRV_LOG(ERR, "NSP HWinfo lookup failed: %d", ret);
+ return ret;
+ }
+
+ if (strnlen(buf, min_size) == min_size) {
+ PMD_DRV_LOG(ERR, "NSP HWinfo value not NULL terminated");
+ return -EINVAL;
+ }
+
+ return 0;
+
+default_return:
+ strlcpy(buf, default_val, size);
+ return 0;
+}
diff --git a/drivers/net/nfp/nfpcore/nfp_nsp.h b/drivers/net/nfp/nfpcore/nfp_nsp.h
index 003cdc5fa3..cfb5066fc9 100644
--- a/drivers/net/nfp/nfpcore/nfp_nsp.h
+++ b/drivers/net/nfp/nfpcore/nfp_nsp.h
@@ -8,6 +8,18 @@
#include "nfp_cpp.h"
+/* Defines the valid values of the 'abi_drv_reset' hwinfo key */
+#define NFP_NSP_DRV_RESET_DISK 0
+#define NFP_NSP_DRV_RESET_ALWAYS 1
+#define NFP_NSP_DRV_RESET_NEVER 2
+#define NFP_NSP_DRV_RESET_DEFAULT "0"
+
+/* Defines the valid values of the 'app_fw_from_flash' hwinfo key */
+#define NFP_NSP_APP_FW_LOAD_DISK 0
+#define NFP_NSP_APP_FW_LOAD_FLASH 1
+#define NFP_NSP_APP_FW_LOAD_PREF 2
+#define NFP_NSP_APP_FW_LOAD_DEFAULT "2"
+
struct nfp_nsp;
struct nfp_nsp *nfp_nsp_open(struct nfp_cpp *cpp);
@@ -225,6 +237,9 @@ enum nfp_nsp_sensor_id {
int nfp_hwmon_read_sensor(struct nfp_cpp *cpp, enum nfp_nsp_sensor_id id,
uint32_t *val);
bool nfp_nsp_fw_loaded(struct nfp_nsp *state);
+int nfp_nsp_load_stored_fw(struct nfp_nsp *state);
+int nfp_nsp_hwinfo_lookup_optional(struct nfp_nsp *state,
+ void *buf, size_t size, const char *default_val);
/* The buf used to receive bitmap of link modes */
struct nfp_eth_media_buf {
--
2.39.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/3] net/nfp: support load firmware from flash
2024-09-03 5:52 [PATCH 0/3] support load firmware from flash 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
2024-10-04 6:15 ` [PATCH 0/3] " Ferruh Yigit
3 siblings, 0 replies; 5+ messages in thread
From: Chaoyong He @ 2024-09-03 5:52 UTC (permalink / raw)
To: dev; +Cc: oss-drivers, Chaoyong He, Long Wu, Peng Zhang
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
^ permalink raw reply [flat|nested] 5+ messages in thread