nx-842-powernv.c 27 KB

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