18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci * Marvell OcteonTX CPT driver 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2019 Marvell International Ltd. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 78c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License version 2 as 88c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifndef __OTX_CPTVF_REQUEST_MANAGER_H 128c2ecf20Sopenharmony_ci#define __OTX_CPTVF_REQUEST_MANAGER_H 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <linux/types.h> 158c2ecf20Sopenharmony_ci#include <linux/crypto.h> 168c2ecf20Sopenharmony_ci#include <linux/pci.h> 178c2ecf20Sopenharmony_ci#include "otx_cpt_hw_types.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* 208c2ecf20Sopenharmony_ci * Maximum total number of SG buffers is 100, we divide it equally 218c2ecf20Sopenharmony_ci * between input and output 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ci#define OTX_CPT_MAX_SG_IN_CNT 50 248c2ecf20Sopenharmony_ci#define OTX_CPT_MAX_SG_OUT_CNT 50 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* DMA mode direct or SG */ 278c2ecf20Sopenharmony_ci#define OTX_CPT_DMA_DIRECT_DIRECT 0 288c2ecf20Sopenharmony_ci#define OTX_CPT_DMA_GATHER_SCATTER 1 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* Context source CPTR or DPTR */ 318c2ecf20Sopenharmony_ci#define OTX_CPT_FROM_CPTR 0 328c2ecf20Sopenharmony_ci#define OTX_CPT_FROM_DPTR 1 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci/* CPT instruction queue alignment */ 358c2ecf20Sopenharmony_ci#define OTX_CPT_INST_Q_ALIGNMENT 128 368c2ecf20Sopenharmony_ci#define OTX_CPT_MAX_REQ_SIZE 65535 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci/* Default command timeout in seconds */ 398c2ecf20Sopenharmony_ci#define OTX_CPT_COMMAND_TIMEOUT 4 408c2ecf20Sopenharmony_ci#define OTX_CPT_TIMER_HOLD 0x03F 418c2ecf20Sopenharmony_ci#define OTX_CPT_COUNT_HOLD 32 428c2ecf20Sopenharmony_ci#define OTX_CPT_TIME_IN_RESET_COUNT 5 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* Minimum and maximum values for interrupt coalescing */ 458c2ecf20Sopenharmony_ci#define OTX_CPT_COALESC_MIN_TIME_WAIT 0x0 468c2ecf20Sopenharmony_ci#define OTX_CPT_COALESC_MAX_TIME_WAIT ((1<<16)-1) 478c2ecf20Sopenharmony_ci#define OTX_CPT_COALESC_MIN_NUM_WAIT 0x0 488c2ecf20Sopenharmony_ci#define OTX_CPT_COALESC_MAX_NUM_WAIT ((1<<20)-1) 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ciunion otx_cpt_opcode_info { 518c2ecf20Sopenharmony_ci u16 flags; 528c2ecf20Sopenharmony_ci struct { 538c2ecf20Sopenharmony_ci u8 major; 548c2ecf20Sopenharmony_ci u8 minor; 558c2ecf20Sopenharmony_ci } s; 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistruct otx_cptvf_request { 598c2ecf20Sopenharmony_ci u32 param1; 608c2ecf20Sopenharmony_ci u32 param2; 618c2ecf20Sopenharmony_ci u16 dlen; 628c2ecf20Sopenharmony_ci union otx_cpt_opcode_info opcode; 638c2ecf20Sopenharmony_ci}; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistruct otx_cpt_buf_ptr { 668c2ecf20Sopenharmony_ci u8 *vptr; 678c2ecf20Sopenharmony_ci dma_addr_t dma_addr; 688c2ecf20Sopenharmony_ci u16 size; 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ciunion otx_cpt_ctrl_info { 728c2ecf20Sopenharmony_ci u32 flags; 738c2ecf20Sopenharmony_ci struct { 748c2ecf20Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD) 758c2ecf20Sopenharmony_ci u32 reserved0:26; 768c2ecf20Sopenharmony_ci u32 grp:3; /* Group bits */ 778c2ecf20Sopenharmony_ci u32 dma_mode:2; /* DMA mode */ 788c2ecf20Sopenharmony_ci u32 se_req:1; /* To SE core */ 798c2ecf20Sopenharmony_ci#else 808c2ecf20Sopenharmony_ci u32 se_req:1; /* To SE core */ 818c2ecf20Sopenharmony_ci u32 dma_mode:2; /* DMA mode */ 828c2ecf20Sopenharmony_ci u32 grp:3; /* Group bits */ 838c2ecf20Sopenharmony_ci u32 reserved0:26; 848c2ecf20Sopenharmony_ci#endif 858c2ecf20Sopenharmony_ci } s; 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/* 898c2ecf20Sopenharmony_ci * CPT_INST_S software command definitions 908c2ecf20Sopenharmony_ci * Words EI (0-3) 918c2ecf20Sopenharmony_ci */ 928c2ecf20Sopenharmony_ciunion otx_cpt_iq_cmd_word0 { 938c2ecf20Sopenharmony_ci u64 u64; 948c2ecf20Sopenharmony_ci struct { 958c2ecf20Sopenharmony_ci __be16 opcode; 968c2ecf20Sopenharmony_ci __be16 param1; 978c2ecf20Sopenharmony_ci __be16 param2; 988c2ecf20Sopenharmony_ci __be16 dlen; 998c2ecf20Sopenharmony_ci } s; 1008c2ecf20Sopenharmony_ci}; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ciunion otx_cpt_iq_cmd_word3 { 1038c2ecf20Sopenharmony_ci u64 u64; 1048c2ecf20Sopenharmony_ci struct { 1058c2ecf20Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD) 1068c2ecf20Sopenharmony_ci u64 grp:3; 1078c2ecf20Sopenharmony_ci u64 cptr:61; 1088c2ecf20Sopenharmony_ci#else 1098c2ecf20Sopenharmony_ci u64 cptr:61; 1108c2ecf20Sopenharmony_ci u64 grp:3; 1118c2ecf20Sopenharmony_ci#endif 1128c2ecf20Sopenharmony_ci } s; 1138c2ecf20Sopenharmony_ci}; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistruct otx_cpt_iq_cmd { 1168c2ecf20Sopenharmony_ci union otx_cpt_iq_cmd_word0 cmd; 1178c2ecf20Sopenharmony_ci u64 dptr; 1188c2ecf20Sopenharmony_ci u64 rptr; 1198c2ecf20Sopenharmony_ci union otx_cpt_iq_cmd_word3 cptr; 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistruct otx_cpt_sglist_component { 1238c2ecf20Sopenharmony_ci union { 1248c2ecf20Sopenharmony_ci u64 len; 1258c2ecf20Sopenharmony_ci struct { 1268c2ecf20Sopenharmony_ci __be16 len0; 1278c2ecf20Sopenharmony_ci __be16 len1; 1288c2ecf20Sopenharmony_ci __be16 len2; 1298c2ecf20Sopenharmony_ci __be16 len3; 1308c2ecf20Sopenharmony_ci } s; 1318c2ecf20Sopenharmony_ci } u; 1328c2ecf20Sopenharmony_ci __be64 ptr0; 1338c2ecf20Sopenharmony_ci __be64 ptr1; 1348c2ecf20Sopenharmony_ci __be64 ptr2; 1358c2ecf20Sopenharmony_ci __be64 ptr3; 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistruct otx_cpt_pending_entry { 1398c2ecf20Sopenharmony_ci u64 *completion_addr; /* Completion address */ 1408c2ecf20Sopenharmony_ci struct otx_cpt_info_buffer *info; 1418c2ecf20Sopenharmony_ci /* Kernel async request callback */ 1428c2ecf20Sopenharmony_ci void (*callback)(int status, void *arg1, void *arg2); 1438c2ecf20Sopenharmony_ci struct crypto_async_request *areq; /* Async request callback arg */ 1448c2ecf20Sopenharmony_ci u8 resume_sender; /* Notify sender to resume sending requests */ 1458c2ecf20Sopenharmony_ci u8 busy; /* Entry status (free/busy) */ 1468c2ecf20Sopenharmony_ci}; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistruct otx_cpt_pending_queue { 1498c2ecf20Sopenharmony_ci struct otx_cpt_pending_entry *head; /* Head of the queue */ 1508c2ecf20Sopenharmony_ci u32 front; /* Process work from here */ 1518c2ecf20Sopenharmony_ci u32 rear; /* Append new work here */ 1528c2ecf20Sopenharmony_ci u32 pending_count; /* Pending requests count */ 1538c2ecf20Sopenharmony_ci u32 qlen; /* Queue length */ 1548c2ecf20Sopenharmony_ci spinlock_t lock; /* Queue lock */ 1558c2ecf20Sopenharmony_ci}; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistruct otx_cpt_req_info { 1588c2ecf20Sopenharmony_ci /* Kernel async request callback */ 1598c2ecf20Sopenharmony_ci void (*callback)(int status, void *arg1, void *arg2); 1608c2ecf20Sopenharmony_ci struct crypto_async_request *areq; /* Async request callback arg */ 1618c2ecf20Sopenharmony_ci struct otx_cptvf_request req;/* Request information (core specific) */ 1628c2ecf20Sopenharmony_ci union otx_cpt_ctrl_info ctrl;/* User control information */ 1638c2ecf20Sopenharmony_ci struct otx_cpt_buf_ptr in[OTX_CPT_MAX_SG_IN_CNT]; 1648c2ecf20Sopenharmony_ci struct otx_cpt_buf_ptr out[OTX_CPT_MAX_SG_OUT_CNT]; 1658c2ecf20Sopenharmony_ci u8 *iv_out; /* IV to send back */ 1668c2ecf20Sopenharmony_ci u16 rlen; /* Output length */ 1678c2ecf20Sopenharmony_ci u8 incnt; /* Number of input buffers */ 1688c2ecf20Sopenharmony_ci u8 outcnt; /* Number of output buffers */ 1698c2ecf20Sopenharmony_ci u8 req_type; /* Type of request */ 1708c2ecf20Sopenharmony_ci u8 is_enc; /* Is a request an encryption request */ 1718c2ecf20Sopenharmony_ci u8 is_trunc_hmac;/* Is truncated hmac used */ 1728c2ecf20Sopenharmony_ci}; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_cistruct otx_cpt_info_buffer { 1758c2ecf20Sopenharmony_ci struct otx_cpt_pending_entry *pentry; 1768c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req; 1778c2ecf20Sopenharmony_ci struct pci_dev *pdev; 1788c2ecf20Sopenharmony_ci u64 *completion_addr; 1798c2ecf20Sopenharmony_ci u8 *out_buffer; 1808c2ecf20Sopenharmony_ci u8 *in_buffer; 1818c2ecf20Sopenharmony_ci dma_addr_t dptr_baddr; 1828c2ecf20Sopenharmony_ci dma_addr_t rptr_baddr; 1838c2ecf20Sopenharmony_ci dma_addr_t comp_baddr; 1848c2ecf20Sopenharmony_ci unsigned long time_in; 1858c2ecf20Sopenharmony_ci u32 dlen; 1868c2ecf20Sopenharmony_ci u32 dma_len; 1878c2ecf20Sopenharmony_ci u8 extra_time; 1888c2ecf20Sopenharmony_ci}; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_cistatic inline void do_request_cleanup(struct pci_dev *pdev, 1918c2ecf20Sopenharmony_ci struct otx_cpt_info_buffer *info) 1928c2ecf20Sopenharmony_ci{ 1938c2ecf20Sopenharmony_ci struct otx_cpt_req_info *req; 1948c2ecf20Sopenharmony_ci int i; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci if (info->dptr_baddr) 1978c2ecf20Sopenharmony_ci dma_unmap_single(&pdev->dev, info->dptr_baddr, 1988c2ecf20Sopenharmony_ci info->dma_len, DMA_BIDIRECTIONAL); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci if (info->req) { 2018c2ecf20Sopenharmony_ci req = info->req; 2028c2ecf20Sopenharmony_ci for (i = 0; i < req->outcnt; i++) { 2038c2ecf20Sopenharmony_ci if (req->out[i].dma_addr) 2048c2ecf20Sopenharmony_ci dma_unmap_single(&pdev->dev, 2058c2ecf20Sopenharmony_ci req->out[i].dma_addr, 2068c2ecf20Sopenharmony_ci req->out[i].size, 2078c2ecf20Sopenharmony_ci DMA_BIDIRECTIONAL); 2088c2ecf20Sopenharmony_ci } 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci for (i = 0; i < req->incnt; i++) { 2118c2ecf20Sopenharmony_ci if (req->in[i].dma_addr) 2128c2ecf20Sopenharmony_ci dma_unmap_single(&pdev->dev, 2138c2ecf20Sopenharmony_ci req->in[i].dma_addr, 2148c2ecf20Sopenharmony_ci req->in[i].size, 2158c2ecf20Sopenharmony_ci DMA_BIDIRECTIONAL); 2168c2ecf20Sopenharmony_ci } 2178c2ecf20Sopenharmony_ci } 2188c2ecf20Sopenharmony_ci kfree_sensitive(info); 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_cistruct otx_cptvf_wqe; 2228c2ecf20Sopenharmony_civoid otx_cpt_dump_sg_list(struct pci_dev *pdev, struct otx_cpt_req_info *req); 2238c2ecf20Sopenharmony_civoid otx_cpt_post_process(struct otx_cptvf_wqe *wqe); 2248c2ecf20Sopenharmony_ciint otx_cpt_do_request(struct pci_dev *pdev, struct otx_cpt_req_info *req, 2258c2ecf20Sopenharmony_ci int cpu_num); 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci#endif /* __OTX_CPTVF_REQUEST_MANAGER_H */ 228