root/drivers/net/ethernet/netronome/nfp/devlink_param.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nfp_devlink_param_u8_get
  2. nfp_devlink_param_u8_set
  3. nfp_devlink_param_u8_validate
  4. nfp_devlink_supports_params
  5. nfp_devlink_params_register
  6. nfp_devlink_params_unregister

   1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
   2 /* Copyright (C) 2019 Netronome Systems, Inc. */
   3 
   4 #include <net/devlink.h>
   5 
   6 #include "nfpcore/nfp.h"
   7 #include "nfpcore/nfp_nsp.h"
   8 #include "nfp_main.h"
   9 
  10 /**
  11  * struct nfp_devlink_param_u8_arg - Devlink u8 parameter get/set arguments
  12  * @hwinfo_name:        HWinfo key name
  13  * @default_hi_val:     Default HWinfo value if HWinfo doesn't exist
  14  * @invalid_dl_val:     Devlink value to use if HWinfo is unknown/invalid.
  15  *                      -errno if there is no unknown/invalid value available
  16  * @hi_to_dl:   HWinfo to devlink value mapping
  17  * @dl_to_hi:   Devlink to hwinfo value mapping
  18  * @max_dl_val: Maximum devlink value supported, for validation only
  19  * @max_hi_val: Maximum HWinfo value supported, for validation only
  20  */
  21 struct nfp_devlink_param_u8_arg {
  22         const char *hwinfo_name;
  23         const char *default_hi_val;
  24         int invalid_dl_val;
  25         u8 hi_to_dl[4];
  26         u8 dl_to_hi[4];
  27         u8 max_dl_val;
  28         u8 max_hi_val;
  29 };
  30 
  31 static const struct nfp_devlink_param_u8_arg nfp_devlink_u8_args[] = {
  32         [DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY] = {
  33                 .hwinfo_name = "app_fw_from_flash",
  34                 .default_hi_val = NFP_NSP_APP_FW_LOAD_DEFAULT,
  35                 .invalid_dl_val =
  36                         DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_UNKNOWN,
  37                 .hi_to_dl = {
  38                         [NFP_NSP_APP_FW_LOAD_DISK] =
  39                                 DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DISK,
  40                         [NFP_NSP_APP_FW_LOAD_FLASH] =
  41                                 DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH,
  42                         [NFP_NSP_APP_FW_LOAD_PREF] =
  43                                 DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DRIVER,
  44                 },
  45                 .dl_to_hi = {
  46                         [DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DRIVER] =
  47                                 NFP_NSP_APP_FW_LOAD_PREF,
  48                         [DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH] =
  49                                 NFP_NSP_APP_FW_LOAD_FLASH,
  50                         [DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DISK] =
  51                                 NFP_NSP_APP_FW_LOAD_DISK,
  52                 },
  53                 .max_dl_val = DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DISK,
  54                 .max_hi_val = NFP_NSP_APP_FW_LOAD_PREF,
  55         },
  56         [DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE] = {
  57                 .hwinfo_name = "abi_drv_reset",
  58                 .default_hi_val = NFP_NSP_DRV_RESET_DEFAULT,
  59                 .invalid_dl_val =
  60                         DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_UNKNOWN,
  61                 .hi_to_dl = {
  62                         [NFP_NSP_DRV_RESET_ALWAYS] =
  63                                 DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_ALWAYS,
  64                         [NFP_NSP_DRV_RESET_NEVER] =
  65                                 DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_NEVER,
  66                         [NFP_NSP_DRV_RESET_DISK] =
  67                                 DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_DISK,
  68                 },
  69                 .dl_to_hi = {
  70                         [DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_ALWAYS] =
  71                                 NFP_NSP_DRV_RESET_ALWAYS,
  72                         [DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_NEVER] =
  73                                 NFP_NSP_DRV_RESET_NEVER,
  74                         [DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_DISK] =
  75                                 NFP_NSP_DRV_RESET_DISK,
  76                 },
  77                 .max_dl_val = DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_DISK,
  78                 .max_hi_val = NFP_NSP_DRV_RESET_NEVER,
  79         }
  80 };
  81 
  82 static int
  83 nfp_devlink_param_u8_get(struct devlink *devlink, u32 id,
  84                          struct devlink_param_gset_ctx *ctx)
  85 {
  86         const struct nfp_devlink_param_u8_arg *arg;
  87         struct nfp_pf *pf = devlink_priv(devlink);
  88         struct nfp_nsp *nsp;
  89         char hwinfo[32];
  90         long value;
  91         int err;
  92 
  93         if (id >= ARRAY_SIZE(nfp_devlink_u8_args))
  94                 return -EOPNOTSUPP;
  95 
  96         arg = &nfp_devlink_u8_args[id];
  97 
  98         nsp = nfp_nsp_open(pf->cpp);
  99         if (IS_ERR(nsp)) {
 100                 err = PTR_ERR(nsp);
 101                 nfp_warn(pf->cpp, "can't access NSP: %d\n", err);
 102                 return err;
 103         }
 104 
 105         snprintf(hwinfo, sizeof(hwinfo), arg->hwinfo_name);
 106         err = nfp_nsp_hwinfo_lookup_optional(nsp, hwinfo, sizeof(hwinfo),
 107                                              arg->default_hi_val);
 108         if (err) {
 109                 nfp_warn(pf->cpp, "HWinfo lookup failed: %d\n", err);
 110                 goto exit_close_nsp;
 111         }
 112 
 113         err = kstrtol(hwinfo, 0, &value);
 114         if (err || value < 0 || value > arg->max_hi_val) {
 115                 nfp_warn(pf->cpp, "HWinfo '%s' value %li invalid\n",
 116                          arg->hwinfo_name, value);
 117 
 118                 if (arg->invalid_dl_val >= 0)
 119                         ctx->val.vu8 = arg->invalid_dl_val;
 120                 else
 121                         err = arg->invalid_dl_val;
 122 
 123                 goto exit_close_nsp;
 124         }
 125 
 126         ctx->val.vu8 = arg->hi_to_dl[value];
 127 
 128 exit_close_nsp:
 129         nfp_nsp_close(nsp);
 130         return err;
 131 }
 132 
 133 static int
 134 nfp_devlink_param_u8_set(struct devlink *devlink, u32 id,
 135                          struct devlink_param_gset_ctx *ctx)
 136 {
 137         const struct nfp_devlink_param_u8_arg *arg;
 138         struct nfp_pf *pf = devlink_priv(devlink);
 139         struct nfp_nsp *nsp;
 140         char hwinfo[32];
 141         int err;
 142 
 143         if (id >= ARRAY_SIZE(nfp_devlink_u8_args))
 144                 return -EOPNOTSUPP;
 145 
 146         arg = &nfp_devlink_u8_args[id];
 147 
 148         nsp = nfp_nsp_open(pf->cpp);
 149         if (IS_ERR(nsp)) {
 150                 err = PTR_ERR(nsp);
 151                 nfp_warn(pf->cpp, "can't access NSP: %d\n", err);
 152                 return err;
 153         }
 154 
 155         /* Note the value has already been validated. */
 156         snprintf(hwinfo, sizeof(hwinfo), "%s=%u",
 157                  arg->hwinfo_name, arg->dl_to_hi[ctx->val.vu8]);
 158         err = nfp_nsp_hwinfo_set(nsp, hwinfo, sizeof(hwinfo));
 159         if (err) {
 160                 nfp_warn(pf->cpp, "HWinfo set failed: %d\n", err);
 161                 goto exit_close_nsp;
 162         }
 163 
 164 exit_close_nsp:
 165         nfp_nsp_close(nsp);
 166         return err;
 167 }
 168 
 169 static int
 170 nfp_devlink_param_u8_validate(struct devlink *devlink, u32 id,
 171                               union devlink_param_value val,
 172                               struct netlink_ext_ack *extack)
 173 {
 174         const struct nfp_devlink_param_u8_arg *arg;
 175 
 176         if (id >= ARRAY_SIZE(nfp_devlink_u8_args))
 177                 return -EOPNOTSUPP;
 178 
 179         arg = &nfp_devlink_u8_args[id];
 180 
 181         if (val.vu8 > arg->max_dl_val) {
 182                 NL_SET_ERR_MSG_MOD(extack, "parameter out of range");
 183                 return -EINVAL;
 184         }
 185 
 186         if (val.vu8 == arg->invalid_dl_val) {
 187                 NL_SET_ERR_MSG_MOD(extack, "unknown/invalid value specified");
 188                 return -EINVAL;
 189         }
 190 
 191         return 0;
 192 }
 193 
 194 static const struct devlink_param nfp_devlink_params[] = {
 195         DEVLINK_PARAM_GENERIC(FW_LOAD_POLICY,
 196                               BIT(DEVLINK_PARAM_CMODE_PERMANENT),
 197                               nfp_devlink_param_u8_get,
 198                               nfp_devlink_param_u8_set,
 199                               nfp_devlink_param_u8_validate),
 200         DEVLINK_PARAM_GENERIC(RESET_DEV_ON_DRV_PROBE,
 201                               BIT(DEVLINK_PARAM_CMODE_PERMANENT),
 202                               nfp_devlink_param_u8_get,
 203                               nfp_devlink_param_u8_set,
 204                               nfp_devlink_param_u8_validate),
 205 };
 206 
 207 static int nfp_devlink_supports_params(struct nfp_pf *pf)
 208 {
 209         struct nfp_nsp *nsp;
 210         bool supported;
 211         int err;
 212 
 213         nsp = nfp_nsp_open(pf->cpp);
 214         if (IS_ERR(nsp)) {
 215                 err = PTR_ERR(nsp);
 216                 dev_err(&pf->pdev->dev, "Failed to access the NSP: %d\n", err);
 217                 return err;
 218         }
 219 
 220         supported = nfp_nsp_has_hwinfo_lookup(nsp) &&
 221                     nfp_nsp_has_hwinfo_set(nsp);
 222 
 223         nfp_nsp_close(nsp);
 224         return supported;
 225 }
 226 
 227 int nfp_devlink_params_register(struct nfp_pf *pf)
 228 {
 229         struct devlink *devlink = priv_to_devlink(pf);
 230         int err;
 231 
 232         err = nfp_devlink_supports_params(pf);
 233         if (err <= 0)
 234                 return err;
 235 
 236         err = devlink_params_register(devlink, nfp_devlink_params,
 237                                       ARRAY_SIZE(nfp_devlink_params));
 238         if (err)
 239                 return err;
 240 
 241         devlink_params_publish(devlink);
 242         return 0;
 243 }
 244 
 245 void nfp_devlink_params_unregister(struct nfp_pf *pf)
 246 {
 247         int err;
 248 
 249         err = nfp_devlink_supports_params(pf);
 250         if (err <= 0)
 251                 return;
 252 
 253         devlink_params_unregister(priv_to_devlink(pf), nfp_devlink_params,
 254                                   ARRAY_SIZE(nfp_devlink_params));
 255 }

/* [<][>][^][v][top][bottom][index][help] */