1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Huawei HiNIC PCI Express Linux driver
4 * Copyright(c) 2017 Huawei Technologies Co., Ltd
10 #include <linux/types.h>
11 #include <linux/spinlock.h>
12 #include <linux/completion.h>
13 #include <linux/pci.h>
15 #include "hinic_hw_if.h"
16 #include "hinic_hw_wq.h"
18 #define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT 0
19 #define HINIC_CMDQ_CTXT_EQ_ID_SHIFT 56
20 #define HINIC_CMDQ_CTXT_CEQ_ARM_SHIFT 61
21 #define HINIC_CMDQ_CTXT_CEQ_EN_SHIFT 62
22 #define HINIC_CMDQ_CTXT_WRAPPED_SHIFT 63
24 #define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK 0xFFFFFFFFFFFFF
25 #define HINIC_CMDQ_CTXT_EQ_ID_MASK 0x1F
26 #define HINIC_CMDQ_CTXT_CEQ_ARM_MASK 0x1
27 #define HINIC_CMDQ_CTXT_CEQ_EN_MASK 0x1
28 #define HINIC_CMDQ_CTXT_WRAPPED_MASK 0x1
30 #define HINIC_CMDQ_CTXT_PAGE_INFO_SET(val, member) \
31 (((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
32 << HINIC_CMDQ_CTXT_##member##_SHIFT)
34 #define HINIC_CMDQ_CTXT_PAGE_INFO_CLEAR(val, member) \
35 ((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
36 << HINIC_CMDQ_CTXT_##member##_SHIFT)))
38 #define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT 0
39 #define HINIC_CMDQ_CTXT_CI_SHIFT 52
41 #define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_MASK 0xFFFFFFFFFFFFF
42 #define HINIC_CMDQ_CTXT_CI_MASK 0xFFF
44 #define HINIC_CMDQ_CTXT_BLOCK_INFO_SET(val, member) \
45 (((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
46 << HINIC_CMDQ_CTXT_##member##_SHIFT)
48 #define HINIC_CMDQ_CTXT_BLOCK_INFO_CLEAR(val, member) \
49 ((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
50 << HINIC_CMDQ_CTXT_##member##_SHIFT)))
52 #define HINIC_SAVED_DATA_ARM_SHIFT 31
54 #define HINIC_SAVED_DATA_ARM_MASK 0x1
56 #define HINIC_SAVED_DATA_SET(val, member) \
57 (((u32)(val) & HINIC_SAVED_DATA_##member##_MASK) \
58 << HINIC_SAVED_DATA_##member##_SHIFT)
60 #define HINIC_SAVED_DATA_GET(val, member) \
61 (((val) >> HINIC_SAVED_DATA_##member##_SHIFT) \
62 & HINIC_SAVED_DATA_##member##_MASK)
64 #define HINIC_SAVED_DATA_CLEAR(val, member) \
65 ((val) & (~(HINIC_SAVED_DATA_##member##_MASK \
66 << HINIC_SAVED_DATA_##member##_SHIFT)))
68 #define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_SHIFT 0
69 #define HINIC_CMDQ_DB_INFO_PATH_SHIFT 23
70 #define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_SHIFT 24
71 #define HINIC_CMDQ_DB_INFO_DB_TYPE_SHIFT 27
73 #define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_MASK 0xFF
74 #define HINIC_CMDQ_DB_INFO_PATH_MASK 0x1
75 #define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_MASK 0x7
76 #define HINIC_CMDQ_DB_INFO_DB_TYPE_MASK 0x1F
78 #define HINIC_CMDQ_DB_INFO_SET(val, member) \
79 (((u32)(val) & HINIC_CMDQ_DB_INFO_##member##_MASK) \
80 << HINIC_CMDQ_DB_INFO_##member##_SHIFT)
82 #define HINIC_CMDQ_BUF_SIZE 2048
84 #define HINIC_CMDQ_BUF_HW_RSVD 8
85 #define HINIC_CMDQ_MAX_DATA_SIZE (HINIC_CMDQ_BUF_SIZE - \
86 HINIC_CMDQ_BUF_HW_RSVD)
88 enum hinic_cmdq_type
{
94 enum hinic_set_arm_qtype
{
98 enum hinic_cmd_ack_type
{
99 HINIC_CMD_ACK_TYPE_CMDQ
,
102 struct hinic_cmdq_buf
{
108 struct hinic_cmdq_arm_bit
{
113 struct hinic_cmdq_ctxt_info
{
114 u64 curr_wqe_page_pfn
;
118 struct hinic_cmdq_ctxt
{
129 struct hinic_cmdq_ctxt_info ctxt_info
;
135 enum hinic_cmdq_type cmdq_type
;
138 /* Lock for keeping the doorbell order */
139 spinlock_t cmdq_lock
;
141 struct completion
**done
;
145 void __iomem
*db_base
;
149 struct hinic_hwif
*hwif
;
151 struct dma_pool
*cmdq_buf_pool
;
153 struct hinic_wq
*saved_wqs
;
155 struct hinic_cmdq_pages cmdq_pages
;
157 struct hinic_cmdq cmdq
[HINIC_MAX_CMDQ_TYPES
];
160 int hinic_alloc_cmdq_buf(struct hinic_cmdqs
*cmdqs
,
161 struct hinic_cmdq_buf
*cmdq_buf
);
163 void hinic_free_cmdq_buf(struct hinic_cmdqs
*cmdqs
,
164 struct hinic_cmdq_buf
*cmdq_buf
);
166 int hinic_cmdq_direct_resp(struct hinic_cmdqs
*cmdqs
,
167 enum hinic_mod_type mod
, u8 cmd
,
168 struct hinic_cmdq_buf
*buf_in
, u64
*out_param
);
170 int hinic_set_arm_bit(struct hinic_cmdqs
*cmdqs
,
171 enum hinic_set_arm_qtype q_type
, u32 q_id
);
173 int hinic_init_cmdqs(struct hinic_cmdqs
*cmdqs
, struct hinic_hwif
*hwif
,
174 void __iomem
**db_area
);
176 void hinic_free_cmdqs(struct hinic_cmdqs
*cmdqs
);