nx-842-powernv.c 27 KB

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