^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);