mlxsw: pci: Obtain info about ports used by eXtended mezanine
authorJiri Pirko <jiri@nvidia.com>
Mon, 14 Dec 2020 11:30:30 +0000 (13:30 +0200)
committerJakub Kicinski <kuba@kernel.org>
Tue, 15 Dec 2020 03:09:54 +0000 (19:09 -0800)
The output of boardinfo command was extended to contain information
about XM. Indicates if is present and in case it is, tells which
localports are used for the connection. So parse this info and store it
in bus_info passed up to the driver.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/cmd.h
drivers/net/ethernet/mellanox/mlxsw/core.h
drivers/net/ethernet/mellanox/mlxsw/pci.c

index 5ffdfb532cb7f9e4a16f1423283648e8f85bce1a..4de15c56542fe2791e37460ee1263b51d4a0ec0c 100644 (file)
@@ -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.
index 92f7398287bef588f70fda92b8d1586955e66d9b..ec424d388eccb9cafd5016208878fed360a6d8a4 100644 (file)
@@ -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;
index 641cdd81882b87be67073d3d3f433c88610ea16e..aae472f0e62fdbfa031bded205ac1b98afa4f949 100644 (file)
@@ -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,