Commit c384cee1 authored by David S. Miller's avatar David S. Miller
Browse files
Tony Nguyen says:

====================
100GbE Intel Wired LAN Driver Updates 2021-11-22

Shiraz Saleem says:

Currently E800 devices come up as RoCEv2 devices by default.

This series add supports for users to configure iWARP or RoCEv2 functionality
per PCI function. devlink parameters is used to realize this and is keyed
off similar work in [1].

[1] https://lore.kernel.org/linux-rdma/20210810132424.9129-1-parav@nvidia.com/


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5f11542f 774a90c1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -109,6 +109,9 @@ own name.
     - Boolean
     - When enabled, the device driver will instantiate VDPA networking
       specific auxiliary device of the devlink device.
   * - ``enable_iwarp``
     - Boolean
     - Enable handling of iWARP traffic in the device.
   * - ``internal_err_reset``
     - Boolean
     - When enabled, the device driver will reset the device on internal
+2 −1
Original line number Diff line number Diff line
@@ -228,7 +228,8 @@ static void irdma_fill_device_info(struct irdma_device *iwdev, struct ice_pf *pf
	rf->msix_count =  pf->num_rdma_msix;
	rf->msix_entries = &pf->msix_entries[pf->rdma_base_vector];
	rf->default_vsi.vsi_idx = vsi->vsi_num;
	rf->protocol_used = IRDMA_ROCE_PROTOCOL_ONLY;
	rf->protocol_used = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2 ?
			    IRDMA_ROCE_PROTOCOL_ONLY : IRDMA_IWARP_PROTOCOL_ONLY;
	rf->rdma_ver = IRDMA_GEN_2;
	rf->rsrc_profile = IRDMA_HMC_PROFILE_DEFAULT;
	rf->rst_to = IRDMA_RST_TIMEOUT_HZ;
+1 −0
Original line number Diff line number Diff line
@@ -576,6 +576,7 @@ struct ice_pf {
	struct ice_hw_port_stats stats_prev;
	struct ice_hw hw;
	u8 stat_prev_loaded:1; /* has previous stats been loaded */
	u8 rdma_mode;
	u16 dcbx_cap;
	u32 tx_timeout_count;
	unsigned long tx_timeout_last_recovery;
+144 −0
Original line number Diff line number Diff line
@@ -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
+6 −0
Original line number Diff line number Diff line
@@ -4,10 +4,16 @@
#ifndef _ICE_DEVLINK_H_
#define _ICE_DEVLINK_H_

enum ice_devlink_param_id {
	ICE_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
};

struct ice_pf *ice_allocate_pf(struct device *dev);

void ice_devlink_register(struct ice_pf *pf);
void ice_devlink_unregister(struct ice_pf *pf);
int ice_devlink_register_params(struct ice_pf *pf);
void ice_devlink_unregister_params(struct ice_pf *pf);
int ice_devlink_create_pf_port(struct ice_pf *pf);
void ice_devlink_destroy_pf_port(struct ice_pf *pf);
int ice_devlink_create_vf_port(struct ice_vf *vf);
Loading