xref: /openbmc/linux/drivers/s390/net/ism.h (revision 7ce05074)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef S390_ISM_H
3 #define S390_ISM_H
4 
5 #include <linux/spinlock.h>
6 #include <linux/types.h>
7 #include <linux/pci.h>
8 #include <net/smc.h>
9 #include <asm/pci_insn.h>
10 
11 #define UTIL_STR_LEN	16
12 
13 /*
14  * Do not use the first word of the DMB bits to ensure 8 byte aligned access.
15  */
16 #define ISM_DMB_WORD_OFFSET	1
17 #define ISM_DMB_BIT_OFFSET	(ISM_DMB_WORD_OFFSET * 32)
18 #define ISM_NR_DMBS		1920
19 #define ISM_IDENT_MASK		0x00FFFF
20 
21 #define ISM_REG_SBA	0x1
22 #define ISM_REG_IEQ	0x2
23 #define ISM_READ_GID	0x3
24 #define ISM_ADD_VLAN_ID	0x4
25 #define ISM_DEL_VLAN_ID	0x5
26 #define ISM_SET_VLAN	0x6
27 #define ISM_RESET_VLAN	0x7
28 #define ISM_QUERY_INFO	0x8
29 #define ISM_QUERY_RGID	0x9
30 #define ISM_REG_DMB	0xA
31 #define ISM_UNREG_DMB	0xB
32 #define ISM_SIGNAL_IEQ	0xE
33 #define ISM_UNREG_SBA	0x11
34 #define ISM_UNREG_IEQ	0x12
35 
36 struct ism_req_hdr {
37 	u32 cmd;
38 	u16 : 16;
39 	u16 len;
40 };
41 
42 struct ism_resp_hdr {
43 	u32 cmd;
44 	u16 ret;
45 	u16 len;
46 };
47 
48 union ism_reg_sba {
49 	struct {
50 		struct ism_req_hdr hdr;
51 		u64 sba;
52 	} request;
53 	struct {
54 		struct ism_resp_hdr hdr;
55 	} response;
56 } __aligned(16);
57 
58 union ism_reg_ieq {
59 	struct {
60 		struct ism_req_hdr hdr;
61 		u64 ieq;
62 		u64 len;
63 	} request;
64 	struct {
65 		struct ism_resp_hdr hdr;
66 	} response;
67 } __aligned(16);
68 
69 union ism_read_gid {
70 	struct {
71 		struct ism_req_hdr hdr;
72 	} request;
73 	struct {
74 		struct ism_resp_hdr hdr;
75 		u64 gid;
76 	} response;
77 } __aligned(16);
78 
79 union ism_qi {
80 	struct {
81 		struct ism_req_hdr hdr;
82 	} request;
83 	struct {
84 		struct ism_resp_hdr hdr;
85 		u32 version;
86 		u32 max_len;
87 		u64 ism_state;
88 		u64 my_gid;
89 		u64 sba;
90 		u64 ieq;
91 		u32 ieq_len;
92 		u32 : 32;
93 		u32 dmbs_owned;
94 		u32 dmbs_used;
95 		u32 vlan_required;
96 		u32 vlan_nr_ids;
97 		u16 vlan_id[64];
98 	} response;
99 } __aligned(64);
100 
101 union ism_query_rgid {
102 	struct {
103 		struct ism_req_hdr hdr;
104 		u64 rgid;
105 		u32 vlan_valid;
106 		u32 vlan_id;
107 	} request;
108 	struct {
109 		struct ism_resp_hdr hdr;
110 	} response;
111 } __aligned(16);
112 
113 union ism_reg_dmb {
114 	struct {
115 		struct ism_req_hdr hdr;
116 		u64 dmb;
117 		u32 dmb_len;
118 		u32 sba_idx;
119 		u32 vlan_valid;
120 		u32 vlan_id;
121 		u64 rgid;
122 	} request;
123 	struct {
124 		struct ism_resp_hdr hdr;
125 		u64 dmb_tok;
126 	} response;
127 } __aligned(32);
128 
129 union ism_sig_ieq {
130 	struct {
131 		struct ism_req_hdr hdr;
132 		u64 rgid;
133 		u32 trigger_irq;
134 		u32 event_code;
135 		u64 info;
136 	} request;
137 	struct {
138 		struct ism_resp_hdr hdr;
139 	} response;
140 } __aligned(32);
141 
142 union ism_unreg_dmb {
143 	struct {
144 		struct ism_req_hdr hdr;
145 		u64 dmb_tok;
146 	} request;
147 	struct {
148 		struct ism_resp_hdr hdr;
149 	} response;
150 } __aligned(16);
151 
152 union ism_cmd_simple {
153 	struct {
154 		struct ism_req_hdr hdr;
155 	} request;
156 	struct {
157 		struct ism_resp_hdr hdr;
158 	} response;
159 } __aligned(8);
160 
161 union ism_set_vlan_id {
162 	struct {
163 		struct ism_req_hdr hdr;
164 		u64 vlan_id;
165 	} request;
166 	struct {
167 		struct ism_resp_hdr hdr;
168 	} response;
169 } __aligned(16);
170 
171 struct ism_eq_header {
172 	u64 idx;
173 	u64 ieq_len;
174 	u64 entry_len;
175 	u64 : 64;
176 };
177 
178 struct ism_eq {
179 	struct ism_eq_header header;
180 	struct smcd_event entry[15];
181 };
182 
183 struct ism_sba {
184 	u32 s : 1;	/* summary bit */
185 	u32 e : 1;	/* event bit */
186 	u32 : 30;
187 	u32 dmb_bits[ISM_NR_DMBS / 32];
188 	u32 reserved[3];
189 	u16 dmbe_mask[ISM_NR_DMBS];
190 };
191 
192 struct ism_dev {
193 	spinlock_t lock;
194 	struct pci_dev *pdev;
195 	struct smcd_dev *smcd;
196 
197 	struct ism_sba *sba;
198 	dma_addr_t sba_dma_addr;
199 	DECLARE_BITMAP(sba_bitmap, ISM_NR_DMBS);
200 
201 	struct ism_eq *ieq;
202 	dma_addr_t ieq_dma_addr;
203 
204 	int ieq_idx;
205 };
206 
207 #define ISM_CREATE_REQ(dmb, idx, sf, offset)		\
208 	((dmb) | (idx) << 24 | (sf) << 23 | (offset))
209 
210 struct ism_systemeid {
211 	u8	seid_string[24];
212 	u8	serial_number[4];
213 	u8	type[4];
214 };
215 
216 static inline void __ism_read_cmd(struct ism_dev *ism, void *data,
217 				  unsigned long offset, unsigned long len)
218 {
219 	struct zpci_dev *zdev = to_zpci(ism->pdev);
220 	u64 req = ZPCI_CREATE_REQ(zdev->fh, 2, 8);
221 
222 	while (len > 0) {
223 		__zpci_load(data, req, offset);
224 		offset += 8;
225 		data += 8;
226 		len -= 8;
227 	}
228 }
229 
230 static inline void __ism_write_cmd(struct ism_dev *ism, void *data,
231 				   unsigned long offset, unsigned long len)
232 {
233 	struct zpci_dev *zdev = to_zpci(ism->pdev);
234 	u64 req = ZPCI_CREATE_REQ(zdev->fh, 2, len);
235 
236 	if (len)
237 		__zpci_store_block(data, req, offset);
238 }
239 
240 static inline int __ism_move(struct ism_dev *ism, u64 dmb_req, void *data,
241 			     unsigned int size)
242 {
243 	struct zpci_dev *zdev = to_zpci(ism->pdev);
244 	u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, size);
245 
246 	return __zpci_store_block(data, req, dmb_req);
247 }
248 
249 #endif /* S390_ISM_H */
250