Commit 37ba803d authored by David S. Miller's avatar David S. Miller
Browse files


Tony Nguyen says:

====================
100GbE Intel Wired LAN Driver Updates 2021-10-19

This series contains updates to ice driver only.

Brett implements support for ndo_set_vf_rate allowing for min_tx_rate
and max_tx_rate to be set for a VF.

Jesse updates DIM moderation to improve latency and resolves problems
with reported rate limit and extra software generated interrupts.

Wojciech moves a check for trusted VFs to the correct function,
disables lb_en for switchdev offloads, and refactors ethtool ops due
to differences in support for PF and port representor support.

Cai Huoqing utilizes the helper function devm_add_action_or_reset().

Gustavo A. R. Silva replaces uses of allocation to devm_kcalloc() as
applicable.

Dan Carpenter propagates an error instead of returning success.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 623acf87 8702ed0b
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -452,10 +452,8 @@ struct ice_pf *ice_allocate_pf(struct device *dev)
		return NULL;

	/* Add an action to teardown the devlink when unwinding the driver */
	if (devm_add_action(dev, ice_devlink_free, devlink)) {
		devlink_free(devlink);
	if (devm_add_action_or_reset(dev, ice_devlink_free, devlink))
		return NULL;
	}

	return devlink_priv(devlink);
}
+85 −31
Original line number Diff line number Diff line
@@ -192,7 +192,6 @@ __ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo,

	strscpy(drvinfo->bus_info, pci_name(pf->pdev),
		sizeof(drvinfo->bus_info));
	drvinfo->n_priv_flags = ICE_PRIV_FLAG_ARRAY_SIZE;
}

static void
@@ -201,18 +200,8 @@ ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
	struct ice_netdev_priv *np = netdev_priv(netdev);

	__ice_get_drvinfo(netdev, drvinfo, np->vsi);
}

static void
ice_repr_get_drvinfo(struct net_device *netdev,
		     struct ethtool_drvinfo *drvinfo)
{
	struct ice_repr *repr = ice_netdev_to_repr(netdev);

	if (ice_check_vf_ready_for_cfg(repr->vf))
		return;

	__ice_get_drvinfo(netdev, drvinfo, repr->src_vsi);
	drvinfo->n_priv_flags = ICE_PRIV_FLAG_ARRAY_SIZE;
}

static int ice_get_regs_len(struct net_device __always_unused *netdev)
@@ -886,10 +875,10 @@ ice_self_test(struct net_device *netdev, struct ethtool_test *eth_test,
	netdev_info(netdev, "testing finished\n");
}

static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
static void
__ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data,
		  struct ice_vsi *vsi)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);
	struct ice_vsi *vsi = ice_get_netdev_priv_vsi(np);
	unsigned int i;
	u8 *p = data;

@@ -940,6 +929,13 @@ static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
	}
}

static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);

	__ice_get_strings(netdev, stringset, data, np->vsi);
}

static int
ice_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
{
@@ -1331,9 +1327,6 @@ static int ice_get_sset_count(struct net_device *netdev, int sset)
		 * order of strings will suffer from race conditions and are
		 * not safe.
		 */
		if (ice_is_port_repr_netdev(netdev))
			return ICE_VSI_STATS_LEN;

		return ICE_ALL_STATS_LEN(netdev);
	case ETH_SS_TEST:
		return ICE_TEST_LEN;
@@ -1345,11 +1338,10 @@ static int ice_get_sset_count(struct net_device *netdev, int sset)
}

static void
ice_get_ethtool_stats(struct net_device *netdev,
		      struct ethtool_stats __always_unused *stats, u64 *data)
__ice_get_ethtool_stats(struct net_device *netdev,
			struct ethtool_stats __always_unused *stats, u64 *data,
			struct ice_vsi *vsi)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);
	struct ice_vsi *vsi = ice_get_netdev_priv_vsi(np);
	struct ice_pf *pf = vsi->back;
	struct ice_tx_ring *tx_ring;
	struct ice_rx_ring *rx_ring;
@@ -1416,6 +1408,15 @@ ice_get_ethtool_stats(struct net_device *netdev,
	}
}

static void
ice_get_ethtool_stats(struct net_device *netdev,
		      struct ethtool_stats __always_unused *stats, u64 *data)
{
	struct ice_netdev_priv *np = netdev_priv(netdev);

	__ice_get_ethtool_stats(netdev, stats, data, np->vsi);
}

#define ICE_PHY_TYPE_LOW_MASK_MIN_1G	(ICE_PHY_TYPE_LOW_100BASE_TX | \
					 ICE_PHY_TYPE_LOW_100M_SGMII)

@@ -3640,6 +3641,9 @@ ice_set_rc_coalesce(struct ethtool_coalesce *ec,

	switch (rc->type) {
	case ICE_RX_CONTAINER:
	{
		struct ice_q_vector *q_vector = rc->rx_ring->q_vector;

		if (ec->rx_coalesce_usecs_high > ICE_MAX_INTRL ||
		    (ec->rx_coalesce_usecs_high &&
		     ec->rx_coalesce_usecs_high < pf->hw.intrl_gran)) {
@@ -3648,22 +3652,20 @@ ice_set_rc_coalesce(struct ethtool_coalesce *ec,
				    ICE_MAX_INTRL);
			return -EINVAL;
		}
		if (ec->rx_coalesce_usecs_high != rc->rx_ring->q_vector->intrl &&
		if (ec->rx_coalesce_usecs_high != q_vector->intrl &&
		    (ec->use_adaptive_rx_coalesce || ec->use_adaptive_tx_coalesce)) {
			netdev_info(vsi->netdev, "Invalid value, %s-usecs-high cannot be changed if adaptive-tx or adaptive-rx is enabled\n",
				    c_type_str);
			return -EINVAL;
		}
		if (ec->rx_coalesce_usecs_high != rc->rx_ring->q_vector->intrl) {
			rc->rx_ring->q_vector->intrl = ec->rx_coalesce_usecs_high;
			ice_write_intrl(rc->rx_ring->q_vector,
					ec->rx_coalesce_usecs_high);
		}
		if (ec->rx_coalesce_usecs_high != q_vector->intrl)
			q_vector->intrl = ec->rx_coalesce_usecs_high;

		use_adaptive_coalesce = ec->use_adaptive_rx_coalesce;
		coalesce_usecs = ec->rx_coalesce_usecs;

		break;
	}
	case ICE_TX_CONTAINER:
		use_adaptive_coalesce = ec->use_adaptive_tx_coalesce;
		coalesce_usecs = ec->tx_coalesce_usecs;
@@ -3808,6 +3810,8 @@ __ice_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec,

			if (ice_set_q_coalesce(vsi, ec, v_idx))
				return -EINVAL;

			ice_set_q_vector_intrl(vsi->q_vectors[v_idx]);
		}
		goto set_complete;
	}
@@ -3815,6 +3819,8 @@ __ice_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec,
	if (ice_set_q_coalesce(vsi, ec, q_num))
		return -EINVAL;

	ice_set_q_vector_intrl(vsi->q_vectors[q_num]);

set_complete:
	return 0;
}
@@ -3834,6 +3840,54 @@ ice_set_per_q_coalesce(struct net_device *netdev, u32 q_num,
	return __ice_set_coalesce(netdev, ec, q_num);
}

static void
ice_repr_get_drvinfo(struct net_device *netdev,
		     struct ethtool_drvinfo *drvinfo)
{
	struct ice_repr *repr = ice_netdev_to_repr(netdev);

	if (ice_check_vf_ready_for_cfg(repr->vf))
		return;

	__ice_get_drvinfo(netdev, drvinfo, repr->src_vsi);
}

static void
ice_repr_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
{
	struct ice_repr *repr = ice_netdev_to_repr(netdev);

	/* for port representors only ETH_SS_STATS is supported */
	if (ice_check_vf_ready_for_cfg(repr->vf) ||
	    stringset != ETH_SS_STATS)
		return;

	__ice_get_strings(netdev, stringset, data, repr->src_vsi);
}

static void
ice_repr_get_ethtool_stats(struct net_device *netdev,
			   struct ethtool_stats __always_unused *stats,
			   u64 *data)
{
	struct ice_repr *repr = ice_netdev_to_repr(netdev);

	if (ice_check_vf_ready_for_cfg(repr->vf))
		return;

	__ice_get_ethtool_stats(netdev, stats, data, repr->src_vsi);
}

static int ice_repr_get_sset_count(struct net_device *netdev, int sset)
{
	switch (sset) {
	case ETH_SS_STATS:
		return ICE_VSI_STATS_LEN;
	default:
		return -EOPNOTSUPP;
	}
}

#define ICE_I2C_EEPROM_DEV_ADDR		0xA0
#define ICE_I2C_EEPROM_DEV_ADDR2	0xA2
#define ICE_MODULE_TYPE_SFP		0x03
@@ -4088,9 +4142,9 @@ void ice_set_ethtool_safe_mode_ops(struct net_device *netdev)
static const struct ethtool_ops ice_ethtool_repr_ops = {
	.get_drvinfo		= ice_repr_get_drvinfo,
	.get_link		= ethtool_op_get_link,
	.get_strings		= ice_get_strings,
	.get_ethtool_stats      = ice_get_ethtool_stats,
	.get_sset_count		= ice_get_sset_count,
	.get_strings		= ice_repr_get_strings,
	.get_ethtool_stats      = ice_repr_get_ethtool_stats,
	.get_sset_count		= ice_repr_get_sset_count,
};

/**
+2 −2
Original line number Diff line number Diff line
@@ -706,7 +706,7 @@ ice_create_init_fdir_rule(struct ice_pf *pf, enum ice_fltr_ptype flow)
	if (!seg)
		return -ENOMEM;

	tun_seg = devm_kzalloc(dev, sizeof(*seg) * ICE_FD_HW_SEG_MAX,
	tun_seg = devm_kcalloc(dev, sizeof(*seg), ICE_FD_HW_SEG_MAX,
			       GFP_KERNEL);
	if (!tun_seg) {
		devm_kfree(dev, seg);
@@ -1068,7 +1068,7 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp,
	if (!seg)
		return -ENOMEM;

	tun_seg = devm_kzalloc(dev, sizeof(*seg) * ICE_FD_HW_SEG_MAX,
	tun_seg = devm_kcalloc(dev, sizeof(*seg), ICE_FD_HW_SEG_MAX,
			       GFP_KERNEL);
	if (!tun_seg) {
		devm_kfree(dev, seg);
+0 −127
Original line number Diff line number Diff line
@@ -453,133 +453,6 @@ static u32 ice_fltr_build_action(u16 vsi_id)
		ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
}

/**
 * ice_fltr_find_adv_entry - find advanced rule
 * @rules: list of rules
 * @rule_id: id of wanted rule
 */
static struct ice_adv_fltr_mgmt_list_entry *
ice_fltr_find_adv_entry(struct list_head *rules, u16 rule_id)
{
	struct ice_adv_fltr_mgmt_list_entry *entry;

	list_for_each_entry(entry, rules, list_entry) {
		if (entry->rule_info.fltr_rule_id == rule_id)
			return entry;
	}

	return NULL;
}

/**
 * ice_fltr_update_adv_rule_flags - update flags on advanced rule
 * @vsi: pointer to VSI
 * @recipe_id: id of recipe
 * @entry: advanced rule entry
 * @new_flags: flags to update
 */
static enum ice_status
ice_fltr_update_adv_rule_flags(struct ice_vsi *vsi, u16 recipe_id,
			       struct ice_adv_fltr_mgmt_list_entry *entry,
			       u32 new_flags)
{
	struct ice_adv_rule_info *info = &entry->rule_info;
	struct ice_sw_act_ctrl *act = &info->sw_act;
	u32 action;

	if (act->fltr_act != ICE_FWD_TO_VSI)
		return ICE_ERR_NOT_SUPPORTED;

	action = ice_fltr_build_action(act->fwd_id.hw_vsi_id);

	return ice_fltr_update_rule_flags(&vsi->back->hw, info->fltr_rule_id,
					  recipe_id, action, info->sw_act.flag,
					  act->src, new_flags);
}

/**
 * ice_fltr_find_regular_entry - find regular rule
 * @rules: list of rules
 * @rule_id: id of wanted rule
 */
static struct ice_fltr_mgmt_list_entry *
ice_fltr_find_regular_entry(struct list_head *rules, u16 rule_id)
{
	struct ice_fltr_mgmt_list_entry *entry;

	list_for_each_entry(entry, rules, list_entry) {
		if (entry->fltr_info.fltr_rule_id == rule_id)
			return entry;
	}

	return NULL;
}

/**
 * ice_fltr_update_regular_rule - update flags on regular rule
 * @vsi: pointer to VSI
 * @recipe_id: id of recipe
 * @entry: regular rule entry
 * @new_flags: flags to update
 */
static enum ice_status
ice_fltr_update_regular_rule(struct ice_vsi *vsi, u16 recipe_id,
			     struct ice_fltr_mgmt_list_entry *entry,
			     u32 new_flags)
{
	struct ice_fltr_info *info = &entry->fltr_info;
	u32 action;

	if (info->fltr_act != ICE_FWD_TO_VSI)
		return ICE_ERR_NOT_SUPPORTED;

	action = ice_fltr_build_action(info->fwd_id.hw_vsi_id);

	return ice_fltr_update_rule_flags(&vsi->back->hw, info->fltr_rule_id,
					  recipe_id, action, info->flag,
					  info->src, new_flags);
}

/**
 * ice_fltr_update_flags - update flags on rule
 * @vsi: pointer to VSI
 * @rule_id: id of rule
 * @recipe_id: id of recipe
 * @new_flags: flags to update
 *
 * Function updates flags on regular and advance rule.
 *
 * Flags should be a combination of ICE_SINGLE_ACT_LB_ENABLE and
 * ICE_SINGLE_ACT_LAN_ENABLE.
 */
enum ice_status
ice_fltr_update_flags(struct ice_vsi *vsi, u16 rule_id, u16 recipe_id,
		      u32 new_flags)
{
	struct ice_adv_fltr_mgmt_list_entry *adv_entry;
	struct ice_fltr_mgmt_list_entry *regular_entry;
	struct ice_hw *hw = &vsi->back->hw;
	struct ice_sw_recipe *recp_list;
	struct list_head *fltr_rules;

	recp_list = &hw->switch_info->recp_list[recipe_id];
	if (!recp_list)
		return ICE_ERR_DOES_NOT_EXIST;

	fltr_rules = &recp_list->filt_rules;
	regular_entry = ice_fltr_find_regular_entry(fltr_rules, rule_id);
	if (regular_entry)
		return ice_fltr_update_regular_rule(vsi, recipe_id,
						    regular_entry, new_flags);

	adv_entry = ice_fltr_find_adv_entry(fltr_rules, rule_id);
	if (adv_entry)
		return ice_fltr_update_adv_rule_flags(vsi, recipe_id,
						      adv_entry, new_flags);

	return ICE_ERR_DOES_NOT_EXIST;
}

/**
 * ice_fltr_update_flags_dflt_rule - update flags on default rule
 * @vsi: pointer to VSI
+0 −4
Original line number Diff line number Diff line
@@ -36,10 +36,6 @@ enum ice_status
ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
		    enum ice_sw_fwd_act_type action);
void ice_fltr_remove_all(struct ice_vsi *vsi);

enum ice_status
ice_fltr_update_flags(struct ice_vsi *vsi, u16 rule_id, u16 recipe_id,
		      u32 new_flags);
enum ice_status
ice_fltr_update_flags_dflt_rule(struct ice_vsi *vsi, u16 rule_id, u8 direction,
				u32 new_flags);
Loading