Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Driver for IBM PowerNV compression accelerator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2015 Dan Streetman, IBM Corp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include "nx-842.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <asm/icswx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <asm/vas.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <asm/reg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <asm/opal-api.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <asm/opal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) MODULE_DESCRIPTION("H/W Compression driver for IBM PowerNV processors");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) MODULE_ALIAS_CRYPTO("842");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) MODULE_ALIAS_CRYPTO("842-nx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #define WORKMEM_ALIGN	(CRB_ALIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define CSB_WAIT_MAX	(5000) /* ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define VAS_RETRIES	(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) struct nx842_workmem {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	/* Below fields must be properly aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	struct coprocessor_request_block crb; /* CRB_ALIGN align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 	struct data_descriptor_entry ddl_in[DDL_LEN_MAX]; /* DDE_ALIGN align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	struct data_descriptor_entry ddl_out[DDL_LEN_MAX]; /* DDE_ALIGN align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	/* Above fields must be properly aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	ktime_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	char padding[WORKMEM_ALIGN]; /* unused, to allow alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) } __packed __aligned(WORKMEM_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) struct nx_coproc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	unsigned int chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	unsigned int ct;	/* Can be 842 or GZIP high/normal*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	unsigned int ci;	/* Coprocessor instance, used with icswx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 		struct vas_window *rxwin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 		int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	} vas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  * Send the request to NX engine on the chip for the corresponding CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)  * where the process is executing. Use with VAS function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) static DEFINE_PER_CPU(struct vas_window *, cpu_txwin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) /* no cpu hotplug on powernv, so this list never changes after init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) static LIST_HEAD(nx_coprocs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) static unsigned int nx842_ct;	/* used in icswx function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65)  * Using same values as in skiboot or coprocessor type representing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66)  * in NX workbook.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define NX_CT_GZIP	(2)	/* on P9 and later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define NX_CT_842	(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) static int (*nx842_powernv_exec)(const unsigned char *in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 				unsigned int inlen, unsigned char *out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 				unsigned int *outlenp, void *workmem, int fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  * setup_indirect_dde - Setup an indirect DDE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  * The DDE is setup with the the DDE count, byte count, and address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  * first direct DDE in the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) static void setup_indirect_dde(struct data_descriptor_entry *dde,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 			       struct data_descriptor_entry *ddl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 			       unsigned int dde_count, unsigned int byte_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	dde->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	dde->count = dde_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	dde->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	dde->length = cpu_to_be32(byte_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	dde->address = cpu_to_be64(nx842_get_pa(ddl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93)  * setup_direct_dde - Setup single DDE from buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95)  * The DDE is setup with the buffer and length.  The buffer must be properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96)  * aligned.  The used length is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)  *   N    Successfully set up DDE with N bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) static unsigned int setup_direct_dde(struct data_descriptor_entry *dde,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 				     unsigned long pa, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	unsigned int l = min_t(unsigned int, len, LEN_ON_PAGE(pa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	dde->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	dde->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	dde->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	dde->length = cpu_to_be32(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	dde->address = cpu_to_be64(pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	return l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115)  * setup_ddl - Setup DDL from buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118)  *   0		Successfully set up DDL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) static int setup_ddl(struct data_descriptor_entry *dde,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		     struct data_descriptor_entry *ddl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 		     unsigned char *buf, unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		     bool in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	unsigned long pa = nx842_get_pa(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	int i, ret, total_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	if (!IS_ALIGNED(pa, DDE_BUFFER_ALIGN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		pr_debug("%s buffer pa 0x%lx not 0x%x-byte aligned\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 			 in ? "input" : "output", pa, DDE_BUFFER_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	/* only need to check last mult; since buffer must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	 * DDE_BUFFER_ALIGN aligned, and that is a multiple of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	 * DDE_BUFFER_SIZE_MULT, and pre-last page DDE buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	 * are guaranteed a multiple of DDE_BUFFER_SIZE_MULT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	if (len % DDE_BUFFER_LAST_MULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		pr_debug("%s buffer len 0x%x not a multiple of 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 			 in ? "input" : "output", len, DDE_BUFFER_LAST_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		if (in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 		len = round_down(len, DDE_BUFFER_LAST_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	/* use a single direct DDE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	if (len <= LEN_ON_PAGE(pa)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		ret = setup_direct_dde(dde, pa, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 		WARN_ON(ret < len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	/* use the DDL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	for (i = 0; i < DDL_LEN_MAX && len > 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 		ret = setup_direct_dde(&ddl[i], pa, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		buf += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		len -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		pa = nx842_get_pa(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	if (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		pr_debug("0x%x total %s bytes 0x%x too many for DDL.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 			 total_len, in ? "input" : "output", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		if (in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 			return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		total_len -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	setup_indirect_dde(dde, ddl, i, total_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) #define CSB_ERR(csb, msg, ...)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	pr_err("ERROR: " msg " : %02x %02x %02x %02x %08x\n",	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	       ##__VA_ARGS__, (csb)->flags,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	       (csb)->cs, (csb)->cc, (csb)->ce,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	       be32_to_cpu((csb)->count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) #define CSB_ERR_ADDR(csb, msg, ...)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	CSB_ERR(csb, msg " at %lx", ##__VA_ARGS__,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		(unsigned long)be64_to_cpu((csb)->address))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185)  * wait_for_csb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) static int wait_for_csb(struct nx842_workmem *wmem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 			struct coprocessor_status_block *csb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	ktime_t start = wmem->start, now = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	ktime_t timeout = ktime_add_ms(start, CSB_WAIT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	while (!(READ_ONCE(csb->flags) & CSB_V)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		now = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		if (ktime_after(now, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	/* hw has updated csb and output buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	/* check CSB flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if (!(csb->flags & CSB_V)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		CSB_ERR(csb, "CSB still not valid after %ld us, giving up",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 			(long)ktime_us_delta(now, start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	if (csb->flags & CSB_F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		CSB_ERR(csb, "Invalid CSB format");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	if (csb->flags & CSB_CH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		CSB_ERR(csb, "Invalid CSB chaining state");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	/* verify CSB completion sequence is 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	if (csb->cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		CSB_ERR(csb, "Invalid CSB completion sequence");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	/* check CSB Completion Code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	switch (csb->cc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	/* no error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	case CSB_CC_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	case CSB_CC_TPBC_GT_SPBC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		/* not an error, but the compressed data is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		 * larger than the uncompressed data :(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	/* input data errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	case CSB_CC_OPERAND_OVERLAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		/* input and output buffers overlap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		CSB_ERR(csb, "Operand Overlap error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	case CSB_CC_INVALID_OPERAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		CSB_ERR(csb, "Invalid operand");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	case CSB_CC_NOSPC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		/* output buffer too small */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	case CSB_CC_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		CSB_ERR(csb, "Function aborted");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	case CSB_CC_CRC_MISMATCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		CSB_ERR(csb, "CRC mismatch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	case CSB_CC_TEMPL_INVALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		CSB_ERR(csb, "Compressed data template invalid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	case CSB_CC_TEMPL_OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		CSB_ERR(csb, "Compressed data template shows data past end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	case CSB_CC_EXCEED_BYTE_COUNT:	/* P9 or later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		 * DDE byte count exceeds the limit specified in Maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		 * byte count register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		CSB_ERR(csb, "DDE byte count exceeds the limit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	/* these should not happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	case CSB_CC_INVALID_ALIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		/* setup_ddl should have detected this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		CSB_ERR_ADDR(csb, "Invalid alignment");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	case CSB_CC_DATA_LENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		/* setup_ddl should have detected this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		CSB_ERR(csb, "Invalid data length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	case CSB_CC_WR_TRANSLATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	case CSB_CC_TRANSLATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	case CSB_CC_TRANSLATION_DUP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	case CSB_CC_TRANSLATION_DUP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	case CSB_CC_TRANSLATION_DUP3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	case CSB_CC_TRANSLATION_DUP4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	case CSB_CC_TRANSLATION_DUP5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	case CSB_CC_TRANSLATION_DUP6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		/* should not happen, we use physical addrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		CSB_ERR_ADDR(csb, "Translation error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	case CSB_CC_WR_PROTECTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	case CSB_CC_PROTECTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	case CSB_CC_PROTECTION_DUP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	case CSB_CC_PROTECTION_DUP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	case CSB_CC_PROTECTION_DUP3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	case CSB_CC_PROTECTION_DUP4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	case CSB_CC_PROTECTION_DUP5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	case CSB_CC_PROTECTION_DUP6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		/* should not happen, we use physical addrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		CSB_ERR_ADDR(csb, "Protection error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	case CSB_CC_PRIVILEGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		/* shouldn't happen, we're in HYP mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		CSB_ERR(csb, "Insufficient Privilege error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	case CSB_CC_EXCESSIVE_DDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		/* shouldn't happen, setup_ddl doesn't use many dde's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		CSB_ERR(csb, "Too many DDEs in DDL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	case CSB_CC_TRANSPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	case CSB_CC_INVALID_CRB:	/* P9 or later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		/* shouldn't happen, we setup CRB correctly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		CSB_ERR(csb, "Invalid CRB");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	case CSB_CC_INVALID_DDE:	/* P9 or later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		 * shouldn't happen, setup_direct/indirect_dde creates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		 * DDE right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		CSB_ERR(csb, "Invalid DDE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	case CSB_CC_SEGMENTED_DDL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		/* shouldn't happen, setup_ddl creates DDL right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		CSB_ERR(csb, "Segmented DDL error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	case CSB_CC_DDE_OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		/* shouldn't happen, setup_ddl creates DDL right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		CSB_ERR(csb, "DDE overflow error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	case CSB_CC_SESSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		/* should not happen with ICSWX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		CSB_ERR(csb, "Session violation error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	case CSB_CC_CHAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		/* should not happen, we don't use chained CRBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		CSB_ERR(csb, "Chained CRB error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	case CSB_CC_SEQUENCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		/* should not happen, we don't use chained CRBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		CSB_ERR(csb, "CRB sequence number error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	case CSB_CC_UNKNOWN_CODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		CSB_ERR(csb, "Unknown subfunction code");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	/* hardware errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	case CSB_CC_RD_EXTERNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	case CSB_CC_RD_EXTERNAL_DUP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	case CSB_CC_RD_EXTERNAL_DUP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	case CSB_CC_RD_EXTERNAL_DUP3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		CSB_ERR_ADDR(csb, "Read error outside coprocessor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	case CSB_CC_WR_EXTERNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		CSB_ERR_ADDR(csb, "Write error outside coprocessor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	case CSB_CC_INTERNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		CSB_ERR(csb, "Internal error in coprocessor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	case CSB_CC_PROVISION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		CSB_ERR(csb, "Storage provision error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	case CSB_CC_HW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		CSB_ERR(csb, "Correctable hardware error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	case CSB_CC_HW_EXPIRED_TIMER:	/* P9 or later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		CSB_ERR(csb, "Job did not finish within allowed time");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		CSB_ERR(csb, "Invalid CC %d", csb->cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	/* check Completion Extension state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	if (csb->ce & CSB_CE_TERMINATION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		CSB_ERR(csb, "CSB request was terminated");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	if (csb->ce & CSB_CE_INCOMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		CSB_ERR(csb, "CSB request not complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	if (!(csb->ce & CSB_CE_TPBC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		CSB_ERR(csb, "TPBC not provided, unknown target length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	/* successful completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	pr_debug_ratelimited("Processed %u bytes in %lu us\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 			     be32_to_cpu(csb->count),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 			     (unsigned long)ktime_us_delta(now, start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) static int nx842_config_crb(const unsigned char *in, unsigned int inlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 			unsigned char *out, unsigned int outlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 			struct nx842_workmem *wmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	struct coprocessor_request_block *crb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	struct coprocessor_status_block *csb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	u64 csb_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	crb = &wmem->crb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	csb = &crb->csb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	/* Clear any previous values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	memset(crb, 0, sizeof(*crb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	/* set up DDLs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	ret = setup_ddl(&crb->source, wmem->ddl_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			(unsigned char *)in, inlen, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	ret = setup_ddl(&crb->target, wmem->ddl_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 			out, outlen, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	/* set up CRB's CSB addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	csb_addr = nx842_get_pa(csb) & CRB_CSB_ADDRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	csb_addr |= CRB_CSB_AT; /* Addrs are phys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	crb->csb_addr = cpu_to_be64(csb_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426)  * nx842_exec_icswx - compress/decompress data using the 842 algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428)  * (De)compression provided by the NX842 coprocessor on IBM PowerNV systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)  * This compresses or decompresses the provided input buffer into the provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)  * output buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432)  * Upon return from this function @outlen contains the length of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433)  * output data.  If there is an error then @outlen will be 0 and an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434)  * error will be specified by the return code from this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436)  * The @workmem buffer should only be used by one function call at a time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438)  * @in: input buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439)  * @inlen: input buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440)  * @out: output buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441)  * @outlenp: output buffer size pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442)  * @workmem: working memory buffer pointer, size determined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443)  *           nx842_powernv_driver.workmem_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444)  * @fc: function code, see CCW Function Codes in nx-842.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447)  *   0		Success, output of length @outlenp stored in the buffer at @out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448)  *   -ENODEV	Hardware unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449)  *   -ENOSPC	Output buffer is to small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450)  *   -EMSGSIZE	Input buffer too large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451)  *   -EINVAL	buffer constraints do not fix nx842_constraints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452)  *   -EPROTO	hardware error during operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453)  *   -ETIMEDOUT	hardware did not complete operation in reasonable time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454)  *   -EINTR	operation was aborted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) static int nx842_exec_icswx(const unsigned char *in, unsigned int inlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 				  unsigned char *out, unsigned int *outlenp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 				  void *workmem, int fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	struct coprocessor_request_block *crb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	struct coprocessor_status_block *csb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	struct nx842_workmem *wmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	u32 ccw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	unsigned int outlen = *outlenp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	wmem = PTR_ALIGN(workmem, WORKMEM_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	*outlenp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	/* shoudn't happen, we don't load without a coproc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	if (!nx842_ct) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		pr_err_ratelimited("coprocessor CT is 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	ret = nx842_config_crb(in, inlen, out, outlen, wmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	crb = &wmem->crb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	csb = &crb->csb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	/* set up CCW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	ccw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	ccw = SET_FIELD(CCW_CT, ccw, nx842_ct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	ccw = SET_FIELD(CCW_CI_842, ccw, 0); /* use 0 for hw auto-selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	ccw = SET_FIELD(CCW_FC_842, ccw, fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	wmem->start = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	/* do ICSWX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	ret = icswx(cpu_to_be32(ccw), crb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	pr_debug_ratelimited("icswx CR %x ccw %x crb->ccw %x\n", ret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			     (unsigned int)ccw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 			     (unsigned int)be32_to_cpu(crb->ccw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	 * NX842 coprocessor sets 3rd bit in CR register with XER[S0].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	 * XER[S0] is the integer summary overflow bit which is nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	 * to do NX. Since this bit can be set with other return values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	 * mask this bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	ret &= ~ICSWX_XERS0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	case ICSWX_INITIATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		ret = wait_for_csb(wmem, csb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	case ICSWX_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		pr_debug_ratelimited("842 Coprocessor busy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	case ICSWX_REJECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		pr_err_ratelimited("ICSWX rejected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		ret = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		*outlenp = be32_to_cpu(csb->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528)  * nx842_exec_vas - compress/decompress data using the 842 algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530)  * (De)compression provided by the NX842 coprocessor on IBM PowerNV systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531)  * This compresses or decompresses the provided input buffer into the provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532)  * output buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534)  * Upon return from this function @outlen contains the length of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)  * output data.  If there is an error then @outlen will be 0 and an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536)  * error will be specified by the return code from this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538)  * The @workmem buffer should only be used by one function call at a time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540)  * @in: input buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541)  * @inlen: input buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542)  * @out: output buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543)  * @outlenp: output buffer size pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544)  * @workmem: working memory buffer pointer, size determined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545)  *           nx842_powernv_driver.workmem_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546)  * @fc: function code, see CCW Function Codes in nx-842.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549)  *   0		Success, output of length @outlenp stored in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550)  *		at @out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551)  *   -ENODEV	Hardware unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552)  *   -ENOSPC	Output buffer is to small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553)  *   -EMSGSIZE	Input buffer too large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554)  *   -EINVAL	buffer constraints do not fix nx842_constraints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555)  *   -EPROTO	hardware error during operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556)  *   -ETIMEDOUT	hardware did not complete operation in reasonable time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557)  *   -EINTR	operation was aborted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) static int nx842_exec_vas(const unsigned char *in, unsigned int inlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 				  unsigned char *out, unsigned int *outlenp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 				  void *workmem, int fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	struct coprocessor_request_block *crb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	struct coprocessor_status_block *csb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	struct nx842_workmem *wmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	struct vas_window *txwin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	int ret, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	u32 ccw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	unsigned int outlen = *outlenp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	wmem = PTR_ALIGN(workmem, WORKMEM_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	*outlenp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	crb = &wmem->crb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	csb = &crb->csb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	ret = nx842_config_crb(in, inlen, out, outlen, wmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	ccw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	ccw = SET_FIELD(CCW_FC_842, ccw, fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	crb->ccw = cpu_to_be32(ccw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		wmem->start = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		txwin = this_cpu_read(cpu_txwin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		 * VAS copy CRB into L2 cache. Refer <asm/vas.h>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		 * @crb and @offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		vas_copy_crb(crb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		 * VAS paste previously copied CRB to NX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		 * @txwin, @offset and @last (must be true).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		ret = vas_paste_crb(txwin, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		 * Retry copy/paste function for VAS failures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	} while (ret && (i++ < VAS_RETRIES));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		pr_err_ratelimited("VAS copy/paste failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	ret = wait_for_csb(wmem, csb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		*outlenp = be32_to_cpu(csb->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621)  * nx842_powernv_compress - Compress data using the 842 algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623)  * Compression provided by the NX842 coprocessor on IBM PowerNV systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624)  * The input buffer is compressed and the result is stored in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625)  * provided output buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627)  * Upon return from this function @outlen contains the length of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628)  * compressed data.  If there is an error then @outlen will be 0 and an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629)  * error will be specified by the return code from this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)  * @in: input buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  * @inlen: input buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)  * @out: output buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634)  * @outlenp: output buffer size pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635)  * @workmem: working memory buffer pointer, size determined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636)  *           nx842_powernv_driver.workmem_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638)  * Returns: see @nx842_powernv_exec()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 				  unsigned char *out, unsigned int *outlenp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 				  void *wmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	return nx842_powernv_exec(in, inlen, out, outlenp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 				      wmem, CCW_FC_842_COMP_CRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649)  * nx842_powernv_decompress - Decompress data using the 842 algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651)  * Decompression provided by the NX842 coprocessor on IBM PowerNV systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652)  * The input buffer is decompressed and the result is stored in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653)  * provided output buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655)  * Upon return from this function @outlen contains the length of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  * decompressed data.  If there is an error then @outlen will be 0 and an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657)  * error will be specified by the return code from this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659)  * @in: input buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660)  * @inlen: input buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661)  * @out: output buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662)  * @outlenp: output buffer size pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663)  * @workmem: working memory buffer pointer, size determined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664)  *           nx842_powernv_driver.workmem_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666)  * Returns: see @nx842_powernv_exec()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 				    unsigned char *out, unsigned int *outlenp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 				    void *wmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	return nx842_powernv_exec(in, inlen, out, outlenp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 				      wmem, CCW_FC_842_DECOMP_CRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) static inline void nx_add_coprocs_list(struct nx_coproc *coproc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 					int chipid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	coproc->chip_id = chipid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	INIT_LIST_HEAD(&coproc->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	list_add(&coproc->list, &nx_coprocs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) static struct vas_window *nx_alloc_txwin(struct nx_coproc *coproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	struct vas_window *txwin = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	struct vas_tx_win_attr txattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	 * Kernel requests will be high priority. So open send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	 * windows only for high priority RxFIFO entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	vas_init_tx_win_attr(&txattr, coproc->ct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	txattr.lpid = 0;	/* lpid is 0 for kernel requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	 * Open a VAS send window which is used to send request to NX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	txwin = vas_tx_win_open(coproc->vas.id, coproc->ct, &txattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	if (IS_ERR(txwin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		pr_err("ibm,nx-842: Can not open TX window: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 				PTR_ERR(txwin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	return txwin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708)  * Identify chip ID for each CPU, open send wndow for the corresponding NX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709)  * engine and save txwin in percpu cpu_txwin.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710)  * cpu_txwin is used in copy/paste operation for each compression /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711)  * decompression request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) static int nx_open_percpu_txwins(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	struct nx_coproc *coproc, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	unsigned int i, chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		struct vas_window *txwin = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		chip_id = cpu_to_chip_id(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		list_for_each_entry_safe(coproc, n, &nx_coprocs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 			 * Kernel requests use only high priority FIFOs. So
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			 * open send windows for these FIFOs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			 * GZIP is not supported in kernel right now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			if (coproc->ct != VAS_COP_TYPE_842_HIPRI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			if (coproc->chip_id == chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 				txwin = nx_alloc_txwin(coproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 				if (IS_ERR(txwin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 					return PTR_ERR(txwin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 				per_cpu(cpu_txwin, i) = txwin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		if (!per_cpu(cpu_txwin, i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			/* shouldn't happen, Each chip will have NX engine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			pr_err("NX engine is not available for CPU %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) static int __init nx_set_ct(struct nx_coproc *coproc, const char *priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 				int high, int normal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	if (!strcmp(priority, "High"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		coproc->ct = high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	else if (!strcmp(priority, "Normal"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		coproc->ct = normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		pr_err("Invalid RxFIFO priority value\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 					int vasid, int type, int *ct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	struct vas_window *rxwin = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	struct vas_rx_win_attr rxattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	u32 lpid, pid, tid, fifo_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	struct nx_coproc *coproc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	u64 rx_fifo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	const char *priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	ret = of_property_read_u64(dn, "rx-fifo-address", &rx_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		pr_err("Missing rx-fifo-address property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	ret = of_property_read_u32(dn, "rx-fifo-size", &fifo_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		pr_err("Missing rx-fifo-size property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	ret = of_property_read_u32(dn, "lpid", &lpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		pr_err("Missing lpid property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	ret = of_property_read_u32(dn, "pid", &pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		pr_err("Missing pid property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	ret = of_property_read_u32(dn, "tid", &tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		pr_err("Missing tid property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	ret = of_property_read_string(dn, "priority", &priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		pr_err("Missing priority property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	coproc = kzalloc(sizeof(*coproc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	if (!coproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	if (type == NX_CT_842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		ret = nx_set_ct(coproc, priority, VAS_COP_TYPE_842_HIPRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			VAS_COP_TYPE_842);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	else if (type == NX_CT_GZIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		ret = nx_set_ct(coproc, priority, VAS_COP_TYPE_GZIP_HIPRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 				VAS_COP_TYPE_GZIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	vas_init_rx_win_attr(&rxattr, coproc->ct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	rxattr.rx_fifo = (void *)rx_fifo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	rxattr.rx_fifo_size = fifo_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	rxattr.lnotify_lpid = lpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	rxattr.lnotify_pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	rxattr.lnotify_tid = tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	 * Maximum RX window credits can not be more than #CRBs in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	 * RxFIFO. Otherwise, can get checkstop if RxFIFO overruns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	rxattr.wcreds_max = fifo_size / CRB_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	 * Open a VAS receice window which is used to configure RxFIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	 * for NX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	rxwin = vas_rx_win_open(vasid, coproc->ct, &rxattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	if (IS_ERR(rxwin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		ret = PTR_ERR(rxwin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		pr_err("setting RxFIFO with VAS failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	coproc->vas.rxwin = rxwin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	coproc->vas.id = vasid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	nx_add_coprocs_list(coproc, chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	 * (lpid, pid, tid) combination has to be unique for each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	 * coprocessor instance in the system. So to make it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	 * unique, skiboot uses coprocessor type such as 842 or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	 * GZIP for pid and provides this value to kernel in pid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	 * device-tree property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	*ct = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	kfree(coproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) static int __init nx_coproc_init(int chip_id, int ct_842, int ct_gzip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	if (opal_check_token(OPAL_NX_COPROC_INIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		ret = opal_nx_coproc_init(chip_id, ct_842);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			ret = opal_nx_coproc_init(chip_id, ct_gzip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 			ret = opal_error_code(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			pr_err("Failed to initialize NX for chip(%d): %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 				chip_id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		pr_warn("Firmware doesn't support NX initialization\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) static int __init find_nx_device_tree(struct device_node *dn, int chip_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 					int vasid, int type, char *devname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 					int *ct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	if (of_device_is_compatible(dn, devname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		ret  = vas_cfg_coproc_info(dn, chip_id, vasid, type, ct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			of_node_put(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) static int __init nx_powernv_probe_vas(struct device_node *pn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	int chip_id, vasid, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	int ct_842 = 0, ct_gzip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	struct device_node *dn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	chip_id = of_get_ibm_chip_id(pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	if (chip_id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		pr_err("ibm,chip-id missing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	vasid = chip_to_vas_id(chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	if (vasid < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		pr_err("Unable to map chip_id %d to vasid\n", chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	for_each_child_of_node(pn, dn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		ret = find_nx_device_tree(dn, chip_id, vasid, NX_CT_842,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 					"ibm,p9-nx-842", &ct_842);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			ret = find_nx_device_tree(dn, chip_id, vasid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 				NX_CT_GZIP, "ibm,p9-nx-gzip", &ct_gzip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	if (!ct_842 || !ct_gzip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		pr_err("NX FIFO nodes are missing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	 * Initialize NX instance for both high and normal priority FIFOs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	ret = nx_coproc_init(chip_id, ct_842, ct_gzip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) static int __init nx842_powernv_probe(struct device_node *dn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	struct nx_coproc *coproc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	unsigned int ct, ci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	int chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	chip_id = of_get_ibm_chip_id(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	if (chip_id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		pr_err("ibm,chip-id missing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (of_property_read_u32(dn, "ibm,842-coprocessor-type", &ct)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		pr_err("ibm,842-coprocessor-type missing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	if (of_property_read_u32(dn, "ibm,842-coprocessor-instance", &ci)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		pr_err("ibm,842-coprocessor-instance missing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	coproc = kzalloc(sizeof(*coproc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	if (!coproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	coproc->ct = ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	coproc->ci = ci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	nx_add_coprocs_list(coproc, chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	pr_info("coprocessor found on chip %d, CT %d CI %d\n", chip_id, ct, ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	if (!nx842_ct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		nx842_ct = ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	else if (nx842_ct != ct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		pr_err("NX842 chip %d, CT %d != first found CT %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		       chip_id, ct, nx842_ct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) static void nx_delete_coprocs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	struct nx_coproc *coproc, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	struct vas_window *txwin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	 * close percpu txwins that are opened for the corresponding coproc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		txwin = per_cpu(cpu_txwin, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		if (txwin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 			vas_win_close(txwin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		per_cpu(cpu_txwin, i) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	list_for_each_entry_safe(coproc, n, &nx_coprocs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		if (coproc->vas.rxwin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			vas_win_close(coproc->vas.rxwin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		list_del(&coproc->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		kfree(coproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static struct nx842_constraints nx842_powernv_constraints = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	.alignment =	DDE_BUFFER_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	.multiple =	DDE_BUFFER_LAST_MULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	.minimum =	DDE_BUFFER_LAST_MULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	.maximum =	(DDL_LEN_MAX - 1) * PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static struct nx842_driver nx842_powernv_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	.name =		KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	.owner =	THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	.workmem_size =	sizeof(struct nx842_workmem),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	.constraints =	&nx842_powernv_constraints,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	.compress =	nx842_powernv_compress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	.decompress =	nx842_powernv_decompress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) static int nx842_powernv_crypto_init(struct crypto_tfm *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	return nx842_crypto_init(tfm, &nx842_powernv_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static struct crypto_alg nx842_powernv_alg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	.cra_name		= "842",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	.cra_driver_name	= "842-nx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	.cra_priority		= 300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	.cra_ctxsize		= sizeof(struct nx842_crypto_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	.cra_module		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	.cra_init		= nx842_powernv_crypto_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	.cra_exit		= nx842_crypto_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	.cra_u			= { .compress = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	.coa_compress		= nx842_crypto_compress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	.coa_decompress		= nx842_crypto_decompress } }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static __init int nx_compress_powernv_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	struct device_node *dn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	/* verify workmem size/align restrictions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	BUILD_BUG_ON(WORKMEM_ALIGN % CRB_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	BUILD_BUG_ON(CRB_ALIGN % DDE_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	BUILD_BUG_ON(CRB_SIZE % DDE_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	/* verify buffer size/align restrictions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	BUILD_BUG_ON(PAGE_SIZE % DDE_BUFFER_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	BUILD_BUG_ON(DDE_BUFFER_ALIGN % DDE_BUFFER_SIZE_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	BUILD_BUG_ON(DDE_BUFFER_SIZE_MULT % DDE_BUFFER_LAST_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	for_each_compatible_node(dn, NULL, "ibm,power9-nx") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		ret = nx_powernv_probe_vas(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			nx_delete_coprocs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			of_node_put(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	if (list_empty(&nx_coprocs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		for_each_compatible_node(dn, NULL, "ibm,power-nx")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			nx842_powernv_probe(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		if (!nx842_ct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		nx842_powernv_exec = nx842_exec_icswx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		 * Register VAS user space API for NX GZIP so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		 * that user space can use GZIP engine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		 * Using high FIFO priority for kernel requests and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		 * normal FIFO priority is assigned for userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		 * 842 compression is supported only in kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		ret = vas_register_coproc_api(THIS_MODULE, VAS_COP_TYPE_GZIP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 						"nx-gzip");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		 * GZIP is not supported in kernel right now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		 * So open tx windows only for 842.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 			ret = nx_open_percpu_txwins();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			nx_delete_coprocs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		nx842_powernv_exec = nx842_exec_vas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	ret = crypto_register_alg(&nx842_powernv_alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		nx_delete_coprocs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) module_init(nx_compress_powernv_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) static void __exit nx_compress_powernv_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	 * GZIP engine is supported only in power9 or later and nx842_ct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	 * is used on power8 (icswx).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	 * VAS API for NX GZIP is registered during init for user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	 * use. So delete this API use for GZIP engine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	if (!nx842_ct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		vas_unregister_coproc_api();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	crypto_unregister_alg(&nx842_powernv_alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	nx_delete_coprocs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) module_exit(nx_compress_powernv_exit);