eMMC controller may have an Inline Crypto Engine (ICE) attached, which can be used to encrypt/decrypt data going to/from eMMC. This patch adds a new client driver sdhci-msm-ice.c which interacts with ICE driver present in (drivers/crypto/msm/) and thus provides an interface to the low-level SDHCI driver to do the data encryption/decryption. mmc: sdhci-msm: Add Inline Crypto Engine (ICE) support Add ICE support to low-level driver sdhci-msm.c. This code is primarily responsible for enabling ICE (if present), managing ICE clocks, managing ICE suspend/resume and also provides a few host->ops for sdhci driver to use ICE functionality. mmc: sdhci: Add Inline Crypto Engine (ICE) support This patch adds ICE support to sdhci driver. It uses the new ICE host->ops like config/reset to configure/reset the ICE HW as appropriate. mmc: cqhci: Add Inline Crypto Engine (ICE) support Add changes to configure ICE for data encryption/decryption using CQE. mmc: cqe: add new crypto_cfg_reset host operation When encryption/decryption is enabled in CQ mode, the legacy commands that are sent in HALT state will use different slot other than slot 0 for crypto configuration information. The slot that is selected depends on the last slot that was used when it is in CQ mode. This is causing the data of legacy commands to be encrypted/decrypted based on the wrong slot usage for crypto config details. Hence, clear the crypto configuration of the slot used in CQ mode whenever it gets completed. mmc: sdhci-msm-ice: Add crypto register dump for debug upon error Dump crypto related register information upon error for debugging purpose. crypto: ice: Make ICE init & reset API synchronous ICE init & reset can be synchronous now because ICE does not need to go to secure side for any ICE configuration. This would simplify interface and make call more efficient. crypto: ice: general driver clean-up * Removed spinlock as it was not locking against anything * Removed conversion of interrupt status to error number as it is not used by API client, and in case several bits are set only 1 error is ever handled and the rest get lost. Instead pass to the client the complete status. * Removed redundant includes, variables * vops structure is returned after performing a lookup in the DTS. There's no need for that as we already know the structure to return. * Other minor corrections mmc: sdhci-msm-ice: Update ice config vop to config_start The config vop of the ice driver has been updated to config_start. Updated the sdhci-ice driver to reflect this change. mmc: sdhci-msm-ice: Enable ICE HCI if supported Check if the SDHC has ICE HCI support. If support is present, enable the cryptoghrapic support inside SDHC. Also ensure that it is re-enabled after SDHC is reset. By default ICE HCI is disabled. mmc: sdhci-msm: Update ICE reset register offset for ICE HCI SDHC v5.0 onwards the ICE reset register offset got updated. Update the register offset based on the SDHC version. mmc: sdhci-msm-ice: Factor out update config from sdhci_msm_ice_cfg Factor out the logic of updating the SDHC ICE config registers from sdhci_msm_ice_cfg(). For ICE3.0, different set of SDHC ICE registers are need to be updated. So having this logic in separate functions, we can have logical separation for ICE2.0 and ICE3.0. mmc: sdhci-mmc-ice: Factor out ice_cfg_start from sdhci_msm_ice_cfg Factor out the logic of getting ice config parameters from sdhci_msm_ice_cfg(). With ICE2.0, same sdhci_msm_ice_cfg function is being called from cmdq and noncq. But with ICE3.0 support, cmdq needs a separate host op. Since this logic of getting ice config is common for noncq and cmdq, by having it in separate function, same can be reused in cmdq host op as-well. mmc: sdhci-msm-ice: Add new sdhci host_op for updating ice config Add new sdhci host_op for updating ice configuration while sending request through cmdq. Adding provision for supporting the ice context configuration for ICE HCI. mmc: cmdq_hci: ice: Changes for supporting ICE HCI in CMDQ mode On SDHC v5.0 onwards, SDHC includes the inline interface for cryptographic operations which is ICE HCI. This patch includes the driver changes for supporting crypto operations with ICE HCI in cmdq mode. Adding support for clearing ice configuration. Once mmc request processing is completed, mmc driver has to call config_end to ensure key information is cleared by ICE driver. This call is optional for FDE but required for FBE. mmc: sdhci-msm-ice: Changes for supporting ICE HCI in non CMDQ mode SDHC v5.0 onwards, SDHC includes the inline interface for cryptographic operations which is ICE HCI. This patch includes the driver changes for supporting crypto operations with ICE HCI in noncq mode. mmc: host: sdhci: Add new host_op for clearing ice configuration Add new host op for clearing ice configuration. This config_end host op need to invoked for clearing ice configuration, once mmc request processing is completed. mmc: sdhci-msm-ice: add support for FBE over F2FS Add support for FBE to work with F2FS filesystem on eMMC based devices. For F2FS+FBE on eMMC, the cryto data unit size (CDU size) should be 4KB as F2FS encrypts/decrypts the data at min. 4KB blocks with (inode|pgidx) as it's corresponding data unit number (DUN). mmc: card: Set INLINECRYPT queue flag based on host capability Set INLINECRYPT queue flag if the host can support h/w based inline encryption. This is needed to let the filesystem know that underlying storage device can support inline encryption so that data encryption/ decryption would be handled at h/w level, not at filesystem. Set inline-crypto support host flag if sdhc controller is capable do performing inline encryption/decryption. mmc: sdhci-msm: get the load notification from clock scaling This is needed to scale up/down the ICE clock during runtime as per the load on eMMC. mmc: block: add req pointer to mmc request This is needed by ICE (Inline Crypto Engine) driver to get the ICE configuration data from the request. Change-Id: Ie69c64f4dc0c31290dec50d905e8b3d436c86d62 Signed-off-by: Veerabhadrarao Badiganti <vbadigan@codeaurora.org> Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org> Signed-off-by: Ram Prakash Gupta <rampraka@codeaurora.org>
165 lines
4.7 KiB
C
165 lines
4.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2015, 2017, 2019, The Linux Foundation. All rights reserved.
|
|
*/
|
|
|
|
#ifndef __SDHCI_MSM_ICE_H__
|
|
#define __SDHCI_MSM_ICE_H__
|
|
|
|
#include <linux/io.h>
|
|
#include <linux/of.h>
|
|
#include <linux/blkdev.h>
|
|
#include <crypto/ice.h>
|
|
|
|
#include "sdhci-msm.h"
|
|
|
|
#define SDHC_MSM_CRYPTO_LABEL "sdhc-msm-crypto"
|
|
/* Timeout waiting for ICE initialization, that requires TZ access */
|
|
#define SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS 500
|
|
|
|
/*
|
|
* SDHCI host controller ICE registers. There are n [0..31]
|
|
* of each of these registers
|
|
*/
|
|
#define NUM_SDHCI_MSM_ICE_CTRL_INFO_n_REGS 32
|
|
|
|
#define CORE_VENDOR_SPEC_ICE_CTRL 0x300
|
|
#define CORE_VENDOR_SPEC_ICE_CTRL_INFO_1_n 0x304
|
|
#define CORE_VENDOR_SPEC_ICE_CTRL_INFO_2_n 0x308
|
|
#define CORE_VENDOR_SPEC_ICE_CTRL_INFO_3_n 0x30C
|
|
|
|
/* ICE3.0 register which got added cmdq reg space */
|
|
#define ICE_CQ_CAPABILITIES 0x04
|
|
#define ICE_HCI_SUPPORT (1 << 28)
|
|
#define ICE_CQ_CONFIG 0x08
|
|
#define CRYPTO_GENERAL_ENABLE (1 << 1)
|
|
#define ICE_NONCQ_CRYPTO_PARAMS 0x70
|
|
#define ICE_NONCQ_CRYPTO_DUN 0x74
|
|
|
|
/* ICE3.0 register which got added hc reg space */
|
|
#define HC_VENDOR_SPECIFIC_FUNC4 0x260
|
|
#define DISABLE_CRYPTO (1 << 15)
|
|
#define HC_VENDOR_SPECIFIC_ICE_CTRL 0x800
|
|
#define ICE_SW_RST_EN (1 << 0)
|
|
|
|
/* SDHCI MSM ICE CTRL Info register offset */
|
|
enum {
|
|
OFFSET_SDHCI_MSM_ICE_CTRL_INFO_BYPASS = 0,
|
|
OFFSET_SDHCI_MSM_ICE_CTRL_INFO_KEY_INDEX = 1,
|
|
OFFSET_SDHCI_MSM_ICE_CTRL_INFO_CDU = 6,
|
|
OFFSET_SDHCI_MSM_ICE_HCI_PARAM_CCI = 0,
|
|
OFFSET_SDHCI_MSM_ICE_HCI_PARAM_CE = 8,
|
|
};
|
|
|
|
/* SDHCI MSM ICE CTRL Info register masks */
|
|
enum {
|
|
MASK_SDHCI_MSM_ICE_CTRL_INFO_BYPASS = 0x1,
|
|
MASK_SDHCI_MSM_ICE_CTRL_INFO_KEY_INDEX = 0x1F,
|
|
MASK_SDHCI_MSM_ICE_CTRL_INFO_CDU = 0x7,
|
|
MASK_SDHCI_MSM_ICE_HCI_PARAM_CE = 0x1,
|
|
MASK_SDHCI_MSM_ICE_HCI_PARAM_CCI = 0xff
|
|
};
|
|
|
|
/* SDHCI MSM ICE encryption/decryption bypass state */
|
|
enum {
|
|
SDHCI_MSM_ICE_DISABLE_BYPASS = 0,
|
|
SDHCI_MSM_ICE_ENABLE_BYPASS = 1,
|
|
};
|
|
|
|
/* SDHCI MSM ICE Crypto Data Unit of target DUN of Transfer Request */
|
|
enum {
|
|
SDHCI_MSM_ICE_TR_DATA_UNIT_512_B = 0,
|
|
SDHCI_MSM_ICE_TR_DATA_UNIT_1_KB = 1,
|
|
SDHCI_MSM_ICE_TR_DATA_UNIT_2_KB = 2,
|
|
SDHCI_MSM_ICE_TR_DATA_UNIT_4_KB = 3,
|
|
SDHCI_MSM_ICE_TR_DATA_UNIT_8_KB = 4,
|
|
SDHCI_MSM_ICE_TR_DATA_UNIT_16_KB = 5,
|
|
SDHCI_MSM_ICE_TR_DATA_UNIT_32_KB = 6,
|
|
SDHCI_MSM_ICE_TR_DATA_UNIT_64_KB = 7,
|
|
};
|
|
|
|
/* SDHCI MSM ICE internal state */
|
|
enum {
|
|
SDHCI_MSM_ICE_STATE_DISABLED = 0,
|
|
SDHCI_MSM_ICE_STATE_ACTIVE = 1,
|
|
SDHCI_MSM_ICE_STATE_SUSPENDED = 2,
|
|
};
|
|
|
|
/* crypto context fields in cmdq data command task descriptor */
|
|
#define DATA_UNIT_NUM(x) (((u64)(x) & 0xFFFFFFFF) << 0)
|
|
#define CRYPTO_CONFIG_INDEX(x) (((u64)(x) & 0xFF) << 32)
|
|
#define CRYPTO_ENABLE(x) (((u64)(x) & 0x1) << 47)
|
|
|
|
#ifdef CONFIG_MMC_SDHCI_MSM_ICE
|
|
int sdhci_msm_ice_get_dev(struct sdhci_host *host);
|
|
int sdhci_msm_ice_init(struct sdhci_host *host);
|
|
void sdhci_msm_ice_cfg_reset(struct sdhci_host *host, u32 slot);
|
|
int sdhci_msm_ice_cfg(struct sdhci_host *host, struct mmc_request *mrq,
|
|
u32 slot);
|
|
int sdhci_msm_ice_cqe_cfg(struct sdhci_host *host,
|
|
struct mmc_request *mrq, u32 slot, u64 *ice_ctx);
|
|
int sdhci_msm_ice_cfg_end(struct sdhci_host *host, struct mmc_request *mrq);
|
|
int sdhci_msm_ice_reset(struct sdhci_host *host);
|
|
int sdhci_msm_ice_resume(struct sdhci_host *host);
|
|
int sdhci_msm_ice_suspend(struct sdhci_host *host);
|
|
int sdhci_msm_ice_get_status(struct sdhci_host *host, int *ice_status);
|
|
void sdhci_msm_ice_print_regs(struct sdhci_host *host);
|
|
#else
|
|
inline int sdhci_msm_ice_get_dev(struct sdhci_host *host)
|
|
{
|
|
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
|
struct sdhci_msm_host *msm_host = pltfm_host->priv;
|
|
|
|
if (msm_host) {
|
|
msm_host->ice.pdev = NULL;
|
|
msm_host->ice.vops = NULL;
|
|
}
|
|
return -ENODEV;
|
|
}
|
|
inline int sdhci_msm_ice_init(struct sdhci_host *host)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
inline void sdhci_msm_ice_cfg_reset(struct sdhci_host *host, u32 slot)
|
|
{
|
|
}
|
|
|
|
inline int sdhci_msm_ice_cfg(struct sdhci_host *host,
|
|
struct mmc_request *mrq, u32 slot)
|
|
{
|
|
return 0;
|
|
}
|
|
inline int sdhci_msm_ice_cqe_cfg(struct sdhci_host *host,
|
|
struct mmc_request *mrq, u32 slot, u64 *ice_ctx)
|
|
{
|
|
return 0;
|
|
}
|
|
inline int sdhci_msm_ice_cfg_end(struct sdhci_host *host,
|
|
struct mmc_request *mrq)
|
|
{
|
|
return 0;
|
|
}
|
|
inline int sdhci_msm_ice_reset(struct sdhci_host *host)
|
|
{
|
|
return 0;
|
|
}
|
|
inline int sdhci_msm_ice_resume(struct sdhci_host *host)
|
|
{
|
|
return 0;
|
|
}
|
|
inline int sdhci_msm_ice_suspend(struct sdhci_host *host)
|
|
{
|
|
return 0;
|
|
}
|
|
inline int sdhci_msm_ice_get_status(struct sdhci_host *host,
|
|
int *ice_status)
|
|
{
|
|
return 0;
|
|
}
|
|
inline void sdhci_msm_ice_print_regs(struct sdhci_host *host)
|
|
{
|
|
}
|
|
#endif /* CONFIG_MMC_SDHCI_MSM_ICE */
|
|
#endif /* __SDHCI_MSM_ICE_H__ */
|