1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright IBM Corp. 2000, 2009 |
4 | * Author(s): Utz Bacher <utz.bacher@de.ibm.com> |
5 | * Jan Glauber <jang@linux.vnet.ibm.com> |
6 | */ |
7 | #ifndef _CIO_QDIO_H |
8 | #define _CIO_QDIO_H |
9 | |
10 | #include <asm/page.h> |
11 | #include <asm/schid.h> |
12 | #include <asm/debug.h> |
13 | #include "chsc.h" |
14 | |
15 | #define QDIO_BUSY_BIT_PATIENCE (100 << 12) /* 100 microseconds */ |
16 | #define QDIO_BUSY_BIT_RETRY_DELAY 10 /* 10 milliseconds */ |
17 | #define QDIO_BUSY_BIT_RETRIES 1000 /* = 10s retry time */ |
18 | |
19 | enum qdio_irq_states { |
20 | QDIO_IRQ_STATE_INACTIVE, |
21 | QDIO_IRQ_STATE_ESTABLISHED, |
22 | QDIO_IRQ_STATE_ACTIVE, |
23 | QDIO_IRQ_STATE_STOPPED, |
24 | QDIO_IRQ_STATE_CLEANUP, |
25 | QDIO_IRQ_STATE_ERR, |
26 | NR_QDIO_IRQ_STATES, |
27 | }; |
28 | |
29 | /* used as intparm in do_IO */ |
30 | #define QDIO_DOING_ESTABLISH 1 |
31 | #define QDIO_DOING_ACTIVATE 2 |
32 | #define QDIO_DOING_CLEANUP 3 |
33 | |
34 | #define SLSB_STATE_NOT_INIT 0x0 |
35 | #define SLSB_STATE_EMPTY 0x1 |
36 | #define SLSB_STATE_PRIMED 0x2 |
37 | #define SLSB_STATE_PENDING 0x3 |
38 | #define SLSB_STATE_HALTED 0xe |
39 | #define SLSB_STATE_ERROR 0xf |
40 | #define SLSB_TYPE_INPUT 0x0 |
41 | #define SLSB_TYPE_OUTPUT 0x20 |
42 | #define SLSB_OWNER_PROG 0x80 |
43 | #define SLSB_OWNER_CU 0x40 |
44 | |
45 | #define SLSB_P_INPUT_NOT_INIT \ |
46 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_NOT_INIT) /* 0x80 */ |
47 | #define SLSB_P_INPUT_ACK \ |
48 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_EMPTY) /* 0x81 */ |
49 | #define SLSB_CU_INPUT_EMPTY \ |
50 | (SLSB_OWNER_CU | SLSB_TYPE_INPUT | SLSB_STATE_EMPTY) /* 0x41 */ |
51 | #define SLSB_P_INPUT_PRIMED \ |
52 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_PRIMED) /* 0x82 */ |
53 | #define SLSB_P_INPUT_HALTED \ |
54 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_HALTED) /* 0x8e */ |
55 | #define SLSB_P_INPUT_ERROR \ |
56 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_ERROR) /* 0x8f */ |
57 | #define SLSB_P_OUTPUT_NOT_INIT \ |
58 | (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_NOT_INIT) /* 0xa0 */ |
59 | #define SLSB_P_OUTPUT_EMPTY \ |
60 | (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_EMPTY) /* 0xa1 */ |
61 | #define SLSB_P_OUTPUT_PENDING \ |
62 | (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_PENDING) /* 0xa3 */ |
63 | #define SLSB_CU_OUTPUT_PRIMED \ |
64 | (SLSB_OWNER_CU | SLSB_TYPE_OUTPUT | SLSB_STATE_PRIMED) /* 0x62 */ |
65 | #define SLSB_P_OUTPUT_HALTED \ |
66 | (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_HALTED) /* 0xae */ |
67 | #define SLSB_P_OUTPUT_ERROR \ |
68 | (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_ERROR) /* 0xaf */ |
69 | |
70 | #define SLSB_ERROR_DURING_LOOKUP 0xff |
71 | |
72 | /* additional CIWs returned by extended Sense-ID */ |
73 | #define CIW_TYPE_EQUEUE 0x3 /* establish QDIO queues */ |
74 | #define CIW_TYPE_AQUEUE 0x4 /* activate QDIO queues */ |
75 | |
76 | /* flags for st qdio sch data */ |
77 | #define CHSC_FLAG_QDIO_CAPABILITY 0x80 |
78 | #define CHSC_FLAG_VALIDITY 0x40 |
79 | |
80 | /* SIGA flags */ |
81 | #define QDIO_SIGA_WRITE 0x00 |
82 | #define QDIO_SIGA_READ 0x01 |
83 | #define QDIO_SIGA_SYNC 0x02 |
84 | #define QDIO_SIGA_WRITEM 0x03 |
85 | #define QDIO_SIGA_WRITEQ 0x04 |
86 | #define QDIO_SIGA_QEBSM_FLAG 0x80 |
87 | |
88 | static inline int do_sqbs(u64 token, unsigned char state, int queue, |
89 | int *start, int *count) |
90 | { |
91 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; |
92 | unsigned long _ccq = *count; |
93 | |
94 | asm volatile( |
95 | " lgr 1,%[token]\n" |
96 | " .insn rsy,0xeb000000008a,%[qs],%[ccq],0(%[state])" |
97 | : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart) |
98 | : [state] "a" ((unsigned long)state), [token] "d" (token) |
99 | : "memory" , "cc" , "1" ); |
100 | *count = _ccq & 0xff; |
101 | *start = _queuestart & 0xff; |
102 | |
103 | return (_ccq >> 32) & 0xff; |
104 | } |
105 | |
106 | static inline int do_eqbs(u64 token, unsigned char *state, int queue, |
107 | int *start, int *count, int ack) |
108 | { |
109 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; |
110 | unsigned long _state = (unsigned long)ack << 63; |
111 | unsigned long _ccq = *count; |
112 | |
113 | asm volatile( |
114 | " lgr 1,%[token]\n" |
115 | " .insn rrf,0xb99c0000,%[qs],%[state],%[ccq],0" |
116 | : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart), |
117 | [state] "+&d" (_state) |
118 | : [token] "d" (token) |
119 | : "memory" , "cc" , "1" ); |
120 | *count = _ccq & 0xff; |
121 | *start = _queuestart & 0xff; |
122 | *state = _state & 0xff; |
123 | |
124 | return (_ccq >> 32) & 0xff; |
125 | } |
126 | |
127 | struct qdio_irq; |
128 | |
129 | struct qdio_dev_perf_stat { |
130 | unsigned int adapter_int; |
131 | unsigned int qdio_int; |
132 | |
133 | unsigned int siga_read; |
134 | unsigned int siga_write; |
135 | unsigned int siga_sync; |
136 | |
137 | unsigned int inbound_call; |
138 | unsigned int stop_polling; |
139 | unsigned int inbound_queue_full; |
140 | unsigned int outbound_call; |
141 | unsigned int outbound_queue_full; |
142 | unsigned int fast_requeue; |
143 | unsigned int target_full; |
144 | unsigned int eqbs; |
145 | unsigned int eqbs_partial; |
146 | unsigned int sqbs; |
147 | unsigned int sqbs_partial; |
148 | unsigned int int_discarded; |
149 | } ____cacheline_aligned; |
150 | |
151 | struct qdio_queue_perf_stat { |
152 | /* Sorted into order-2 buckets: 1, 2-3, 4-7, ... 64-127, 128. */ |
153 | unsigned int nr_sbals[8]; |
154 | unsigned int nr_sbal_error; |
155 | unsigned int nr_sbal_nop; |
156 | unsigned int nr_sbal_total; |
157 | }; |
158 | |
159 | enum qdio_irq_poll_states { |
160 | QDIO_IRQ_DISABLED, |
161 | }; |
162 | |
163 | struct qdio_input_q { |
164 | /* Batch of SBALs that we processed while polling the queue: */ |
165 | unsigned int batch_start; |
166 | unsigned int batch_count; |
167 | }; |
168 | |
169 | struct qdio_output_q { |
170 | }; |
171 | |
172 | /* |
173 | * Note on cache alignment: grouped slsb and write mostly data at the beginning |
174 | * sbal[] is read-only and starts on a new cacheline followed by read mostly. |
175 | */ |
176 | struct qdio_q { |
177 | struct slsb slsb; |
178 | |
179 | union { |
180 | struct qdio_input_q in; |
181 | struct qdio_output_q out; |
182 | } u; |
183 | |
184 | /* |
185 | * inbound: next buffer the program should check for |
186 | * outbound: next buffer to check if adapter processed it |
187 | */ |
188 | int first_to_check; |
189 | |
190 | /* number of buffers in use by the adapter */ |
191 | atomic_t nr_buf_used; |
192 | |
193 | /* last scan of the queue */ |
194 | u64 timestamp; |
195 | |
196 | struct qdio_queue_perf_stat q_stats; |
197 | |
198 | struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q] ____cacheline_aligned; |
199 | |
200 | /* queue number */ |
201 | int nr; |
202 | |
203 | /* bitmask of queue number */ |
204 | int mask; |
205 | |
206 | /* input or output queue */ |
207 | int is_input_q; |
208 | |
209 | /* upper-layer program handler */ |
210 | qdio_handler_t (*handler); |
211 | |
212 | struct qdio_irq *irq_ptr; |
213 | struct sl *sl; |
214 | /* |
215 | * A page is allocated under this pointer and used for slib and sl. |
216 | * slib is 2048 bytes big and sl points to offset PAGE_SIZE / 2. |
217 | */ |
218 | struct slib *slib; |
219 | } __attribute__ ((aligned(256))); |
220 | |
221 | struct qdio_irq { |
222 | struct qib qib; |
223 | u32 *dsci; /* address of device state change indicator */ |
224 | struct ccw_device *cdev; |
225 | struct list_head entry; /* list of thinint devices */ |
226 | struct dentry *debugfs_dev; |
227 | u64 last_data_irq_time; |
228 | |
229 | unsigned long int_parm; |
230 | struct subchannel_id schid; |
231 | unsigned long sch_token; /* QEBSM facility */ |
232 | |
233 | enum qdio_irq_states state; |
234 | u8 qdioac1; |
235 | |
236 | int nr_input_qs; |
237 | int nr_output_qs; |
238 | |
239 | struct ccw1 *ccw; |
240 | |
241 | struct qdio_ssqd_desc ssqd_desc; |
242 | void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); |
243 | qdio_handler_t (*error_handler); |
244 | |
245 | int perf_stat_enabled; |
246 | |
247 | struct qdr *qdr; |
248 | unsigned long chsc_page; |
249 | |
250 | struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ]; |
251 | struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ]; |
252 | unsigned int max_input_qs; |
253 | unsigned int max_output_qs; |
254 | |
255 | void (*irq_poll)(struct ccw_device *cdev, unsigned long data); |
256 | unsigned long poll_state; |
257 | |
258 | debug_info_t *debug_area; |
259 | struct mutex setup_mutex; |
260 | struct qdio_dev_perf_stat perf_stat; |
261 | }; |
262 | |
263 | /* helper functions */ |
264 | #define queue_type(q) q->irq_ptr->qib.qfmt |
265 | #define SCH_NO(q) (q->irq_ptr->schid.sch_no) |
266 | |
267 | #define is_thinint_irq(irq) \ |
268 | (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ |
269 | css_general_characteristics.aif_osa) |
270 | |
271 | #define qperf(__qdev, __attr) ((__qdev)->perf_stat.(__attr)) |
272 | |
273 | #define QDIO_PERF_STAT_INC(__irq, __attr) \ |
274 | ({ \ |
275 | struct qdio_irq *qdev = __irq; \ |
276 | if (qdev->perf_stat_enabled) \ |
277 | (qdev->perf_stat.__attr)++; \ |
278 | }) |
279 | |
280 | #define qperf_inc(__q, __attr) QDIO_PERF_STAT_INC((__q)->irq_ptr, __attr) |
281 | |
282 | static inline void account_sbals_error(struct qdio_q *q, int count) |
283 | { |
284 | q->q_stats.nr_sbal_error += count; |
285 | q->q_stats.nr_sbal_total += count; |
286 | } |
287 | |
288 | /* the highest iqdio queue is used for multicast */ |
289 | static inline int multicast_outbound(struct qdio_q *q) |
290 | { |
291 | return (q->irq_ptr->nr_output_qs > 1) && |
292 | (q->nr == q->irq_ptr->nr_output_qs - 1); |
293 | } |
294 | |
295 | static inline void qdio_deliver_irq(struct qdio_irq *irq) |
296 | { |
297 | if (!test_and_set_bit(nr: QDIO_IRQ_DISABLED, addr: &irq->poll_state)) |
298 | irq->irq_poll(irq->cdev, irq->int_parm); |
299 | else |
300 | QDIO_PERF_STAT_INC(irq, int_discarded); |
301 | } |
302 | |
303 | #define pci_out_supported(irq) ((irq)->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) |
304 | #define is_qebsm(q) (q->irq_ptr->sch_token != 0) |
305 | |
306 | #define qdio_need_siga_in(irq) ((irq)->qdioac1 & AC1_SIGA_INPUT_NEEDED) |
307 | #define qdio_need_siga_out(irq) ((irq)->qdioac1 & AC1_SIGA_OUTPUT_NEEDED) |
308 | #define qdio_need_siga_sync(irq) (unlikely((irq)->qdioac1 & AC1_SIGA_SYNC_NEEDED)) |
309 | |
310 | #define for_each_input_queue(irq_ptr, q, i) \ |
311 | for (i = 0; i < irq_ptr->nr_input_qs && \ |
312 | ({ q = irq_ptr->input_qs[i]; 1; }); i++) |
313 | #define for_each_output_queue(irq_ptr, q, i) \ |
314 | for (i = 0; i < irq_ptr->nr_output_qs && \ |
315 | ({ q = irq_ptr->output_qs[i]; 1; }); i++) |
316 | |
317 | #define add_buf(bufnr, inc) QDIO_BUFNR((bufnr) + (inc)) |
318 | #define next_buf(bufnr) add_buf(bufnr, 1) |
319 | #define sub_buf(bufnr, dec) QDIO_BUFNR((bufnr) - (dec)) |
320 | #define prev_buf(bufnr) sub_buf(bufnr, 1) |
321 | |
322 | extern u64 last_ai_time; |
323 | |
324 | /* prototypes for thin interrupt */ |
325 | int qdio_establish_thinint(struct qdio_irq *irq_ptr); |
326 | void qdio_shutdown_thinint(struct qdio_irq *irq_ptr); |
327 | int qdio_thinint_init(void); |
328 | void qdio_thinint_exit(void); |
329 | int test_nonshared_ind(struct qdio_irq *); |
330 | |
331 | /* prototypes for setup */ |
332 | void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, |
333 | struct irb *irb); |
334 | int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, |
335 | int nr_output_qs); |
336 | void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr); |
337 | int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr, |
338 | struct subchannel_id *schid, |
339 | struct qdio_ssqd_desc *data); |
340 | void qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data); |
341 | void qdio_shutdown_irq(struct qdio_irq *irq); |
342 | void qdio_print_subchannel_info(struct qdio_irq *irq_ptr); |
343 | void qdio_free_queues(struct qdio_irq *irq_ptr); |
344 | int qdio_setup_init(void); |
345 | void qdio_setup_exit(void); |
346 | |
347 | int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr, |
348 | unsigned char *state); |
349 | #endif /* _CIO_QDIO_H */ |
350 | |