@@ -6,6 +6,8 @@
#include "nfpcore/nfp.h"
#include "nfpcore/nfp_nsp.h"
#include "nfp_main.h"
+#include "nfp_net.h"
+#include "nfp_net_ctrl.h"
/**
* struct nfp_devlink_param_u8_arg - Devlink u8 parameter get/set arguments
@@ -192,6 +194,48 @@ nfp_devlink_param_u8_validate(struct devlink *devlink, u32 id,
return 0;
}
+static int
+nfp_devlink_param_enable_vnet_get(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct nfp_pf *pf = devlink_priv(devlink);
+
+ ctx->val.vbool = pf->enable_vnet;
+
+ return 0;
+}
+
+static int
+nfp_devlink_param_enable_vnet_set(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack)
+{
+ struct nfp_pf *pf = devlink_priv(devlink);
+ struct nfp_net *nn;
+ int err;
+
+ nn = list_first_entry(&pf->vnics, struct nfp_net, vnic_list);
+ if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_ENABLE_VNET)) {
+ NL_SET_ERR_MSG_MOD(extack, "NFP_NET_CFG_CTRL_ENABLE_VNET not enabled");
+ return -EOPNOTSUPP;
+ }
+
+ if (pf->num_vfs > 0) {
+ NL_SET_ERR_MSG_FMT_MOD(extack, "%d VFs already created. Please remove them first",
+ pf->num_vfs);
+ return -EBUSY;
+ }
+
+ err = nfp_net_update_enable_vnet(pf, ctx->val.vbool);
+ if (err < 0) {
+ NL_SET_ERR_MSG_MOD(extack, "Write ENABLE_VNET to firmware failed");
+ return err;
+ }
+
+ pf->enable_vnet = ctx->val.vbool;
+ return 0;
+}
+
static const struct devlink_param nfp_devlink_params[] = {
DEVLINK_PARAM_GENERIC(FW_LOAD_POLICY,
BIT(DEVLINK_PARAM_CMODE_PERMANENT),
@@ -203,6 +247,11 @@ static const struct devlink_param nfp_devlink_params[] = {
nfp_devlink_param_u8_get,
nfp_devlink_param_u8_set,
nfp_devlink_param_u8_validate),
+ DEVLINK_PARAM_GENERIC(ENABLE_VNET,
+ BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+ nfp_devlink_param_enable_vnet_get,
+ nfp_devlink_param_enable_vnet_set,
+ NULL),
};
static int nfp_devlink_supports_params(struct nfp_pf *pf)
@@ -65,6 +65,7 @@ struct nfp_dumpspec {
* @num_vfs: Number of SR-IOV VFs enabled
* @fw_loaded: Is the firmware loaded?
* @unload_fw_on_remove:Do we need to unload firmware on driver removal?
+ * @enable_vnet: Devlink parameter config, instantiate VDPA VF when enabled
* @ctrl_vnic: Pointer to the control vNIC if available
* @mip: MIP handle
* @rtbl: RTsym table
@@ -114,6 +115,7 @@ struct nfp_pf {
bool fw_loaded;
bool unload_fw_on_remove;
+ bool enable_vnet;
struct nfp_net *ctrl_vnic;
@@ -194,4 +196,5 @@ void nfp_devlink_params_unregister(struct nfp_pf *pf);
unsigned int nfp_net_lr2speed(unsigned int linkrate);
unsigned int nfp_net_speed2lr(unsigned int speed);
+int nfp_net_update_enable_vnet(struct nfp_pf *pf, bool enable_vnet);
#endif /* NFP_MAIN_H */
@@ -150,6 +150,7 @@
#define NFP_NET_CFG_UPDATE_MBOX (0x1 << 12) /* Mailbox update */
#define NFP_NET_CFG_UPDATE_VF (0x1 << 13) /* VF settings change */
#define NFP_NET_CFG_UPDATE_CRYPTO (0x1 << 14) /* Crypto on/off */
+#define NFP_NET_CFG_UPDATE_VF_VIRTIO (0x1 << 16) /* VF virtio enable change */
#define NFP_NET_CFG_UPDATE_ERR (0x1 << 31) /* A error occurred */
#define NFP_NET_CFG_TXRS_ENABLE 0x0008
#define NFP_NET_CFG_RXRS_ENABLE 0x0010
@@ -270,7 +271,9 @@
#define NFP_NET_CFG_CTRL_MCAST_FILTER (0x1 << 2) /* Multicast Filter */
#define NFP_NET_CFG_CTRL_FREELIST_EN (0x1 << 6) /* Freelist enable flag bit */
#define NFP_NET_CFG_CTRL_FLOW_STEER (0x1 << 8) /* Flow steering */
+#define NFP_NET_CFG_CTRL_VIRTIO (0x1 << 10) /* Virtio service flag */
#define NFP_NET_CFG_CTRL_USO (0x1 << 16) /* UDP segmentation offload */
+#define NFP_NET_CFG_CTRL_ENABLE_VNET (0x1 << 18) /* vDPA networking device enable */
#define NFP_NET_CFG_CAP_WORD1 0x00a4
@@ -684,6 +684,16 @@ int nfp_net_refresh_eth_port(struct nfp_port *port)
return ret;
}
+int nfp_net_update_enable_vnet(struct nfp_pf *pf, bool enable_vnet)
+{
+ struct nfp_net *nn;
+
+ nn = list_first_entry(&pf->vnics, struct nfp_net, vnic_list);
+ nn_writel(nn, NFP_NET_CFG_CTRL_WORD1, enable_vnet ? NFP_NET_CFG_CTRL_ENABLE_VNET : 0);
+
+ return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_VF_VIRTIO);
+}
+
/*
* PCI device functions
*/