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