diff options
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c')
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c | 77 |
1 files changed, 73 insertions, 4 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c index 9a08623c325d..f18e787fa9ad 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c @@ -96,6 +96,8 @@ enum nfp_nsp_cmd { SPCODE_NSP_IDENTIFY = 13, /* Read NSP version */ SPCODE_FW_STORED = 16, /* If no FW loaded, load flash app FW */ SPCODE_HWINFO_LOOKUP = 17, /* Lookup HWinfo with overwrites etc. */ + SPCODE_HWINFO_SET = 18, /* Set HWinfo entry */ + SPCODE_FW_LOADED = 19, /* Is application firmware loaded */ SPCODE_VERSIONS = 21, /* Report FW versions */ SPCODE_READ_SFF_EEPROM = 22, /* Read module EEPROM */ }; @@ -143,6 +145,8 @@ struct nfp_nsp { * @option: NFP SP Command Argument * @buf: NFP SP Buffer Address * @error_cb: Callback for interpreting option if error occurred + * @error_quiet:Don't print command error/warning. Protocol errors are still + * logged. */ struct nfp_nsp_command_arg { u16 code; @@ -151,6 +155,7 @@ struct nfp_nsp_command_arg { u32 option; u64 buf; void (*error_cb)(struct nfp_nsp *state, u32 ret_val); + bool error_quiet; }; /** @@ -405,8 +410,10 @@ __nfp_nsp_command(struct nfp_nsp *state, const struct nfp_nsp_command_arg *arg) err = FIELD_GET(NSP_STATUS_RESULT, reg); if (err) { - nfp_warn(cpp, "Result (error) code set: %d (%d) command: %d\n", - -err, (int)ret_val, arg->code); + if (!arg->error_quiet) + nfp_warn(cpp, "Result (error) code set: %d (%d) command: %d\n", + -err, (int)ret_val, arg->code); + if (arg->error_cb) arg->error_cb(state, ret_val); else @@ -891,12 +898,14 @@ int nfp_nsp_load_stored_fw(struct nfp_nsp *state) } static int -__nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size) +__nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int 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, @@ -913,7 +922,7 @@ int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size) size = min_t(u32, size, NFP_HWINFO_LOOKUP_SIZE); - err = __nfp_nsp_hwinfo_lookup(state, buf, size); + err = __nfp_nsp_hwinfo_lookup(state, buf, size, false); if (err) return err; @@ -925,6 +934,66 @@ int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size) return 0; } +int nfp_nsp_hwinfo_lookup_optional(struct nfp_nsp *state, void *buf, + unsigned int size, const char *default_val) +{ + int err; + + /* Ensure that the default value is usable irrespective of whether + * it is actually going to be used. + */ + if (strnlen(default_val, size) == size) + return -EINVAL; + + if (!nfp_nsp_has_hwinfo_lookup(state)) { + strcpy(buf, default_val); + return 0; + } + + size = min_t(u32, size, NFP_HWINFO_LOOKUP_SIZE); + + err = __nfp_nsp_hwinfo_lookup(state, buf, size, true); + if (err) { + if (err == -ENOENT) { + strcpy(buf, default_val); + return 0; + } + + nfp_err(state->cpp, "NSP HWinfo lookup failed: %d\n", err); + return err; + } + + if (strnlen(buf, size) == size) { + nfp_err(state->cpp, "NSP HWinfo value not NULL-terminated\n"); + return -EINVAL; + } + + return 0; +} + +int nfp_nsp_hwinfo_set(struct nfp_nsp *state, void *buf, unsigned int size) +{ + struct nfp_nsp_command_buf_arg hwinfo_set = { + { + .code = SPCODE_HWINFO_SET, + .option = size, + }, + .in_buf = buf, + .in_size = size, + }; + + return nfp_nsp_command_buf(state, &hwinfo_set); +} + +int nfp_nsp_fw_loaded(struct nfp_nsp *state) +{ + const struct nfp_nsp_command_arg arg = { + .code = SPCODE_FW_LOADED, + }; + + return __nfp_nsp_command(state, &arg); +} + int nfp_nsp_versions(struct nfp_nsp *state, void *buf, unsigned int size) { struct nfp_nsp_command_buf_arg versions = { |