nx-common-pseries.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Driver for IBM Power 842 compression accelerator
  4. *
  5. * Copyright (C) IBM Corporation, 2012
  6. *
  7. * Authors: Robert Jennings <rcj@linux.vnet.ibm.com>
  8. * Seth Jennings <sjenning@linux.vnet.ibm.com>
  9. */
  10. #include <asm/vio.h>
  11. #include <asm/hvcall.h>
  12. #include <asm/vas.h>
  13. #include "nx-842.h"
  14. #include "nx_csbcpb.h" /* struct nx_csbcpb */
  15. MODULE_LICENSE("GPL");
  16. MODULE_AUTHOR("Robert Jennings <rcj@linux.vnet.ibm.com>");
  17. MODULE_DESCRIPTION("842 H/W Compression driver for IBM Power processors");
  18. MODULE_ALIAS_CRYPTO("842");
  19. MODULE_ALIAS_CRYPTO("842-nx");
  20. /*
  21. * Coprocessor type specific capabilities from the hypervisor.
  22. */
  23. struct hv_nx_cop_caps {
  24. __be64 descriptor;
  25. __be64 req_max_processed_len; /* Max bytes in one GZIP request */
  26. __be64 min_compress_len; /* Min compression size in bytes */
  27. __be64 min_decompress_len; /* Min decompression size in bytes */
  28. } __packed __aligned(0x1000);
  29. /*
  30. * Coprocessor type specific capabilities.
  31. */
  32. struct nx_cop_caps {
  33. u64 descriptor;
  34. u64 req_max_processed_len; /* Max bytes in one GZIP request */
  35. u64 min_compress_len; /* Min compression in bytes */
  36. u64 min_decompress_len; /* Min decompression in bytes */
  37. };
  38. static u64 caps_feat;
  39. static struct nx_cop_caps nx_cop_caps;
  40. static struct nx842_constraints nx842_pseries_constraints = {
  41. .alignment = DDE_BUFFER_ALIGN,
  42. .multiple = DDE_BUFFER_LAST_MULT,
  43. .minimum = DDE_BUFFER_LAST_MULT,
  44. .maximum = PAGE_SIZE, /* dynamic, max_sync_size */
  45. };
  46. static int check_constraints(unsigned long buf, unsigned int *len, bool in)
  47. {
  48. if (!IS_ALIGNED(buf, nx842_pseries_constraints.alignment)) {
  49. pr_debug("%s buffer 0x%lx not aligned to 0x%x\n",
  50. in ? "input" : "output", buf,
  51. nx842_pseries_constraints.alignment);
  52. return -EINVAL;
  53. }
  54. if (*len % nx842_pseries_constraints.multiple) {
  55. pr_debug("%s buffer len 0x%x not multiple of 0x%x\n",
  56. in ? "input" : "output", *len,
  57. nx842_pseries_constraints.multiple);
  58. if (in)
  59. return -EINVAL;
  60. *len = round_down(*len, nx842_pseries_constraints.multiple);
  61. }
  62. if (*len < nx842_pseries_constraints.minimum) {
  63. pr_debug("%s buffer len 0x%x under minimum 0x%x\n",
  64. in ? "input" : "output", *len,
  65. nx842_pseries_constraints.minimum);
  66. return -EINVAL;
  67. }
  68. if (*len > nx842_pseries_constraints.maximum) {
  69. pr_debug("%s buffer len 0x%x over maximum 0x%x\n",
  70. in ? "input" : "output", *len,
  71. nx842_pseries_constraints.maximum);
  72. if (in)
  73. return -EINVAL;
  74. *len = nx842_pseries_constraints.maximum;
  75. }
  76. return 0;
  77. }
  78. /* I assume we need to align the CSB? */
  79. #define WORKMEM_ALIGN (256)
  80. struct nx842_workmem {
  81. /* scatterlist */
  82. char slin[4096];
  83. char slout[4096];
  84. /* coprocessor status/parameter block */
  85. struct nx_csbcpb csbcpb;
  86. char padding[WORKMEM_ALIGN];
  87. } __aligned(WORKMEM_ALIGN);
  88. /* Macros for fields within nx_csbcpb */
  89. /* Check the valid bit within the csbcpb valid field */
  90. #define NX842_CSBCBP_VALID_CHK(x) (x & BIT_MASK(7))
  91. /* CE macros operate on the completion_extension field bits in the csbcpb.
  92. * CE0 0=full completion, 1=partial completion
  93. * CE1 0=CE0 indicates completion, 1=termination (output may be modified)
  94. * CE2 0=processed_bytes is source bytes, 1=processed_bytes is target bytes */
  95. #define NX842_CSBCPB_CE0(x) (x & BIT_MASK(7))
  96. #define NX842_CSBCPB_CE1(x) (x & BIT_MASK(6))
  97. #define NX842_CSBCPB_CE2(x) (x & BIT_MASK(5))
  98. /* The NX unit accepts data only on 4K page boundaries */
  99. #define NX842_HW_PAGE_SIZE (4096)
  100. #define NX842_HW_PAGE_MASK (~(NX842_HW_PAGE_SIZE-1))
  101. struct ibm_nx842_counters {
  102. atomic64_t comp_complete;
  103. atomic64_t comp_failed;
  104. atomic64_t decomp_complete;
  105. atomic64_t decomp_failed;
  106. atomic64_t swdecomp;
  107. atomic64_t comp_times[32];
  108. atomic64_t decomp_times[32];
  109. };
  110. struct nx842_devdata {
  111. struct vio_dev *vdev;
  112. struct device *dev;
  113. struct ibm_nx842_counters *counters;
  114. unsigned int max_sg_len;
  115. unsigned int max_sync_size;
  116. unsigned int max_sync_sg;
  117. };
  118. static struct nx842_devdata __rcu *devdata;
  119. static DEFINE_SPINLOCK(devdata_mutex);
  120. #define NX842_COUNTER_INC(_x) \
  121. static inline void nx842_inc_##_x( \
  122. const struct nx842_devdata *dev) { \
  123. if (dev) \
  124. atomic64_inc(&dev->counters->_x); \
  125. }
  126. NX842_COUNTER_INC(comp_complete);
  127. NX842_COUNTER_INC(comp_failed);
  128. NX842_COUNTER_INC(decomp_complete);
  129. NX842_COUNTER_INC(decomp_failed);
  130. NX842_COUNTER_INC(swdecomp);
  131. #define NX842_HIST_SLOTS 16
  132. static void ibm_nx842_incr_hist(atomic64_t *times, unsigned int time)
  133. {
  134. int bucket = fls(time);
  135. if (bucket)
  136. bucket = min((NX842_HIST_SLOTS - 1), bucket - 1);
  137. atomic64_inc(&times[bucket]);
  138. }
  139. /* NX unit operation flags */
  140. #define NX842_OP_COMPRESS 0x0
  141. #define NX842_OP_CRC 0x1
  142. #define NX842_OP_DECOMPRESS 0x2
  143. #define NX842_OP_COMPRESS_CRC (NX842_OP_COMPRESS | NX842_OP_CRC)
  144. #define NX842_OP_DECOMPRESS_CRC (NX842_OP_DECOMPRESS | NX842_OP_CRC)
  145. #define NX842_OP_ASYNC (1<<23)
  146. #define NX842_OP_NOTIFY (1<<22)
  147. #define NX842_OP_NOTIFY_INT(x) ((x & 0xff)<<8)
  148. static unsigned long nx842_get_desired_dma(struct vio_dev *viodev)
  149. {
  150. /* No use of DMA mappings within the driver. */
  151. return 0;
  152. }
  153. struct nx842_slentry {
  154. __be64 ptr; /* Real address (use __pa()) */
  155. __be64 len;
  156. };
  157. /* pHyp scatterlist entry */
  158. struct nx842_scatterlist {
  159. int entry_nr; /* number of slentries */
  160. struct nx842_slentry *entries; /* ptr to array of slentries */
  161. };
  162. /* Does not include sizeof(entry_nr) in the size */
  163. static inline unsigned long nx842_get_scatterlist_size(
  164. struct nx842_scatterlist *sl)
  165. {
  166. return sl->entry_nr * sizeof(struct nx842_slentry);
  167. }
  168. static int nx842_build_scatterlist(unsigned long buf, int len,
  169. struct nx842_scatterlist *sl)
  170. {
  171. unsigned long entrylen;
  172. struct nx842_slentry *entry;
  173. sl->entry_nr = 0;
  174. entry = sl->entries;
  175. while (len) {
  176. entry->ptr = cpu_to_be64(nx842_get_pa((void *)buf));
  177. entrylen = min_t(int, len,
  178. LEN_ON_SIZE(buf, NX842_HW_PAGE_SIZE));
  179. entry->len = cpu_to_be64(entrylen);
  180. len -= entrylen;
  181. buf += entrylen;
  182. sl->entry_nr++;
  183. entry++;
  184. }
  185. return 0;
  186. }
  187. static int nx842_validate_result(struct device *dev,
  188. struct cop_status_block *csb)
  189. {
  190. /* The csb must be valid after returning from vio_h_cop_sync */
  191. if (!NX842_CSBCBP_VALID_CHK(csb->valid)) {
  192. dev_err(dev, "%s: cspcbp not valid upon completion.\n",
  193. __func__);
  194. dev_dbg(dev, "valid:0x%02x cs:0x%02x cc:0x%02x ce:0x%02x\n",
  195. csb->valid,
  196. csb->crb_seq_number,
  197. csb->completion_code,
  198. csb->completion_extension);
  199. dev_dbg(dev, "processed_bytes:%d address:0x%016lx\n",
  200. be32_to_cpu(csb->processed_byte_count),
  201. (unsigned long)be64_to_cpu(csb->address));
  202. return -EIO;
  203. }
  204. /* Check return values from the hardware in the CSB */
  205. switch (csb->completion_code) {
  206. case 0: /* Completed without error */
  207. break;
  208. case 64: /* Compression ok, but output larger than input */
  209. dev_dbg(dev, "%s: output size larger than input size\n",
  210. __func__);
  211. break;
  212. case 13: /* Output buffer too small */
  213. dev_dbg(dev, "%s: Out of space in output buffer\n",
  214. __func__);
  215. return -ENOSPC;
  216. case 65: /* Calculated CRC doesn't match the passed value */
  217. dev_dbg(dev, "%s: CRC mismatch for decompression\n",
  218. __func__);
  219. return -EINVAL;
  220. case 66: /* Input data contains an illegal template field */
  221. case 67: /* Template indicates data past the end of the input stream */
  222. dev_dbg(dev, "%s: Bad data for decompression (code:%d)\n",
  223. __func__, csb->completion_code);
  224. return -EINVAL;
  225. default:
  226. dev_dbg(dev, "%s: Unspecified error (code:%d)\n",
  227. __func__, csb->completion_code);
  228. return -EIO;
  229. }
  230. /* Hardware sanity check */
  231. if (!NX842_CSBCPB_CE2(csb->completion_extension)) {
  232. dev_err(dev, "%s: No error returned by hardware, but "
  233. "data returned is unusable, contact support.\n"
  234. "(Additional info: csbcbp->processed bytes "
  235. "does not specify processed bytes for the "
  236. "target buffer.)\n", __func__);
  237. return -EIO;
  238. }
  239. return 0;
  240. }
  241. /**
  242. * nx842_pseries_compress - Compress data using the 842 algorithm
  243. *
  244. * Compression provide by the NX842 coprocessor on IBM Power systems.
  245. * The input buffer is compressed and the result is stored in the
  246. * provided output buffer.
  247. *
  248. * Upon return from this function @outlen contains the length of the
  249. * compressed data. If there is an error then @outlen will be 0 and an
  250. * error will be specified by the return code from this function.
  251. *
  252. * @in: Pointer to input buffer
  253. * @inlen: Length of input buffer
  254. * @out: Pointer to output buffer
  255. * @outlen: Length of output buffer
  256. * @wmem: ptr to buffer for working memory, size determined by
  257. * nx842_pseries_driver.workmem_size
  258. *
  259. * Returns:
  260. * 0 Success, output of length @outlen stored in the buffer at @out
  261. * -ENOMEM Unable to allocate internal buffers
  262. * -ENOSPC Output buffer is to small
  263. * -EIO Internal error
  264. * -ENODEV Hardware unavailable
  265. */
  266. static int nx842_pseries_compress(const unsigned char *in, unsigned int inlen,
  267. unsigned char *out, unsigned int *outlen,
  268. void *wmem)
  269. {
  270. struct nx842_devdata *local_devdata;
  271. struct device *dev = NULL;
  272. struct nx842_workmem *workmem;
  273. struct nx842_scatterlist slin, slout;
  274. struct nx_csbcpb *csbcpb;
  275. int ret = 0;
  276. unsigned long inbuf, outbuf;
  277. struct vio_pfo_op op = {
  278. .done = NULL,
  279. .handle = 0,
  280. .timeout = 0,
  281. };
  282. unsigned long start = get_tb();
  283. inbuf = (unsigned long)in;
  284. if (check_constraints(inbuf, &inlen, true))
  285. return -EINVAL;
  286. outbuf = (unsigned long)out;
  287. if (check_constraints(outbuf, outlen, false))
  288. return -EINVAL;
  289. rcu_read_lock();
  290. local_devdata = rcu_dereference(devdata);
  291. if (!local_devdata || !local_devdata->dev) {
  292. rcu_read_unlock();
  293. return -ENODEV;
  294. }
  295. dev = local_devdata->dev;
  296. /* Init scatterlist */
  297. workmem = PTR_ALIGN(wmem, WORKMEM_ALIGN);
  298. slin.entries = (struct nx842_slentry *)workmem->slin;
  299. slout.entries = (struct nx842_slentry *)workmem->slout;
  300. /* Init operation */
  301. op.flags = NX842_OP_COMPRESS_CRC;
  302. csbcpb = &workmem->csbcpb;
  303. memset(csbcpb, 0, sizeof(*csbcpb));
  304. op.csbcpb = nx842_get_pa(csbcpb);
  305. if ((inbuf & NX842_HW_PAGE_MASK) ==
  306. ((inbuf + inlen - 1) & NX842_HW_PAGE_MASK)) {
  307. /* Create direct DDE */
  308. op.in = nx842_get_pa((void *)inbuf);
  309. op.inlen = inlen;
  310. } else {
  311. /* Create indirect DDE (scatterlist) */
  312. nx842_build_scatterlist(inbuf, inlen, &slin);
  313. op.in = nx842_get_pa(slin.entries);
  314. op.inlen = -nx842_get_scatterlist_size(&slin);
  315. }
  316. if ((outbuf & NX842_HW_PAGE_MASK) ==
  317. ((outbuf + *outlen - 1) & NX842_HW_PAGE_MASK)) {
  318. /* Create direct DDE */
  319. op.out = nx842_get_pa((void *)outbuf);
  320. op.outlen = *outlen;
  321. } else {
  322. /* Create indirect DDE (scatterlist) */
  323. nx842_build_scatterlist(outbuf, *outlen, &slout);
  324. op.out = nx842_get_pa(slout.entries);
  325. op.outlen = -nx842_get_scatterlist_size(&slout);
  326. }
  327. dev_dbg(dev, "%s: op.in %lx op.inlen %ld op.out %lx op.outlen %ld\n",
  328. __func__, (unsigned long)op.in, (long)op.inlen,
  329. (unsigned long)op.out, (long)op.outlen);
  330. /* Send request to pHyp */
  331. ret = vio_h_cop_sync(local_devdata->vdev, &op);
  332. /* Check for pHyp error */
  333. if (ret) {
  334. dev_dbg(dev, "%s: vio_h_cop_sync error (ret=%d, hret=%ld)\n",
  335. __func__, ret, op.hcall_err);
  336. ret = -EIO;
  337. goto unlock;
  338. }
  339. /* Check for hardware error */
  340. ret = nx842_validate_result(dev, &csbcpb->csb);
  341. if (ret)
  342. goto unlock;
  343. *outlen = be32_to_cpu(csbcpb->csb.processed_byte_count);
  344. dev_dbg(dev, "%s: processed_bytes=%d\n", __func__, *outlen);
  345. unlock:
  346. if (ret)
  347. nx842_inc_comp_failed(local_devdata);
  348. else {
  349. nx842_inc_comp_complete(local_devdata);
  350. ibm_nx842_incr_hist(local_devdata->counters->comp_times,
  351. (get_tb() - start) / tb_ticks_per_usec);
  352. }
  353. rcu_read_unlock();
  354. return ret;
  355. }
  356. /**
  357. * nx842_pseries_decompress - Decompress data using the 842 algorithm
  358. *
  359. * Decompression provide by the NX842 coprocessor on IBM Power systems.
  360. * The input buffer is decompressed and the result is stored in the
  361. * provided output buffer. The size allocated to the output buffer is
  362. * provided by the caller of this function in @outlen. Upon return from
  363. * this function @outlen contains the length of the decompressed data.
  364. * If there is an error then @outlen will be 0 and an error will be
  365. * specified by the return code from this function.
  366. *
  367. * @in: Pointer to input buffer
  368. * @inlen: Length of input buffer
  369. * @out: Pointer to output buffer
  370. * @outlen: Length of output buffer
  371. * @wmem: ptr to buffer for working memory, size determined by
  372. * nx842_pseries_driver.workmem_size
  373. *
  374. * Returns:
  375. * 0 Success, output of length @outlen stored in the buffer at @out
  376. * -ENODEV Hardware decompression device is unavailable
  377. * -ENOMEM Unable to allocate internal buffers
  378. * -ENOSPC Output buffer is to small
  379. * -EINVAL Bad input data encountered when attempting decompress
  380. * -EIO Internal error
  381. */
  382. static int nx842_pseries_decompress(const unsigned char *in, unsigned int inlen,
  383. unsigned char *out, unsigned int *outlen,
  384. void *wmem)
  385. {
  386. struct nx842_devdata *local_devdata;
  387. struct device *dev = NULL;
  388. struct nx842_workmem *workmem;
  389. struct nx842_scatterlist slin, slout;
  390. struct nx_csbcpb *csbcpb;
  391. int ret = 0;
  392. unsigned long inbuf, outbuf;
  393. struct vio_pfo_op op = {
  394. .done = NULL,
  395. .handle = 0,
  396. .timeout = 0,
  397. };
  398. unsigned long start = get_tb();
  399. /* Ensure page alignment and size */
  400. inbuf = (unsigned long)in;
  401. if (check_constraints(inbuf, &inlen, true))
  402. return -EINVAL;
  403. outbuf = (unsigned long)out;
  404. if (check_constraints(outbuf, outlen, false))
  405. return -EINVAL;
  406. rcu_read_lock();
  407. local_devdata = rcu_dereference(devdata);
  408. if (!local_devdata || !local_devdata->dev) {
  409. rcu_read_unlock();
  410. return -ENODEV;
  411. }
  412. dev = local_devdata->dev;
  413. workmem = PTR_ALIGN(wmem, WORKMEM_ALIGN);
  414. /* Init scatterlist */
  415. slin.entries = (struct nx842_slentry *)workmem->slin;
  416. slout.entries = (struct nx842_slentry *)workmem->slout;
  417. /* Init operation */
  418. op.flags = NX842_OP_DECOMPRESS_CRC;
  419. csbcpb = &workmem->csbcpb;
  420. memset(csbcpb, 0, sizeof(*csbcpb));
  421. op.csbcpb = nx842_get_pa(csbcpb);
  422. if ((inbuf & NX842_HW_PAGE_MASK) ==
  423. ((inbuf + inlen - 1) & NX842_HW_PAGE_MASK)) {
  424. /* Create direct DDE */
  425. op.in = nx842_get_pa((void *)inbuf);
  426. op.inlen = inlen;
  427. } else {
  428. /* Create indirect DDE (scatterlist) */
  429. nx842_build_scatterlist(inbuf, inlen, &slin);
  430. op.in = nx842_get_pa(slin.entries);
  431. op.inlen = -nx842_get_scatterlist_size(&slin);
  432. }
  433. if ((outbuf & NX842_HW_PAGE_MASK) ==
  434. ((outbuf + *outlen - 1) & NX842_HW_PAGE_MASK)) {
  435. /* Create direct DDE */
  436. op.out = nx842_get_pa((void *)outbuf);
  437. op.outlen = *outlen;
  438. } else {
  439. /* Create indirect DDE (scatterlist) */
  440. nx842_build_scatterlist(outbuf, *outlen, &slout);
  441. op.out = nx842_get_pa(slout.entries);
  442. op.outlen = -nx842_get_scatterlist_size(&slout);
  443. }
  444. dev_dbg(dev, "%s: op.in %lx op.inlen %ld op.out %lx op.outlen %ld\n",
  445. __func__, (unsigned long)op.in, (long)op.inlen,
  446. (unsigned long)op.out, (long)op.outlen);
  447. /* Send request to pHyp */
  448. ret = vio_h_cop_sync(local_devdata->vdev, &op);
  449. /* Check for pHyp error */
  450. if (ret) {
  451. dev_dbg(dev, "%s: vio_h_cop_sync error (ret=%d, hret=%ld)\n",
  452. __func__, ret, op.hcall_err);
  453. goto unlock;
  454. }
  455. /* Check for hardware error */
  456. ret = nx842_validate_result(dev, &csbcpb->csb);
  457. if (ret)
  458. goto unlock;
  459. *outlen = be32_to_cpu(csbcpb->csb.processed_byte_count);
  460. unlock:
  461. if (ret)
  462. /* decompress fail */
  463. nx842_inc_decomp_failed(local_devdata);
  464. else {
  465. nx842_inc_decomp_complete(local_devdata);
  466. ibm_nx842_incr_hist(local_devdata->counters->decomp_times,
  467. (get_tb() - start) / tb_ticks_per_usec);
  468. }
  469. rcu_read_unlock();
  470. return ret;
  471. }
  472. /**
  473. * nx842_OF_set_defaults -- Set default (disabled) values for devdata
  474. *
  475. * @devdata: struct nx842_devdata to update
  476. *
  477. * Returns:
  478. * 0 on success
  479. * -ENOENT if @devdata ptr is NULL
  480. */
  481. static int nx842_OF_set_defaults(struct nx842_devdata *devdata)
  482. {
  483. if (devdata) {
  484. devdata->max_sync_size = 0;
  485. devdata->max_sync_sg = 0;
  486. devdata->max_sg_len = 0;
  487. return 0;
  488. } else
  489. return -ENOENT;
  490. }
  491. /**
  492. * nx842_OF_upd_status -- Check the device info from OF status prop
  493. *
  494. * The status property indicates if the accelerator is enabled. If the
  495. * device is in the OF tree it indicates that the hardware is present.
  496. * The status field indicates if the device is enabled when the status
  497. * is 'okay'. Otherwise the device driver will be disabled.
  498. *
  499. * @devdata: struct nx842_devdata to use for dev_info
  500. * @prop: struct property point containing the maxsyncop for the update
  501. *
  502. * Returns:
  503. * 0 - Device is available
  504. * -ENODEV - Device is not available
  505. */
  506. static int nx842_OF_upd_status(struct nx842_devdata *devdata,
  507. struct property *prop)
  508. {
  509. const char *status = (const char *)prop->value;
  510. if (!strncmp(status, "okay", (size_t)prop->length))
  511. return 0;
  512. if (!strncmp(status, "disabled", (size_t)prop->length))
  513. return -ENODEV;
  514. dev_info(devdata->dev, "%s: unknown status '%s'\n", __func__, status);
  515. return -EINVAL;
  516. }
  517. /**
  518. * nx842_OF_upd_maxsglen -- Update the device info from OF maxsglen prop
  519. *
  520. * Definition of the 'ibm,max-sg-len' OF property:
  521. * This field indicates the maximum byte length of a scatter list
  522. * for the platform facility. It is a single cell encoded as with encode-int.
  523. *
  524. * Example:
  525. * # od -x ibm,max-sg-len
  526. * 0000000 0000 0ff0
  527. *
  528. * In this example, the maximum byte length of a scatter list is
  529. * 0x0ff0 (4,080).
  530. *
  531. * @devdata: struct nx842_devdata to update
  532. * @prop: struct property point containing the maxsyncop for the update
  533. *
  534. * Returns:
  535. * 0 on success
  536. * -EINVAL on failure
  537. */
  538. static int nx842_OF_upd_maxsglen(struct nx842_devdata *devdata,
  539. struct property *prop) {
  540. int ret = 0;
  541. const unsigned int maxsglen = of_read_number(prop->value, 1);
  542. if (prop->length != sizeof(maxsglen)) {
  543. dev_err(devdata->dev, "%s: unexpected format for ibm,max-sg-len property\n", __func__);
  544. dev_dbg(devdata->dev, "%s: ibm,max-sg-len is %d bytes long, expected %lu bytes\n", __func__,
  545. prop->length, sizeof(maxsglen));
  546. ret = -EINVAL;
  547. } else {
  548. devdata->max_sg_len = min_t(unsigned int,
  549. maxsglen, NX842_HW_PAGE_SIZE);
  550. }
  551. return ret;
  552. }
  553. /**
  554. * nx842_OF_upd_maxsyncop -- Update the device info from OF maxsyncop prop
  555. *
  556. * Definition of the 'ibm,max-sync-cop' OF property:
  557. * Two series of cells. The first series of cells represents the maximums
  558. * that can be synchronously compressed. The second series of cells
  559. * represents the maximums that can be synchronously decompressed.
  560. * 1. The first cell in each series contains the count of the number of
  561. * data length, scatter list elements pairs that follow – each being
  562. * of the form
  563. * a. One cell data byte length
  564. * b. One cell total number of scatter list elements
  565. *
  566. * Example:
  567. * # od -x ibm,max-sync-cop
  568. * 0000000 0000 0001 0000 1000 0000 01fe 0000 0001
  569. * 0000020 0000 1000 0000 01fe
  570. *
  571. * In this example, compression supports 0x1000 (4,096) data byte length
  572. * and 0x1fe (510) total scatter list elements. Decompression supports
  573. * 0x1000 (4,096) data byte length and 0x1f3 (510) total scatter list
  574. * elements.
  575. *
  576. * @devdata: struct nx842_devdata to update
  577. * @prop: struct property point containing the maxsyncop for the update
  578. *
  579. * Returns:
  580. * 0 on success
  581. * -EINVAL on failure
  582. */
  583. static int nx842_OF_upd_maxsyncop(struct nx842_devdata *devdata,
  584. struct property *prop) {
  585. int ret = 0;
  586. unsigned int comp_data_limit, decomp_data_limit;
  587. unsigned int comp_sg_limit, decomp_sg_limit;
  588. const struct maxsynccop_t {
  589. __be32 comp_elements;
  590. __be32 comp_data_limit;
  591. __be32 comp_sg_limit;
  592. __be32 decomp_elements;
  593. __be32 decomp_data_limit;
  594. __be32 decomp_sg_limit;
  595. } *maxsynccop;
  596. if (prop->length != sizeof(*maxsynccop)) {
  597. dev_err(devdata->dev, "%s: unexpected format for ibm,max-sync-cop property\n", __func__);
  598. dev_dbg(devdata->dev, "%s: ibm,max-sync-cop is %d bytes long, expected %lu bytes\n", __func__, prop->length,
  599. sizeof(*maxsynccop));
  600. ret = -EINVAL;
  601. goto out;
  602. }
  603. maxsynccop = (const struct maxsynccop_t *)prop->value;
  604. comp_data_limit = be32_to_cpu(maxsynccop->comp_data_limit);
  605. comp_sg_limit = be32_to_cpu(maxsynccop->comp_sg_limit);
  606. decomp_data_limit = be32_to_cpu(maxsynccop->decomp_data_limit);
  607. decomp_sg_limit = be32_to_cpu(maxsynccop->decomp_sg_limit);
  608. /* Use one limit rather than separate limits for compression and
  609. * decompression. Set a maximum for this so as not to exceed the
  610. * size that the header can support and round the value down to
  611. * the hardware page size (4K) */
  612. devdata->max_sync_size = min(comp_data_limit, decomp_data_limit);
  613. devdata->max_sync_size = min_t(unsigned int, devdata->max_sync_size,
  614. 65536);
  615. if (devdata->max_sync_size < 4096) {
  616. dev_err(devdata->dev, "%s: hardware max data size (%u) is "
  617. "less than the driver minimum, unable to use "
  618. "the hardware device\n",
  619. __func__, devdata->max_sync_size);
  620. ret = -EINVAL;
  621. goto out;
  622. }
  623. nx842_pseries_constraints.maximum = devdata->max_sync_size;
  624. devdata->max_sync_sg = min(comp_sg_limit, decomp_sg_limit);
  625. if (devdata->max_sync_sg < 1) {
  626. dev_err(devdata->dev, "%s: hardware max sg size (%u) is "
  627. "less than the driver minimum, unable to use "
  628. "the hardware device\n",
  629. __func__, devdata->max_sync_sg);
  630. ret = -EINVAL;
  631. goto out;
  632. }
  633. out:
  634. return ret;
  635. }
  636. /**
  637. * nx842_OF_upd -- Handle OF properties updates for the device.
  638. *
  639. * Set all properties from the OF tree. Optionally, a new property
  640. * can be provided by the @new_prop pointer to overwrite an existing value.
  641. * The device will remain disabled until all values are valid, this function
  642. * will return an error for updates unless all values are valid.
  643. *
  644. * @new_prop: If not NULL, this property is being updated. If NULL, update
  645. * all properties from the current values in the OF tree.
  646. *
  647. * Returns:
  648. * 0 - Success
  649. * -ENOMEM - Could not allocate memory for new devdata structure
  650. * -EINVAL - property value not found, new_prop is not a recognized
  651. * property for the device or property value is not valid.
  652. * -ENODEV - Device is not available
  653. */
  654. static int nx842_OF_upd(struct property *new_prop)
  655. {
  656. struct nx842_devdata *old_devdata = NULL;
  657. struct nx842_devdata *new_devdata = NULL;
  658. struct device_node *of_node = NULL;
  659. struct property *status = NULL;
  660. struct property *maxsglen = NULL;
  661. struct property *maxsyncop = NULL;
  662. int ret = 0;
  663. unsigned long flags;
  664. new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS);
  665. if (!new_devdata)
  666. return -ENOMEM;
  667. spin_lock_irqsave(&devdata_mutex, flags);
  668. old_devdata = rcu_dereference_check(devdata,
  669. lockdep_is_held(&devdata_mutex));
  670. if (old_devdata)
  671. of_node = old_devdata->dev->of_node;
  672. if (!old_devdata || !of_node) {
  673. pr_err("%s: device is not available\n", __func__);
  674. spin_unlock_irqrestore(&devdata_mutex, flags);
  675. kfree(new_devdata);
  676. return -ENODEV;
  677. }
  678. memcpy(new_devdata, old_devdata, sizeof(*old_devdata));
  679. new_devdata->counters = old_devdata->counters;
  680. /* Set ptrs for existing properties */
  681. status = of_find_property(of_node, "status", NULL);
  682. maxsglen = of_find_property(of_node, "ibm,max-sg-len", NULL);
  683. maxsyncop = of_find_property(of_node, "ibm,max-sync-cop", NULL);
  684. if (!status || !maxsglen || !maxsyncop) {
  685. dev_err(old_devdata->dev, "%s: Could not locate device properties\n", __func__);
  686. ret = -EINVAL;
  687. goto error_out;
  688. }
  689. /*
  690. * If this is a property update, there are only certain properties that
  691. * we care about. Bail if it isn't in the below list
  692. */
  693. if (new_prop && (strncmp(new_prop->name, "status", new_prop->length) ||
  694. strncmp(new_prop->name, "ibm,max-sg-len", new_prop->length) ||
  695. strncmp(new_prop->name, "ibm,max-sync-cop", new_prop->length)))
  696. goto out;
  697. /* Perform property updates */
  698. ret = nx842_OF_upd_status(new_devdata, status);
  699. if (ret)
  700. goto error_out;
  701. ret = nx842_OF_upd_maxsglen(new_devdata, maxsglen);
  702. if (ret)
  703. goto error_out;
  704. ret = nx842_OF_upd_maxsyncop(new_devdata, maxsyncop);
  705. if (ret)
  706. goto error_out;
  707. out:
  708. dev_info(old_devdata->dev, "%s: max_sync_size new:%u old:%u\n",
  709. __func__, new_devdata->max_sync_size,
  710. old_devdata->max_sync_size);
  711. dev_info(old_devdata->dev, "%s: max_sync_sg new:%u old:%u\n",
  712. __func__, new_devdata->max_sync_sg,
  713. old_devdata->max_sync_sg);
  714. dev_info(old_devdata->dev, "%s: max_sg_len new:%u old:%u\n",
  715. __func__, new_devdata->max_sg_len,
  716. old_devdata->max_sg_len);
  717. rcu_assign_pointer(devdata, new_devdata);
  718. spin_unlock_irqrestore(&devdata_mutex, flags);
  719. synchronize_rcu();
  720. dev_set_drvdata(new_devdata->dev, new_devdata);
  721. kfree(old_devdata);
  722. return 0;
  723. error_out:
  724. if (new_devdata) {
  725. dev_info(old_devdata->dev, "%s: device disabled\n", __func__);
  726. nx842_OF_set_defaults(new_devdata);
  727. rcu_assign_pointer(devdata, new_devdata);
  728. spin_unlock_irqrestore(&devdata_mutex, flags);
  729. synchronize_rcu();
  730. dev_set_drvdata(new_devdata->dev, new_devdata);
  731. kfree(old_devdata);
  732. } else {
  733. dev_err(old_devdata->dev, "%s: could not update driver from hardware\n", __func__);
  734. spin_unlock_irqrestore(&devdata_mutex, flags);
  735. }
  736. if (!ret)
  737. ret = -EINVAL;
  738. return ret;
  739. }
  740. /**
  741. * nx842_OF_notifier - Process updates to OF properties for the device
  742. *
  743. * @np: notifier block
  744. * @action: notifier action
  745. * @data: struct of_reconfig_data pointer
  746. *
  747. * Returns:
  748. * NOTIFY_OK on success
  749. * NOTIFY_BAD encoded with error number on failure, use
  750. * notifier_to_errno() to decode this value
  751. */
  752. static int nx842_OF_notifier(struct notifier_block *np, unsigned long action,
  753. void *data)
  754. {
  755. struct of_reconfig_data *upd = data;
  756. struct nx842_devdata *local_devdata;
  757. struct device_node *node = NULL;
  758. rcu_read_lock();
  759. local_devdata = rcu_dereference(devdata);
  760. if (local_devdata)
  761. node = local_devdata->dev->of_node;
  762. if (local_devdata &&
  763. action == OF_RECONFIG_UPDATE_PROPERTY &&
  764. !strcmp(upd->dn->name, node->name)) {
  765. rcu_read_unlock();
  766. nx842_OF_upd(upd->prop);
  767. } else
  768. rcu_read_unlock();
  769. return NOTIFY_OK;
  770. }
  771. static struct notifier_block nx842_of_nb = {
  772. .notifier_call = nx842_OF_notifier,
  773. };
  774. #define nx842_counter_read(_name) \
  775. static ssize_t nx842_##_name##_show(struct device *dev, \
  776. struct device_attribute *attr, \
  777. char *buf) { \
  778. struct nx842_devdata *local_devdata; \
  779. int p = 0; \
  780. rcu_read_lock(); \
  781. local_devdata = rcu_dereference(devdata); \
  782. if (local_devdata) \
  783. p = snprintf(buf, PAGE_SIZE, "%lld\n", \
  784. atomic64_read(&local_devdata->counters->_name)); \
  785. rcu_read_unlock(); \
  786. return p; \
  787. }
  788. #define NX842DEV_COUNTER_ATTR_RO(_name) \
  789. nx842_counter_read(_name); \
  790. static struct device_attribute dev_attr_##_name = __ATTR(_name, \
  791. 0444, \
  792. nx842_##_name##_show,\
  793. NULL);
  794. NX842DEV_COUNTER_ATTR_RO(comp_complete);
  795. NX842DEV_COUNTER_ATTR_RO(comp_failed);
  796. NX842DEV_COUNTER_ATTR_RO(decomp_complete);
  797. NX842DEV_COUNTER_ATTR_RO(decomp_failed);
  798. NX842DEV_COUNTER_ATTR_RO(swdecomp);
  799. static ssize_t nx842_timehist_show(struct device *,
  800. struct device_attribute *, char *);
  801. static struct device_attribute dev_attr_comp_times = __ATTR(comp_times, 0444,
  802. nx842_timehist_show, NULL);
  803. static struct device_attribute dev_attr_decomp_times = __ATTR(decomp_times,
  804. 0444, nx842_timehist_show, NULL);
  805. static ssize_t nx842_timehist_show(struct device *dev,
  806. struct device_attribute *attr, char *buf) {
  807. char *p = buf;
  808. struct nx842_devdata *local_devdata;
  809. atomic64_t *times;
  810. int bytes_remain = PAGE_SIZE;
  811. int bytes;
  812. int i;
  813. rcu_read_lock();
  814. local_devdata = rcu_dereference(devdata);
  815. if (!local_devdata) {
  816. rcu_read_unlock();
  817. return 0;
  818. }
  819. if (attr == &dev_attr_comp_times)
  820. times = local_devdata->counters->comp_times;
  821. else if (attr == &dev_attr_decomp_times)
  822. times = local_devdata->counters->decomp_times;
  823. else {
  824. rcu_read_unlock();
  825. return 0;
  826. }
  827. for (i = 0; i < (NX842_HIST_SLOTS - 2); i++) {
  828. bytes = snprintf(p, bytes_remain, "%u-%uus:\t%lld\n",
  829. i ? (2<<(i-1)) : 0, (2<<i)-1,
  830. atomic64_read(&times[i]));
  831. bytes_remain -= bytes;
  832. p += bytes;
  833. }
  834. /* The last bucket holds everything over
  835. * 2<<(NX842_HIST_SLOTS - 2) us */
  836. bytes = snprintf(p, bytes_remain, "%uus - :\t%lld\n",
  837. 2<<(NX842_HIST_SLOTS - 2),
  838. atomic64_read(&times[(NX842_HIST_SLOTS - 1)]));
  839. p += bytes;
  840. rcu_read_unlock();
  841. return p - buf;
  842. }
  843. static struct attribute *nx842_sysfs_entries[] = {
  844. &dev_attr_comp_complete.attr,
  845. &dev_attr_comp_failed.attr,
  846. &dev_attr_decomp_complete.attr,
  847. &dev_attr_decomp_failed.attr,
  848. &dev_attr_swdecomp.attr,
  849. &dev_attr_comp_times.attr,
  850. &dev_attr_decomp_times.attr,
  851. NULL,
  852. };
  853. static const struct attribute_group nx842_attribute_group = {
  854. .name = NULL, /* put in device directory */
  855. .attrs = nx842_sysfs_entries,
  856. };
  857. #define nxcop_caps_read(_name) \
  858. static ssize_t nxcop_##_name##_show(struct device *dev, \
  859. struct device_attribute *attr, char *buf) \
  860. { \
  861. return sprintf(buf, "%lld\n", nx_cop_caps._name); \
  862. }
  863. #define NXCT_ATTR_RO(_name) \
  864. nxcop_caps_read(_name); \
  865. static struct device_attribute dev_attr_##_name = __ATTR(_name, \
  866. 0444, \
  867. nxcop_##_name##_show, \
  868. NULL);
  869. NXCT_ATTR_RO(req_max_processed_len);
  870. NXCT_ATTR_RO(min_compress_len);
  871. NXCT_ATTR_RO(min_decompress_len);
  872. static struct attribute *nxcop_caps_sysfs_entries[] = {
  873. &dev_attr_req_max_processed_len.attr,
  874. &dev_attr_min_compress_len.attr,
  875. &dev_attr_min_decompress_len.attr,
  876. NULL,
  877. };
  878. static const struct attribute_group nxcop_caps_attr_group = {
  879. .name = "nx_gzip_caps",
  880. .attrs = nxcop_caps_sysfs_entries,
  881. };
  882. static struct nx842_driver nx842_pseries_driver = {
  883. .name = KBUILD_MODNAME,
  884. .owner = THIS_MODULE,
  885. .workmem_size = sizeof(struct nx842_workmem),
  886. .constraints = &nx842_pseries_constraints,
  887. .compress = nx842_pseries_compress,
  888. .decompress = nx842_pseries_decompress,
  889. };
  890. static int nx842_pseries_crypto_init(struct crypto_tfm *tfm)
  891. {
  892. return nx842_crypto_init(tfm, &nx842_pseries_driver);
  893. }
  894. static struct crypto_alg nx842_pseries_alg = {
  895. .cra_name = "842",
  896. .cra_driver_name = "842-nx",
  897. .cra_priority = 300,
  898. .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
  899. .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
  900. .cra_module = THIS_MODULE,
  901. .cra_init = nx842_pseries_crypto_init,
  902. .cra_exit = nx842_crypto_exit,
  903. .cra_u = { .compress = {
  904. .coa_compress = nx842_crypto_compress,
  905. .coa_decompress = nx842_crypto_decompress } }
  906. };
  907. static int nx842_probe(struct vio_dev *viodev,
  908. const struct vio_device_id *id)
  909. {
  910. struct nx842_devdata *old_devdata, *new_devdata = NULL;
  911. unsigned long flags;
  912. int ret = 0;
  913. new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS);
  914. if (!new_devdata)
  915. return -ENOMEM;
  916. new_devdata->counters = kzalloc(sizeof(*new_devdata->counters),
  917. GFP_NOFS);
  918. if (!new_devdata->counters) {
  919. kfree(new_devdata);
  920. return -ENOMEM;
  921. }
  922. spin_lock_irqsave(&devdata_mutex, flags);
  923. old_devdata = rcu_dereference_check(devdata,
  924. lockdep_is_held(&devdata_mutex));
  925. if (old_devdata && old_devdata->vdev != NULL) {
  926. dev_err(&viodev->dev, "%s: Attempt to register more than one instance of the hardware\n", __func__);
  927. ret = -1;
  928. goto error_unlock;
  929. }
  930. dev_set_drvdata(&viodev->dev, NULL);
  931. new_devdata->vdev = viodev;
  932. new_devdata->dev = &viodev->dev;
  933. nx842_OF_set_defaults(new_devdata);
  934. rcu_assign_pointer(devdata, new_devdata);
  935. spin_unlock_irqrestore(&devdata_mutex, flags);
  936. synchronize_rcu();
  937. kfree(old_devdata);
  938. of_reconfig_notifier_register(&nx842_of_nb);
  939. ret = nx842_OF_upd(NULL);
  940. if (ret)
  941. goto error;
  942. ret = crypto_register_alg(&nx842_pseries_alg);
  943. if (ret) {
  944. dev_err(&viodev->dev, "could not register comp alg: %d\n", ret);
  945. goto error;
  946. }
  947. rcu_read_lock();
  948. dev_set_drvdata(&viodev->dev, rcu_dereference(devdata));
  949. rcu_read_unlock();
  950. if (sysfs_create_group(&viodev->dev.kobj, &nx842_attribute_group)) {
  951. dev_err(&viodev->dev, "could not create sysfs device attributes\n");
  952. ret = -1;
  953. goto error;
  954. }
  955. if (caps_feat) {
  956. if (sysfs_create_group(&viodev->dev.kobj,
  957. &nxcop_caps_attr_group)) {
  958. dev_err(&viodev->dev,
  959. "Could not create sysfs NX capability entries\n");
  960. ret = -1;
  961. goto error;
  962. }
  963. }
  964. return 0;
  965. error_unlock:
  966. spin_unlock_irqrestore(&devdata_mutex, flags);
  967. if (new_devdata)
  968. kfree(new_devdata->counters);
  969. kfree(new_devdata);
  970. error:
  971. return ret;
  972. }
  973. static void nx842_remove(struct vio_dev *viodev)
  974. {
  975. struct nx842_devdata *old_devdata;
  976. unsigned long flags;
  977. pr_info("Removing IBM Power 842 compression device\n");
  978. sysfs_remove_group(&viodev->dev.kobj, &nx842_attribute_group);
  979. if (caps_feat)
  980. sysfs_remove_group(&viodev->dev.kobj, &nxcop_caps_attr_group);
  981. crypto_unregister_alg(&nx842_pseries_alg);
  982. spin_lock_irqsave(&devdata_mutex, flags);
  983. old_devdata = rcu_dereference_check(devdata,
  984. lockdep_is_held(&devdata_mutex));
  985. of_reconfig_notifier_unregister(&nx842_of_nb);
  986. RCU_INIT_POINTER(devdata, NULL);
  987. spin_unlock_irqrestore(&devdata_mutex, flags);
  988. synchronize_rcu();
  989. dev_set_drvdata(&viodev->dev, NULL);
  990. if (old_devdata)
  991. kfree(old_devdata->counters);
  992. kfree(old_devdata);
  993. }
  994. /*
  995. * Get NX capabilities from the hypervisor.
  996. * Only NXGZIP capabilities are provided by the hypersvisor right
  997. * now and these values are available to user space with sysfs.
  998. */
  999. static void __init nxcop_get_capabilities(void)
  1000. {
  1001. struct hv_vas_all_caps *hv_caps;
  1002. struct hv_nx_cop_caps *hv_nxc;
  1003. u64 feat;
  1004. int rc;
  1005. hv_caps = kmalloc(sizeof(*hv_caps), GFP_KERNEL);
  1006. if (!hv_caps)
  1007. return;
  1008. /*
  1009. * Get NX overall capabilities with feature type=0
  1010. */
  1011. rc = h_query_vas_capabilities(H_QUERY_NX_CAPABILITIES, 0,
  1012. (u64)virt_to_phys(hv_caps));
  1013. if (!rc)
  1014. feat = be64_to_cpu(hv_caps->feat_type);
  1015. kfree(hv_caps);
  1016. if (rc)
  1017. return;
  1018. if (!(feat & VAS_NX_GZIP_FEAT_BIT))
  1019. return;
  1020. /*
  1021. * NX-GZIP feature available
  1022. */
  1023. hv_nxc = kmalloc(sizeof(*hv_nxc), GFP_KERNEL);
  1024. if (!hv_nxc)
  1025. return;
  1026. /*
  1027. * Get capabilities for NX-GZIP feature
  1028. */
  1029. rc = h_query_vas_capabilities(H_QUERY_NX_CAPABILITIES,
  1030. VAS_NX_GZIP_FEAT,
  1031. (u64)virt_to_phys(hv_nxc));
  1032. if (!rc) {
  1033. nx_cop_caps.descriptor = be64_to_cpu(hv_nxc->descriptor);
  1034. nx_cop_caps.req_max_processed_len =
  1035. be64_to_cpu(hv_nxc->req_max_processed_len);
  1036. nx_cop_caps.min_compress_len =
  1037. be64_to_cpu(hv_nxc->min_compress_len);
  1038. nx_cop_caps.min_decompress_len =
  1039. be64_to_cpu(hv_nxc->min_decompress_len);
  1040. caps_feat = feat;
  1041. }
  1042. kfree(hv_nxc);
  1043. }
  1044. static const struct vio_device_id nx842_vio_driver_ids[] = {
  1045. {"ibm,compression-v1", "ibm,compression"},
  1046. {"", ""},
  1047. };
  1048. MODULE_DEVICE_TABLE(vio, nx842_vio_driver_ids);
  1049. static struct vio_driver nx842_vio_driver = {
  1050. .name = KBUILD_MODNAME,
  1051. .probe = nx842_probe,
  1052. .remove = nx842_remove,
  1053. .get_desired_dma = nx842_get_desired_dma,
  1054. .id_table = nx842_vio_driver_ids,
  1055. };
  1056. static int __init nx842_pseries_init(void)
  1057. {
  1058. struct nx842_devdata *new_devdata;
  1059. struct device_node *np;
  1060. int ret;
  1061. np = of_find_compatible_node(NULL, NULL, "ibm,compression");
  1062. if (!np)
  1063. return -ENODEV;
  1064. of_node_put(np);
  1065. RCU_INIT_POINTER(devdata, NULL);
  1066. new_devdata = kzalloc(sizeof(*new_devdata), GFP_KERNEL);
  1067. if (!new_devdata)
  1068. return -ENOMEM;
  1069. RCU_INIT_POINTER(devdata, new_devdata);
  1070. /*
  1071. * Get NX capabilities from the hypervisor.
  1072. */
  1073. nxcop_get_capabilities();
  1074. ret = vio_register_driver(&nx842_vio_driver);
  1075. if (ret) {
  1076. pr_err("Could not register VIO driver %d\n", ret);
  1077. kfree(new_devdata);
  1078. return ret;
  1079. }
  1080. ret = vas_register_api_pseries(THIS_MODULE, VAS_COP_TYPE_GZIP,
  1081. "nx-gzip");
  1082. if (ret)
  1083. pr_err("NX-GZIP is not supported. Returned=%d\n", ret);
  1084. return 0;
  1085. }
  1086. module_init(nx842_pseries_init);
  1087. static void __exit nx842_pseries_exit(void)
  1088. {
  1089. struct nx842_devdata *old_devdata;
  1090. unsigned long flags;
  1091. vas_unregister_api_pseries();
  1092. crypto_unregister_alg(&nx842_pseries_alg);
  1093. spin_lock_irqsave(&devdata_mutex, flags);
  1094. old_devdata = rcu_dereference_check(devdata,
  1095. lockdep_is_held(&devdata_mutex));
  1096. RCU_INIT_POINTER(devdata, NULL);
  1097. spin_unlock_irqrestore(&devdata_mutex, flags);
  1098. synchronize_rcu();
  1099. if (old_devdata && old_devdata->dev)
  1100. dev_set_drvdata(old_devdata->dev, NULL);
  1101. kfree(old_devdata);
  1102. vio_unregister_driver(&nx842_vio_driver);
  1103. }
  1104. module_exit(nx842_pseries_exit);