.. | .. |
---|
| 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); |
---|