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