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