2 * Huawei HiNIC PCI Express Linux driver
3 * Copyright(c) 2017 Huawei Technologies Co., Ltd
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.
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
19 #include <linux/types.h>
20 #include <linux/spinlock.h>
21 #include <linux/completion.h>
22 #include <linux/pci.h>
24 #include "hinic_hw_if.h"
25 #include "hinic_hw_wq.h"
27 #define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT 0
28 #define HINIC_CMDQ_CTXT_EQ_ID_SHIFT 56
29 #define HINIC_CMDQ_CTXT_CEQ_ARM_SHIFT 61
30 #define HINIC_CMDQ_CTXT_CEQ_EN_SHIFT 62
31 #define HINIC_CMDQ_CTXT_WRAPPED_SHIFT 63
33 #define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK 0xFFFFFFFFFFFFF
34 #define HINIC_CMDQ_CTXT_EQ_ID_MASK 0x1F
35 #define HINIC_CMDQ_CTXT_CEQ_ARM_MASK 0x1
36 #define HINIC_CMDQ_CTXT_CEQ_EN_MASK 0x1
37 #define HINIC_CMDQ_CTXT_WRAPPED_MASK 0x1
39 #define HINIC_CMDQ_CTXT_PAGE_INFO_SET(val, member) \
40 (((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
41 << HINIC_CMDQ_CTXT_##member##_SHIFT)
43 #define HINIC_CMDQ_CTXT_PAGE_INFO_CLEAR(val, member) \
44 ((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
45 << HINIC_CMDQ_CTXT_##member##_SHIFT)))
47 #define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT 0
48 #define HINIC_CMDQ_CTXT_CI_SHIFT 52
50 #define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_MASK 0xFFFFFFFFFFFFF
51 #define HINIC_CMDQ_CTXT_CI_MASK 0xFFF
53 #define HINIC_CMDQ_CTXT_BLOCK_INFO_SET(val, member) \
54 (((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \
55 << HINIC_CMDQ_CTXT_##member##_SHIFT)
57 #define HINIC_CMDQ_CTXT_BLOCK_INFO_CLEAR(val, member) \
58 ((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \
59 << HINIC_CMDQ_CTXT_##member##_SHIFT)))
61 #define HINIC_SAVED_DATA_ARM_SHIFT 31
63 #define HINIC_SAVED_DATA_ARM_MASK 0x1
65 #define HINIC_SAVED_DATA_SET(val, member) \
66 (((u32)(val) & HINIC_SAVED_DATA_##member##_MASK) \
67 << HINIC_SAVED_DATA_##member##_SHIFT)
69 #define HINIC_SAVED_DATA_GET(val, member) \
70 (((val) >> HINIC_SAVED_DATA_##member##_SHIFT) \
71 & HINIC_SAVED_DATA_##member##_MASK)
73 #define HINIC_SAVED_DATA_CLEAR(val, member) \
74 ((val) & (~(HINIC_SAVED_DATA_##member##_MASK \
75 << HINIC_SAVED_DATA_##member##_SHIFT)))
77 #define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_SHIFT 0
78 #define HINIC_CMDQ_DB_INFO_PATH_SHIFT 23
79 #define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_SHIFT 24
80 #define HINIC_CMDQ_DB_INFO_DB_TYPE_SHIFT 27
82 #define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_MASK 0xFF
83 #define HINIC_CMDQ_DB_INFO_PATH_MASK 0x1
84 #define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_MASK 0x7
85 #define HINIC_CMDQ_DB_INFO_DB_TYPE_MASK 0x1F
87 #define HINIC_CMDQ_DB_INFO_SET(val, member) \
88 (((u32)(val) & HINIC_CMDQ_DB_INFO_##member##_MASK) \
89 << HINIC_CMDQ_DB_INFO_##member##_SHIFT)
91 #define HINIC_CMDQ_BUF_SIZE 2048
93 #define HINIC_CMDQ_BUF_HW_RSVD 8
94 #define HINIC_CMDQ_MAX_DATA_SIZE (HINIC_CMDQ_BUF_SIZE - \
95 HINIC_CMDQ_BUF_HW_RSVD)
97 enum hinic_cmdq_type
{
100 HINIC_MAX_CMDQ_TYPES
,
103 enum hinic_set_arm_qtype
{
107 enum hinic_cmd_ack_type
{
108 HINIC_CMD_ACK_TYPE_CMDQ
,
111 struct hinic_cmdq_buf
{
117 struct hinic_cmdq_arm_bit
{
122 struct hinic_cmdq_ctxt_info
{
123 u64 curr_wqe_page_pfn
;
127 struct hinic_cmdq_ctxt
{
138 struct hinic_cmdq_ctxt_info ctxt_info
;
144 enum hinic_cmdq_type cmdq_type
;
147 /* Lock for keeping the doorbell order */
148 spinlock_t cmdq_lock
;
150 struct completion
**done
;
154 void __iomem
*db_base
;
158 struct hinic_hwif
*hwif
;
160 struct dma_pool
*cmdq_buf_pool
;
162 struct hinic_wq
*saved_wqs
;
164 struct hinic_cmdq_pages cmdq_pages
;
166 struct hinic_cmdq cmdq
[HINIC_MAX_CMDQ_TYPES
];
169 int hinic_alloc_cmdq_buf(struct hinic_cmdqs
*cmdqs
,
170 struct hinic_cmdq_buf
*cmdq_buf
);
172 void hinic_free_cmdq_buf(struct hinic_cmdqs
*cmdqs
,
173 struct hinic_cmdq_buf
*cmdq_buf
);
175 int hinic_cmdq_direct_resp(struct hinic_cmdqs
*cmdqs
,
176 enum hinic_mod_type mod
, u8 cmd
,
177 struct hinic_cmdq_buf
*buf_in
, u64
*out_param
);
179 int hinic_set_arm_bit(struct hinic_cmdqs
*cmdqs
,
180 enum hinic_set_arm_qtype q_type
, u32 q_id
);
182 int hinic_init_cmdqs(struct hinic_cmdqs
*cmdqs
, struct hinic_hwif
*hwif
,
183 void __iomem
**db_area
);
185 void hinic_free_cmdqs(struct hinic_cmdqs
*cmdqs
);