18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci#ifndef __NX_842_H__ 48c2ecf20Sopenharmony_ci#define __NX_842_H__ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/kernel.h> 78c2ecf20Sopenharmony_ci#include <linux/init.h> 88c2ecf20Sopenharmony_ci#include <linux/module.h> 98c2ecf20Sopenharmony_ci#include <linux/crypto.h> 108c2ecf20Sopenharmony_ci#include <linux/of.h> 118c2ecf20Sopenharmony_ci#include <linux/slab.h> 128c2ecf20Sopenharmony_ci#include <linux/io.h> 138c2ecf20Sopenharmony_ci#include <linux/mm.h> 148c2ecf20Sopenharmony_ci#include <linux/ratelimit.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* Restrictions on Data Descriptor List (DDL) and Entry (DDE) buffers 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * From NX P8 workbook, sec 4.9.1 "842 details" 198c2ecf20Sopenharmony_ci * Each DDE buffer is 128 byte aligned 208c2ecf20Sopenharmony_ci * Each DDE buffer size is a multiple of 32 bytes (except the last) 218c2ecf20Sopenharmony_ci * The last DDE buffer size is a multiple of 8 bytes 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ci#define DDE_BUFFER_ALIGN (128) 248c2ecf20Sopenharmony_ci#define DDE_BUFFER_SIZE_MULT (32) 258c2ecf20Sopenharmony_ci#define DDE_BUFFER_LAST_MULT (8) 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* Arbitrary DDL length limit 288c2ecf20Sopenharmony_ci * Allows max buffer size of MAX-1 to MAX pages 298c2ecf20Sopenharmony_ci * (depending on alignment) 308c2ecf20Sopenharmony_ci */ 318c2ecf20Sopenharmony_ci#define DDL_LEN_MAX (17) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/* CCW 842 CI/FC masks 348c2ecf20Sopenharmony_ci * NX P8 workbook, section 4.3.1, figure 4-6 358c2ecf20Sopenharmony_ci * "CI/FC Boundary by NX CT type" 368c2ecf20Sopenharmony_ci */ 378c2ecf20Sopenharmony_ci#define CCW_CI_842 (0x00003ff8) 388c2ecf20Sopenharmony_ci#define CCW_FC_842 (0x00000007) 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* CCW Function Codes (FC) for 842 418c2ecf20Sopenharmony_ci * NX P8 workbook, section 4.9, table 4-28 428c2ecf20Sopenharmony_ci * "Function Code Definitions for 842 Memory Compression" 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci#define CCW_FC_842_COMP_NOCRC (0) 458c2ecf20Sopenharmony_ci#define CCW_FC_842_COMP_CRC (1) 468c2ecf20Sopenharmony_ci#define CCW_FC_842_DECOMP_NOCRC (2) 478c2ecf20Sopenharmony_ci#define CCW_FC_842_DECOMP_CRC (3) 488c2ecf20Sopenharmony_ci#define CCW_FC_842_MOVE (4) 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci/* CSB CC Error Types for 842 518c2ecf20Sopenharmony_ci * NX P8 workbook, section 4.10.3, table 4-30 528c2ecf20Sopenharmony_ci * "Reported Error Types Summary Table" 538c2ecf20Sopenharmony_ci */ 548c2ecf20Sopenharmony_ci/* These are all duplicates of existing codes defined in icswx.h. */ 558c2ecf20Sopenharmony_ci#define CSB_CC_TRANSLATION_DUP1 (80) 568c2ecf20Sopenharmony_ci#define CSB_CC_TRANSLATION_DUP2 (82) 578c2ecf20Sopenharmony_ci#define CSB_CC_TRANSLATION_DUP3 (84) 588c2ecf20Sopenharmony_ci#define CSB_CC_TRANSLATION_DUP4 (86) 598c2ecf20Sopenharmony_ci#define CSB_CC_TRANSLATION_DUP5 (92) 608c2ecf20Sopenharmony_ci#define CSB_CC_TRANSLATION_DUP6 (94) 618c2ecf20Sopenharmony_ci#define CSB_CC_PROTECTION_DUP1 (81) 628c2ecf20Sopenharmony_ci#define CSB_CC_PROTECTION_DUP2 (83) 638c2ecf20Sopenharmony_ci#define CSB_CC_PROTECTION_DUP3 (85) 648c2ecf20Sopenharmony_ci#define CSB_CC_PROTECTION_DUP4 (87) 658c2ecf20Sopenharmony_ci#define CSB_CC_PROTECTION_DUP5 (93) 668c2ecf20Sopenharmony_ci#define CSB_CC_PROTECTION_DUP6 (95) 678c2ecf20Sopenharmony_ci#define CSB_CC_RD_EXTERNAL_DUP1 (89) 688c2ecf20Sopenharmony_ci#define CSB_CC_RD_EXTERNAL_DUP2 (90) 698c2ecf20Sopenharmony_ci#define CSB_CC_RD_EXTERNAL_DUP3 (91) 708c2ecf20Sopenharmony_ci/* These are specific to NX */ 718c2ecf20Sopenharmony_ci/* 842 codes */ 728c2ecf20Sopenharmony_ci#define CSB_CC_TPBC_GT_SPBC (64) /* no error, but >1 comp ratio */ 738c2ecf20Sopenharmony_ci#define CSB_CC_CRC_MISMATCH (65) /* decomp crc mismatch */ 748c2ecf20Sopenharmony_ci#define CSB_CC_TEMPL_INVALID (66) /* decomp invalid template value */ 758c2ecf20Sopenharmony_ci#define CSB_CC_TEMPL_OVERFLOW (67) /* decomp template shows data after end */ 768c2ecf20Sopenharmony_ci/* sym crypt codes */ 778c2ecf20Sopenharmony_ci#define CSB_CC_DECRYPT_OVERFLOW (64) 788c2ecf20Sopenharmony_ci/* asym crypt codes */ 798c2ecf20Sopenharmony_ci#define CSB_CC_MINV_OVERFLOW (128) 808c2ecf20Sopenharmony_ci/* 818c2ecf20Sopenharmony_ci * HW error - Job did not finish in the maximum time allowed. 828c2ecf20Sopenharmony_ci * Job terminated. 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci#define CSB_CC_HW_EXPIRED_TIMER (224) 858c2ecf20Sopenharmony_ci/* These are reserved for hypervisor use */ 868c2ecf20Sopenharmony_ci#define CSB_CC_HYP_RESERVE_START (240) 878c2ecf20Sopenharmony_ci#define CSB_CC_HYP_RESERVE_END (253) 888c2ecf20Sopenharmony_ci#define CSB_CC_HYP_RESERVE_P9_END (251) 898c2ecf20Sopenharmony_ci/* No valid interrupt server (P9 or later). */ 908c2ecf20Sopenharmony_ci#define CSB_CC_HYP_RESERVE_NO_INTR_SERVER (252) 918c2ecf20Sopenharmony_ci#define CSB_CC_HYP_NO_HW (254) 928c2ecf20Sopenharmony_ci#define CSB_CC_HYP_HANG_ABORTED (255) 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci/* CCB Completion Modes (CM) for 842 958c2ecf20Sopenharmony_ci * NX P8 workbook, section 4.3, figure 4-5 968c2ecf20Sopenharmony_ci * "CRB Details - Normal Cop_Req (CL=00, C=1)" 978c2ecf20Sopenharmony_ci */ 988c2ecf20Sopenharmony_ci#define CCB_CM_EXTRA_WRITE (CCB_CM0_ALL_COMPLETIONS & CCB_CM12_STORE) 998c2ecf20Sopenharmony_ci#define CCB_CM_INTERRUPT (CCB_CM0_ALL_COMPLETIONS & CCB_CM12_INTERRUPT) 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci#define LEN_ON_SIZE(pa, size) ((size) - ((pa) & ((size) - 1))) 1028c2ecf20Sopenharmony_ci#define LEN_ON_PAGE(pa) LEN_ON_SIZE(pa, PAGE_SIZE) 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistatic inline unsigned long nx842_get_pa(void *addr) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci if (!is_vmalloc_addr(addr)) 1078c2ecf20Sopenharmony_ci return __pa(addr); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci return page_to_phys(vmalloc_to_page(addr)) + offset_in_page(addr); 1108c2ecf20Sopenharmony_ci} 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci/** 1138c2ecf20Sopenharmony_ci * This provides the driver's constraints. Different nx842 implementations 1148c2ecf20Sopenharmony_ci * may have varying requirements. The constraints are: 1158c2ecf20Sopenharmony_ci * @alignment: All buffers should be aligned to this 1168c2ecf20Sopenharmony_ci * @multiple: All buffer lengths should be a multiple of this 1178c2ecf20Sopenharmony_ci * @minimum: Buffer lengths must not be less than this amount 1188c2ecf20Sopenharmony_ci * @maximum: Buffer lengths must not be more than this amount 1198c2ecf20Sopenharmony_ci * 1208c2ecf20Sopenharmony_ci * The constraints apply to all buffers and lengths, both input and output, 1218c2ecf20Sopenharmony_ci * for both compression and decompression, except for the minimum which 1228c2ecf20Sopenharmony_ci * only applies to compression input and decompression output; the 1238c2ecf20Sopenharmony_ci * compressed data can be less than the minimum constraint. It can be 1248c2ecf20Sopenharmony_ci * assumed that compressed data will always adhere to the multiple 1258c2ecf20Sopenharmony_ci * constraint. 1268c2ecf20Sopenharmony_ci * 1278c2ecf20Sopenharmony_ci * The driver may succeed even if these constraints are violated; 1288c2ecf20Sopenharmony_ci * however the driver can return failure or suffer reduced performance 1298c2ecf20Sopenharmony_ci * if any constraint is not met. 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_cistruct nx842_constraints { 1328c2ecf20Sopenharmony_ci int alignment; 1338c2ecf20Sopenharmony_ci int multiple; 1348c2ecf20Sopenharmony_ci int minimum; 1358c2ecf20Sopenharmony_ci int maximum; 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistruct nx842_driver { 1398c2ecf20Sopenharmony_ci char *name; 1408c2ecf20Sopenharmony_ci struct module *owner; 1418c2ecf20Sopenharmony_ci size_t workmem_size; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci struct nx842_constraints *constraints; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci int (*compress)(const unsigned char *in, unsigned int in_len, 1468c2ecf20Sopenharmony_ci unsigned char *out, unsigned int *out_len, 1478c2ecf20Sopenharmony_ci void *wrkmem); 1488c2ecf20Sopenharmony_ci int (*decompress)(const unsigned char *in, unsigned int in_len, 1498c2ecf20Sopenharmony_ci unsigned char *out, unsigned int *out_len, 1508c2ecf20Sopenharmony_ci void *wrkmem); 1518c2ecf20Sopenharmony_ci}; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_cistruct nx842_crypto_header_group { 1548c2ecf20Sopenharmony_ci __be16 padding; /* unused bytes at start of group */ 1558c2ecf20Sopenharmony_ci __be32 compressed_length; /* compressed bytes in group */ 1568c2ecf20Sopenharmony_ci __be32 uncompressed_length; /* bytes after decompression */ 1578c2ecf20Sopenharmony_ci} __packed; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistruct nx842_crypto_header { 1608c2ecf20Sopenharmony_ci __be16 magic; /* NX842_CRYPTO_MAGIC */ 1618c2ecf20Sopenharmony_ci __be16 ignore; /* decompressed end bytes to ignore */ 1628c2ecf20Sopenharmony_ci u8 groups; /* total groups in this header */ 1638c2ecf20Sopenharmony_ci struct nx842_crypto_header_group group[]; 1648c2ecf20Sopenharmony_ci} __packed; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci#define NX842_CRYPTO_GROUP_MAX (0x20) 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistruct nx842_crypto_ctx { 1698c2ecf20Sopenharmony_ci spinlock_t lock; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci u8 *wmem; 1728c2ecf20Sopenharmony_ci u8 *sbounce, *dbounce; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci struct nx842_crypto_header header; 1758c2ecf20Sopenharmony_ci struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX]; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci struct nx842_driver *driver; 1788c2ecf20Sopenharmony_ci}; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ciint nx842_crypto_init(struct crypto_tfm *tfm, struct nx842_driver *driver); 1818c2ecf20Sopenharmony_civoid nx842_crypto_exit(struct crypto_tfm *tfm); 1828c2ecf20Sopenharmony_ciint nx842_crypto_compress(struct crypto_tfm *tfm, 1838c2ecf20Sopenharmony_ci const u8 *src, unsigned int slen, 1848c2ecf20Sopenharmony_ci u8 *dst, unsigned int *dlen); 1858c2ecf20Sopenharmony_ciint nx842_crypto_decompress(struct crypto_tfm *tfm, 1868c2ecf20Sopenharmony_ci const u8 *src, unsigned int slen, 1878c2ecf20Sopenharmony_ci u8 *dst, unsigned int *dlen); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci#endif /* __NX_842_H__ */ 190