Commit 75c2a8fe authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'mlxsw-introduce-initial-xm-router-support'

Ido Schimmel says:

====================
mlxsw: Introduce initial XM router support

This patch set implements initial eXtended Mezzanine (XM) router
support.

The XM is an external device connected to the Spectrum-{2,3} ASICs using
dedicated Ethernet ports. Its purpose is to increase the number of
routes that can be offloaded to hardware. This is achieved by having the
ASIC act as a cache that refers cache misses to the XM where the FIB is
stored and LPM lookup is performed.

Future patch sets will add more sophisticated cache flushing and
selftests that utilize cache counters on the ASIC, which we plan to
expose via devlink-metric [1].

Patch set overview:

Patches #1-#2 add registers to insert/remove routes to/from the XM and
to enable/disable it. Patch #3 utilizes these registers in order to
implement XM-specific router low-level operations.

Patches #4-#5 query from firmware the availability of the XM and the
local ports that are used to connect the ASIC to the XM, so that netdevs
will not be created for them.

Patches #6-#8 initialize the XM by configuring its cache parameters.

Patch #9-#10 implement cache management, so that LPM lookup will be
correctly cached in the ASIC.

Patches #11-#13 implement cache flushing, so that routes
insertions/removals to/from the XM will flush the affected entries in
the cache.

Patch #14 configures the ASIC to allocate half of its memory for the
cache, so that room will be left for other entries (e.g., FDBs,
neighbours).

Patch #15 starts using the XM for IPv4 route offload, when available.

[1] https://lore.kernel.org/netdev/20200817125059.193242-1-idosch@idosch.org/
====================

Link: https://lore.kernel.org/r/20201214113041.2789043-1-idosch@idosch.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 22f07b86 88a31b18
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ mlxsw_switchx2-objs := switchx2.o
obj-$(CONFIG_MLXSW_SPECTRUM)	+= mlxsw_spectrum.o
mlxsw_spectrum-objs		:= spectrum.o spectrum_buffers.o \
				   spectrum_switchdev.o spectrum_router.o \
				   spectrum_router_xm.o \
				   spectrum1_kvdl.o spectrum2_kvdl.o \
				   spectrum_kvdl.o \
				   spectrum_acl_tcam.o spectrum_acl_ctcam.o \
+30 −0
Original line number Diff line number Diff line
@@ -343,6 +343,23 @@ static inline int mlxsw_cmd_boardinfo(struct mlxsw_core *mlxsw_core,
				  0, 0, false, out_mbox, MLXSW_CMD_MBOX_SIZE);
}

/* cmd_mbox_xm_num_local_ports
 * Number of local_ports connected to the xm.
 * Each local port is a 4x
 * Spectrum-2/3: 25G
 * Spectrum-4: 50G
 */
MLXSW_ITEM32(cmd_mbox, boardinfo, xm_num_local_ports, 0x00, 4, 3);

/* cmd_mbox_xm_exists
 * An XM (eXtanded Mezanine, e.g. used for the XLT) is connected on the board.
 */
MLXSW_ITEM32(cmd_mbox, boardinfo, xm_exists, 0x00, 0, 1);

/* cmd_mbox_xm_local_port_entry
 */
MLXSW_ITEM_BIT_ARRAY(cmd_mbox, boardinfo, xm_local_port_entry, 0x04, 4, 8);

/* cmd_mbox_boardinfo_intapin
 * When PCIe interrupt messages are being used, this value is used for clearing
 * an interrupt. When using MSI-X, this register is not used.
@@ -657,6 +674,12 @@ MLXSW_ITEM32(cmd_mbox, config_profile, set_kvd_hash_double_size, 0x0C, 26, 1);
 */
MLXSW_ITEM32(cmd_mbox, config_profile, set_cqe_version, 0x08, 0, 1);

/* cmd_mbox_config_set_kvh_xlt_cache_mode
 * Capability bit. Setting a bit to 1 configures the profile
 * according to the mailbox contents.
 */
MLXSW_ITEM32(cmd_mbox, config_profile, set_kvh_xlt_cache_mode, 0x08, 3, 1);

/* cmd_mbox_config_profile_max_vepa_channels
 * Maximum number of VEPA channels per port (0 through 16)
 * 0 - multi-channel VEPA is disabled
@@ -783,6 +806,13 @@ MLXSW_ITEM32(cmd_mbox, config_profile, adaptive_routing_group_cap, 0x4C, 0, 16);
 */
MLXSW_ITEM32(cmd_mbox, config_profile, arn, 0x50, 31, 1);

/* cmd_mbox_config_profile_kvh_xlt_cache_mode
 * KVH XLT cache mode:
 * 0 - XLT can use all KVH as best-effort
 * 1 - XLT cache uses 1/2 KVH
 */
MLXSW_ITEM32(cmd_mbox, config_profile, kvh_xlt_cache_mode, 0x50, 8, 4);

/* cmd_mbox_config_kvd_linear_size
 * KVD Linear Size
 * Valid for Spectrum only
+12 −0
Original line number Diff line number Diff line
@@ -2856,6 +2856,18 @@ mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
}
EXPORT_SYMBOL(mlxsw_core_port_devlink_port_get);

bool mlxsw_core_port_is_xm(const struct mlxsw_core *mlxsw_core, u8 local_port)
{
	const struct mlxsw_bus_info *bus_info = mlxsw_core->bus_info;
	int i;

	for (i = 0; i < bus_info->xm_local_ports_count; i++)
		if (bus_info->xm_local_ports[i] == local_port)
			return true;
	return false;
}
EXPORT_SYMBOL(mlxsw_core_port_is_xm);

struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core)
{
	return mlxsw_core->env;
+10 −2
Original line number Diff line number Diff line
@@ -223,6 +223,7 @@ enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
struct devlink_port *
mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
				 u8 local_port);
bool mlxsw_core_port_is_xm(const struct mlxsw_core *mlxsw_core, u8 local_port);
struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core);
bool mlxsw_core_is_initialized(const struct mlxsw_core *mlxsw_core);
int mlxsw_core_module_max_width(struct mlxsw_core *mlxsw_core, u8 module);
@@ -255,7 +256,8 @@ struct mlxsw_config_profile {
		used_max_pkey:1,
		used_ar_sec:1,
		used_adaptive_routing_group_cap:1,
		used_kvd_sizes:1;
		used_kvd_sizes:1,
		used_kvh_xlt_cache_mode:1;
	u8	max_vepa_channels;
	u16	max_mid;
	u16	max_pgt;
@@ -277,6 +279,7 @@ struct mlxsw_config_profile {
	u32	kvd_linear_size;
	u8	kvd_hash_single_parts;
	u8	kvd_hash_double_parts;
	u8	kvh_xlt_cache_mode;
	struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
};

@@ -435,6 +438,8 @@ struct mlxsw_fw_rev {
	u16 can_reset_minor;
};

#define MLXSW_BUS_INFO_XM_LOCAL_PORTS_MAX 4

struct mlxsw_bus_info {
	const char *device_kind;
	const char *device_name;
@@ -443,7 +448,10 @@ struct mlxsw_bus_info {
	u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
	u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
	u8 low_frequency:1,
	   read_frc_capable:1;
	   read_frc_capable:1,
	   xm_exists:1;
	u8 xm_local_ports_count;
	u8 xm_local_ports[MLXSW_BUS_INFO_XM_LOCAL_PORTS_MAX];
};

struct mlxsw_hwmon;
+2 −1
Original line number Diff line number Diff line
@@ -291,7 +291,8 @@ static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)

	/* Create port objects for each valid entry */
	for (i = 0; i < mlxsw_m->max_ports; i++) {
		if (mlxsw_m->module_to_port[i] > 0) {
		if (mlxsw_m->module_to_port[i] > 0 &&
		    !mlxsw_core_port_is_xm(mlxsw_m->core, i)) {
			err = mlxsw_m_port_create(mlxsw_m,
						  mlxsw_m->module_to_port[i],
						  i);
Loading