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

crypto: qat - add bank save and restore flows

Add logic to save, restore, quiesce and drain a ring bank for QAT GEN4
devices.
This allows to save and restore the state of a Virtual Function (VF) and
will be used to implement VM live migration.

Signed-off-by: Siming Wan <siming.wan@intel.com>
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Xin Zeng <xin.zeng@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Siming Wan and committed by
Herbert Xu
bbfdde7d 3fa1057e

+338
+2
drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c
··· 455 455 hw_data->get_ring_to_svc_map = adf_gen4_get_ring_to_svc_map; 456 456 hw_data->disable_iov = adf_disable_sriov; 457 457 hw_data->ring_pair_reset = adf_gen4_ring_pair_reset; 458 + hw_data->bank_state_save = adf_gen4_bank_state_save; 459 + hw_data->bank_state_restore = adf_gen4_bank_state_restore; 458 460 hw_data->enable_pm = adf_gen4_enable_pm; 459 461 hw_data->handle_pm_interrupt = adf_gen4_handle_pm_interrupt; 460 462 hw_data->dev_config = adf_gen4_dev_config;
+38
drivers/crypto/intel/qat/qat_common/adf_accel_devices.h
··· 140 140 u32 mailbox_offset; 141 141 }; 142 142 143 + struct ring_config { 144 + u64 base; 145 + u32 config; 146 + u32 head; 147 + u32 tail; 148 + u32 reserved0; 149 + }; 150 + 151 + struct bank_state { 152 + u32 ringstat0; 153 + u32 ringstat1; 154 + u32 ringuostat; 155 + u32 ringestat; 156 + u32 ringnestat; 157 + u32 ringnfstat; 158 + u32 ringfstat; 159 + u32 ringcstat0; 160 + u32 ringcstat1; 161 + u32 ringcstat2; 162 + u32 ringcstat3; 163 + u32 iaintflagen; 164 + u32 iaintflagreg; 165 + u32 iaintflagsrcsel0; 166 + u32 iaintflagsrcsel1; 167 + u32 iaintcolen; 168 + u32 iaintcolctl; 169 + u32 iaintflagandcolen; 170 + u32 ringexpstat; 171 + u32 ringexpintenable; 172 + u32 ringsrvarben; 173 + u32 reserved0; 174 + struct ring_config rings[ADF_ETR_MAX_RINGS_PER_BANK]; 175 + }; 176 + 143 177 struct adf_hw_csr_ops { 144 178 u64 (*build_csr_ring_base_addr)(dma_addr_t addr, u32 size); 145 179 u32 (*read_csr_ring_head)(void __iomem *csr_base_addr, u32 bank, ··· 305 271 void (*enable_ints)(struct adf_accel_dev *accel_dev); 306 272 void (*set_ssm_wdtimer)(struct adf_accel_dev *accel_dev); 307 273 int (*ring_pair_reset)(struct adf_accel_dev *accel_dev, u32 bank_nr); 274 + int (*bank_state_save)(struct adf_accel_dev *accel_dev, u32 bank_number, 275 + struct bank_state *state); 276 + int (*bank_state_restore)(struct adf_accel_dev *accel_dev, 277 + u32 bank_number, struct bank_state *state); 308 278 void (*reset_device)(struct adf_accel_dev *accel_dev); 309 279 void (*set_msix_rttable)(struct adf_accel_dev *accel_dev); 310 280 const char *(*uof_get_name)(struct adf_accel_dev *accel_dev, u32 obj_num);
+279
drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c
··· 1 1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) 2 2 /* Copyright(c) 2020 Intel Corporation */ 3 3 #include <linux/iopoll.h> 4 + #include <asm/div64.h> 4 5 #include "adf_accel_devices.h" 5 6 #include "adf_cfg_services.h" 6 7 #include "adf_common_drv.h" ··· 391 390 return ring_to_svc_map; 392 391 } 393 392 EXPORT_SYMBOL_GPL(adf_gen4_get_ring_to_svc_map); 393 + 394 + /* 395 + * adf_gen4_bank_quiesce_coal_timer() - quiesce bank coalesced interrupt timer 396 + * @accel_dev: Pointer to the device structure 397 + * @bank_idx: Offset to the bank within this device 398 + * @timeout_ms: Timeout in milliseconds for the operation 399 + * 400 + * This function tries to quiesce the coalesced interrupt timer of a bank if 401 + * it has been enabled and triggered. 402 + * 403 + * Returns 0 on success, error code otherwise 404 + * 405 + */ 406 + int adf_gen4_bank_quiesce_coal_timer(struct adf_accel_dev *accel_dev, 407 + u32 bank_idx, int timeout_ms) 408 + { 409 + struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev); 410 + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); 411 + void __iomem *csr_misc = adf_get_pmisc_base(accel_dev); 412 + void __iomem *csr_etr = adf_get_etr_base(accel_dev); 413 + u32 int_col_ctl, int_col_mask, int_col_en; 414 + u32 e_stat, intsrc; 415 + u64 wait_us; 416 + int ret; 417 + 418 + if (timeout_ms < 0) 419 + return -EINVAL; 420 + 421 + int_col_ctl = csr_ops->read_csr_int_col_ctl(csr_etr, bank_idx); 422 + int_col_mask = csr_ops->get_int_col_ctl_enable_mask(); 423 + if (!(int_col_ctl & int_col_mask)) 424 + return 0; 425 + 426 + int_col_en = csr_ops->read_csr_int_col_en(csr_etr, bank_idx); 427 + int_col_en &= BIT(ADF_WQM_CSR_RP_IDX_RX); 428 + 429 + e_stat = csr_ops->read_csr_e_stat(csr_etr, bank_idx); 430 + if (!(~e_stat & int_col_en)) 431 + return 0; 432 + 433 + wait_us = 2 * ((int_col_ctl & ~int_col_mask) << 8) * USEC_PER_SEC; 434 + do_div(wait_us, hw_data->clock_frequency); 435 + wait_us = min(wait_us, (u64)timeout_ms * USEC_PER_MSEC); 436 + dev_dbg(&GET_DEV(accel_dev), 437 + "wait for bank %d - coalesced timer expires in %llu us (max=%u ms estat=0x%x intcolen=0x%x)\n", 438 + bank_idx, wait_us, timeout_ms, e_stat, int_col_en); 439 + 440 + ret = read_poll_timeout(ADF_CSR_RD, intsrc, intsrc, 441 + ADF_COALESCED_POLL_DELAY_US, wait_us, true, 442 + csr_misc, ADF_WQM_CSR_RPINTSOU(bank_idx)); 443 + if (ret) 444 + dev_warn(&GET_DEV(accel_dev), 445 + "coalesced timer for bank %d expired (%llu us)\n", 446 + bank_idx, wait_us); 447 + 448 + return ret; 449 + } 450 + EXPORT_SYMBOL_GPL(adf_gen4_bank_quiesce_coal_timer); 451 + 452 + static int drain_bank(void __iomem *csr, u32 bank_number, int timeout_us) 453 + { 454 + u32 status; 455 + 456 + ADF_CSR_WR(csr, ADF_WQM_CSR_RPRESETCTL(bank_number), 457 + ADF_WQM_CSR_RPRESETCTL_DRAIN); 458 + 459 + return read_poll_timeout(ADF_CSR_RD, status, 460 + status & ADF_WQM_CSR_RPRESETSTS_STATUS, 461 + ADF_RPRESET_POLL_DELAY_US, timeout_us, true, 462 + csr, ADF_WQM_CSR_RPRESETSTS(bank_number)); 463 + } 464 + 465 + void adf_gen4_bank_drain_finish(struct adf_accel_dev *accel_dev, 466 + u32 bank_number) 467 + { 468 + void __iomem *csr = adf_get_etr_base(accel_dev); 469 + 470 + ADF_CSR_WR(csr, ADF_WQM_CSR_RPRESETSTS(bank_number), 471 + ADF_WQM_CSR_RPRESETSTS_STATUS); 472 + } 473 + 474 + int adf_gen4_bank_drain_start(struct adf_accel_dev *accel_dev, 475 + u32 bank_number, int timeout_us) 476 + { 477 + void __iomem *csr = adf_get_etr_base(accel_dev); 478 + int ret; 479 + 480 + dev_dbg(&GET_DEV(accel_dev), "Drain bank %d\n", bank_number); 481 + 482 + ret = drain_bank(csr, bank_number, timeout_us); 483 + if (ret) 484 + dev_err(&GET_DEV(accel_dev), "Bank drain failed (timeout)\n"); 485 + else 486 + dev_dbg(&GET_DEV(accel_dev), "Bank drain successful\n"); 487 + 488 + return ret; 489 + } 490 + 491 + static void bank_state_save(struct adf_hw_csr_ops *ops, void __iomem *base, 492 + u32 bank, struct bank_state *state, u32 num_rings) 493 + { 494 + u32 i; 495 + 496 + state->ringstat0 = ops->read_csr_stat(base, bank); 497 + state->ringuostat = ops->read_csr_uo_stat(base, bank); 498 + state->ringestat = ops->read_csr_e_stat(base, bank); 499 + state->ringnestat = ops->read_csr_ne_stat(base, bank); 500 + state->ringnfstat = ops->read_csr_nf_stat(base, bank); 501 + state->ringfstat = ops->read_csr_f_stat(base, bank); 502 + state->ringcstat0 = ops->read_csr_c_stat(base, bank); 503 + state->iaintflagen = ops->read_csr_int_en(base, bank); 504 + state->iaintflagreg = ops->read_csr_int_flag(base, bank); 505 + state->iaintflagsrcsel0 = ops->read_csr_int_srcsel(base, bank); 506 + state->iaintcolen = ops->read_csr_int_col_en(base, bank); 507 + state->iaintcolctl = ops->read_csr_int_col_ctl(base, bank); 508 + state->iaintflagandcolen = ops->read_csr_int_flag_and_col(base, bank); 509 + state->ringexpstat = ops->read_csr_exp_stat(base, bank); 510 + state->ringexpintenable = ops->read_csr_exp_int_en(base, bank); 511 + state->ringsrvarben = ops->read_csr_ring_srv_arb_en(base, bank); 512 + 513 + for (i = 0; i < num_rings; i++) { 514 + state->rings[i].head = ops->read_csr_ring_head(base, bank, i); 515 + state->rings[i].tail = ops->read_csr_ring_tail(base, bank, i); 516 + state->rings[i].config = ops->read_csr_ring_config(base, bank, i); 517 + state->rings[i].base = ops->read_csr_ring_base(base, bank, i); 518 + } 519 + } 520 + 521 + #define CHECK_STAT(op, expect_val, name, args...) \ 522 + ({ \ 523 + u32 __expect_val = (expect_val); \ 524 + u32 actual_val = op(args); \ 525 + (__expect_val == actual_val) ? 0 : \ 526 + (pr_err("QAT: Fail to restore %s register. Expected 0x%x, actual 0x%x\n", \ 527 + name, __expect_val, actual_val), -EINVAL); \ 528 + }) 529 + 530 + static int bank_state_restore(struct adf_hw_csr_ops *ops, void __iomem *base, 531 + u32 bank, struct bank_state *state, u32 num_rings, 532 + int tx_rx_gap) 533 + { 534 + u32 val, tmp_val, i; 535 + int ret; 536 + 537 + for (i = 0; i < num_rings; i++) 538 + ops->write_csr_ring_base(base, bank, i, state->rings[i].base); 539 + 540 + for (i = 0; i < num_rings; i++) 541 + ops->write_csr_ring_config(base, bank, i, state->rings[i].config); 542 + 543 + for (i = 0; i < num_rings / 2; i++) { 544 + int tx = i * (tx_rx_gap + 1); 545 + int rx = tx + tx_rx_gap; 546 + 547 + ops->write_csr_ring_head(base, bank, tx, state->rings[tx].head); 548 + ops->write_csr_ring_tail(base, bank, tx, state->rings[tx].tail); 549 + 550 + /* 551 + * The TX ring head needs to be updated again to make sure that 552 + * the HW will not consider the ring as full when it is empty 553 + * and the correct state flags are set to match the recovered state. 554 + */ 555 + if (state->ringestat & BIT(tx)) { 556 + val = ops->read_csr_int_srcsel(base, bank); 557 + val |= ADF_RP_INT_SRC_SEL_F_RISE_MASK; 558 + ops->write_csr_int_srcsel_w_val(base, bank, val); 559 + ops->write_csr_ring_head(base, bank, tx, state->rings[tx].head); 560 + } 561 + 562 + ops->write_csr_ring_tail(base, bank, rx, state->rings[rx].tail); 563 + val = ops->read_csr_int_srcsel(base, bank); 564 + val |= ADF_RP_INT_SRC_SEL_F_RISE_MASK << ADF_RP_INT_SRC_SEL_RANGE_WIDTH; 565 + ops->write_csr_int_srcsel_w_val(base, bank, val); 566 + 567 + ops->write_csr_ring_head(base, bank, rx, state->rings[rx].head); 568 + val = ops->read_csr_int_srcsel(base, bank); 569 + val |= ADF_RP_INT_SRC_SEL_F_FALL_MASK << ADF_RP_INT_SRC_SEL_RANGE_WIDTH; 570 + ops->write_csr_int_srcsel_w_val(base, bank, val); 571 + 572 + /* 573 + * The RX ring tail needs to be updated again to make sure that 574 + * the HW will not consider the ring as empty when it is full 575 + * and the correct state flags are set to match the recovered state. 576 + */ 577 + if (state->ringfstat & BIT(rx)) 578 + ops->write_csr_ring_tail(base, bank, rx, state->rings[rx].tail); 579 + } 580 + 581 + ops->write_csr_int_flag_and_col(base, bank, state->iaintflagandcolen); 582 + ops->write_csr_int_en(base, bank, state->iaintflagen); 583 + ops->write_csr_int_col_en(base, bank, state->iaintcolen); 584 + ops->write_csr_int_srcsel_w_val(base, bank, state->iaintflagsrcsel0); 585 + ops->write_csr_exp_int_en(base, bank, state->ringexpintenable); 586 + ops->write_csr_int_col_ctl(base, bank, state->iaintcolctl); 587 + ops->write_csr_ring_srv_arb_en(base, bank, state->ringsrvarben); 588 + 589 + /* Check that all ring statuses match the saved state. */ 590 + ret = CHECK_STAT(ops->read_csr_stat, state->ringstat0, "ringstat", 591 + base, bank); 592 + if (ret) 593 + return ret; 594 + 595 + ret = CHECK_STAT(ops->read_csr_e_stat, state->ringestat, "ringestat", 596 + base, bank); 597 + if (ret) 598 + return ret; 599 + 600 + ret = CHECK_STAT(ops->read_csr_ne_stat, state->ringnestat, "ringnestat", 601 + base, bank); 602 + if (ret) 603 + return ret; 604 + 605 + ret = CHECK_STAT(ops->read_csr_nf_stat, state->ringnfstat, "ringnfstat", 606 + base, bank); 607 + if (ret) 608 + return ret; 609 + 610 + ret = CHECK_STAT(ops->read_csr_f_stat, state->ringfstat, "ringfstat", 611 + base, bank); 612 + if (ret) 613 + return ret; 614 + 615 + ret = CHECK_STAT(ops->read_csr_c_stat, state->ringcstat0, "ringcstat", 616 + base, bank); 617 + if (ret) 618 + return ret; 619 + 620 + tmp_val = ops->read_csr_exp_stat(base, bank); 621 + val = state->ringexpstat; 622 + if (tmp_val && !val) { 623 + pr_err("QAT: Bank was restored with exception: 0x%x\n", val); 624 + return -EINVAL; 625 + } 626 + 627 + return 0; 628 + } 629 + 630 + int adf_gen4_bank_state_save(struct adf_accel_dev *accel_dev, u32 bank_number, 631 + struct bank_state *state) 632 + { 633 + struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev); 634 + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); 635 + void __iomem *csr_base = adf_get_etr_base(accel_dev); 636 + 637 + if (bank_number >= hw_data->num_banks || !state) 638 + return -EINVAL; 639 + 640 + dev_dbg(&GET_DEV(accel_dev), "Saving state of bank %d\n", bank_number); 641 + 642 + bank_state_save(csr_ops, csr_base, bank_number, state, 643 + hw_data->num_rings_per_bank); 644 + 645 + return 0; 646 + } 647 + EXPORT_SYMBOL_GPL(adf_gen4_bank_state_save); 648 + 649 + int adf_gen4_bank_state_restore(struct adf_accel_dev *accel_dev, u32 bank_number, 650 + struct bank_state *state) 651 + { 652 + struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev); 653 + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); 654 + void __iomem *csr_base = adf_get_etr_base(accel_dev); 655 + int ret; 656 + 657 + if (bank_number >= hw_data->num_banks || !state) 658 + return -EINVAL; 659 + 660 + dev_dbg(&GET_DEV(accel_dev), "Restoring state of bank %d\n", bank_number); 661 + 662 + ret = bank_state_restore(csr_ops, csr_base, bank_number, state, 663 + hw_data->num_rings_per_bank, hw_data->tx_rx_gap); 664 + if (ret) 665 + dev_err(&GET_DEV(accel_dev), 666 + "Unable to restore state of bank %d\n", bank_number); 667 + 668 + return ret; 669 + } 670 + EXPORT_SYMBOL_GPL(adf_gen4_bank_state_restore);
+19
drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h
··· 77 77 #define ADF_RPRESET_POLL_TIMEOUT_US (5 * USEC_PER_SEC) 78 78 #define ADF_RPRESET_POLL_DELAY_US 20 79 79 #define ADF_WQM_CSR_RPRESETCTL_RESET BIT(0) 80 + #define ADF_WQM_CSR_RPRESETCTL_DRAIN BIT(2) 80 81 #define ADF_WQM_CSR_RPRESETCTL(bank) (0x6000 + ((bank) << 3)) 81 82 #define ADF_WQM_CSR_RPRESETSTS_STATUS BIT(0) 82 83 #define ADF_WQM_CSR_RPRESETSTS(bank) (ADF_WQM_CSR_RPRESETCTL(bank) + 4) 84 + 85 + /* Ring interrupt */ 86 + #define ADF_RP_INT_SRC_SEL_F_RISE_MASK BIT(2) 87 + #define ADF_RP_INT_SRC_SEL_F_FALL_MASK GENMASK(2, 0) 88 + #define ADF_RP_INT_SRC_SEL_RANGE_WIDTH 4 89 + #define ADF_COALESCED_POLL_DELAY_US 1000 90 + #define ADF_WQM_CSR_RPINTSOU(bank) (0x200000 + ((bank) << 12)) 91 + #define ADF_WQM_CSR_RP_IDX_RX 1 83 92 84 93 /* Error source registers */ 85 94 #define ADF_GEN4_ERRSOU0 (0x41A200) ··· 159 150 void adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev); 160 151 int adf_gen4_init_thd2arb_map(struct adf_accel_dev *accel_dev); 161 152 u16 adf_gen4_get_ring_to_svc_map(struct adf_accel_dev *accel_dev); 153 + int adf_gen4_bank_quiesce_coal_timer(struct adf_accel_dev *accel_dev, 154 + u32 bank_idx, int timeout_ms); 155 + int adf_gen4_bank_drain_start(struct adf_accel_dev *accel_dev, 156 + u32 bank_number, int timeout_us); 157 + void adf_gen4_bank_drain_finish(struct adf_accel_dev *accel_dev, 158 + u32 bank_number); 159 + int adf_gen4_bank_state_save(struct adf_accel_dev *accel_dev, u32 bank_number, 160 + struct bank_state *state); 161 + int adf_gen4_bank_state_restore(struct adf_accel_dev *accel_dev, 162 + u32 bank_number, struct bank_state *state); 162 163 163 164 #endif