Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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