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