net/ice: Add support for enable_iwarp and enable_roce devlink param
[linux-2.6-block.git] / drivers / net / ethernet / intel / ice / ice_devlink.c
index b9bd9f9472f6cc842420413fdcc0dd6c48f790df..478412b28a76106ee3fb77e32af07acd9d096aba 100644 (file)
@@ -430,6 +430,120 @@ static const struct devlink_ops ice_devlink_ops = {
        .flash_update = ice_devlink_flash_update,
 };
 
+static int
+ice_devlink_enable_roce_get(struct devlink *devlink, u32 id,
+                           struct devlink_param_gset_ctx *ctx)
+{
+       struct ice_pf *pf = devlink_priv(devlink);
+
+       ctx->val.vbool = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2;
+
+       return 0;
+}
+
+static int
+ice_devlink_enable_roce_set(struct devlink *devlink, u32 id,
+                           struct devlink_param_gset_ctx *ctx)
+{
+       struct ice_pf *pf = devlink_priv(devlink);
+       bool roce_ena = ctx->val.vbool;
+       int ret;
+
+       if (!roce_ena) {
+               ice_unplug_aux_dev(pf);
+               pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_ROCEV2;
+               return 0;
+       }
+
+       pf->rdma_mode |= IIDC_RDMA_PROTOCOL_ROCEV2;
+       ret = ice_plug_aux_dev(pf);
+       if (ret)
+               pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_ROCEV2;
+
+       return ret;
+}
+
+static int
+ice_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
+                                union devlink_param_value val,
+                                struct netlink_ext_ack *extack)
+{
+       struct ice_pf *pf = devlink_priv(devlink);
+
+       if (!test_bit(ICE_FLAG_RDMA_ENA, pf->flags))
+               return -EOPNOTSUPP;
+
+       if (pf->rdma_mode & IIDC_RDMA_PROTOCOL_IWARP) {
+               NL_SET_ERR_MSG_MOD(extack, "iWARP is currently enabled. This device cannot enable iWARP and RoCEv2 simultaneously");
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+static int
+ice_devlink_enable_iw_get(struct devlink *devlink, u32 id,
+                         struct devlink_param_gset_ctx *ctx)
+{
+       struct ice_pf *pf = devlink_priv(devlink);
+
+       ctx->val.vbool = pf->rdma_mode & IIDC_RDMA_PROTOCOL_IWARP;
+
+       return 0;
+}
+
+static int
+ice_devlink_enable_iw_set(struct devlink *devlink, u32 id,
+                         struct devlink_param_gset_ctx *ctx)
+{
+       struct ice_pf *pf = devlink_priv(devlink);
+       bool iw_ena = ctx->val.vbool;
+       int ret;
+
+       if (!iw_ena) {
+               ice_unplug_aux_dev(pf);
+               pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_IWARP;
+               return 0;
+       }
+
+       pf->rdma_mode |= IIDC_RDMA_PROTOCOL_IWARP;
+       ret = ice_plug_aux_dev(pf);
+       if (ret)
+               pf->rdma_mode &= ~IIDC_RDMA_PROTOCOL_IWARP;
+
+       return ret;
+}
+
+static int
+ice_devlink_enable_iw_validate(struct devlink *devlink, u32 id,
+                              union devlink_param_value val,
+                              struct netlink_ext_ack *extack)
+{
+       struct ice_pf *pf = devlink_priv(devlink);
+
+       if (!test_bit(ICE_FLAG_RDMA_ENA, pf->flags))
+               return -EOPNOTSUPP;
+
+       if (pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2) {
+               NL_SET_ERR_MSG_MOD(extack, "RoCEv2 is currently enabled. This device cannot enable iWARP and RoCEv2 simultaneously");
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+static const struct devlink_param ice_devlink_params[] = {
+       DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+                             ice_devlink_enable_roce_get,
+                             ice_devlink_enable_roce_set,
+                             ice_devlink_enable_roce_validate),
+       DEVLINK_PARAM_GENERIC(ENABLE_IWARP, BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+                             ice_devlink_enable_iw_get,
+                             ice_devlink_enable_iw_set,
+                             ice_devlink_enable_iw_validate),
+
+};
+
 static void ice_devlink_free(void *devlink_ptr)
 {
        devlink_free((struct devlink *)devlink_ptr);
@@ -484,6 +598,36 @@ void ice_devlink_unregister(struct ice_pf *pf)
        devlink_unregister(priv_to_devlink(pf));
 }
 
+int ice_devlink_register_params(struct ice_pf *pf)
+{
+       struct devlink *devlink = priv_to_devlink(pf);
+       union devlink_param_value value;
+       int err;
+
+       err = devlink_params_register(devlink, ice_devlink_params,
+                                     ARRAY_SIZE(ice_devlink_params));
+       if (err)
+               return err;
+
+       value.vbool = false;
+       devlink_param_driverinit_value_set(devlink,
+                                          DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
+                                          value);
+
+       value.vbool = test_bit(ICE_FLAG_RDMA_ENA, pf->flags) ? true : false;
+       devlink_param_driverinit_value_set(devlink,
+                                          DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
+                                          value);
+
+       return 0;
+}
+
+void ice_devlink_unregister_params(struct ice_pf *pf)
+{
+       devlink_params_unregister(priv_to_devlink(pf), ice_devlink_params,
+                                 ARRAY_SIZE(ice_devlink_params));
+}
+
 /**
  * ice_devlink_create_pf_port - Create a devlink port for this PF
  * @pf: the PF to create a devlink port for