diff --git a/drivers/scsi/ufs/ufshcd-crypto.c b/drivers/scsi/ufs/ufshcd-crypto.c index 4a7b7a411fd4..f6f51e9bdfe5 100644 --- a/drivers/scsi/ufs/ufshcd-crypto.c +++ b/drivers/scsi/ufs/ufshcd-crypto.c @@ -119,11 +119,13 @@ bool ufshcd_crypto_enable(struct ufs_hba *hba) if (!(hba->caps & UFSHCD_CAP_CRYPTO)) return false; - if (hba->quirks & UFSHCD_QUIRK_NO_KEYSLOTS) + /* Reset might clear all keys, so reprogram all the keys. */ + if (hba->ksm.num_slots) + blk_ksm_reprogram_all_keys(&hba->ksm); + + if (hba->quirks & UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE) return false; - /* Reset might clear all keys, so reprogram all the keys. */ - blk_ksm_reprogram_all_keys(&hba->ksm); return true; } @@ -160,7 +162,7 @@ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba) int err = 0; enum blk_crypto_mode_num blk_mode_num; - if (hba->quirks & UFSHCD_QUIRK_NO_KEYSLOTS) + if (hba->quirks & UFSHCD_QUIRK_BROKEN_CRYPTO_CAPS) return 0; /* @@ -234,11 +236,8 @@ void ufshcd_init_crypto(struct ufs_hba *hba) if (!(hba->caps & UFSHCD_CAP_CRYPTO)) return; - if (hba->quirks & UFSHCD_QUIRK_NO_KEYSLOTS) - return; - - /* Clear all keyslots - the number of keyslots is (CFGC + 1) */ - for (slot = 0; slot < hba->crypto_capabilities.config_count + 1; slot++) + /* Clear all keyslots */ + for (slot = 0; slot < hba->ksm.num_slots; slot++) ufshcd_clear_keyslot(hba, slot); } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 6497799213a1..90e5a3307993 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -547,19 +547,25 @@ enum ufshcd_quirks { /* * This quirk needs to be enabled if the host controller supports inline - * encryption, but it uses a nonstandard mechanism where the standard - * crypto registers aren't used and there is no concept of keyslots. - * ufs_hba_variant_ops::init() is expected to initialize ufs_hba::ksm as - * a passthrough keyslot manager. + * encryption, but it doesn't use the standard crypto capability + * registers. If enabled, the standard code won't initialize the + * keyslot manager; ufs_hba_variant_ops::init() must do it instead. */ - UFSHCD_QUIRK_NO_KEYSLOTS = 1 << 12, + UFSHCD_QUIRK_BROKEN_CRYPTO_CAPS = 1 << 20, + + /* + * This quirk needs to be enabled if the host controller supports inline + * encryption, but the CRYPTO_GENERAL_ENABLE bit is not implemented and + * breaks the HCE sequence if used. + */ + UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE = 1 << 21, /* * This quirk needs to be enabled if the host controller requires that * the PRDT be cleared after each encrypted request because encryption * keys were stored in it. */ - UFSHCD_QUIRK_KEYS_IN_PRDT = 1 << 13, + UFSHCD_QUIRK_KEYS_IN_PRDT = 1 << 22, }; enum ufshcd_caps {