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 
21 #include "hinic_hw_if.h"
22 
23 #define HINIC_API_CMD_CHAIN_REQ_RESTART_SHIFT                   1
24 
25 #define HINIC_API_CMD_CHAIN_REQ_RESTART_MASK                    0x1
26 
27 #define HINIC_API_CMD_CHAIN_REQ_SET(val, member)                \
28 	(((u32)(val) & HINIC_API_CMD_CHAIN_REQ_##member##_MASK) << \
29 	 HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT)
30 
31 #define HINIC_API_CMD_CHAIN_REQ_GET(val, member)                \
32 	(((val) >> HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT) &  \
33 	 HINIC_API_CMD_CHAIN_REQ_##member##_MASK)
34 
35 #define HINIC_API_CMD_CHAIN_REQ_CLEAR(val, member)              \
36 	((val) & (~(HINIC_API_CMD_CHAIN_REQ_##member##_MASK     \
37 	 << HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT)))
38 
39 #define HINIC_API_CMD_CHAIN_CTRL_RESTART_WB_STAT_SHIFT          1
40 #define HINIC_API_CMD_CHAIN_CTRL_XOR_ERR_SHIFT                  2
41 #define HINIC_API_CMD_CHAIN_CTRL_AEQE_EN_SHIFT                  4
42 #define HINIC_API_CMD_CHAIN_CTRL_AEQ_ID_SHIFT                   8
43 #define HINIC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_SHIFT               28
44 #define HINIC_API_CMD_CHAIN_CTRL_CELL_SIZE_SHIFT                30
45 
46 #define HINIC_API_CMD_CHAIN_CTRL_RESTART_WB_STAT_MASK           0x1
47 #define HINIC_API_CMD_CHAIN_CTRL_XOR_ERR_MASK                   0x1
48 #define HINIC_API_CMD_CHAIN_CTRL_AEQE_EN_MASK                   0x1
49 #define HINIC_API_CMD_CHAIN_CTRL_AEQ_ID_MASK                    0x3
50 #define HINIC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_MASK                0x3
51 #define HINIC_API_CMD_CHAIN_CTRL_CELL_SIZE_MASK                 0x3
52 
53 #define HINIC_API_CMD_CHAIN_CTRL_SET(val, member)               \
54 	(((u32)(val) & HINIC_API_CMD_CHAIN_CTRL_##member##_MASK) << \
55 	 HINIC_API_CMD_CHAIN_CTRL_##member##_SHIFT)
56 
57 #define HINIC_API_CMD_CHAIN_CTRL_CLEAR(val, member)             \
58 	((val) & (~(HINIC_API_CMD_CHAIN_CTRL_##member##_MASK    \
59 	 << HINIC_API_CMD_CHAIN_CTRL_##member##_SHIFT)))
60 
61 enum hinic_api_cmd_chain_type {
62 	HINIC_API_CMD_WRITE_TO_MGMT_CPU = 2,
63 
64 	HINIC_API_CMD_MAX,
65 };
66 
67 struct hinic_api_cmd_chain_attr {
68 	struct hinic_hwif               *hwif;
69 	enum hinic_api_cmd_chain_type   chain_type;
70 
71 	u32                             num_cells;
72 	u16                             cell_size;
73 };
74 
75 struct hinic_api_cmd_status {
76 	u64     header;
77 	u32     status;
78 	u32     rsvd0;
79 	u32     rsvd1;
80 	u32     rsvd2;
81 	u64     rsvd3;
82 };
83 
84 /* HW struct */
85 struct hinic_api_cmd_cell {
86 	u64 ctrl;
87 
88 	/* address is 64 bit in HW struct */
89 	u64 next_cell_paddr;
90 
91 	u64 desc;
92 
93 	/* HW struct */
94 	union {
95 		struct {
96 			u64 hw_cmd_paddr;
97 		} write;
98 
99 		struct {
100 			u64 hw_wb_resp_paddr;
101 			u64 hw_cmd_paddr;
102 		} read;
103 	};
104 };
105 
106 struct hinic_api_cmd_cell_ctxt {
107 	dma_addr_t                      cell_paddr;
108 	struct hinic_api_cmd_cell       *cell_vaddr;
109 
110 	dma_addr_t                      api_cmd_paddr;
111 	u8                              *api_cmd_vaddr;
112 };
113 
114 struct hinic_api_cmd_chain {
115 	struct hinic_hwif               *hwif;
116 	enum hinic_api_cmd_chain_type   chain_type;
117 
118 	u32                             num_cells;
119 	u16                             cell_size;
120 
121 	/* HW members in 24 bit format */
122 	u32                             prod_idx;
123 	u32                             cons_idx;
124 
125 	struct hinic_api_cmd_cell_ctxt  *cell_ctxt;
126 
127 	dma_addr_t                      wb_status_paddr;
128 	struct hinic_api_cmd_status     *wb_status;
129 
130 	dma_addr_t                      head_cell_paddr;
131 	struct hinic_api_cmd_cell       *head_node;
132 	struct hinic_api_cmd_cell       *curr_node;
133 };
134 
135 int hinic_api_cmd_write(struct hinic_api_cmd_chain *chain,
136 			enum hinic_node_id dest, u8 *cmd, u16 size);
137 
138 int hinic_api_cmd_init(struct hinic_api_cmd_chain **chain,
139 		       struct hinic_hwif *hwif);
140 
141 void hinic_api_cmd_free(struct hinic_api_cmd_chain **chain);
142 
143 #endif
144