nx-common-powernv.c 29 KB

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