| .. | .. |
|---|
| 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> |
|---|
| .. | .. |
|---|
| 73 | 64 | #define CMDQ_WQE_SIZE 64 |
|---|
| 74 | 65 | #define CMDQ_DEPTH SZ_4K |
|---|
| 75 | 66 | |
|---|
| 76 | | -#define CMDQ_WQ_PAGE_SIZE SZ_4K |
|---|
| 67 | +#define CMDQ_WQ_PAGE_SIZE SZ_256K |
|---|
| 77 | 68 | |
|---|
| 78 | 69 | #define WQE_LCMD_SIZE 64 |
|---|
| 79 | 70 | #define WQE_SCMD_SIZE 64 |
|---|
| .. | .. |
|---|
| 410 | 401 | |
|---|
| 411 | 402 | spin_unlock_bh(&cmdq->cmdq_lock); |
|---|
| 412 | 403 | |
|---|
| 404 | + hinic_dump_ceq_info(cmdq->hwdev); |
|---|
| 413 | 405 | return -ETIMEDOUT; |
|---|
| 414 | 406 | } |
|---|
| 415 | 407 | |
|---|
| .. | .. |
|---|
| 633 | 625 | if (!CMDQ_WQE_COMPLETED(be32_to_cpu(ctrl->ctrl_info))) |
|---|
| 634 | 626 | return -EBUSY; |
|---|
| 635 | 627 | |
|---|
| 628 | + dma_rmb(); |
|---|
| 629 | + |
|---|
| 636 | 630 | errcode = CMDQ_WQE_ERRCODE_GET(be32_to_cpu(status->status_info), VAL); |
|---|
| 637 | 631 | |
|---|
| 638 | 632 | cmdq_sync_cmd_handler(cmdq, ci, errcode); |
|---|
| .. | .. |
|---|
| 712 | 706 | /* The data in the HW is in Big Endian Format */ |
|---|
| 713 | 707 | wq_first_page_paddr = be64_to_cpu(*wq->block_vaddr); |
|---|
| 714 | 708 | |
|---|
| 715 | | - pfn = CMDQ_PFN(wq_first_page_paddr, wq->wq_page_size); |
|---|
| 709 | + pfn = CMDQ_PFN(wq_first_page_paddr, SZ_4K); |
|---|
| 716 | 710 | |
|---|
| 717 | 711 | ctxt_info->curr_wqe_page_pfn = |
|---|
| 718 | 712 | HINIC_CMDQ_CTXT_PAGE_INFO_SET(pfn, CURR_WQE_PAGE_PFN) | |
|---|
| .. | .. |
|---|
| 721 | 715 | HINIC_CMDQ_CTXT_PAGE_INFO_SET(1, CEQ_EN) | |
|---|
| 722 | 716 | HINIC_CMDQ_CTXT_PAGE_INFO_SET(cmdq->wrapped, WRAPPED); |
|---|
| 723 | 717 | |
|---|
| 724 | | - /* block PFN - Read Modify Write */ |
|---|
| 725 | | - cmdq_first_block_paddr = cmdq_pages->page_paddr; |
|---|
| 718 | + if (wq->num_q_pages != 1) { |
|---|
| 719 | + /* block PFN - Read Modify Write */ |
|---|
| 720 | + cmdq_first_block_paddr = cmdq_pages->page_paddr; |
|---|
| 726 | 721 | |
|---|
| 727 | | - pfn = CMDQ_PFN(cmdq_first_block_paddr, wq->wq_page_size); |
|---|
| 722 | + pfn = CMDQ_PFN(cmdq_first_block_paddr, wq->wq_page_size); |
|---|
| 723 | + } |
|---|
| 728 | 724 | |
|---|
| 729 | 725 | ctxt_info->wq_block_pfn = |
|---|
| 730 | 726 | HINIC_CMDQ_CTXT_BLOCK_INFO_SET(pfn, WQ_BLOCK_PFN) | |
|---|
| 731 | 727 | HINIC_CMDQ_CTXT_BLOCK_INFO_SET(atomic_read(&wq->cons_idx), CI); |
|---|
| 732 | 728 | |
|---|
| 733 | 729 | cmdq_ctxt->func_idx = HINIC_HWIF_FUNC_IDX(cmdqs->hwif); |
|---|
| 730 | + cmdq_ctxt->ppf_idx = HINIC_HWIF_PPF_IDX(cmdqs->hwif); |
|---|
| 734 | 731 | cmdq_ctxt->cmdq_type = cmdq->cmdq_type; |
|---|
| 735 | 732 | } |
|---|
| 736 | 733 | |
|---|
| .. | .. |
|---|
| 787 | 784 | * init_cmdqs_ctxt - write the cmdq ctxt to HW after init all cmdq |
|---|
| 788 | 785 | * @hwdev: the NIC HW device |
|---|
| 789 | 786 | * @cmdqs: cmdqs to write the ctxts for |
|---|
| 790 | | - * &db_area: db_area for all the cmdqs |
|---|
| 787 | + * @db_area: db_area for all the cmdqs |
|---|
| 791 | 788 | * |
|---|
| 792 | 789 | * Return 0 - Success, negative - Failure |
|---|
| 793 | 790 | **/ |
|---|
| .. | .. |
|---|
| 799 | 796 | struct hinic_cmdq_ctxt *cmdq_ctxts; |
|---|
| 800 | 797 | struct pci_dev *pdev = hwif->pdev; |
|---|
| 801 | 798 | struct hinic_pfhwdev *pfhwdev; |
|---|
| 802 | | - size_t cmdq_ctxts_size; |
|---|
| 803 | 799 | int err; |
|---|
| 804 | 800 | |
|---|
| 805 | | - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { |
|---|
| 806 | | - dev_err(&pdev->dev, "Unsupported PCI function type\n"); |
|---|
| 807 | | - return -EINVAL; |
|---|
| 808 | | - } |
|---|
| 809 | | - |
|---|
| 810 | | - cmdq_ctxts_size = HINIC_MAX_CMDQ_TYPES * sizeof(*cmdq_ctxts); |
|---|
| 811 | | - cmdq_ctxts = devm_kzalloc(&pdev->dev, cmdq_ctxts_size, GFP_KERNEL); |
|---|
| 801 | + cmdq_ctxts = devm_kcalloc(&pdev->dev, HINIC_MAX_CMDQ_TYPES, |
|---|
| 802 | + sizeof(*cmdq_ctxts), GFP_KERNEL); |
|---|
| 812 | 803 | if (!cmdq_ctxts) |
|---|
| 813 | 804 | return -ENOMEM; |
|---|
| 814 | 805 | |
|---|
| .. | .. |
|---|
| 816 | 807 | |
|---|
| 817 | 808 | cmdq_type = HINIC_CMDQ_SYNC; |
|---|
| 818 | 809 | for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) { |
|---|
| 810 | + cmdqs->cmdq[cmdq_type].hwdev = hwdev; |
|---|
| 819 | 811 | err = init_cmdq(&cmdqs->cmdq[cmdq_type], |
|---|
| 820 | 812 | &cmdqs->saved_wqs[cmdq_type], cmdq_type, |
|---|
| 821 | 813 | db_area[cmdq_type]); |
|---|
| .. | .. |
|---|
| 858 | 850 | return err; |
|---|
| 859 | 851 | } |
|---|
| 860 | 852 | |
|---|
| 853 | +static int hinic_set_cmdq_depth(struct hinic_hwdev *hwdev, u16 cmdq_depth) |
|---|
| 854 | +{ |
|---|
| 855 | + struct hinic_cmd_hw_ioctxt hw_ioctxt = { 0 }; |
|---|
| 856 | + struct hinic_pfhwdev *pfhwdev; |
|---|
| 857 | + |
|---|
| 858 | + pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); |
|---|
| 859 | + |
|---|
| 860 | + hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif); |
|---|
| 861 | + hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif); |
|---|
| 862 | + |
|---|
| 863 | + hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_ENABLE; |
|---|
| 864 | + hw_ioctxt.cmdq_depth = (u8)ilog2(cmdq_depth); |
|---|
| 865 | + |
|---|
| 866 | + return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, |
|---|
| 867 | + HINIC_COMM_CMD_HWCTXT_SET, |
|---|
| 868 | + &hw_ioctxt, sizeof(hw_ioctxt), NULL, |
|---|
| 869 | + NULL, HINIC_MGMT_MSG_SYNC); |
|---|
| 870 | +} |
|---|
| 871 | + |
|---|
| 861 | 872 | /** |
|---|
| 862 | 873 | * hinic_init_cmdqs - init all cmdqs |
|---|
| 863 | 874 | * @cmdqs: cmdqs to init |
|---|
| .. | .. |
|---|
| 872 | 883 | struct hinic_func_to_io *func_to_io = cmdqs_to_func_to_io(cmdqs); |
|---|
| 873 | 884 | struct pci_dev *pdev = hwif->pdev; |
|---|
| 874 | 885 | struct hinic_hwdev *hwdev; |
|---|
| 875 | | - size_t saved_wqs_size; |
|---|
| 876 | 886 | u16 max_wqe_size; |
|---|
| 877 | 887 | int err; |
|---|
| 878 | 888 | |
|---|
| .. | .. |
|---|
| 883 | 893 | if (!cmdqs->cmdq_buf_pool) |
|---|
| 884 | 894 | return -ENOMEM; |
|---|
| 885 | 895 | |
|---|
| 886 | | - saved_wqs_size = HINIC_MAX_CMDQ_TYPES * sizeof(struct hinic_wq); |
|---|
| 887 | | - cmdqs->saved_wqs = devm_kzalloc(&pdev->dev, saved_wqs_size, GFP_KERNEL); |
|---|
| 896 | + cmdqs->saved_wqs = devm_kcalloc(&pdev->dev, HINIC_MAX_CMDQ_TYPES, |
|---|
| 897 | + sizeof(*cmdqs->saved_wqs), GFP_KERNEL); |
|---|
| 888 | 898 | if (!cmdqs->saved_wqs) { |
|---|
| 889 | 899 | err = -ENOMEM; |
|---|
| 890 | 900 | goto err_saved_wqs; |
|---|
| .. | .. |
|---|
| 908 | 918 | |
|---|
| 909 | 919 | hinic_ceq_register_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ, cmdqs, |
|---|
| 910 | 920 | cmdq_ceq_handler); |
|---|
| 921 | + |
|---|
| 922 | + err = hinic_set_cmdq_depth(hwdev, CMDQ_DEPTH); |
|---|
| 923 | + if (err) { |
|---|
| 924 | + dev_err(&hwif->pdev->dev, "Failed to set cmdq depth\n"); |
|---|
| 925 | + goto err_set_cmdq_depth; |
|---|
| 926 | + } |
|---|
| 927 | + |
|---|
| 911 | 928 | return 0; |
|---|
| 912 | 929 | |
|---|
| 930 | +err_set_cmdq_depth: |
|---|
| 931 | + hinic_ceq_unregister_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ); |
|---|
| 932 | + free_cmdq(&cmdqs->cmdq[HINIC_CMDQ_SYNC]); |
|---|
| 913 | 933 | err_cmdq_ctxt: |
|---|
| 914 | 934 | hinic_wqs_cmdq_free(&cmdqs->cmdq_pages, cmdqs->saved_wqs, |
|---|
| 915 | 935 | HINIC_MAX_CMDQ_TYPES); |
|---|