@@ -18,6 +18,8 @@ Parameters
- permanent
* - ``reset_dev_on_drv_probe``
- permanent
+ * - ``vf_max_queue``
+ - runtime
Info versions
=============
@@ -6,6 +6,7 @@
#include "nfpcore/nfp.h"
#include "nfpcore/nfp_nsp.h"
#include "nfp_main.h"
+#include "nfp_net.h"
/**
* struct nfp_devlink_param_u8_arg - Devlink u8 parameter get/set arguments
@@ -191,7 +192,120 @@ nfp_devlink_param_u8_validate(struct devlink *devlink, u32 id,
return 0;
}
+static int
+nfp_devlink_vq_config_get(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct nfp_pf *pf = devlink_priv(devlink);
+ char config[4 * NFP_NET_CFG_QUEUE_TYPE];
+ int i, len;
+
+ if (!pf)
+ return -ENODEV;
+
+ for (i = 0, len = 0; i < NFP_NET_CFG_QUEUE_TYPE; i++)
+ len += snprintf(config + len, sizeof(config), "%03d-", pf->config_vfs_queue[i]);
+ config[len - 1] = '\0';
+
+ strscpy(ctx->val.vstr, config, sizeof(ctx->val.vstr));
+
+ return 0;
+}
+
+static int
+nfp_devlink_vq_config_set(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ int config_vfs_queue[NFP_NET_CFG_QUEUE_TYPE];
+ char vq[__DEVLINK_PARAM_MAX_STRING_VALUE];
+ struct nfp_pf *pf = devlink_priv(devlink);
+ char *num_vf, *value;
+ u8 config = 0;
+ int i;
+
+ if (!pf)
+ return -ENODEV;
+
+ strscpy(vq, ctx->val.vstr, sizeof(vq));
+ value = vq;
+ memset(config_vfs_queue, 0, sizeof(config_vfs_queue));
+
+ num_vf = strsep(&value, "-");
+ while (num_vf) {
+ if (kstrtouint(num_vf, 10, &config_vfs_queue[config++]))
+ return -EINVAL;
+ num_vf = strsep(&value, "-");
+ }
+
+ pf->default_config_vfs_queue = true;
+ memset(pf->config_vfs_queue, 0, sizeof(pf->config_vfs_queue));
+
+ for (i = NFP_NET_CFG_QUEUE_TYPE - 1; i >= 0; i--) {
+ if (config >= 1) {
+ pf->config_vfs_queue[i] = config_vfs_queue[--config];
+ if (pf->config_vfs_queue[i] && pf->default_config_vfs_queue)
+ pf->default_config_vfs_queue = false;
+ }
+ }
+
+ return 0;
+}
+
+static int
+nfp_devlink_vq_config_validate(struct devlink *devlink, u32 id,
+ union devlink_param_value val,
+ struct netlink_ext_ack *extack)
+{
+ int config_vfs_queue[NFP_NET_CFG_QUEUE_TYPE];
+ char vq[__DEVLINK_PARAM_MAX_STRING_VALUE];
+ struct nfp_pf *pf = devlink_priv(devlink);
+ char *num_vf, *value;
+ u32 total_q_num = 0;
+ u32 config = 0;
+ int i;
+
+ if (!pf) {
+ NL_SET_ERR_MSG_MOD(extack, "Can't find the device.");
+ return -ENODEV;
+ }
+
+ strscpy(vq, val.vstr, sizeof(vq));
+ value = vq;
+ memset(config_vfs_queue, 0, sizeof(config_vfs_queue));
+
+ num_vf = strsep(&value, "-");
+ while (num_vf) {
+ if (kstrtouint(num_vf, 10, &config_vfs_queue[config++])) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "The input format is error, expected format: %d-%d-%d-%d-%d.");
+ return -EINVAL;
+ }
+
+ if (config > NFP_NET_CFG_QUEUE_TYPE) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "The config queue type is more than the max_cfg_queue_type.");
+ return -EINVAL;
+ }
+ num_vf = strsep(&value, "-");
+ }
+
+ for (i = NFP_NET_CFG_QUEUE_TYPE - 1; i >= 0 && config; i--)
+ total_q_num += config_vfs_queue[--config] * NFP_NET_CFG_MAX_Q(i);
+
+ if (total_q_num > pf->max_vf_queues) {
+ NL_SET_ERR_MSG_MOD(extack, "The set queue is more than the MAX queue.");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct devlink_param nfp_devlink_params[] = {
+ DEVLINK_PARAM_GENERIC(MAX_VF_QUEUE,
+ BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+ nfp_devlink_vq_config_get,
+ nfp_devlink_vq_config_set,
+ nfp_devlink_vq_config_validate),
DEVLINK_PARAM_GENERIC(FW_LOAD_POLICY,
BIT(DEVLINK_PARAM_CMODE_PERMANENT),
nfp_devlink_param_u8_get,