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