1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Huawei HiNIC PCI Express Linux driver
4  * Copyright(c) 2017 Huawei Technologies Co., Ltd
5  */
6 
7 #ifndef HINIC_HW_API_CMD_H
8 #define HINIC_HW_API_CMD_H
9 
10 #include <linux/types.h>
11 #include <linux/semaphore.h>
12 
13 #include "hinic_hw_if.h"
14 
15 #define HINIC_API_CMD_PI_IDX_SHIFT                              0
16 
17 #define HINIC_API_CMD_PI_IDX_MASK                               0xFFFFFF
18 
19 #define HINIC_API_CMD_PI_SET(val, member)                       \
20 	(((u32)(val) & HINIC_API_CMD_PI_##member##_MASK) <<     \
21 	 HINIC_API_CMD_PI_##member##_SHIFT)
22 
23 #define HINIC_API_CMD_PI_CLEAR(val, member)                     \
24 	((val) & (~(HINIC_API_CMD_PI_##member##_MASK            \
25 	 << HINIC_API_CMD_PI_##member##_SHIFT)))
26 
27 #define HINIC_API_CMD_CHAIN_REQ_RESTART_SHIFT                   1
28 
29 #define HINIC_API_CMD_CHAIN_REQ_RESTART_MASK                    0x1
30 
31 #define HINIC_API_CMD_CHAIN_REQ_SET(val, member)                \
32 	(((u32)(val) & HINIC_API_CMD_CHAIN_REQ_##member##_MASK) << \
33 	 HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT)
34 
35 #define HINIC_API_CMD_CHAIN_REQ_GET(val, member)                \
36 	(((val) >> HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT) &  \
37 	 HINIC_API_CMD_CHAIN_REQ_##member##_MASK)
38 
39 #define HINIC_API_CMD_CHAIN_REQ_CLEAR(val, member)              \
40 	((val) & (~(HINIC_API_CMD_CHAIN_REQ_##member##_MASK     \
41 	 << HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT)))
42 
43 #define HINIC_API_CMD_CHAIN_CTRL_RESTART_WB_STAT_SHIFT          1
44 #define HINIC_API_CMD_CHAIN_CTRL_XOR_ERR_SHIFT                  2
45 #define HINIC_API_CMD_CHAIN_CTRL_AEQE_EN_SHIFT                  4
46 #define HINIC_API_CMD_CHAIN_CTRL_AEQ_ID_SHIFT                   8
47 #define HINIC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_SHIFT               28
48 #define HINIC_API_CMD_CHAIN_CTRL_CELL_SIZE_SHIFT                30
49 
50 #define HINIC_API_CMD_CHAIN_CTRL_RESTART_WB_STAT_MASK           0x1
51 #define HINIC_API_CMD_CHAIN_CTRL_XOR_ERR_MASK                   0x1
52 #define HINIC_API_CMD_CHAIN_CTRL_AEQE_EN_MASK                   0x1
53 #define HINIC_API_CMD_CHAIN_CTRL_AEQ_ID_MASK                    0x3
54 #define HINIC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_MASK                0x3
55 #define HINIC_API_CMD_CHAIN_CTRL_CELL_SIZE_MASK                 0x3
56 
57 #define HINIC_API_CMD_CHAIN_CTRL_SET(val, member)               \
58 	(((u32)(val) & HINIC_API_CMD_CHAIN_CTRL_##member##_MASK) << \
59 	 HINIC_API_CMD_CHAIN_CTRL_##member##_SHIFT)
60 
61 #define HINIC_API_CMD_CHAIN_CTRL_CLEAR(val, member)             \
62 	((val) & (~(HINIC_API_CMD_CHAIN_CTRL_##member##_MASK    \
63 	 << HINIC_API_CMD_CHAIN_CTRL_##member##_SHIFT)))
64 
65 #define HINIC_API_CMD_CELL_CTRL_DATA_SZ_SHIFT                   0
66 #define HINIC_API_CMD_CELL_CTRL_RD_DMA_ATTR_SHIFT               16
67 #define HINIC_API_CMD_CELL_CTRL_WR_DMA_ATTR_SHIFT               24
68 #define HINIC_API_CMD_CELL_CTRL_XOR_CHKSUM_SHIFT                56
69 
70 #define HINIC_API_CMD_CELL_CTRL_DATA_SZ_MASK                    0x3F
71 #define HINIC_API_CMD_CELL_CTRL_RD_DMA_ATTR_MASK                0x3F
72 #define HINIC_API_CMD_CELL_CTRL_WR_DMA_ATTR_MASK                0x3F
73 #define HINIC_API_CMD_CELL_CTRL_XOR_CHKSUM_MASK                 0xFF
74 
75 #define HINIC_API_CMD_CELL_CTRL_SET(val, member)                \
76 	((((u64)val) & HINIC_API_CMD_CELL_CTRL_##member##_MASK) << \
77 	 HINIC_API_CMD_CELL_CTRL_##member##_SHIFT)
78 
79 #define HINIC_API_CMD_DESC_API_TYPE_SHIFT                       0
80 #define HINIC_API_CMD_DESC_RD_WR_SHIFT                          1
81 #define HINIC_API_CMD_DESC_MGMT_BYPASS_SHIFT                    2
82 #define HINIC_API_CMD_DESC_DEST_SHIFT                           32
83 #define HINIC_API_CMD_DESC_SIZE_SHIFT                           40
84 #define HINIC_API_CMD_DESC_XOR_CHKSUM_SHIFT                     56
85 
86 #define HINIC_API_CMD_DESC_API_TYPE_MASK                        0x1
87 #define HINIC_API_CMD_DESC_RD_WR_MASK                           0x1
88 #define HINIC_API_CMD_DESC_MGMT_BYPASS_MASK                     0x1
89 #define HINIC_API_CMD_DESC_DEST_MASK                            0x1F
90 #define HINIC_API_CMD_DESC_SIZE_MASK                            0x7FF
91 #define HINIC_API_CMD_DESC_XOR_CHKSUM_MASK                      0xFF
92 
93 #define HINIC_API_CMD_DESC_SET(val, member)                     \
94 	((((u64)val) & HINIC_API_CMD_DESC_##member##_MASK) <<   \
95 	 HINIC_API_CMD_DESC_##member##_SHIFT)
96 
97 #define HINIC_API_CMD_STATUS_HEADER_CHAIN_ID_SHIFT              16
98 
99 #define HINIC_API_CMD_STATUS_HEADER_CHAIN_ID_MASK               0xFF
100 
101 #define HINIC_API_CMD_STATUS_HEADER_GET(val, member)            \
102 	(((val) >> HINIC_API_CMD_STATUS_HEADER_##member##_SHIFT) & \
103 	 HINIC_API_CMD_STATUS_HEADER_##member##_MASK)
104 
105 #define HINIC_API_CMD_STATUS_CONS_IDX_SHIFT                     0
106 #define HINIC_API_CMD_STATUS_FSM_SHIFT				24
107 #define HINIC_API_CMD_STATUS_CHKSUM_ERR_SHIFT                   28
108 #define HINIC_API_CMD_STATUS_CPLD_ERR_SHIFT			30
109 
110 #define HINIC_API_CMD_STATUS_CONS_IDX_MASK                      0xFFFFFF
111 #define HINIC_API_CMD_STATUS_FSM_MASK				0xFU
112 #define HINIC_API_CMD_STATUS_CHKSUM_ERR_MASK                    0x3
113 #define HINIC_API_CMD_STATUS_CPLD_ERR_MASK			0x1U
114 
115 #define HINIC_API_CMD_STATUS_GET(val, member)                   \
116 	(((val) >> HINIC_API_CMD_STATUS_##member##_SHIFT) &     \
117 	 HINIC_API_CMD_STATUS_##member##_MASK)
118 
119 enum hinic_api_cmd_chain_type {
120 	HINIC_API_CMD_WRITE_TO_MGMT_CPU = 2,
121 
122 	HINIC_API_CMD_MAX,
123 };
124 
125 struct hinic_api_cmd_chain_attr {
126 	struct hinic_hwif               *hwif;
127 	enum hinic_api_cmd_chain_type   chain_type;
128 
129 	u32                             num_cells;
130 	u16                             cell_size;
131 };
132 
133 struct hinic_api_cmd_status {
134 	u64     header;
135 	u32     status;
136 	u32     rsvd0;
137 	u32     rsvd1;
138 	u32     rsvd2;
139 	u64     rsvd3;
140 };
141 
142 /* HW struct */
143 struct hinic_api_cmd_cell {
144 	u64 ctrl;
145 
146 	/* address is 64 bit in HW struct */
147 	u64 next_cell_paddr;
148 
149 	u64 desc;
150 
151 	/* HW struct */
152 	union {
153 		struct {
154 			u64 hw_cmd_paddr;
155 		} write;
156 
157 		struct {
158 			u64 hw_wb_resp_paddr;
159 			u64 hw_cmd_paddr;
160 		} read;
161 	};
162 };
163 
164 struct hinic_api_cmd_cell_ctxt {
165 	dma_addr_t                      cell_paddr;
166 	struct hinic_api_cmd_cell       *cell_vaddr;
167 
168 	dma_addr_t                      api_cmd_paddr;
169 	u8                              *api_cmd_vaddr;
170 };
171 
172 struct hinic_api_cmd_chain {
173 	struct hinic_hwif               *hwif;
174 	enum hinic_api_cmd_chain_type   chain_type;
175 
176 	u32                             num_cells;
177 	u16                             cell_size;
178 
179 	/* HW members in 24 bit format */
180 	u32                             prod_idx;
181 	u32                             cons_idx;
182 
183 	struct semaphore                sem;
184 
185 	struct hinic_api_cmd_cell_ctxt  *cell_ctxt;
186 
187 	dma_addr_t                      wb_status_paddr;
188 	struct hinic_api_cmd_status     *wb_status;
189 
190 	dma_addr_t                      head_cell_paddr;
191 	struct hinic_api_cmd_cell       *head_node;
192 	struct hinic_api_cmd_cell       *curr_node;
193 };
194 
195 int hinic_api_cmd_write(struct hinic_api_cmd_chain *chain,
196 			enum hinic_node_id dest, u8 *cmd, u16 size);
197 
198 int hinic_api_cmd_init(struct hinic_api_cmd_chain **chain,
199 		       struct hinic_hwif *hwif);
200 
201 void hinic_api_cmd_free(struct hinic_api_cmd_chain **chain);
202 
203 #endif
204