Commit 74612cda authored by Dirk van der Merwe's avatar Dirk van der Merwe Committed by David S. Miller

nfp: nsp: add support for optional hwinfo lookup

There are cases where we want to read a hwinfo entry from the NFP, and
if it doesn't exist, use a default value instead.

To support this, we must silence warning/error messages when the hwinfo
entry doesn't exist since this is a valid use case. The NSP command
structure provides the ability to silence command errors, in which case
the caller should log any command errors appropriately. Protocol errors
are unaffected by this.
Signed-off-by: default avatarDirk van der Merwe <dirk.vandermerwe@netronome.com>
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1da16f0c
...@@ -144,6 +144,8 @@ struct nfp_nsp { ...@@ -144,6 +144,8 @@ struct nfp_nsp {
* @option: NFP SP Command Argument * @option: NFP SP Command Argument
* @buf: NFP SP Buffer Address * @buf: NFP SP Buffer Address
* @error_cb: Callback for interpreting option if error occurred * @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 { struct nfp_nsp_command_arg {
u16 code; u16 code;
...@@ -152,6 +154,7 @@ struct nfp_nsp_command_arg { ...@@ -152,6 +154,7 @@ struct nfp_nsp_command_arg {
u32 option; u32 option;
u64 buf; u64 buf;
void (*error_cb)(struct nfp_nsp *state, u32 ret_val); void (*error_cb)(struct nfp_nsp *state, u32 ret_val);
bool error_quiet;
}; };
/** /**
...@@ -406,8 +409,10 @@ __nfp_nsp_command(struct nfp_nsp *state, const struct nfp_nsp_command_arg *arg) ...@@ -406,8 +409,10 @@ __nfp_nsp_command(struct nfp_nsp *state, const struct nfp_nsp_command_arg *arg)
err = FIELD_GET(NSP_STATUS_RESULT, reg); err = FIELD_GET(NSP_STATUS_RESULT, reg);
if (err) { if (err) {
nfp_warn(cpp, "Result (error) code set: %d (%d) command: %d\n", if (!arg->error_quiet)
-err, (int)ret_val, arg->code); nfp_warn(cpp, "Result (error) code set: %d (%d) command: %d\n",
-err, (int)ret_val, arg->code);
if (arg->error_cb) if (arg->error_cb)
arg->error_cb(state, ret_val); arg->error_cb(state, ret_val);
else else
...@@ -892,12 +897,14 @@ int nfp_nsp_load_stored_fw(struct nfp_nsp *state) ...@@ -892,12 +897,14 @@ int nfp_nsp_load_stored_fw(struct nfp_nsp *state)
} }
static int 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 = { struct nfp_nsp_command_buf_arg hwinfo_lookup = {
{ {
.code = SPCODE_HWINFO_LOOKUP, .code = SPCODE_HWINFO_LOOKUP,
.option = size, .option = size,
.error_quiet = optional,
}, },
.in_buf = buf, .in_buf = buf,
.in_size = size, .in_size = size,
...@@ -914,7 +921,7 @@ int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size) ...@@ -914,7 +921,7 @@ int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size)
size = min_t(u32, size, NFP_HWINFO_LOOKUP_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) if (err)
return err; return err;
...@@ -926,6 +933,43 @@ int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size) ...@@ -926,6 +933,43 @@ int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size)
return 0; 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_fw_loaded(struct nfp_nsp *state) int nfp_nsp_fw_loaded(struct nfp_nsp *state)
{ {
const struct nfp_nsp_command_arg arg = { const struct nfp_nsp_command_arg arg = {
......
...@@ -22,6 +22,8 @@ int nfp_nsp_write_flash(struct nfp_nsp *state, const struct firmware *fw); ...@@ -22,6 +22,8 @@ int nfp_nsp_write_flash(struct nfp_nsp *state, const struct firmware *fw);
int nfp_nsp_mac_reinit(struct nfp_nsp *state); int nfp_nsp_mac_reinit(struct nfp_nsp *state);
int nfp_nsp_load_stored_fw(struct nfp_nsp *state); int nfp_nsp_load_stored_fw(struct nfp_nsp *state);
int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size); int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size);
int nfp_nsp_hwinfo_lookup_optional(struct nfp_nsp *state, void *buf,
unsigned int size, const char *default_val);
int nfp_nsp_fw_loaded(struct nfp_nsp *state); int nfp_nsp_fw_loaded(struct nfp_nsp *state);
int nfp_nsp_read_module_eeprom(struct nfp_nsp *state, int eth_index, int nfp_nsp_read_module_eeprom(struct nfp_nsp *state, int eth_index,
unsigned int offset, void *data, unsigned int offset, void *data,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment