| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Huawei HiNIC PCI Express Linux driver |
|---|
| 3 | 4 | * Copyright(c) 2017 Huawei Technologies Co., Ltd |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 7 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|---|
| 12 | | - * for more details. |
|---|
| 13 | | - * |
|---|
| 14 | 5 | */ |
|---|
| 15 | 6 | |
|---|
| 16 | 7 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 26 | 17 | #include <asm/byteorder.h> |
|---|
| 27 | 18 | #include <asm/barrier.h> |
|---|
| 28 | 19 | |
|---|
| 20 | +#include "hinic_hw_dev.h" |
|---|
| 29 | 21 | #include "hinic_hw_csr.h" |
|---|
| 30 | 22 | #include "hinic_hw_if.h" |
|---|
| 31 | 23 | #include "hinic_hw_eqs.h" |
|---|
| .. | .. |
|---|
| 114 | 106 | * @aeqs: pointer to Async eqs of the chip |
|---|
| 115 | 107 | * @event: aeq event to register callback for it |
|---|
| 116 | 108 | * @handle: private data will be used by the callback |
|---|
| 117 | | - * @hw_handler: callback function |
|---|
| 109 | + * @hwe_handler: callback function |
|---|
| 118 | 110 | **/ |
|---|
| 119 | 111 | void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs, |
|---|
| 120 | 112 | enum hinic_aeq_type event, void *handle, |
|---|
| .. | .. |
|---|
| 196 | 188 | /** |
|---|
| 197 | 189 | * eq_update_ci - update the HW cons idx of event queue |
|---|
| 198 | 190 | * @eq: the event queue to update the cons idx for |
|---|
| 191 | + * @arm_state: the arm bit value of eq's interrupt |
|---|
| 199 | 192 | **/ |
|---|
| 200 | | -static void eq_update_ci(struct hinic_eq *eq) |
|---|
| 193 | +static void eq_update_ci(struct hinic_eq *eq, u32 arm_state) |
|---|
| 201 | 194 | { |
|---|
| 202 | 195 | u32 val, addr = EQ_CONS_IDX_REG_ADDR(eq); |
|---|
| 203 | 196 | |
|---|
| .. | .. |
|---|
| 211 | 204 | |
|---|
| 212 | 205 | val |= HINIC_EQ_CI_SET(eq->cons_idx, IDX) | |
|---|
| 213 | 206 | HINIC_EQ_CI_SET(eq->wrapped, WRAPPED) | |
|---|
| 214 | | - HINIC_EQ_CI_SET(EQ_ARMED, INT_ARMED); |
|---|
| 207 | + HINIC_EQ_CI_SET(arm_state, INT_ARMED); |
|---|
| 215 | 208 | |
|---|
| 216 | 209 | val |= HINIC_EQ_CI_SET(eq_cons_idx_checksum_set(val), XOR_CHKSUM); |
|---|
| 217 | 210 | |
|---|
| .. | .. |
|---|
| 243 | 236 | /* HW toggles the wrapped bit, when it adds eq element */ |
|---|
| 244 | 237 | if (HINIC_EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) == eq->wrapped) |
|---|
| 245 | 238 | break; |
|---|
| 239 | + |
|---|
| 240 | + dma_rmb(); |
|---|
| 246 | 241 | |
|---|
| 247 | 242 | event = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, TYPE); |
|---|
| 248 | 243 | if (event >= HINIC_MAX_AEQ_EVENTS) { |
|---|
| .. | .. |
|---|
| 356 | 351 | else if (eq->type == HINIC_CEQ) |
|---|
| 357 | 352 | ceq_irq_handler(eq); |
|---|
| 358 | 353 | |
|---|
| 359 | | - eq_update_ci(eq); |
|---|
| 354 | + eq_update_ci(eq, EQ_ARMED); |
|---|
| 360 | 355 | } |
|---|
| 361 | 356 | |
|---|
| 362 | 357 | /** |
|---|
| .. | .. |
|---|
| 374 | 369 | |
|---|
| 375 | 370 | /** |
|---|
| 376 | 371 | * ceq_tasklet - the tasklet of the EQ that received the event |
|---|
| 377 | | - * @ceq_data: the eq |
|---|
| 372 | + * @t: the tasklet struct pointer |
|---|
| 378 | 373 | **/ |
|---|
| 379 | | -static void ceq_tasklet(unsigned long ceq_data) |
|---|
| 374 | +static void ceq_tasklet(struct tasklet_struct *t) |
|---|
| 380 | 375 | { |
|---|
| 381 | | - struct hinic_eq *ceq = (struct hinic_eq *)ceq_data; |
|---|
| 376 | + struct hinic_eq *ceq = from_tasklet(ceq, t, ceq_tasklet); |
|---|
| 382 | 377 | |
|---|
| 383 | 378 | eq_irq_handler(ceq); |
|---|
| 384 | 379 | } |
|---|
| .. | .. |
|---|
| 423 | 418 | return IRQ_HANDLED; |
|---|
| 424 | 419 | } |
|---|
| 425 | 420 | |
|---|
| 426 | | -static void set_ctrl0(struct hinic_eq *eq) |
|---|
| 421 | +static u32 get_ctrl0_val(struct hinic_eq *eq, u32 addr) |
|---|
| 427 | 422 | { |
|---|
| 428 | 423 | struct msix_entry *msix_entry = &eq->msix_entry; |
|---|
| 429 | 424 | enum hinic_eq_type type = eq->type; |
|---|
| 430 | | - u32 addr, val, ctrl0; |
|---|
| 425 | + u32 val, ctrl0; |
|---|
| 431 | 426 | |
|---|
| 432 | 427 | if (type == HINIC_AEQ) { |
|---|
| 433 | 428 | /* RMW Ctrl0 */ |
|---|
| .. | .. |
|---|
| 447 | 442 | HINIC_AEQ_CTRL_0_SET(EQ_INT_MODE_ARMED, INT_MODE); |
|---|
| 448 | 443 | |
|---|
| 449 | 444 | val |= ctrl0; |
|---|
| 450 | | - |
|---|
| 451 | | - hinic_hwif_write_reg(eq->hwif, addr, val); |
|---|
| 452 | | - } else if (type == HINIC_CEQ) { |
|---|
| 445 | + } else { |
|---|
| 453 | 446 | /* RMW Ctrl0 */ |
|---|
| 454 | 447 | addr = HINIC_CSR_CEQ_CTRL_0_ADDR(eq->q_id); |
|---|
| 455 | 448 | |
|---|
| .. | .. |
|---|
| 469 | 462 | HINIC_CEQ_CTRL_0_SET(EQ_INT_MODE_ARMED, INTR_MODE); |
|---|
| 470 | 463 | |
|---|
| 471 | 464 | val |= ctrl0; |
|---|
| 472 | | - |
|---|
| 473 | | - hinic_hwif_write_reg(eq->hwif, addr, val); |
|---|
| 474 | 465 | } |
|---|
| 466 | + return val; |
|---|
| 475 | 467 | } |
|---|
| 476 | 468 | |
|---|
| 477 | | -static void set_ctrl1(struct hinic_eq *eq) |
|---|
| 469 | +static void set_ctrl0(struct hinic_eq *eq) |
|---|
| 478 | 470 | { |
|---|
| 471 | + u32 val, addr; |
|---|
| 472 | + |
|---|
| 473 | + if (eq->type == HINIC_AEQ) |
|---|
| 474 | + addr = HINIC_CSR_AEQ_CTRL_0_ADDR(eq->q_id); |
|---|
| 475 | + else |
|---|
| 476 | + addr = HINIC_CSR_CEQ_CTRL_0_ADDR(eq->q_id); |
|---|
| 477 | + |
|---|
| 478 | + val = get_ctrl0_val(eq, addr); |
|---|
| 479 | + |
|---|
| 480 | + hinic_hwif_write_reg(eq->hwif, addr, val); |
|---|
| 481 | +} |
|---|
| 482 | + |
|---|
| 483 | +static u32 get_ctrl1_val(struct hinic_eq *eq, u32 addr) |
|---|
| 484 | +{ |
|---|
| 485 | + u32 page_size_val, elem_size, val, ctrl1; |
|---|
| 479 | 486 | enum hinic_eq_type type = eq->type; |
|---|
| 480 | | - u32 page_size_val, elem_size; |
|---|
| 481 | | - u32 addr, val, ctrl1; |
|---|
| 482 | 487 | |
|---|
| 483 | 488 | if (type == HINIC_AEQ) { |
|---|
| 484 | 489 | /* RMW Ctrl1 */ |
|---|
| .. | .. |
|---|
| 498 | 503 | HINIC_AEQ_CTRL_1_SET(page_size_val, PAGE_SIZE); |
|---|
| 499 | 504 | |
|---|
| 500 | 505 | val |= ctrl1; |
|---|
| 501 | | - |
|---|
| 502 | | - hinic_hwif_write_reg(eq->hwif, addr, val); |
|---|
| 503 | | - } else if (type == HINIC_CEQ) { |
|---|
| 506 | + } else { |
|---|
| 504 | 507 | /* RMW Ctrl1 */ |
|---|
| 505 | 508 | addr = HINIC_CSR_CEQ_CTRL_1_ADDR(eq->q_id); |
|---|
| 506 | 509 | |
|---|
| .. | .. |
|---|
| 515 | 518 | HINIC_CEQ_CTRL_1_SET(page_size_val, PAGE_SIZE); |
|---|
| 516 | 519 | |
|---|
| 517 | 520 | val |= ctrl1; |
|---|
| 518 | | - |
|---|
| 519 | | - hinic_hwif_write_reg(eq->hwif, addr, val); |
|---|
| 520 | 521 | } |
|---|
| 522 | + return val; |
|---|
| 523 | +} |
|---|
| 524 | + |
|---|
| 525 | +static void set_ctrl1(struct hinic_eq *eq) |
|---|
| 526 | +{ |
|---|
| 527 | + u32 addr, val; |
|---|
| 528 | + |
|---|
| 529 | + if (eq->type == HINIC_AEQ) |
|---|
| 530 | + addr = HINIC_CSR_AEQ_CTRL_1_ADDR(eq->q_id); |
|---|
| 531 | + else |
|---|
| 532 | + addr = HINIC_CSR_CEQ_CTRL_1_ADDR(eq->q_id); |
|---|
| 533 | + |
|---|
| 534 | + val = get_ctrl1_val(eq, addr); |
|---|
| 535 | + |
|---|
| 536 | + hinic_hwif_write_reg(eq->hwif, addr, val); |
|---|
| 537 | +} |
|---|
| 538 | + |
|---|
| 539 | +static int set_ceq_ctrl_reg(struct hinic_eq *eq) |
|---|
| 540 | +{ |
|---|
| 541 | + struct hinic_ceq_ctrl_reg ceq_ctrl = {0}; |
|---|
| 542 | + struct hinic_hwdev *hwdev = eq->hwdev; |
|---|
| 543 | + u16 out_size = sizeof(ceq_ctrl); |
|---|
| 544 | + u16 in_size = sizeof(ceq_ctrl); |
|---|
| 545 | + struct hinic_pfhwdev *pfhwdev; |
|---|
| 546 | + u32 addr; |
|---|
| 547 | + int err; |
|---|
| 548 | + |
|---|
| 549 | + pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
|---|
| 550 | + |
|---|
| 551 | + addr = HINIC_CSR_CEQ_CTRL_0_ADDR(eq->q_id); |
|---|
| 552 | + ceq_ctrl.ctrl0 = get_ctrl0_val(eq, addr); |
|---|
| 553 | + addr = HINIC_CSR_CEQ_CTRL_1_ADDR(eq->q_id); |
|---|
| 554 | + ceq_ctrl.ctrl1 = get_ctrl1_val(eq, addr); |
|---|
| 555 | + |
|---|
| 556 | + ceq_ctrl.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); |
|---|
| 557 | + ceq_ctrl.q_id = eq->q_id; |
|---|
| 558 | + |
|---|
| 559 | + err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, |
|---|
| 560 | + HINIC_COMM_CMD_CEQ_CTRL_REG_WR_BY_UP, |
|---|
| 561 | + &ceq_ctrl, in_size, |
|---|
| 562 | + &ceq_ctrl, &out_size, HINIC_MGMT_MSG_SYNC); |
|---|
| 563 | + if (err || !out_size || ceq_ctrl.status) { |
|---|
| 564 | + dev_err(&hwdev->hwif->pdev->dev, |
|---|
| 565 | + "Failed to set ceq %d ctrl reg, err: %d status: 0x%x, out_size: 0x%x\n", |
|---|
| 566 | + eq->q_id, err, ceq_ctrl.status, out_size); |
|---|
| 567 | + return -EFAULT; |
|---|
| 568 | + } |
|---|
| 569 | + |
|---|
| 570 | + return 0; |
|---|
| 521 | 571 | } |
|---|
| 522 | 572 | |
|---|
| 523 | 573 | /** |
|---|
| 524 | 574 | * set_eq_ctrls - setting eq's ctrl registers |
|---|
| 525 | 575 | * @eq: the Event Queue for setting |
|---|
| 526 | 576 | **/ |
|---|
| 527 | | -static void set_eq_ctrls(struct hinic_eq *eq) |
|---|
| 577 | +static int set_eq_ctrls(struct hinic_eq *eq) |
|---|
| 528 | 578 | { |
|---|
| 579 | + if (HINIC_IS_VF(eq->hwif) && eq->type == HINIC_CEQ) |
|---|
| 580 | + return set_ceq_ctrl_reg(eq); |
|---|
| 581 | + |
|---|
| 529 | 582 | set_ctrl0(eq); |
|---|
| 530 | 583 | set_ctrl1(eq); |
|---|
| 584 | + return 0; |
|---|
| 531 | 585 | } |
|---|
| 532 | 586 | |
|---|
| 533 | 587 | /** |
|---|
| .. | .. |
|---|
| 577 | 631 | struct hinic_hwif *hwif = eq->hwif; |
|---|
| 578 | 632 | struct pci_dev *pdev = hwif->pdev; |
|---|
| 579 | 633 | u32 init_val, addr, val; |
|---|
| 580 | | - size_t addr_size; |
|---|
| 581 | 634 | int err, pg; |
|---|
| 582 | 635 | |
|---|
| 583 | | - addr_size = eq->num_pages * sizeof(*eq->dma_addr); |
|---|
| 584 | | - eq->dma_addr = devm_kzalloc(&pdev->dev, addr_size, GFP_KERNEL); |
|---|
| 636 | + eq->dma_addr = devm_kcalloc(&pdev->dev, eq->num_pages, |
|---|
| 637 | + sizeof(*eq->dma_addr), GFP_KERNEL); |
|---|
| 585 | 638 | if (!eq->dma_addr) |
|---|
| 586 | 639 | return -ENOMEM; |
|---|
| 587 | 640 | |
|---|
| 588 | | - addr_size = eq->num_pages * sizeof(*eq->virt_addr); |
|---|
| 589 | | - eq->virt_addr = devm_kzalloc(&pdev->dev, addr_size, GFP_KERNEL); |
|---|
| 641 | + eq->virt_addr = devm_kcalloc(&pdev->dev, eq->num_pages, |
|---|
| 642 | + sizeof(*eq->virt_addr), GFP_KERNEL); |
|---|
| 590 | 643 | if (!eq->virt_addr) { |
|---|
| 591 | 644 | err = -ENOMEM; |
|---|
| 592 | 645 | goto err_virt_addr_alloc; |
|---|
| 593 | 646 | } |
|---|
| 594 | 647 | |
|---|
| 595 | 648 | for (pg = 0; pg < eq->num_pages; pg++) { |
|---|
| 596 | | - eq->virt_addr[pg] = dma_zalloc_coherent(&pdev->dev, |
|---|
| 597 | | - eq->page_size, |
|---|
| 598 | | - &eq->dma_addr[pg], |
|---|
| 599 | | - GFP_KERNEL); |
|---|
| 649 | + eq->virt_addr[pg] = dma_alloc_coherent(&pdev->dev, |
|---|
| 650 | + eq->page_size, |
|---|
| 651 | + &eq->dma_addr[pg], |
|---|
| 652 | + GFP_KERNEL); |
|---|
| 600 | 653 | if (!eq->virt_addr[pg]) { |
|---|
| 601 | 654 | err = -ENOMEM; |
|---|
| 602 | 655 | goto err_dma_alloc; |
|---|
| .. | .. |
|---|
| 710 | 763 | return -EINVAL; |
|---|
| 711 | 764 | } |
|---|
| 712 | 765 | |
|---|
| 713 | | - set_eq_ctrls(eq); |
|---|
| 714 | | - eq_update_ci(eq); |
|---|
| 766 | + err = set_eq_ctrls(eq); |
|---|
| 767 | + if (err) { |
|---|
| 768 | + dev_err(&pdev->dev, "Failed to set eq ctrls\n"); |
|---|
| 769 | + return err; |
|---|
| 770 | + } |
|---|
| 771 | + |
|---|
| 772 | + eq_update_ci(eq, EQ_ARMED); |
|---|
| 715 | 773 | |
|---|
| 716 | 774 | err = alloc_eq_pages(eq); |
|---|
| 717 | 775 | if (err) { |
|---|
| .. | .. |
|---|
| 724 | 782 | |
|---|
| 725 | 783 | INIT_WORK(&aeq_work->work, eq_irq_work); |
|---|
| 726 | 784 | } else if (type == HINIC_CEQ) { |
|---|
| 727 | | - tasklet_init(&eq->ceq_tasklet, ceq_tasklet, |
|---|
| 728 | | - (unsigned long)eq); |
|---|
| 785 | + tasklet_setup(&eq->ceq_tasklet, ceq_tasklet); |
|---|
| 729 | 786 | } |
|---|
| 730 | 787 | |
|---|
| 731 | 788 | /* set the attributes of the msix entry */ |
|---|
| .. | .. |
|---|
| 736 | 793 | HINIC_EQ_MSIX_LLI_CREDIT_LIMIT_DEFAULT, |
|---|
| 737 | 794 | HINIC_EQ_MSIX_RESEND_TIMER_DEFAULT); |
|---|
| 738 | 795 | |
|---|
| 739 | | - if (type == HINIC_AEQ) |
|---|
| 740 | | - err = request_irq(entry.vector, aeq_interrupt, 0, |
|---|
| 741 | | - "hinic_aeq", eq); |
|---|
| 742 | | - else if (type == HINIC_CEQ) |
|---|
| 743 | | - err = request_irq(entry.vector, ceq_interrupt, 0, |
|---|
| 744 | | - "hinic_ceq", eq); |
|---|
| 796 | + if (type == HINIC_AEQ) { |
|---|
| 797 | + snprintf(eq->irq_name, sizeof(eq->irq_name), "hinic_aeq%d@pci:%s", eq->q_id, |
|---|
| 798 | + pci_name(pdev)); |
|---|
| 799 | + err = request_irq(entry.vector, aeq_interrupt, 0, eq->irq_name, eq); |
|---|
| 800 | + } else if (type == HINIC_CEQ) { |
|---|
| 801 | + snprintf(eq->irq_name, sizeof(eq->irq_name), "hinic_ceq%d@pci:%s", eq->q_id, |
|---|
| 802 | + pci_name(pdev)); |
|---|
| 803 | + err = request_irq(entry.vector, ceq_interrupt, 0, eq->irq_name, eq); |
|---|
| 804 | + } |
|---|
| 745 | 805 | |
|---|
| 746 | 806 | if (err) { |
|---|
| 747 | 807 | dev_err(&pdev->dev, "Failed to request irq for the EQ\n"); |
|---|
| .. | .. |
|---|
| 761 | 821 | **/ |
|---|
| 762 | 822 | static void remove_eq(struct hinic_eq *eq) |
|---|
| 763 | 823 | { |
|---|
| 764 | | - struct msix_entry *entry = &eq->msix_entry; |
|---|
| 765 | | - |
|---|
| 766 | | - free_irq(entry->vector, eq); |
|---|
| 824 | + hinic_set_msix_state(eq->hwif, eq->msix_entry.entry, |
|---|
| 825 | + HINIC_MSIX_DISABLE); |
|---|
| 826 | + free_irq(eq->msix_entry.vector, eq); |
|---|
| 767 | 827 | |
|---|
| 768 | 828 | if (eq->type == HINIC_AEQ) { |
|---|
| 769 | 829 | struct hinic_eq_work *aeq_work = &eq->aeq_work; |
|---|
| 770 | 830 | |
|---|
| 771 | 831 | cancel_work_sync(&aeq_work->work); |
|---|
| 832 | + /* clear aeq_len to avoid hw access host memory */ |
|---|
| 833 | + hinic_hwif_write_reg(eq->hwif, |
|---|
| 834 | + HINIC_CSR_AEQ_CTRL_1_ADDR(eq->q_id), 0); |
|---|
| 772 | 835 | } else if (eq->type == HINIC_CEQ) { |
|---|
| 773 | 836 | tasklet_kill(&eq->ceq_tasklet); |
|---|
| 837 | + /* clear ceq_len to avoid hw access host memory */ |
|---|
| 838 | + hinic_hwif_write_reg(eq->hwif, |
|---|
| 839 | + HINIC_CSR_CEQ_CTRL_1_ADDR(eq->q_id), 0); |
|---|
| 774 | 840 | } |
|---|
| 841 | + |
|---|
| 842 | + /* update cons_idx to avoid invalid interrupt */ |
|---|
| 843 | + eq->cons_idx = hinic_hwif_read_reg(eq->hwif, EQ_PROD_IDX_REG_ADDR(eq)); |
|---|
| 844 | + eq_update_ci(eq, EQ_NOT_ARMED); |
|---|
| 775 | 845 | |
|---|
| 776 | 846 | free_eq_pages(eq); |
|---|
| 777 | 847 | } |
|---|
| .. | .. |
|---|
| 856 | 926 | ceqs->num_ceqs = num_ceqs; |
|---|
| 857 | 927 | |
|---|
| 858 | 928 | for (q_id = 0; q_id < num_ceqs; q_id++) { |
|---|
| 929 | + ceqs->ceq[q_id].hwdev = ceqs->hwdev; |
|---|
| 859 | 930 | err = init_eq(&ceqs->ceq[q_id], hwif, HINIC_CEQ, q_id, q_len, |
|---|
| 860 | 931 | page_size, msix_entries[q_id]); |
|---|
| 861 | 932 | if (err) { |
|---|
| .. | .. |
|---|
| 884 | 955 | for (q_id = 0; q_id < ceqs->num_ceqs; q_id++) |
|---|
| 885 | 956 | remove_eq(&ceqs->ceq[q_id]); |
|---|
| 886 | 957 | } |
|---|
| 958 | + |
|---|
| 959 | +void hinic_dump_ceq_info(struct hinic_hwdev *hwdev) |
|---|
| 960 | +{ |
|---|
| 961 | + struct hinic_eq *eq = NULL; |
|---|
| 962 | + u32 addr, ci, pi; |
|---|
| 963 | + int q_id; |
|---|
| 964 | + |
|---|
| 965 | + for (q_id = 0; q_id < hwdev->func_to_io.ceqs.num_ceqs; q_id++) { |
|---|
| 966 | + eq = &hwdev->func_to_io.ceqs.ceq[q_id]; |
|---|
| 967 | + addr = EQ_CONS_IDX_REG_ADDR(eq); |
|---|
| 968 | + ci = hinic_hwif_read_reg(hwdev->hwif, addr); |
|---|
| 969 | + addr = EQ_PROD_IDX_REG_ADDR(eq); |
|---|
| 970 | + pi = hinic_hwif_read_reg(hwdev->hwif, addr); |
|---|
| 971 | + dev_err(&hwdev->hwif->pdev->dev, "Ceq id: %d, ci: 0x%08x, sw_ci: 0x%08x, pi: 0x%x, tasklet_state: 0x%lx, wrap: %d, ceqe: 0x%x\n", |
|---|
| 972 | + q_id, ci, eq->cons_idx, pi, |
|---|
| 973 | + eq->ceq_tasklet.state, |
|---|
| 974 | + eq->wrapped, be32_to_cpu(*(__be32 *)(GET_CURR_CEQ_ELEM(eq)))); |
|---|
| 975 | + } |
|---|
| 976 | +} |
|---|
| 977 | + |
|---|
| 978 | +void hinic_dump_aeq_info(struct hinic_hwdev *hwdev) |
|---|
| 979 | +{ |
|---|
| 980 | + struct hinic_aeq_elem *aeqe_pos = NULL; |
|---|
| 981 | + struct hinic_eq *eq = NULL; |
|---|
| 982 | + u32 addr, ci, pi; |
|---|
| 983 | + int q_id; |
|---|
| 984 | + |
|---|
| 985 | + for (q_id = 0; q_id < hwdev->aeqs.num_aeqs; q_id++) { |
|---|
| 986 | + eq = &hwdev->aeqs.aeq[q_id]; |
|---|
| 987 | + addr = EQ_CONS_IDX_REG_ADDR(eq); |
|---|
| 988 | + ci = hinic_hwif_read_reg(hwdev->hwif, addr); |
|---|
| 989 | + addr = EQ_PROD_IDX_REG_ADDR(eq); |
|---|
| 990 | + pi = hinic_hwif_read_reg(hwdev->hwif, addr); |
|---|
| 991 | + aeqe_pos = GET_CURR_AEQ_ELEM(eq); |
|---|
| 992 | + dev_err(&hwdev->hwif->pdev->dev, "Aeq id: %d, ci: 0x%08x, pi: 0x%x, work_state: 0x%x, wrap: %d, desc: 0x%x\n", |
|---|
| 993 | + q_id, ci, pi, work_busy(&eq->aeq_work.work), |
|---|
| 994 | + eq->wrapped, be32_to_cpu(aeqe_pos->desc)); |
|---|
| 995 | + } |
|---|
| 996 | +} |
|---|