nx-842-powernv.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  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. 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)
  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. rxattr.wcreds_max = MAX_CREDITS_PER_RXFIFO;
  725. /*
  726. * Open a VAS receice window which is used to configure RxFIFO
  727. * for NX.
  728. */
  729. rxwin = vas_rx_win_open(vasid, coproc->ct, &rxattr);
  730. if (IS_ERR(rxwin)) {
  731. ret = PTR_ERR(rxwin);
  732. pr_err("setting RxFIFO with VAS failed: %d\n",
  733. ret);
  734. goto err_out;
  735. }
  736. coproc->vas.rxwin = rxwin;
  737. coproc->vas.id = vasid;
  738. nx842_add_coprocs_list(coproc, chip_id);
  739. return 0;
  740. err_out:
  741. kfree(coproc);
  742. return ret;
  743. }
  744. static int __init nx842_powernv_probe_vas(struct device_node *pn)
  745. {
  746. struct device_node *dn;
  747. int chip_id, vasid, ret = 0;
  748. int nx_fifo_found = 0;
  749. chip_id = of_get_ibm_chip_id(pn);
  750. if (chip_id < 0) {
  751. pr_err("ibm,chip-id missing\n");
  752. return -EINVAL;
  753. }
  754. vasid = chip_to_vas_id(chip_id);
  755. if (vasid < 0) {
  756. pr_err("Unable to map chip_id %d to vasid\n", chip_id);
  757. return -EINVAL;
  758. }
  759. for_each_child_of_node(pn, dn) {
  760. if (of_device_is_compatible(dn, "ibm,p9-nx-842")) {
  761. ret = vas_cfg_coproc_info(dn, chip_id, vasid);
  762. if (ret) {
  763. of_node_put(dn);
  764. return ret;
  765. }
  766. nx_fifo_found++;
  767. }
  768. }
  769. if (!nx_fifo_found) {
  770. pr_err("NX842 FIFO nodes are missing\n");
  771. ret = -EINVAL;
  772. }
  773. return ret;
  774. }
  775. static int __init nx842_powernv_probe(struct device_node *dn)
  776. {
  777. struct nx842_coproc *coproc;
  778. unsigned int ct, ci;
  779. int chip_id;
  780. chip_id = of_get_ibm_chip_id(dn);
  781. if (chip_id < 0) {
  782. pr_err("ibm,chip-id missing\n");
  783. return -EINVAL;
  784. }
  785. if (of_property_read_u32(dn, "ibm,842-coprocessor-type", &ct)) {
  786. pr_err("ibm,842-coprocessor-type missing\n");
  787. return -EINVAL;
  788. }
  789. if (of_property_read_u32(dn, "ibm,842-coprocessor-instance", &ci)) {
  790. pr_err("ibm,842-coprocessor-instance missing\n");
  791. return -EINVAL;
  792. }
  793. coproc = kmalloc(sizeof(*coproc), GFP_KERNEL);
  794. if (!coproc)
  795. return -ENOMEM;
  796. coproc->ct = ct;
  797. coproc->ci = ci;
  798. nx842_add_coprocs_list(coproc, chip_id);
  799. pr_info("coprocessor found on chip %d, CT %d CI %d\n", chip_id, ct, ci);
  800. if (!nx842_ct)
  801. nx842_ct = ct;
  802. else if (nx842_ct != ct)
  803. pr_err("NX842 chip %d, CT %d != first found CT %d\n",
  804. chip_id, ct, nx842_ct);
  805. return 0;
  806. }
  807. static void nx842_delete_coprocs(void)
  808. {
  809. struct nx842_coproc *coproc, *n;
  810. struct vas_window *txwin;
  811. int i;
  812. /*
  813. * close percpu txwins that are opened for the corresponding coproc.
  814. */
  815. for_each_possible_cpu(i) {
  816. txwin = per_cpu(cpu_txwin, i);
  817. if (txwin)
  818. vas_win_close(txwin);
  819. per_cpu(cpu_txwin, i) = 0;
  820. }
  821. list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) {
  822. if (coproc->vas.rxwin)
  823. vas_win_close(coproc->vas.rxwin);
  824. list_del(&coproc->list);
  825. kfree(coproc);
  826. }
  827. }
  828. static struct nx842_constraints nx842_powernv_constraints = {
  829. .alignment = DDE_BUFFER_ALIGN,
  830. .multiple = DDE_BUFFER_LAST_MULT,
  831. .minimum = DDE_BUFFER_LAST_MULT,
  832. .maximum = (DDL_LEN_MAX - 1) * PAGE_SIZE,
  833. };
  834. static struct nx842_driver nx842_powernv_driver = {
  835. .name = KBUILD_MODNAME,
  836. .owner = THIS_MODULE,
  837. .workmem_size = sizeof(struct nx842_workmem),
  838. .constraints = &nx842_powernv_constraints,
  839. .compress = nx842_powernv_compress,
  840. .decompress = nx842_powernv_decompress,
  841. };
  842. static int nx842_powernv_crypto_init(struct crypto_tfm *tfm)
  843. {
  844. return nx842_crypto_init(tfm, &nx842_powernv_driver);
  845. }
  846. static struct crypto_alg nx842_powernv_alg = {
  847. .cra_name = "842",
  848. .cra_driver_name = "842-nx",
  849. .cra_priority = 300,
  850. .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
  851. .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
  852. .cra_module = THIS_MODULE,
  853. .cra_init = nx842_powernv_crypto_init,
  854. .cra_exit = nx842_crypto_exit,
  855. .cra_u = { .compress = {
  856. .coa_compress = nx842_crypto_compress,
  857. .coa_decompress = nx842_crypto_decompress } }
  858. };
  859. static __init int nx842_powernv_init(void)
  860. {
  861. struct device_node *dn;
  862. int ret;
  863. /* verify workmem size/align restrictions */
  864. BUILD_BUG_ON(WORKMEM_ALIGN % CRB_ALIGN);
  865. BUILD_BUG_ON(CRB_ALIGN % DDE_ALIGN);
  866. BUILD_BUG_ON(CRB_SIZE % DDE_ALIGN);
  867. /* verify buffer size/align restrictions */
  868. BUILD_BUG_ON(PAGE_SIZE % DDE_BUFFER_ALIGN);
  869. BUILD_BUG_ON(DDE_BUFFER_ALIGN % DDE_BUFFER_SIZE_MULT);
  870. BUILD_BUG_ON(DDE_BUFFER_SIZE_MULT % DDE_BUFFER_LAST_MULT);
  871. for_each_compatible_node(dn, NULL, "ibm,power9-nx") {
  872. ret = nx842_powernv_probe_vas(dn);
  873. if (ret) {
  874. nx842_delete_coprocs();
  875. return ret;
  876. }
  877. }
  878. if (list_empty(&nx842_coprocs)) {
  879. for_each_compatible_node(dn, NULL, "ibm,power-nx")
  880. nx842_powernv_probe(dn);
  881. if (!nx842_ct)
  882. return -ENODEV;
  883. nx842_powernv_exec = nx842_exec_icswx;
  884. } else {
  885. ret = nx842_open_percpu_txwins();
  886. if (ret) {
  887. nx842_delete_coprocs();
  888. return ret;
  889. }
  890. nx842_powernv_exec = nx842_exec_vas;
  891. }
  892. ret = crypto_register_alg(&nx842_powernv_alg);
  893. if (ret) {
  894. nx842_delete_coprocs();
  895. return ret;
  896. }
  897. return 0;
  898. }
  899. module_init(nx842_powernv_init);
  900. static void __exit nx842_powernv_exit(void)
  901. {
  902. crypto_unregister_alg(&nx842_powernv_alg);
  903. nx842_delete_coprocs();
  904. }
  905. module_exit(nx842_powernv_exit);