nx-842-pseries.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  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. static struct nx842_constraints nx842_pseries_constraints = {
  30. .alignment = DDE_BUFFER_ALIGN,
  31. .multiple = DDE_BUFFER_LAST_MULT,
  32. .minimum = DDE_BUFFER_LAST_MULT,
  33. .maximum = PAGE_SIZE, /* dynamic, max_sync_size */
  34. };
  35. static int check_constraints(unsigned long buf, unsigned int *len, bool in)
  36. {
  37. if (!IS_ALIGNED(buf, nx842_pseries_constraints.alignment)) {
  38. pr_debug("%s buffer 0x%lx not aligned to 0x%x\n",
  39. in ? "input" : "output", buf,
  40. nx842_pseries_constraints.alignment);
  41. return -EINVAL;
  42. }
  43. if (*len % nx842_pseries_constraints.multiple) {
  44. pr_debug("%s buffer len 0x%x not multiple of 0x%x\n",
  45. in ? "input" : "output", *len,
  46. nx842_pseries_constraints.multiple);
  47. if (in)
  48. return -EINVAL;
  49. *len = round_down(*len, nx842_pseries_constraints.multiple);
  50. }
  51. if (*len < nx842_pseries_constraints.minimum) {
  52. pr_debug("%s buffer len 0x%x under minimum 0x%x\n",
  53. in ? "input" : "output", *len,
  54. nx842_pseries_constraints.minimum);
  55. return -EINVAL;
  56. }
  57. if (*len > nx842_pseries_constraints.maximum) {
  58. pr_debug("%s buffer len 0x%x over maximum 0x%x\n",
  59. in ? "input" : "output", *len,
  60. nx842_pseries_constraints.maximum);
  61. if (in)
  62. return -EINVAL;
  63. *len = nx842_pseries_constraints.maximum;
  64. }
  65. return 0;
  66. }
  67. /* I assume we need to align the CSB? */
  68. #define WORKMEM_ALIGN (256)
  69. struct nx842_workmem {
  70. /* scatterlist */
  71. char slin[4096];
  72. char slout[4096];
  73. /* coprocessor status/parameter block */
  74. struct nx_csbcpb csbcpb;
  75. char padding[WORKMEM_ALIGN];
  76. } __aligned(WORKMEM_ALIGN);
  77. /* Macros for fields within nx_csbcpb */
  78. /* Check the valid bit within the csbcpb valid field */
  79. #define NX842_CSBCBP_VALID_CHK(x) (x & BIT_MASK(7))
  80. /* CE macros operate on the completion_extension field bits in the csbcpb.
  81. * CE0 0=full completion, 1=partial completion
  82. * CE1 0=CE0 indicates completion, 1=termination (output may be modified)
  83. * CE2 0=processed_bytes is source bytes, 1=processed_bytes is target bytes */
  84. #define NX842_CSBCPB_CE0(x) (x & BIT_MASK(7))
  85. #define NX842_CSBCPB_CE1(x) (x & BIT_MASK(6))
  86. #define NX842_CSBCPB_CE2(x) (x & BIT_MASK(5))
  87. /* The NX unit accepts data only on 4K page boundaries */
  88. #define NX842_HW_PAGE_SIZE (4096)
  89. #define NX842_HW_PAGE_MASK (~(NX842_HW_PAGE_SIZE-1))
  90. enum nx842_status {
  91. UNAVAILABLE,
  92. AVAILABLE
  93. };
  94. struct ibm_nx842_counters {
  95. atomic64_t comp_complete;
  96. atomic64_t comp_failed;
  97. atomic64_t decomp_complete;
  98. atomic64_t decomp_failed;
  99. atomic64_t swdecomp;
  100. atomic64_t comp_times[32];
  101. atomic64_t decomp_times[32];
  102. };
  103. static struct nx842_devdata {
  104. struct vio_dev *vdev;
  105. struct device *dev;
  106. struct ibm_nx842_counters *counters;
  107. unsigned int max_sg_len;
  108. unsigned int max_sync_size;
  109. unsigned int max_sync_sg;
  110. enum nx842_status status;
  111. } __rcu *devdata;
  112. static DEFINE_SPINLOCK(devdata_mutex);
  113. #define NX842_COUNTER_INC(_x) \
  114. static inline void nx842_inc_##_x( \
  115. const struct nx842_devdata *dev) { \
  116. if (dev) \
  117. atomic64_inc(&dev->counters->_x); \
  118. }
  119. NX842_COUNTER_INC(comp_complete);
  120. NX842_COUNTER_INC(comp_failed);
  121. NX842_COUNTER_INC(decomp_complete);
  122. NX842_COUNTER_INC(decomp_failed);
  123. NX842_COUNTER_INC(swdecomp);
  124. #define NX842_HIST_SLOTS 16
  125. static void ibm_nx842_incr_hist(atomic64_t *times, unsigned int time)
  126. {
  127. int bucket = fls(time);
  128. if (bucket)
  129. bucket = min((NX842_HIST_SLOTS - 1), bucket - 1);
  130. atomic64_inc(&times[bucket]);
  131. }
  132. /* NX unit operation flags */
  133. #define NX842_OP_COMPRESS 0x0
  134. #define NX842_OP_CRC 0x1
  135. #define NX842_OP_DECOMPRESS 0x2
  136. #define NX842_OP_COMPRESS_CRC (NX842_OP_COMPRESS | NX842_OP_CRC)
  137. #define NX842_OP_DECOMPRESS_CRC (NX842_OP_DECOMPRESS | NX842_OP_CRC)
  138. #define NX842_OP_ASYNC (1<<23)
  139. #define NX842_OP_NOTIFY (1<<22)
  140. #define NX842_OP_NOTIFY_INT(x) ((x & 0xff)<<8)
  141. static unsigned long nx842_get_desired_dma(struct vio_dev *viodev)
  142. {
  143. /* No use of DMA mappings within the driver. */
  144. return 0;
  145. }
  146. struct nx842_slentry {
  147. __be64 ptr; /* Real address (use __pa()) */
  148. __be64 len;
  149. };
  150. /* pHyp scatterlist entry */
  151. struct nx842_scatterlist {
  152. int entry_nr; /* number of slentries */
  153. struct nx842_slentry *entries; /* ptr to array of slentries */
  154. };
  155. /* Does not include sizeof(entry_nr) in the size */
  156. static inline unsigned long nx842_get_scatterlist_size(
  157. struct nx842_scatterlist *sl)
  158. {
  159. return sl->entry_nr * sizeof(struct nx842_slentry);
  160. }
  161. static int nx842_build_scatterlist(unsigned long buf, int len,
  162. struct nx842_scatterlist *sl)
  163. {
  164. unsigned long entrylen;
  165. struct nx842_slentry *entry;
  166. sl->entry_nr = 0;
  167. entry = sl->entries;
  168. while (len) {
  169. entry->ptr = cpu_to_be64(nx842_get_pa((void *)buf));
  170. entrylen = min_t(int, len,
  171. LEN_ON_SIZE(buf, NX842_HW_PAGE_SIZE));
  172. entry->len = cpu_to_be64(entrylen);
  173. len -= entrylen;
  174. buf += entrylen;
  175. sl->entry_nr++;
  176. entry++;
  177. }
  178. return 0;
  179. }
  180. static int nx842_validate_result(struct device *dev,
  181. struct cop_status_block *csb)
  182. {
  183. /* The csb must be valid after returning from vio_h_cop_sync */
  184. if (!NX842_CSBCBP_VALID_CHK(csb->valid)) {
  185. dev_err(dev, "%s: cspcbp not valid upon completion.\n",
  186. __func__);
  187. dev_dbg(dev, "valid:0x%02x cs:0x%02x cc:0x%02x ce:0x%02x\n",
  188. csb->valid,
  189. csb->crb_seq_number,
  190. csb->completion_code,
  191. csb->completion_extension);
  192. dev_dbg(dev, "processed_bytes:%d address:0x%016lx\n",
  193. be32_to_cpu(csb->processed_byte_count),
  194. (unsigned long)be64_to_cpu(csb->address));
  195. return -EIO;
  196. }
  197. /* Check return values from the hardware in the CSB */
  198. switch (csb->completion_code) {
  199. case 0: /* Completed without error */
  200. break;
  201. case 64: /* Target bytes > Source bytes during compression */
  202. case 13: /* Output buffer too small */
  203. dev_dbg(dev, "%s: Compression output larger than input\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. devdata->status = UNAVAILABLE;
  476. return 0;
  477. } else
  478. return -ENOENT;
  479. }
  480. /**
  481. * nx842_OF_upd_status -- Update the device info from OF status prop
  482. *
  483. * The status property indicates if the accelerator is enabled. If the
  484. * device is in the OF tree it indicates that the hardware is present.
  485. * The status field indicates if the device is enabled when the status
  486. * is 'okay'. Otherwise the device driver will be disabled.
  487. *
  488. * @devdata - struct nx842_devdata to update
  489. * @prop - struct property point containing the maxsyncop for the update
  490. *
  491. * Returns:
  492. * 0 - Device is available
  493. * -EINVAL - Device is not available
  494. */
  495. static int nx842_OF_upd_status(struct nx842_devdata *devdata,
  496. struct property *prop) {
  497. int ret = 0;
  498. const char *status = (const char *)prop->value;
  499. if (!strncmp(status, "okay", (size_t)prop->length)) {
  500. devdata->status = AVAILABLE;
  501. } else {
  502. dev_info(devdata->dev, "%s: status '%s' is not 'okay'\n",
  503. __func__, status);
  504. devdata->status = UNAVAILABLE;
  505. }
  506. return ret;
  507. }
  508. /**
  509. * nx842_OF_upd_maxsglen -- Update the device info from OF maxsglen prop
  510. *
  511. * Definition of the 'ibm,max-sg-len' OF property:
  512. * This field indicates the maximum byte length of a scatter list
  513. * for the platform facility. It is a single cell encoded as with encode-int.
  514. *
  515. * Example:
  516. * # od -x ibm,max-sg-len
  517. * 0000000 0000 0ff0
  518. *
  519. * In this example, the maximum byte length of a scatter list is
  520. * 0x0ff0 (4,080).
  521. *
  522. * @devdata - struct nx842_devdata to update
  523. * @prop - struct property point containing the maxsyncop for the update
  524. *
  525. * Returns:
  526. * 0 on success
  527. * -EINVAL on failure
  528. */
  529. static int nx842_OF_upd_maxsglen(struct nx842_devdata *devdata,
  530. struct property *prop) {
  531. int ret = 0;
  532. const unsigned int maxsglen = of_read_number(prop->value, 1);
  533. if (prop->length != sizeof(maxsglen)) {
  534. dev_err(devdata->dev, "%s: unexpected format for ibm,max-sg-len property\n", __func__);
  535. dev_dbg(devdata->dev, "%s: ibm,max-sg-len is %d bytes long, expected %lu bytes\n", __func__,
  536. prop->length, sizeof(maxsglen));
  537. ret = -EINVAL;
  538. } else {
  539. devdata->max_sg_len = min_t(unsigned int,
  540. maxsglen, NX842_HW_PAGE_SIZE);
  541. }
  542. return ret;
  543. }
  544. /**
  545. * nx842_OF_upd_maxsyncop -- Update the device info from OF maxsyncop prop
  546. *
  547. * Definition of the 'ibm,max-sync-cop' OF property:
  548. * Two series of cells. The first series of cells represents the maximums
  549. * that can be synchronously compressed. The second series of cells
  550. * represents the maximums that can be synchronously decompressed.
  551. * 1. The first cell in each series contains the count of the number of
  552. * data length, scatter list elements pairs that follow – each being
  553. * of the form
  554. * a. One cell data byte length
  555. * b. One cell total number of scatter list elements
  556. *
  557. * Example:
  558. * # od -x ibm,max-sync-cop
  559. * 0000000 0000 0001 0000 1000 0000 01fe 0000 0001
  560. * 0000020 0000 1000 0000 01fe
  561. *
  562. * In this example, compression supports 0x1000 (4,096) data byte length
  563. * and 0x1fe (510) total scatter list elements. Decompression supports
  564. * 0x1000 (4,096) data byte length and 0x1f3 (510) total scatter list
  565. * elements.
  566. *
  567. * @devdata - struct nx842_devdata to update
  568. * @prop - struct property point containing the maxsyncop for the update
  569. *
  570. * Returns:
  571. * 0 on success
  572. * -EINVAL on failure
  573. */
  574. static int nx842_OF_upd_maxsyncop(struct nx842_devdata *devdata,
  575. struct property *prop) {
  576. int ret = 0;
  577. unsigned int comp_data_limit, decomp_data_limit;
  578. unsigned int comp_sg_limit, decomp_sg_limit;
  579. const struct maxsynccop_t {
  580. __be32 comp_elements;
  581. __be32 comp_data_limit;
  582. __be32 comp_sg_limit;
  583. __be32 decomp_elements;
  584. __be32 decomp_data_limit;
  585. __be32 decomp_sg_limit;
  586. } *maxsynccop;
  587. if (prop->length != sizeof(*maxsynccop)) {
  588. dev_err(devdata->dev, "%s: unexpected format for ibm,max-sync-cop property\n", __func__);
  589. dev_dbg(devdata->dev, "%s: ibm,max-sync-cop is %d bytes long, expected %lu bytes\n", __func__, prop->length,
  590. sizeof(*maxsynccop));
  591. ret = -EINVAL;
  592. goto out;
  593. }
  594. maxsynccop = (const struct maxsynccop_t *)prop->value;
  595. comp_data_limit = be32_to_cpu(maxsynccop->comp_data_limit);
  596. comp_sg_limit = be32_to_cpu(maxsynccop->comp_sg_limit);
  597. decomp_data_limit = be32_to_cpu(maxsynccop->decomp_data_limit);
  598. decomp_sg_limit = be32_to_cpu(maxsynccop->decomp_sg_limit);
  599. /* Use one limit rather than separate limits for compression and
  600. * decompression. Set a maximum for this so as not to exceed the
  601. * size that the header can support and round the value down to
  602. * the hardware page size (4K) */
  603. devdata->max_sync_size = min(comp_data_limit, decomp_data_limit);
  604. devdata->max_sync_size = min_t(unsigned int, devdata->max_sync_size,
  605. 65536);
  606. if (devdata->max_sync_size < 4096) {
  607. dev_err(devdata->dev, "%s: hardware max data size (%u) is "
  608. "less than the driver minimum, unable to use "
  609. "the hardware device\n",
  610. __func__, devdata->max_sync_size);
  611. ret = -EINVAL;
  612. goto out;
  613. }
  614. nx842_pseries_constraints.maximum = devdata->max_sync_size;
  615. devdata->max_sync_sg = min(comp_sg_limit, decomp_sg_limit);
  616. if (devdata->max_sync_sg < 1) {
  617. dev_err(devdata->dev, "%s: hardware max sg size (%u) is "
  618. "less than the driver minimum, unable to use "
  619. "the hardware device\n",
  620. __func__, devdata->max_sync_sg);
  621. ret = -EINVAL;
  622. goto out;
  623. }
  624. out:
  625. return ret;
  626. }
  627. /**
  628. *
  629. * nx842_OF_upd -- Handle OF properties updates for the device.
  630. *
  631. * Set all properties from the OF tree. Optionally, a new property
  632. * can be provided by the @new_prop pointer to overwrite an existing value.
  633. * The device will remain disabled until all values are valid, this function
  634. * will return an error for updates unless all values are valid.
  635. *
  636. * @new_prop: If not NULL, this property is being updated. If NULL, update
  637. * all properties from the current values in the OF tree.
  638. *
  639. * Returns:
  640. * 0 - Success
  641. * -ENOMEM - Could not allocate memory for new devdata structure
  642. * -EINVAL - property value not found, new_prop is not a recognized
  643. * property for the device or property value is not valid.
  644. * -ENODEV - Device is not available
  645. */
  646. static int nx842_OF_upd(struct property *new_prop)
  647. {
  648. struct nx842_devdata *old_devdata = NULL;
  649. struct nx842_devdata *new_devdata = NULL;
  650. struct device_node *of_node = NULL;
  651. struct property *status = NULL;
  652. struct property *maxsglen = NULL;
  653. struct property *maxsyncop = NULL;
  654. int ret = 0;
  655. unsigned long flags;
  656. spin_lock_irqsave(&devdata_mutex, flags);
  657. old_devdata = rcu_dereference_check(devdata,
  658. lockdep_is_held(&devdata_mutex));
  659. if (old_devdata)
  660. of_node = old_devdata->dev->of_node;
  661. if (!old_devdata || !of_node) {
  662. pr_err("%s: device is not available\n", __func__);
  663. spin_unlock_irqrestore(&devdata_mutex, flags);
  664. return -ENODEV;
  665. }
  666. new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS);
  667. if (!new_devdata) {
  668. dev_err(old_devdata->dev, "%s: Could not allocate memory for device data\n", __func__);
  669. ret = -ENOMEM;
  670. goto error_out;
  671. }
  672. memcpy(new_devdata, old_devdata, sizeof(*old_devdata));
  673. new_devdata->counters = old_devdata->counters;
  674. /* Set ptrs for existing properties */
  675. status = of_find_property(of_node, "status", NULL);
  676. maxsglen = of_find_property(of_node, "ibm,max-sg-len", NULL);
  677. maxsyncop = of_find_property(of_node, "ibm,max-sync-cop", NULL);
  678. if (!status || !maxsglen || !maxsyncop) {
  679. dev_err(old_devdata->dev, "%s: Could not locate device properties\n", __func__);
  680. ret = -EINVAL;
  681. goto error_out;
  682. }
  683. /*
  684. * If this is a property update, there are only certain properties that
  685. * we care about. Bail if it isn't in the below list
  686. */
  687. if (new_prop && (strncmp(new_prop->name, "status", new_prop->length) ||
  688. strncmp(new_prop->name, "ibm,max-sg-len", new_prop->length) ||
  689. strncmp(new_prop->name, "ibm,max-sync-cop", new_prop->length)))
  690. goto out;
  691. /* Perform property updates */
  692. ret = nx842_OF_upd_status(new_devdata, status);
  693. if (ret)
  694. goto error_out;
  695. ret = nx842_OF_upd_maxsglen(new_devdata, maxsglen);
  696. if (ret)
  697. goto error_out;
  698. ret = nx842_OF_upd_maxsyncop(new_devdata, maxsyncop);
  699. if (ret)
  700. goto error_out;
  701. out:
  702. dev_info(old_devdata->dev, "%s: max_sync_size new:%u old:%u\n",
  703. __func__, new_devdata->max_sync_size,
  704. old_devdata->max_sync_size);
  705. dev_info(old_devdata->dev, "%s: max_sync_sg new:%u old:%u\n",
  706. __func__, new_devdata->max_sync_sg,
  707. old_devdata->max_sync_sg);
  708. dev_info(old_devdata->dev, "%s: max_sg_len new:%u old:%u\n",
  709. __func__, new_devdata->max_sg_len,
  710. old_devdata->max_sg_len);
  711. rcu_assign_pointer(devdata, new_devdata);
  712. spin_unlock_irqrestore(&devdata_mutex, flags);
  713. synchronize_rcu();
  714. dev_set_drvdata(new_devdata->dev, new_devdata);
  715. kfree(old_devdata);
  716. return 0;
  717. error_out:
  718. if (new_devdata) {
  719. dev_info(old_devdata->dev, "%s: device disabled\n", __func__);
  720. nx842_OF_set_defaults(new_devdata);
  721. rcu_assign_pointer(devdata, new_devdata);
  722. spin_unlock_irqrestore(&devdata_mutex, flags);
  723. synchronize_rcu();
  724. dev_set_drvdata(new_devdata->dev, new_devdata);
  725. kfree(old_devdata);
  726. } else {
  727. dev_err(old_devdata->dev, "%s: could not update driver from hardware\n", __func__);
  728. spin_unlock_irqrestore(&devdata_mutex, flags);
  729. }
  730. if (!ret)
  731. ret = -EINVAL;
  732. return ret;
  733. }
  734. /**
  735. * nx842_OF_notifier - Process updates to OF properties for the device
  736. *
  737. * @np: notifier block
  738. * @action: notifier action
  739. * @update: struct pSeries_reconfig_prop_update pointer if action is
  740. * PSERIES_UPDATE_PROPERTY
  741. *
  742. * Returns:
  743. * NOTIFY_OK on success
  744. * NOTIFY_BAD encoded with error number on failure, use
  745. * notifier_to_errno() to decode this value
  746. */
  747. static int nx842_OF_notifier(struct notifier_block *np, unsigned long action,
  748. void *data)
  749. {
  750. struct of_reconfig_data *upd = data;
  751. struct nx842_devdata *local_devdata;
  752. struct device_node *node = NULL;
  753. rcu_read_lock();
  754. local_devdata = rcu_dereference(devdata);
  755. if (local_devdata)
  756. node = local_devdata->dev->of_node;
  757. if (local_devdata &&
  758. action == OF_RECONFIG_UPDATE_PROPERTY &&
  759. !strcmp(upd->dn->name, node->name)) {
  760. rcu_read_unlock();
  761. nx842_OF_upd(upd->prop);
  762. } else
  763. rcu_read_unlock();
  764. return NOTIFY_OK;
  765. }
  766. static struct notifier_block nx842_of_nb = {
  767. .notifier_call = nx842_OF_notifier,
  768. };
  769. #define nx842_counter_read(_name) \
  770. static ssize_t nx842_##_name##_show(struct device *dev, \
  771. struct device_attribute *attr, \
  772. char *buf) { \
  773. struct nx842_devdata *local_devdata; \
  774. int p = 0; \
  775. rcu_read_lock(); \
  776. local_devdata = rcu_dereference(devdata); \
  777. if (local_devdata) \
  778. p = snprintf(buf, PAGE_SIZE, "%ld\n", \
  779. atomic64_read(&local_devdata->counters->_name)); \
  780. rcu_read_unlock(); \
  781. return p; \
  782. }
  783. #define NX842DEV_COUNTER_ATTR_RO(_name) \
  784. nx842_counter_read(_name); \
  785. static struct device_attribute dev_attr_##_name = __ATTR(_name, \
  786. 0444, \
  787. nx842_##_name##_show,\
  788. NULL);
  789. NX842DEV_COUNTER_ATTR_RO(comp_complete);
  790. NX842DEV_COUNTER_ATTR_RO(comp_failed);
  791. NX842DEV_COUNTER_ATTR_RO(decomp_complete);
  792. NX842DEV_COUNTER_ATTR_RO(decomp_failed);
  793. NX842DEV_COUNTER_ATTR_RO(swdecomp);
  794. static ssize_t nx842_timehist_show(struct device *,
  795. struct device_attribute *, char *);
  796. static struct device_attribute dev_attr_comp_times = __ATTR(comp_times, 0444,
  797. nx842_timehist_show, NULL);
  798. static struct device_attribute dev_attr_decomp_times = __ATTR(decomp_times,
  799. 0444, nx842_timehist_show, NULL);
  800. static ssize_t nx842_timehist_show(struct device *dev,
  801. struct device_attribute *attr, char *buf) {
  802. char *p = buf;
  803. struct nx842_devdata *local_devdata;
  804. atomic64_t *times;
  805. int bytes_remain = PAGE_SIZE;
  806. int bytes;
  807. int i;
  808. rcu_read_lock();
  809. local_devdata = rcu_dereference(devdata);
  810. if (!local_devdata) {
  811. rcu_read_unlock();
  812. return 0;
  813. }
  814. if (attr == &dev_attr_comp_times)
  815. times = local_devdata->counters->comp_times;
  816. else if (attr == &dev_attr_decomp_times)
  817. times = local_devdata->counters->decomp_times;
  818. else {
  819. rcu_read_unlock();
  820. return 0;
  821. }
  822. for (i = 0; i < (NX842_HIST_SLOTS - 2); i++) {
  823. bytes = snprintf(p, bytes_remain, "%u-%uus:\t%ld\n",
  824. i ? (2<<(i-1)) : 0, (2<<i)-1,
  825. atomic64_read(&times[i]));
  826. bytes_remain -= bytes;
  827. p += bytes;
  828. }
  829. /* The last bucket holds everything over
  830. * 2<<(NX842_HIST_SLOTS - 2) us */
  831. bytes = snprintf(p, bytes_remain, "%uus - :\t%ld\n",
  832. 2<<(NX842_HIST_SLOTS - 2),
  833. atomic64_read(&times[(NX842_HIST_SLOTS - 1)]));
  834. p += bytes;
  835. rcu_read_unlock();
  836. return p - buf;
  837. }
  838. static struct attribute *nx842_sysfs_entries[] = {
  839. &dev_attr_comp_complete.attr,
  840. &dev_attr_comp_failed.attr,
  841. &dev_attr_decomp_complete.attr,
  842. &dev_attr_decomp_failed.attr,
  843. &dev_attr_swdecomp.attr,
  844. &dev_attr_comp_times.attr,
  845. &dev_attr_decomp_times.attr,
  846. NULL,
  847. };
  848. static struct attribute_group nx842_attribute_group = {
  849. .name = NULL, /* put in device directory */
  850. .attrs = nx842_sysfs_entries,
  851. };
  852. static struct nx842_driver nx842_pseries_driver = {
  853. .name = KBUILD_MODNAME,
  854. .owner = THIS_MODULE,
  855. .workmem_size = sizeof(struct nx842_workmem),
  856. .constraints = &nx842_pseries_constraints,
  857. .compress = nx842_pseries_compress,
  858. .decompress = nx842_pseries_decompress,
  859. };
  860. static int __init nx842_probe(struct vio_dev *viodev,
  861. const struct vio_device_id *id)
  862. {
  863. struct nx842_devdata *old_devdata, *new_devdata = NULL;
  864. unsigned long flags;
  865. int ret = 0;
  866. spin_lock_irqsave(&devdata_mutex, flags);
  867. old_devdata = rcu_dereference_check(devdata,
  868. lockdep_is_held(&devdata_mutex));
  869. if (old_devdata && old_devdata->vdev != NULL) {
  870. dev_err(&viodev->dev, "%s: Attempt to register more than one instance of the hardware\n", __func__);
  871. ret = -1;
  872. goto error_unlock;
  873. }
  874. dev_set_drvdata(&viodev->dev, NULL);
  875. new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS);
  876. if (!new_devdata) {
  877. dev_err(&viodev->dev, "%s: Could not allocate memory for device data\n", __func__);
  878. ret = -ENOMEM;
  879. goto error_unlock;
  880. }
  881. new_devdata->counters = kzalloc(sizeof(*new_devdata->counters),
  882. GFP_NOFS);
  883. if (!new_devdata->counters) {
  884. dev_err(&viodev->dev, "%s: Could not allocate memory for performance counters\n", __func__);
  885. ret = -ENOMEM;
  886. goto error_unlock;
  887. }
  888. new_devdata->vdev = viodev;
  889. new_devdata->dev = &viodev->dev;
  890. nx842_OF_set_defaults(new_devdata);
  891. rcu_assign_pointer(devdata, new_devdata);
  892. spin_unlock_irqrestore(&devdata_mutex, flags);
  893. synchronize_rcu();
  894. kfree(old_devdata);
  895. of_reconfig_notifier_register(&nx842_of_nb);
  896. ret = nx842_OF_upd(NULL);
  897. if (ret && ret != -ENODEV) {
  898. dev_err(&viodev->dev, "could not parse device tree. %d\n", ret);
  899. ret = -1;
  900. goto error;
  901. }
  902. rcu_read_lock();
  903. dev_set_drvdata(&viodev->dev, rcu_dereference(devdata));
  904. rcu_read_unlock();
  905. if (sysfs_create_group(&viodev->dev.kobj, &nx842_attribute_group)) {
  906. dev_err(&viodev->dev, "could not create sysfs device attributes\n");
  907. ret = -1;
  908. goto error;
  909. }
  910. return 0;
  911. error_unlock:
  912. spin_unlock_irqrestore(&devdata_mutex, flags);
  913. if (new_devdata)
  914. kfree(new_devdata->counters);
  915. kfree(new_devdata);
  916. error:
  917. return ret;
  918. }
  919. static int __exit nx842_remove(struct vio_dev *viodev)
  920. {
  921. struct nx842_devdata *old_devdata;
  922. unsigned long flags;
  923. pr_info("Removing IBM Power 842 compression device\n");
  924. sysfs_remove_group(&viodev->dev.kobj, &nx842_attribute_group);
  925. spin_lock_irqsave(&devdata_mutex, flags);
  926. old_devdata = rcu_dereference_check(devdata,
  927. lockdep_is_held(&devdata_mutex));
  928. of_reconfig_notifier_unregister(&nx842_of_nb);
  929. RCU_INIT_POINTER(devdata, NULL);
  930. spin_unlock_irqrestore(&devdata_mutex, flags);
  931. synchronize_rcu();
  932. dev_set_drvdata(&viodev->dev, NULL);
  933. if (old_devdata)
  934. kfree(old_devdata->counters);
  935. kfree(old_devdata);
  936. return 0;
  937. }
  938. static struct vio_device_id nx842_vio_driver_ids[] = {
  939. {"ibm,compression-v1", "ibm,compression"},
  940. {"", ""},
  941. };
  942. static struct vio_driver nx842_vio_driver = {
  943. .name = KBUILD_MODNAME,
  944. .probe = nx842_probe,
  945. .remove = __exit_p(nx842_remove),
  946. .get_desired_dma = nx842_get_desired_dma,
  947. .id_table = nx842_vio_driver_ids,
  948. };
  949. static int __init nx842_init(void)
  950. {
  951. struct nx842_devdata *new_devdata;
  952. int ret;
  953. pr_info("Registering IBM Power 842 compression driver\n");
  954. if (!of_find_compatible_node(NULL, NULL, "ibm,compression"))
  955. return -ENODEV;
  956. RCU_INIT_POINTER(devdata, NULL);
  957. new_devdata = kzalloc(sizeof(*new_devdata), GFP_KERNEL);
  958. if (!new_devdata) {
  959. pr_err("Could not allocate memory for device data\n");
  960. return -ENOMEM;
  961. }
  962. new_devdata->status = UNAVAILABLE;
  963. RCU_INIT_POINTER(devdata, new_devdata);
  964. ret = vio_register_driver(&nx842_vio_driver);
  965. if (ret) {
  966. pr_err("Could not register VIO driver %d\n", ret);
  967. kfree(new_devdata);
  968. return ret;
  969. }
  970. if (!nx842_platform_driver_set(&nx842_pseries_driver)) {
  971. vio_unregister_driver(&nx842_vio_driver);
  972. kfree(new_devdata);
  973. return -EEXIST;
  974. }
  975. return 0;
  976. }
  977. module_init(nx842_init);
  978. static void __exit nx842_exit(void)
  979. {
  980. struct nx842_devdata *old_devdata;
  981. unsigned long flags;
  982. pr_info("Exiting IBM Power 842 compression driver\n");
  983. nx842_platform_driver_unset(&nx842_pseries_driver);
  984. spin_lock_irqsave(&devdata_mutex, flags);
  985. old_devdata = rcu_dereference_check(devdata,
  986. lockdep_is_held(&devdata_mutex));
  987. RCU_INIT_POINTER(devdata, NULL);
  988. spin_unlock_irqrestore(&devdata_mutex, flags);
  989. synchronize_rcu();
  990. if (old_devdata && old_devdata->dev)
  991. dev_set_drvdata(old_devdata->dev, NULL);
  992. kfree(old_devdata);
  993. vio_unregister_driver(&nx842_vio_driver);
  994. }
  995. module_exit(nx842_exit);