Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2354203imm; Mon, 28 May 2018 06:36:16 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrOUJQ1uGIklotAoytxSWkg3hHxlGmXC7oMAo7LeMPY1sm6r0qGdvMBNJgde2iDbv1hxQ1f X-Received: by 2002:a63:70a:: with SMTP id 10-v6mr10958255pgh.216.1527514576227; Mon, 28 May 2018 06:36:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527514576; cv=none; d=google.com; s=arc-20160816; b=gJfd6IYsZjBO0e1irgy8QCbegMv9evhY4xCP5MMDLpbTm0WwfDcSAO4Lf4aq1p57Rv RJ3vysUohoRU0hkfgbzoEQvJC7bS+suM5hlgg/5nWWFrk0crDZbTjA/DBGvhM3ps7jV4 o0pOpC2Kn8JFi+i/ZOogrzJv6FnhkzfrkP/Eh55Psk3l34gik4hLdh0cLxO8FlT7uWWl TGnWJ9KoV0PZP81PWZ2IzQ5W9Y71geVnIgwYC9b5a6IC7kU2KnzYmzjfJnnAVFqfuhPA VYWQI9g7Pt/evi8qZN2hwN7UCcqz4G+9Yy3Q3LUXRLWqypLVnJZZuS2efdccVNalCVze QKkg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:mime-version:user-agent:date:message-id:from:cc :subject:to:dkim-signature:arc-authentication-results; bh=4wZfHndaQ1qNDgNsE6KO80D9pW2rvGXv96uqltwcAWM=; b=onUQ2m9CLtCj6I6SZaYi+C8wn/XDnEMo7tuSq3LGrk+R6vGG4iumliQ4cZsCuoNhPv mYA7AzcqzPhyhyxq1nascA3yy2DFbg1updj9dDqWWMEriwr26ln2bjHzWs3S3gYadWE1 LZ0FoPDjCfa0tQBWZhNoC0KL9a9pkHQraJM+njfz/+nfsOGwbd8ee/M8D6QjuiCf/HeU MuclFYhSGZ0NlP7mo5uBzcvxKl/HyewuKIWaHHkFKRFB1vuY6pVZxzptxxixVOx6cKFk 2rmEoEvGhUcEOS5hby6BViPL0q4luhCh0Cuk1hfTR5/urX/aarXmxBKD9Y6e5aa7nNaW LFBw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@synopsys.com header.s=mail header.b=dz2zv2iU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=synopsys.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f5-v6si23656722pgc.37.2018.05.28.06.36.01; Mon, 28 May 2018 06:36:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@synopsys.com header.s=mail header.b=dz2zv2iU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=synopsys.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1165382AbeE1Nf3 (ORCPT + 99 others); Mon, 28 May 2018 09:35:29 -0400 Received: from smtprelay6.synopsys.com ([198.182.37.59]:50939 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1163109AbeE1NfJ (ORCPT ); Mon, 28 May 2018 09:35:09 -0400 Received: from mailhost.synopsys.com (mailhost1.synopsys.com [10.12.238.239]) by smtprelay.synopsys.com (Postfix) with ESMTP id C61041E04A3 for ; Mon, 28 May 2018 15:35:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1527514508; bh=ofRtFC8CcC3ZewVgT+igkqKqX3ePAL+P05XtGrTiZ1A=; h=To:Subject:CC:From:Date:From; b=dz2zv2iUpTlJfCQHQd/hB4CSnMsZx4g8LaMJrCaxBS0KkXJTiUvi/8bZ6JNyAb6Yw Gr8FKfDz0uON/U7NBdqyCKdj8wFrrgJ0YLZWa6GsCKfgi1CI2CHNvHEH6XBXRHbwxn nNP2KqqAJkVS/QBjJVSw4IQg+UoSHBC+Ex26tCFRSZj0emuCY33CoALvQN9qydV8lD rENmZ7hVw/eRsf/c445s4hfyMBhj+xBGIYjtmYzVN6fk4rqh/+zqlpIWDERgcJMJFs 2KncljI4MHISn8cNu71Y8pFlP9/55XbSbZ40x/2glq1EldMZlCzq9cyPRxYDCPTkJI Wj2TLEM3QeROQ== Received: from US01WEHTC2.internal.synopsys.com (us01wehtc2.internal.synopsys.com [10.12.239.237]) by mailhost.synopsys.com (Postfix) with ESMTP id 311C15022; Mon, 28 May 2018 06:35:07 -0700 (PDT) Received: from US01WEHTC1.internal.synopsys.com (10.12.239.236) by US01WEHTC2.internal.synopsys.com (10.12.239.237) with Microsoft SMTP Server (TLS) id 14.3.361.1; Mon, 28 May 2018 06:35:07 -0700 Received: from [10.0.2.15] (10.144.133.104) by us01wehtc1.internal.synopsys.com (10.12.239.235) with Microsoft SMTP Server (TLS) id 14.3.361.1; Mon, 28 May 2018 06:35:06 -0700 To: "Vinayak Holikatti ; \"James E.J. Bottomley\" ; \"Martin K. Petersen\"" Subject: [PATCH 5/5] scsi: ufs: Add hooks in UFS HC driver for crypto support CC: , "linux-scsi@vger.kernel.org; Manjunath M Bettegowda ; Prabu Thangamuthu ; Tejas Joglekar ; Joao Pinto" From: Ladvine D Almeida Message-ID: <51bd1b68-1ab2-af04-99f4-07e08852c401@synopsys.com> Date: Mon, 28 May 2018 14:35:02 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.144.133.104] Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds the crypto support in the UFS Host Controller driver like allocation of the crypto resources, registration of crypto algorithm, preparing UTRD requests for inline encryption job, freeing the resources during exit stage. The crypto support is enabled in the UFS Host Controller driver only if the crypto capability is detected in the hardware during the init stage. The changes done for the UFS HC crypto support are guarded with CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION. Signed-off-by: Ladvine D Almeida --- drivers/scsi/ufs/ufshcd.c | 63 ++++++++++++++++++++++++++++++++++++++++++----- drivers/scsi/ufs/ufshcd.h | 29 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 00e7905..7bac5a3 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1839,6 +1839,10 @@ static inline void ufshcd_hba_capabilities(struct ufs_hba *hba) hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1; hba->nutmrs = ((hba->capabilities & MASK_TASK_MANAGEMENT_REQUEST_SLOTS) >> 16) + 1; +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION + /* read crypto capabilities of host controller */ + ufshcd_read_crypto_capabilities(hba); +#endif } /** @@ -2076,7 +2080,7 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, { struct utp_transfer_req_desc *req_desc = lrbp->utr_descriptor_ptr; u32 data_direction; - u32 dword_0; + u32 dword_0 = 0; if (cmd_dir == DMA_FROM_DEVICE) { data_direction = UTP_DEVICE_TO_HOST; @@ -2094,10 +2098,22 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, if (lrbp->intr_cmd) dword_0 |= UTP_REQ_DESC_INT_CMD; +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION /* Transfer request descriptor header fields */ - req_desc->header.dword_0 = cpu_to_le32(dword_0); - /* dword_1 is reserved, hence it is set to 0 */ + if (lrbp->ccfg_idx >= 0) { + dword_0 |= (UTP_REQ_CRYPT_EN_CMD | (lrbp->ccfg_idx & 0xff)); + req_desc->header.dword_1 = lrbp->lba & 0xffffffff; + req_desc->header.dword_3 = (lrbp->lba >> 32) & 0xffffffff; + } else { + req_desc->header.dword_1 = 0; + req_desc->header.dword_3 = 0; + } +#else req_desc->header.dword_1 = 0; + req_desc->header.dword_3 = 0; +#endif + req_desc->header.dword_0 = cpu_to_le32(dword_0); + /* * assigning invalid value for command status. Controller * updates OCS on command completion, with the command @@ -2105,8 +2121,6 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, */ req_desc->header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS); - /* dword_3 is reserved, hence it is set to 0 */ - req_desc->header.dword_3 = 0; req_desc->prd_table_length = 0; } @@ -2355,6 +2369,12 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); lrbp->intr_cmd = !ufshcd_is_intr_aggr_allowed(hba) ? true : false; lrbp->req_abort_skip = false; +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION + lrbp->lba = 0; + lrbp->ccfg_idx = -1; + /* prepare block for crypto */ + ufshcd_prepare_for_crypto(hba, lrbp); +#endif ufshcd_comp_scsi_upiu(hba, lrbp); @@ -3215,6 +3235,7 @@ static inline int ufshcd_read_unit_desc_param(struct ufs_hba *hba, static int ufshcd_memory_alloc(struct ufs_hba *hba) { size_t utmrdl_size, utrdl_size, ucdl_size; + int ret = 0; /* Allocate memory for UTP command descriptors */ ucdl_size = (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs); @@ -3233,6 +3254,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) WARN_ON(hba->ucdl_dma_addr & (PAGE_SIZE - 1))) { dev_err(hba->dev, "Command Descriptor Memory allocation failed\n"); + ret = -ENOMEM; goto out; } @@ -3249,6 +3271,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) WARN_ON(hba->utrdl_dma_addr & (PAGE_SIZE - 1))) { dev_err(hba->dev, "Transfer Descriptor Memory allocation failed\n"); + ret = -ENOMEM; goto out; } @@ -3265,6 +3288,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) WARN_ON(hba->utmrdl_dma_addr & (PAGE_SIZE - 1))) { dev_err(hba->dev, "Task Management Descriptor Memory allocation failed\n"); + ret = -ENOMEM; goto out; } @@ -3274,11 +3298,21 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) GFP_KERNEL); if (!hba->lrb) { dev_err(hba->dev, "LRB Memory allocation failed\n"); + ret = -ENOMEM; + goto out; + } +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION + /* Allocate memory for crypto operations */ + if (ufshcd_is_encryption_supported(hba)) + ret = ufshcd_crypto_memory_alloc(hba); + if (ret != 0) { + dev_err(hba->dev, "Crypto Memory allocation failed\n"); goto out; } +#endif return 0; out: - return -ENOMEM; + return ret; } /** @@ -4208,6 +4242,19 @@ static int ufshcd_link_startup(struct ufs_hba *hba) goto out; ret = ufshcd_make_hba_operational(hba); + if (ret) + goto out; + +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION + /* Enable algorithm if crypto capability is present */ + if (ufshcd_is_encryption_supported(hba)) + ret = ufshcd_enable_crypt_alg(hba); + if (ret) { + dev_err(hba->dev, "Crypto setup failed (%d)\n", + ret); + ret = 0; + } +#endif out: if (ret) { dev_err(hba->dev, "link startup failed %d\n", ret); @@ -7661,6 +7708,10 @@ EXPORT_SYMBOL(ufshcd_shutdown); */ void ufshcd_remove(struct ufs_hba *hba) { +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION + ufshcd_disable_crypt_alg(hba); + ufshcd_remove_crypto_memory(hba); +#endif ufs_sysfs_remove_nodes(hba->dev); scsi_remove_host(hba->host); /* disable interrupts */ diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 8110dcd..b1356ca 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -68,6 +68,9 @@ #include "ufs.h" #include "ufshci.h" +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION + #include "ufshcd-crypto.h" +#endif #define UFSHCD "ufshcd" #define UFSHCD_DRIVER_VERSION "0.2" @@ -168,6 +171,8 @@ struct ufs_pm_lvl_states { * @issue_time_stamp: time stamp for debug purposes * @compl_time_stamp: time stamp for statistics * @req_abort_skip: skip request abort task flag + * @lba: LBA value for crypto engine + * @ccfg_idx: key configuration index for crypto engine */ struct ufshcd_lrb { struct utp_transfer_req_desc *utr_descriptor_ptr; @@ -193,6 +198,10 @@ struct ufshcd_lrb { ktime_t compl_time_stamp; bool req_abort_skip; +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION + u64 lba; + int ccfg_idx; +#endif }; /** @@ -499,6 +508,8 @@ struct ufs_stats { * @urgent_bkops_lvl: keeps track of urgent bkops level for device * @is_urgent_bkops_lvl_checked: keeps track if the urgent bkops level for * device is known or not. + * @cc: stores the crypto capability information. + * @ccxp: stores the crypto configuration information. */ struct ufs_hba { void __iomem *mmio_base; @@ -683,6 +694,17 @@ struct ufs_hba { struct rw_semaphore clk_scaling_lock; struct ufs_desc_size desc_size; + +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION + /* + * Thus capability allows the host controller to perform + * inline encryption once it is configured. + */ +#define UFSHCD_CAP_INLINE_ENCRYPTION (1 << 6) + + struct ufshcd_ccap cc; + struct ufshcd_x_crypto_cap *ccxp; +#endif }; /* Returns true if clocks can be gated. Otherwise false */ @@ -717,6 +739,13 @@ return true; #endif } +#ifdef CONFIG_SCSI_UFSHCD_INLINE_ENCRYPTION +static inline int ufshcd_is_encryption_supported(struct ufs_hba *hba) +{ + return hba->caps & UFSHCD_CAP_INLINE_ENCRYPTION; +} +#endif + #define ufshcd_writel(hba, val, reg) \ writel((val), (hba)->mmio_base + (reg)) #define ufshcd_readl(hba, reg) \ -- 2.7.4