.. | .. |
---|
| 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 | +} |
---|