Skip to content

Commit

Permalink
Merge branch 'mlxsw-introduce-initial-xm-router-support'
Browse files Browse the repository at this point in the history
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/[email protected]/
====================

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Dec 15, 2020
2 parents 22f07b8 + 88a31b1 commit 75c2a8f
Show file tree
Hide file tree
Showing 11 changed files with 1,518 additions and 8 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlxsw/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
30 changes: 30 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 10 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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];
};

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/minimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
33 changes: 32 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,12 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox,
mlxsw_cmd_mbox_config_profile_kvd_hash_double_size_set(mbox,
MLXSW_RES_GET(res, KVD_DOUBLE_SIZE));
}
if (profile->used_kvh_xlt_cache_mode) {
mlxsw_cmd_mbox_config_profile_set_kvh_xlt_cache_mode_set(
mbox, 1);
mlxsw_cmd_mbox_config_profile_kvh_xlt_cache_mode_set(
mbox, profile->kvh_xlt_cache_mode);
}

for (i = 0; i < MLXSW_CONFIG_PROFILE_SWID_COUNT; i++)
mlxsw_pci_config_profile_swid_config(mlxsw_pci, mbox, i,
Expand All @@ -1209,6 +1215,30 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox,
return mlxsw_cmd_config_profile_set(mlxsw_pci->core, mbox);
}

static int mlxsw_pci_boardinfo_xm_process(struct mlxsw_pci *mlxsw_pci,
struct mlxsw_bus_info *bus_info,
char *mbox)
{
int count = mlxsw_cmd_mbox_boardinfo_xm_num_local_ports_get(mbox);
int i;

if (!mlxsw_cmd_mbox_boardinfo_xm_exists_get(mbox))
return 0;

bus_info->xm_exists = true;

if (count > MLXSW_BUS_INFO_XM_LOCAL_PORTS_MAX) {
dev_err(&mlxsw_pci->pdev->dev, "Invalid number of XM local ports\n");
return -EINVAL;
}
bus_info->xm_local_ports_count = count;
for (i = 0; i < count; i++)
bus_info->xm_local_ports[i] =
mlxsw_cmd_mbox_boardinfo_xm_local_port_entry_get(mbox,
i);
return 0;
}

static int mlxsw_pci_boardinfo(struct mlxsw_pci *mlxsw_pci, char *mbox)
{
struct mlxsw_bus_info *bus_info = &mlxsw_pci->bus_info;
Expand All @@ -1220,7 +1250,8 @@ static int mlxsw_pci_boardinfo(struct mlxsw_pci *mlxsw_pci, char *mbox)
return err;
mlxsw_cmd_mbox_boardinfo_vsd_memcpy_from(mbox, bus_info->vsd);
mlxsw_cmd_mbox_boardinfo_psid_memcpy_from(mbox, bus_info->psid);
return 0;

return mlxsw_pci_boardinfo_xm_process(mlxsw_pci, bus_info, mbox);
}

static int mlxsw_pci_fw_area_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
Expand Down
Loading

0 comments on commit 75c2a8f

Please sign in to comment.