Commit 1c2c8c35 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2023-08-07 (ice)

This series contains updates to ice driver only.

Wojciech allows for LAG interfaces to be used for bridge offloads.

Marcin tracks additional metadata for filtering rules to aid in proper
differentiation of similar rules. He also renames some flags that
do not entirely describe their representation.

Karol and Jan add additional waiting for firmware load on devices that
require it.

Przemek refactors RSS implementation to clarify/simplify configurations.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  ice: clean up __ice_aq_get_set_rss_lut()
  ice: add FW load wait
  ice: Add get C827 PHY index function
  ice: Rename enum ice_pkt_flags values
  ice: Add direction metadata
  ice: Accept LAG netdevs in bridge offloads
====================

Link: https://lore.kernel.org/r/20230807204835.3129164-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents f5f502a3 b6143c9b
Loading
Loading
Loading
Loading
+26 −28
Original line number Diff line number Diff line
@@ -1404,6 +1404,7 @@ struct ice_aqc_get_link_topo {
	struct ice_aqc_link_topo_addr addr;
	u8 node_part_num;
#define ICE_AQC_GET_LINK_TOPO_NODE_NR_PCA9575	0x21
#define ICE_AQC_GET_LINK_TOPO_NODE_NR_C827	0x31
	u8 rsvd[9];
};

@@ -1793,11 +1794,10 @@ struct ice_aqc_lldp_filter_ctrl {
	u8 reserved2[12];
};

#define ICE_AQC_RSS_VSI_VALID BIT(15)

/* Get/Set RSS key (indirect 0x0B04/0x0B02) */
struct ice_aqc_get_set_rss_key {
#define ICE_AQC_GSET_RSS_KEY_VSI_VALID	BIT(15)
#define ICE_AQC_GSET_RSS_KEY_VSI_ID_S	0
#define ICE_AQC_GSET_RSS_KEY_VSI_ID_M	(0x3FF << ICE_AQC_GSET_RSS_KEY_VSI_ID_S)
	__le16 vsi_id;
	u8 reserved[6];
	__le32 addr_high;
@@ -1815,35 +1815,33 @@ struct ice_aqc_get_set_rss_keys {
	u8 extended_hash_key[ICE_AQC_GET_SET_RSS_KEY_DATA_HASH_KEY_SIZE];
};

/* Get/Set RSS LUT (indirect 0x0B05/0x0B03) */
struct ice_aqc_get_set_rss_lut {
#define ICE_AQC_GSET_RSS_LUT_VSI_VALID	BIT(15)
#define ICE_AQC_GSET_RSS_LUT_VSI_ID_S	0
#define ICE_AQC_GSET_RSS_LUT_VSI_ID_M	(0x3FF << ICE_AQC_GSET_RSS_LUT_VSI_ID_S)
	__le16 vsi_id;
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S	0
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M	\
				(0x3 << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S)

#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI	 0
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF	 1
#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL	 2
enum ice_lut_type {
	ICE_LUT_VSI = 0,
	ICE_LUT_PF = 1,
	ICE_LUT_GLOBAL = 2,
};

#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S	 2
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M	 \
				(0x3 << ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S)
enum ice_lut_size {
	ICE_LUT_VSI_SIZE = 64,
	ICE_LUT_GLOBAL_SIZE = 512,
	ICE_LUT_PF_SIZE = 2048,
};

#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128	 128
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128_FLAG 0
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512	 512
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG 1
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K	 2048
#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG	 2
/* enum ice_aqc_lut_flags combines constants used to fill
 * &ice_aqc_get_set_rss_lut ::flags, which is an amalgamation of global LUT ID,
 * LUT size and LUT type, last of which does not need neither shift nor mask.
 */
enum ice_aqc_lut_flags {
	ICE_AQC_LUT_SIZE_SMALL = 0, /* size = 64 or 128 */
	ICE_AQC_LUT_SIZE_512 = BIT(2),
	ICE_AQC_LUT_SIZE_2K = BIT(3),

#define ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S	 4
#define ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M	 \
				(0xF << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S)
	ICE_AQC_LUT_GLOBAL_IDX = GENMASK(7, 4),
};

/* Get/Set RSS LUT (indirect 0x0B05/0x0B03) */
struct ice_aqc_get_set_rss_lut {
	__le16 vsi_id;
	__le16 flags;
	__le32 reserved;
	__le32 addr_high;
+120 −85
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include "ice_sched.h"
#include "ice_adminq_cmd.h"
#include "ice_flow.h"
#include "ice_ptp_hw.h"

#define ICE_PF_RESET_WAIT_COUNT	300

@@ -2661,6 +2662,67 @@ ice_parse_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
	ice_recalc_port_limited_caps(hw, &dev_p->common_cap);
}

/**
 * ice_aq_get_netlist_node
 * @hw: pointer to the hw struct
 * @cmd: get_link_topo AQ structure
 * @node_part_number: output node part number if node found
 * @node_handle: output node handle parameter if node found
 */
static int
ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd,
			u8 *node_part_number, u16 *node_handle)
{
	struct ice_aq_desc desc;

	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
	desc.params.get_link_topo = *cmd;

	if (ice_aq_send_cmd(hw, &desc, NULL, 0, NULL))
		return -EIO;

	if (node_handle)
		*node_handle = le16_to_cpu(desc.params.get_link_topo.addr.handle);
	if (node_part_number)
		*node_part_number = desc.params.get_link_topo.node_part_num;

	return 0;
}

/**
 * ice_is_pf_c827 - check if pf contains c827 phy
 * @hw: pointer to the hw struct
 */
bool ice_is_pf_c827(struct ice_hw *hw)
{
	struct ice_aqc_get_link_topo cmd = {};
	u8 node_part_number;
	u16 node_handle;
	int status;

	if (hw->mac_type != ICE_MAC_E810)
		return false;

	if (hw->device_id != ICE_DEV_ID_E810C_QSFP)
		return true;

	cmd.addr.topo_params.node_type_ctx =
		FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_TYPE_M, ICE_AQC_LINK_TOPO_NODE_TYPE_PHY) |
		FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M, ICE_AQC_LINK_TOPO_NODE_CTX_PORT);
	cmd.addr.topo_params.index = 0;

	status = ice_aq_get_netlist_node(hw, &cmd, &node_part_number,
					 &node_handle);

	if (status || node_part_number != ICE_AQC_GET_LINK_TOPO_NODE_NR_C827)
		return false;

	if (node_handle == E810C_QSFP_C827_0_HANDLE || node_handle == E810C_QSFP_C827_1_HANDLE)
		return true;

	return false;
}

/**
 * ice_aq_list_caps - query function/device capabilities
 * @hw: pointer to the HW struct
@@ -3877,6 +3939,34 @@ ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
	return status;
}

static enum ice_lut_size ice_lut_type_to_size(enum ice_lut_type type)
{
	switch (type) {
	case ICE_LUT_VSI:
		return ICE_LUT_VSI_SIZE;
	case ICE_LUT_GLOBAL:
		return ICE_LUT_GLOBAL_SIZE;
	case ICE_LUT_PF:
		return ICE_LUT_PF_SIZE;
	}
	WARN_ONCE(1, "incorrect type passed");
	return ICE_LUT_VSI_SIZE;
}

static enum ice_aqc_lut_flags ice_lut_size_to_flag(enum ice_lut_size size)
{
	switch (size) {
	case ICE_LUT_VSI_SIZE:
		return ICE_AQC_LUT_SIZE_SMALL;
	case ICE_LUT_GLOBAL_SIZE:
		return ICE_AQC_LUT_SIZE_512;
	case ICE_LUT_PF_SIZE:
		return ICE_AQC_LUT_SIZE_2K;
	}
	WARN_ONCE(1, "incorrect size passed");
	return 0;
}

/**
 * __ice_aq_get_set_rss_lut
 * @hw: pointer to the hardware structure
@@ -3886,95 +3976,44 @@ ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
 * Internal function to get (0x0B05) or set (0x0B03) RSS look up table
 */
static int
__ice_aq_get_set_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *params, bool set)
{
	u16 flags = 0, vsi_id, lut_type, lut_size, glob_lut_idx, vsi_handle;
	struct ice_aqc_get_set_rss_lut *cmd_resp;
__ice_aq_get_set_rss_lut(struct ice_hw *hw,
			 struct ice_aq_get_set_rss_lut_params *params, bool set)
{
	u16 opcode, vsi_id, vsi_handle = params->vsi_handle, glob_lut_idx = 0;
	enum ice_lut_type lut_type = params->lut_type;
	struct ice_aqc_get_set_rss_lut *desc_params;
	enum ice_aqc_lut_flags flags;
	enum ice_lut_size lut_size;
	struct ice_aq_desc desc;
	int status;
	u8 *lut;

	if (!params)
		return -EINVAL;
	u8 *lut = params->lut;

	vsi_handle = params->vsi_handle;
	lut = params->lut;

	if (!ice_is_vsi_valid(hw, vsi_handle) || !lut)
	if (!lut || !ice_is_vsi_valid(hw, vsi_handle))
		return -EINVAL;

	lut_size = params->lut_size;
	lut_type = params->lut_type;
	glob_lut_idx = params->global_lut_id;
	vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);

	cmd_resp = &desc.params.get_set_rss_lut;
	lut_size = ice_lut_type_to_size(lut_type);
	if (lut_size > params->lut_size)
		return -EINVAL;
	else if (set && lut_size != params->lut_size)
		return -EINVAL;

	if (set) {
		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_lut);
	opcode = set ? ice_aqc_opc_set_rss_lut : ice_aqc_opc_get_rss_lut;
	ice_fill_dflt_direct_cmd_desc(&desc, opcode);
	if (set)
		desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
	} else {
		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_lut);
	}

	cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
					 ICE_AQC_GSET_RSS_LUT_VSI_ID_S) &
					ICE_AQC_GSET_RSS_LUT_VSI_ID_M) |
				       ICE_AQC_GSET_RSS_LUT_VSI_VALID);

	switch (lut_type) {
	case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI:
	case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF:
	case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL:
		flags |= ((lut_type << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S) &
			  ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M);
		break;
	default:
		status = -EINVAL;
		goto ice_aq_get_set_rss_lut_exit;
	}

	if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL) {
		flags |= ((glob_lut_idx << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S) &
			  ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M);

		if (!set)
			goto ice_aq_get_set_rss_lut_send;
	} else if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
		if (!set)
			goto ice_aq_get_set_rss_lut_send;
	} else {
		goto ice_aq_get_set_rss_lut_send;
	}
	desc_params = &desc.params.get_set_rss_lut;
	vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
	desc_params->vsi_id = cpu_to_le16(vsi_id | ICE_AQC_RSS_VSI_VALID);

	/* LUT size is only valid for Global and PF table types */
	switch (lut_size) {
	case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128:
		break;
	case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512:
		flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG <<
			  ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
			 ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
		break;
	case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K:
		if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
			flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
				  ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
				 ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
			break;
		}
		fallthrough;
	default:
		status = -EINVAL;
		goto ice_aq_get_set_rss_lut_exit;
	}
	if (lut_type == ICE_LUT_GLOBAL)
		glob_lut_idx = FIELD_PREP(ICE_AQC_LUT_GLOBAL_IDX,
					  params->global_lut_id);

ice_aq_get_set_rss_lut_send:
	cmd_resp->flags = cpu_to_le16(flags);
	status = ice_aq_send_cmd(hw, &desc, lut, lut_size, NULL);
	flags = lut_type | glob_lut_idx | ice_lut_size_to_flag(lut_size);
	desc_params->flags = cpu_to_le16(flags);

ice_aq_get_set_rss_lut_exit:
	return status;
	return ice_aq_send_cmd(hw, &desc, lut, lut_size, NULL);
}

/**
@@ -4016,12 +4055,10 @@ static int
__ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id,
			 struct ice_aqc_get_set_rss_keys *key, bool set)
{
	struct ice_aqc_get_set_rss_key *cmd_resp;
	struct ice_aqc_get_set_rss_key *desc_params;
	u16 key_size = sizeof(*key);
	struct ice_aq_desc desc;

	cmd_resp = &desc.params.get_set_rss_key;

	if (set) {
		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_key);
		desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
@@ -4029,10 +4066,8 @@ __ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id,
		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_key);
	}

	cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
					 ICE_AQC_GSET_RSS_KEY_VSI_ID_S) &
					ICE_AQC_GSET_RSS_KEY_VSI_ID_M) |
				       ICE_AQC_GSET_RSS_KEY_VSI_VALID);
	desc_params = &desc.params.get_set_rss_key;
	desc_params->vsi_id = cpu_to_le16(vsi_id | ICE_AQC_RSS_VSI_VALID);

	return ice_aq_send_cmd(hw, &desc, key, key_size, NULL);
}
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ int
ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
		    struct ice_aqc_get_phy_caps_data *caps,
		    struct ice_sq_cd *cd);
bool ice_is_pf_c827(struct ice_hw *hw);
int
ice_aq_list_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
		 enum ice_adminq_opc opc, struct ice_sq_cd *cd);
+42 −5
Original line number Diff line number Diff line
@@ -20,8 +20,23 @@ static const struct rhashtable_params ice_fdb_ht_params = {

static bool ice_eswitch_br_is_dev_valid(const struct net_device *dev)
{
	/* Accept only PF netdev and PRs */
	return ice_is_port_repr_netdev(dev) || netif_is_ice(dev);
	/* Accept only PF netdev, PRs and LAG */
	return ice_is_port_repr_netdev(dev) || netif_is_ice(dev) ||
		netif_is_lag_master(dev);
}

static struct net_device *
ice_eswitch_br_get_uplink_from_lag(struct net_device *lag_dev)
{
	struct net_device *lower;
	struct list_head *iter;

	netdev_for_each_lower_dev(lag_dev, lower, iter) {
		if (netif_is_ice(lower))
			return lower;
	}

	return NULL;
}

static struct ice_esw_br_port *
@@ -31,8 +46,19 @@ ice_eswitch_br_netdev_to_port(struct net_device *dev)
		struct ice_repr *repr = ice_netdev_to_repr(dev);

		return repr->br_port;
	} else if (netif_is_ice(dev)) {
		struct ice_pf *pf = ice_netdev_to_pf(dev);
	} else if (netif_is_ice(dev) || netif_is_lag_master(dev)) {
		struct net_device *ice_dev;
		struct ice_pf *pf;

		if (netif_is_lag_master(dev))
			ice_dev = ice_eswitch_br_get_uplink_from_lag(dev);
		else
			ice_dev = dev;

		if (!ice_dev)
			return NULL;

		pf = ice_netdev_to_pf(ice_dev);

		return pf->br_port;
	}
@@ -1085,7 +1111,18 @@ ice_eswitch_br_port_link(struct ice_esw_br_offloads *br_offloads,
		err = ice_eswitch_br_vf_repr_port_init(bridge, repr);
		trace_ice_eswitch_br_port_link(repr->br_port);
	} else {
		struct ice_pf *pf = ice_netdev_to_pf(dev);
		struct net_device *ice_dev;
		struct ice_pf *pf;

		if (netif_is_lag_master(dev))
			ice_dev = ice_eswitch_br_get_uplink_from_lag(dev);
		else
			ice_dev = dev;

		if (!ice_dev)
			return 0;

		pf = ice_netdev_to_pf(ice_dev);

		err = ice_eswitch_br_uplink_port_init(bridge, pf);
		trace_ice_eswitch_br_port_link(pf->br_port);
+2 −1
Original line number Diff line number Diff line
@@ -335,6 +335,8 @@
#define VP_MDET_TX_TCLAN_VALID_M		BIT(0)
#define VP_MDET_TX_TDPU(_VF)			(0x00040000 + ((_VF) * 4))
#define VP_MDET_TX_TDPU_VALID_M			BIT(0)
#define GL_MNG_FWSM				0x000B6134
#define GL_MNG_FWSM_FW_LOADING_M		BIT(30)
#define GLNVM_FLA				0x000B6108
#define GLNVM_FLA_LOCKED_M			BIT(6)
#define GLNVM_GENS				0x000B6100
@@ -489,7 +491,6 @@
#define VSIQF_FD_CNT_FD_BCNT_M			ICE_M(0x3FFF, 16)
#define VSIQF_FD_SIZE(_VSI)			(0x00462000 + ((_VSI) * 4))
#define VSIQF_HKEY_MAX_INDEX			12
#define VSIQF_HLUT_MAX_INDEX			15
#define PFPM_APM				0x000B8080
#define PFPM_APM_APME_M				BIT(0)
#define PFPM_WUFC				0x0009DC00
Loading