habanalabs: ignore f/w status error
authorOded Gabbay <ogabbay@kernel.org>
Mon, 12 Apr 2021 06:52:05 +0000 (09:52 +0300)
committerOded Gabbay <ogabbay@kernel.org>
Sat, 8 May 2021 08:21:57 +0000 (11:21 +0300)
In case firmware has a bug and erroneously reports a status error
(e.g. device unusable) during boot, allow the user to tell the driver
to continue the boot regardless of the error status.

This will be done via kernel parameter which exposes a mask. The
user that loads the driver can decide exactly which status error to
ignore and which to take into account. The bitmask is according to
defines in hl_boot_if.h

Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
drivers/misc/habanalabs/common/firmware_if.c
drivers/misc/habanalabs/common/habanalabs.h
drivers/misc/habanalabs/common/habanalabs_drv.c

index 377a7ca886feb29caeb2aaeaff57405748a79c95..0713b2c12d54f4fded7b38bf79538c02e1f0fe1e 100644 (file)
@@ -400,7 +400,8 @@ static int fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg,
                err_exists = true;
        }
 
-       if (err_exists)
+       if (err_exists && ((err_val & ~CPU_BOOT_ERR0_ENABLED) &
+                               lower_32_bits(hdev->boot_error_status_mask)))
                return -EIO;
 
        return 0;
index 91291a8e201eec6f17ca4fe1b8a0cea0912b8f4d..6579f8767abdaccc6edee903449a44541b789815 100644 (file)
@@ -1962,6 +1962,12 @@ struct hl_mmu_funcs {
  * @clock_gating_mask: is clock gating enabled. bitmask that represents the
  *                     different engines. See debugfs-driver-habanalabs for
  *                     details.
+ * @boot_error_status_mask: contains a mask of the device boot error status.
+ *                          Each bit represents a different error, according to
+ *                          the defines in hl_boot_if.h. If the bit is cleared,
+ *                          the error will be ignored by the driver during
+ *                          device initialization. Mainly used to debug and
+ *                          workaround firmware bugs
  * @in_reset: is device in reset flow.
  * @curr_pll_profile: current PLL profile.
  * @card_type: Various ASICs have several card types. This indicates the card
@@ -2077,6 +2083,7 @@ struct hl_device {
        u64                             timeout_jiffies;
        u64                             max_power;
        u64                             clock_gating_mask;
+       u64                             boot_error_status_mask;
        atomic_t                        in_reset;
        enum hl_pll_frequency           curr_pll_profile;
        enum cpucp_card_types           card_type;
index 7135f1e03864107b6bcdf8b6040f1f8ff15dfe3e..64d1530db9854501047da270e80f07f5bbb39f08 100644 (file)
@@ -30,6 +30,7 @@ static DEFINE_MUTEX(hl_devs_idr_lock);
 static int timeout_locked = 30;
 static int reset_on_lockup = 1;
 static int memory_scrub = 1;
+static ulong boot_error_status_mask = ULONG_MAX;
 
 module_param(timeout_locked, int, 0444);
 MODULE_PARM_DESC(timeout_locked,
@@ -43,6 +44,10 @@ module_param(memory_scrub, int, 0444);
 MODULE_PARM_DESC(memory_scrub,
        "Scrub device memory in various states (0 = no, 1 = yes, default yes)");
 
+module_param(boot_error_status_mask, ulong, 0444);
+MODULE_PARM_DESC(boot_error_status_mask,
+       "Mask of the error status during device CPU boot (If bitX is cleared then error X is masked. Default all 1's)");
+
 #define PCI_VENDOR_ID_HABANALABS       0x1da3
 
 #define PCI_IDS_GOYA                   0x0001
@@ -319,6 +324,8 @@ int create_hdev(struct hl_device **dev, struct pci_dev *pdev,
        hdev->major = hl_major;
        hdev->reset_on_lockup = reset_on_lockup;
        hdev->memory_scrub = memory_scrub;
+       hdev->boot_error_status_mask = boot_error_status_mask;
+
        hdev->pldm = 0;
 
        set_driver_behavior_per_device(hdev);