net/mlx5: FPGA, Handle QP error event
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / fpga / core.c
index dc8970346521d24c32e082fdff43b7e12937202f..436a8136f26ff5f8b879eb02313beabb717f779e 100644 (file)
@@ -50,6 +50,11 @@ static const char *const mlx5_fpga_error_strings[] = {
        "Temperature Critical",
 };
 
+static const char * const mlx5_fpga_qp_error_strings[] = {
+       "Null Syndrome",
+       "Retry Counter Expired",
+       "RNR Expired",
+};
 static struct mlx5_fpga_device *mlx5_fpga_device_alloc(void)
 {
        struct mlx5_fpga_device *fdev = NULL;
@@ -75,6 +80,21 @@ static const char *mlx5_fpga_image_name(enum mlx5_fpga_image image)
        }
 }
 
+static const char *mlx5_fpga_device_name(u32 device)
+{
+       switch (device) {
+       case MLX5_FPGA_DEVICE_KU040:
+               return "ku040";
+       case MLX5_FPGA_DEVICE_KU060:
+               return "ku060";
+       case MLX5_FPGA_DEVICE_KU060_2:
+               return "ku060_2";
+       case MLX5_FPGA_DEVICE_UNKNOWN:
+       default:
+               return "unknown";
+       }
+}
+
 static int mlx5_fpga_device_load_check(struct mlx5_fpga_device *fdev)
 {
        struct mlx5_fpga_query query;
@@ -128,8 +148,9 @@ static int mlx5_fpga_device_brb(struct mlx5_fpga_device *fdev)
 int mlx5_fpga_device_start(struct mlx5_core_dev *mdev)
 {
        struct mlx5_fpga_device *fdev = mdev->fpga;
-       unsigned long flags;
        unsigned int max_num_qps;
+       unsigned long flags;
+       u32 fpga_device_id;
        int err;
 
        if (!fdev)
@@ -143,12 +164,23 @@ int mlx5_fpga_device_start(struct mlx5_core_dev *mdev)
        if (err)
                goto out;
 
-       mlx5_fpga_info(fdev, "device %u; %s image, version %u\n",
-                      MLX5_CAP_FPGA(fdev->mdev, fpga_device),
+       fpga_device_id = MLX5_CAP_FPGA(fdev->mdev, fpga_device);
+       mlx5_fpga_info(fdev, "%s:%u; %s image, version %u; SBU %06x:%04x version %d\n",
+                      mlx5_fpga_device_name(fpga_device_id),
+                      fpga_device_id,
                       mlx5_fpga_image_name(fdev->last_oper_image),
-                      MLX5_CAP_FPGA(fdev->mdev, image_version));
+                      MLX5_CAP_FPGA(fdev->mdev, image_version),
+                      MLX5_CAP_FPGA(fdev->mdev, ieee_vendor_id),
+                      MLX5_CAP_FPGA(fdev->mdev, sandbox_product_id),
+                      MLX5_CAP_FPGA(fdev->mdev, sandbox_product_version));
 
        max_num_qps = MLX5_CAP_FPGA(mdev, shell_caps.max_num_qps);
+       if (!max_num_qps) {
+               mlx5_fpga_err(fdev, "FPGA reports 0 QPs in SHELL_CAPS\n");
+               err = -ENOTSUPP;
+               goto out;
+       }
+
        err = mlx5_core_reserve_gids(mdev, max_num_qps);
        if (err)
                goto out;
@@ -244,23 +276,38 @@ static const char *mlx5_fpga_syndrome_to_string(u8 syndrome)
        return "Unknown";
 }
 
+static const char *mlx5_fpga_qp_syndrome_to_string(u8 syndrome)
+{
+       if (syndrome < ARRAY_SIZE(mlx5_fpga_qp_error_strings))
+               return mlx5_fpga_qp_error_strings[syndrome];
+       return "Unknown";
+}
+
 void mlx5_fpga_event(struct mlx5_core_dev *mdev, u8 event, void *data)
 {
        struct mlx5_fpga_device *fdev = mdev->fpga;
        const char *event_name;
        bool teardown = false;
        unsigned long flags;
+       u32 fpga_qpn;
        u8 syndrome;
 
-       if (event != MLX5_EVENT_TYPE_FPGA_ERROR) {
+       switch (event) {
+       case MLX5_EVENT_TYPE_FPGA_ERROR:
+               syndrome = MLX5_GET(fpga_error_event, data, syndrome);
+               event_name = mlx5_fpga_syndrome_to_string(syndrome);
+               break;
+       case MLX5_EVENT_TYPE_FPGA_QP_ERROR:
+               syndrome = MLX5_GET(fpga_qp_error_event, data, syndrome);
+               event_name = mlx5_fpga_qp_syndrome_to_string(syndrome);
+               fpga_qpn = MLX5_GET(fpga_qp_error_event, data, fpga_qpn);
+               break;
+       default:
                mlx5_fpga_warn_ratelimited(fdev, "Unexpected event %u\n",
                                           event);
                return;
        }
 
-       syndrome = MLX5_GET(fpga_error_event, data, syndrome);
-       event_name = mlx5_fpga_syndrome_to_string(syndrome);
-
        spin_lock_irqsave(&fdev->state_lock, flags);
        switch (fdev->state) {
        case MLX5_FPGA_STATUS_SUCCESS: