Skip to content

Commit 75c2a8f

Browse files
committed
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/[email protected]/ ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 22f07b8 + 88a31b1 commit 75c2a8f

File tree

11 files changed

+1518
-8
lines changed

11 files changed

+1518
-8
lines changed

drivers/net/ethernet/mellanox/mlxsw/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ mlxsw_switchx2-objs := switchx2.o
1515
obj-$(CONFIG_MLXSW_SPECTRUM) += mlxsw_spectrum.o
1616
mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
1717
spectrum_switchdev.o spectrum_router.o \
18+
spectrum_router_xm.o \
1819
spectrum1_kvdl.o spectrum2_kvdl.o \
1920
spectrum_kvdl.o \
2021
spectrum_acl_tcam.o spectrum_acl_ctcam.o \

drivers/net/ethernet/mellanox/mlxsw/cmd.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,23 @@ static inline int mlxsw_cmd_boardinfo(struct mlxsw_core *mlxsw_core,
343343
0, 0, false, out_mbox, MLXSW_CMD_MBOX_SIZE);
344344
}
345345

346+
/* cmd_mbox_xm_num_local_ports
347+
* Number of local_ports connected to the xm.
348+
* Each local port is a 4x
349+
* Spectrum-2/3: 25G
350+
* Spectrum-4: 50G
351+
*/
352+
MLXSW_ITEM32(cmd_mbox, boardinfo, xm_num_local_ports, 0x00, 4, 3);
353+
354+
/* cmd_mbox_xm_exists
355+
* An XM (eXtanded Mezanine, e.g. used for the XLT) is connected on the board.
356+
*/
357+
MLXSW_ITEM32(cmd_mbox, boardinfo, xm_exists, 0x00, 0, 1);
358+
359+
/* cmd_mbox_xm_local_port_entry
360+
*/
361+
MLXSW_ITEM_BIT_ARRAY(cmd_mbox, boardinfo, xm_local_port_entry, 0x04, 4, 8);
362+
346363
/* cmd_mbox_boardinfo_intapin
347364
* When PCIe interrupt messages are being used, this value is used for clearing
348365
* 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);
657674
*/
658675
MLXSW_ITEM32(cmd_mbox, config_profile, set_cqe_version, 0x08, 0, 1);
659676

677+
/* cmd_mbox_config_set_kvh_xlt_cache_mode
678+
* Capability bit. Setting a bit to 1 configures the profile
679+
* according to the mailbox contents.
680+
*/
681+
MLXSW_ITEM32(cmd_mbox, config_profile, set_kvh_xlt_cache_mode, 0x08, 3, 1);
682+
660683
/* cmd_mbox_config_profile_max_vepa_channels
661684
* Maximum number of VEPA channels per port (0 through 16)
662685
* 0 - multi-channel VEPA is disabled
@@ -783,6 +806,13 @@ MLXSW_ITEM32(cmd_mbox, config_profile, adaptive_routing_group_cap, 0x4C, 0, 16);
783806
*/
784807
MLXSW_ITEM32(cmd_mbox, config_profile, arn, 0x50, 31, 1);
785808

809+
/* cmd_mbox_config_profile_kvh_xlt_cache_mode
810+
* KVH XLT cache mode:
811+
* 0 - XLT can use all KVH as best-effort
812+
* 1 - XLT cache uses 1/2 KVH
813+
*/
814+
MLXSW_ITEM32(cmd_mbox, config_profile, kvh_xlt_cache_mode, 0x50, 8, 4);
815+
786816
/* cmd_mbox_config_kvd_linear_size
787817
* KVD Linear Size
788818
* Valid for Spectrum only

drivers/net/ethernet/mellanox/mlxsw/core.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2856,6 +2856,18 @@ mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
28562856
}
28572857
EXPORT_SYMBOL(mlxsw_core_port_devlink_port_get);
28582858

2859+
bool mlxsw_core_port_is_xm(const struct mlxsw_core *mlxsw_core, u8 local_port)
2860+
{
2861+
const struct mlxsw_bus_info *bus_info = mlxsw_core->bus_info;
2862+
int i;
2863+
2864+
for (i = 0; i < bus_info->xm_local_ports_count; i++)
2865+
if (bus_info->xm_local_ports[i] == local_port)
2866+
return true;
2867+
return false;
2868+
}
2869+
EXPORT_SYMBOL(mlxsw_core_port_is_xm);
2870+
28592871
struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core)
28602872
{
28612873
return mlxsw_core->env;

drivers/net/ethernet/mellanox/mlxsw/core.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
223223
struct devlink_port *
224224
mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
225225
u8 local_port);
226+
bool mlxsw_core_port_is_xm(const struct mlxsw_core *mlxsw_core, u8 local_port);
226227
struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core);
227228
bool mlxsw_core_is_initialized(const struct mlxsw_core *mlxsw_core);
228229
int mlxsw_core_module_max_width(struct mlxsw_core *mlxsw_core, u8 module);
@@ -255,7 +256,8 @@ struct mlxsw_config_profile {
255256
used_max_pkey:1,
256257
used_ar_sec:1,
257258
used_adaptive_routing_group_cap:1,
258-
used_kvd_sizes:1;
259+
used_kvd_sizes:1,
260+
used_kvh_xlt_cache_mode:1;
259261
u8 max_vepa_channels;
260262
u16 max_mid;
261263
u16 max_pgt;
@@ -277,6 +279,7 @@ struct mlxsw_config_profile {
277279
u32 kvd_linear_size;
278280
u8 kvd_hash_single_parts;
279281
u8 kvd_hash_double_parts;
282+
u8 kvh_xlt_cache_mode;
280283
struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
281284
};
282285

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

441+
#define MLXSW_BUS_INFO_XM_LOCAL_PORTS_MAX 4
442+
438443
struct mlxsw_bus_info {
439444
const char *device_kind;
440445
const char *device_name;
@@ -443,7 +448,10 @@ struct mlxsw_bus_info {
443448
u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
444449
u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
445450
u8 low_frequency:1,
446-
read_frc_capable:1;
451+
read_frc_capable:1,
452+
xm_exists:1;
453+
u8 xm_local_ports_count;
454+
u8 xm_local_ports[MLXSW_BUS_INFO_XM_LOCAL_PORTS_MAX];
447455
};
448456

449457
struct mlxsw_hwmon;

drivers/net/ethernet/mellanox/mlxsw/minimal.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
291291

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

drivers/net/ethernet/mellanox/mlxsw/pci.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,12 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox,
11961196
mlxsw_cmd_mbox_config_profile_kvd_hash_double_size_set(mbox,
11971197
MLXSW_RES_GET(res, KVD_DOUBLE_SIZE));
11981198
}
1199+
if (profile->used_kvh_xlt_cache_mode) {
1200+
mlxsw_cmd_mbox_config_profile_set_kvh_xlt_cache_mode_set(
1201+
mbox, 1);
1202+
mlxsw_cmd_mbox_config_profile_kvh_xlt_cache_mode_set(
1203+
mbox, profile->kvh_xlt_cache_mode);
1204+
}
11991205

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

1218+
static int mlxsw_pci_boardinfo_xm_process(struct mlxsw_pci *mlxsw_pci,
1219+
struct mlxsw_bus_info *bus_info,
1220+
char *mbox)
1221+
{
1222+
int count = mlxsw_cmd_mbox_boardinfo_xm_num_local_ports_get(mbox);
1223+
int i;
1224+
1225+
if (!mlxsw_cmd_mbox_boardinfo_xm_exists_get(mbox))
1226+
return 0;
1227+
1228+
bus_info->xm_exists = true;
1229+
1230+
if (count > MLXSW_BUS_INFO_XM_LOCAL_PORTS_MAX) {
1231+
dev_err(&mlxsw_pci->pdev->dev, "Invalid number of XM local ports\n");
1232+
return -EINVAL;
1233+
}
1234+
bus_info->xm_local_ports_count = count;
1235+
for (i = 0; i < count; i++)
1236+
bus_info->xm_local_ports[i] =
1237+
mlxsw_cmd_mbox_boardinfo_xm_local_port_entry_get(mbox,
1238+
i);
1239+
return 0;
1240+
}
1241+
12121242
static int mlxsw_pci_boardinfo(struct mlxsw_pci *mlxsw_pci, char *mbox)
12131243
{
12141244
struct mlxsw_bus_info *bus_info = &mlxsw_pci->bus_info;
@@ -1220,7 +1250,8 @@ static int mlxsw_pci_boardinfo(struct mlxsw_pci *mlxsw_pci, char *mbox)
12201250
return err;
12211251
mlxsw_cmd_mbox_boardinfo_vsd_memcpy_from(mbox, bus_info->vsd);
12221252
mlxsw_cmd_mbox_boardinfo_psid_memcpy_from(mbox, bus_info->psid);
1223-
return 0;
1253+
1254+
return mlxsw_pci_boardinfo_xm_process(mlxsw_pci, bus_info, mbox);
12241255
}
12251256

12261257
static int mlxsw_pci_fw_area_init(struct mlxsw_pci *mlxsw_pci, char *mbox,

0 commit comments

Comments
 (0)