blob: 29fac73ac1913e8d4892acece8320378efd9e0b9 [file] [log] [blame]
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Stultz <john.stultz@linaro.org>
Date: Fri, 8 Nov 2019 04:44:49 +0000
Subject: ANDROID: scsi: ufs-hisi: Enable BROKEN_CRYPTO quirk flag
HiKey960 doesn't play well with the inline crypto logic, and
seems to deviate from the UFS standard.
Eric Biggers noted:
"It declares that it has 32 crypto configurations (a.k.a.
keyslots), starting at offset 1280 from the start of the UFS
registers. Per the UFS standard, each crypto configuration is
128 bytes, so that means they go until offset 5376.
However, the device tree node for the UFS host controller (in
hi3660.dtsi) only declares 4096 bytes for the UFS standard
registers, and then the next 4096 physical bytes are declared to
be vendor-specific UFS registers. The ufs-hisi driver already
uses these vendor-specific registers to do things like reset the
UFS controller and configure the clocks. But if we follow the
UFS standard, the very same memory addresses have a different
meaning.
Also, even if I hardcode the number of keyslots to 22 so they fit
in the first 4096 bytes, then there is either an SError interrupt
while programming keyslot 0, or CRYPTO_GENERAL_ERROR is reported
from the UFS request."
So until we can understand the hardware better disable inline
crypto using the quirks flag in the driver.
Bug: 137270441
Change-Id: I69b1c10018bae9ac8ed2a32b02d253afbff64c34
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/scsi/ufs/ufs-hisi.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c
--- a/drivers/scsi/ufs/ufs-hisi.c
+++ b/drivers/scsi/ufs/ufs-hisi.c
@@ -475,6 +475,14 @@ static int ufs_hisi_init_common(struct ufs_hba *hba)
if (!host)
return -ENOMEM;
+ /*
+ * Inline crypto is currently broken with ufs-hisi because the keyslots
+ * overlap with the vendor-specific SYS CTRL registers -- and even if
+ * software uses only non-overlapping keyslots, the kernel crashes when
+ * programming a key or a UFS error occurs on the first encrypted I/O.
+ */
+ hba->quirks |= UFSHCD_QUIRK_BROKEN_CRYPTO;
+
host->hba = hba;
ufshcd_set_variant(hba, host);