nx-842-pseries.c 32 KB

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