@@ -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.
@@ -435,6 +435,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 +445,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;
@@ -1209,6 +1209,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;
@@ -1220,7 +1244,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,