18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2000, 2009 48c2ecf20Sopenharmony_ci * Author(s): Utz Bacher <utz.bacher@de.ibm.com> 58c2ecf20Sopenharmony_ci * Jan Glauber <jang@linux.vnet.ibm.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#ifndef _CIO_QDIO_H 88c2ecf20Sopenharmony_ci#define _CIO_QDIO_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <asm/page.h> 118c2ecf20Sopenharmony_ci#include <asm/schid.h> 128c2ecf20Sopenharmony_ci#include <asm/debug.h> 138c2ecf20Sopenharmony_ci#include "chsc.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define QDIO_BUSY_BIT_PATIENCE (100 << 12) /* 100 microseconds */ 168c2ecf20Sopenharmony_ci#define QDIO_BUSY_BIT_RETRY_DELAY 10 /* 10 milliseconds */ 178c2ecf20Sopenharmony_ci#define QDIO_BUSY_BIT_RETRIES 1000 /* = 10s retry time */ 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cienum qdio_irq_states { 208c2ecf20Sopenharmony_ci QDIO_IRQ_STATE_INACTIVE, 218c2ecf20Sopenharmony_ci QDIO_IRQ_STATE_ESTABLISHED, 228c2ecf20Sopenharmony_ci QDIO_IRQ_STATE_ACTIVE, 238c2ecf20Sopenharmony_ci QDIO_IRQ_STATE_STOPPED, 248c2ecf20Sopenharmony_ci QDIO_IRQ_STATE_CLEANUP, 258c2ecf20Sopenharmony_ci QDIO_IRQ_STATE_ERR, 268c2ecf20Sopenharmony_ci NR_QDIO_IRQ_STATES, 278c2ecf20Sopenharmony_ci}; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* used as intparm in do_IO */ 308c2ecf20Sopenharmony_ci#define QDIO_DOING_ESTABLISH 1 318c2ecf20Sopenharmony_ci#define QDIO_DOING_ACTIVATE 2 328c2ecf20Sopenharmony_ci#define QDIO_DOING_CLEANUP 3 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define SLSB_STATE_NOT_INIT 0x0 358c2ecf20Sopenharmony_ci#define SLSB_STATE_EMPTY 0x1 368c2ecf20Sopenharmony_ci#define SLSB_STATE_PRIMED 0x2 378c2ecf20Sopenharmony_ci#define SLSB_STATE_PENDING 0x3 388c2ecf20Sopenharmony_ci#define SLSB_STATE_HALTED 0xe 398c2ecf20Sopenharmony_ci#define SLSB_STATE_ERROR 0xf 408c2ecf20Sopenharmony_ci#define SLSB_TYPE_INPUT 0x0 418c2ecf20Sopenharmony_ci#define SLSB_TYPE_OUTPUT 0x20 428c2ecf20Sopenharmony_ci#define SLSB_OWNER_PROG 0x80 438c2ecf20Sopenharmony_ci#define SLSB_OWNER_CU 0x40 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define SLSB_P_INPUT_NOT_INIT \ 468c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_NOT_INIT) /* 0x80 */ 478c2ecf20Sopenharmony_ci#define SLSB_P_INPUT_ACK \ 488c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_EMPTY) /* 0x81 */ 498c2ecf20Sopenharmony_ci#define SLSB_CU_INPUT_EMPTY \ 508c2ecf20Sopenharmony_ci (SLSB_OWNER_CU | SLSB_TYPE_INPUT | SLSB_STATE_EMPTY) /* 0x41 */ 518c2ecf20Sopenharmony_ci#define SLSB_P_INPUT_PRIMED \ 528c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_PRIMED) /* 0x82 */ 538c2ecf20Sopenharmony_ci#define SLSB_P_INPUT_HALTED \ 548c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_HALTED) /* 0x8e */ 558c2ecf20Sopenharmony_ci#define SLSB_P_INPUT_ERROR \ 568c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_ERROR) /* 0x8f */ 578c2ecf20Sopenharmony_ci#define SLSB_P_OUTPUT_NOT_INIT \ 588c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_NOT_INIT) /* 0xa0 */ 598c2ecf20Sopenharmony_ci#define SLSB_P_OUTPUT_EMPTY \ 608c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_EMPTY) /* 0xa1 */ 618c2ecf20Sopenharmony_ci#define SLSB_P_OUTPUT_PENDING \ 628c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_PENDING) /* 0xa3 */ 638c2ecf20Sopenharmony_ci#define SLSB_CU_OUTPUT_PRIMED \ 648c2ecf20Sopenharmony_ci (SLSB_OWNER_CU | SLSB_TYPE_OUTPUT | SLSB_STATE_PRIMED) /* 0x62 */ 658c2ecf20Sopenharmony_ci#define SLSB_P_OUTPUT_HALTED \ 668c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_HALTED) /* 0xae */ 678c2ecf20Sopenharmony_ci#define SLSB_P_OUTPUT_ERROR \ 688c2ecf20Sopenharmony_ci (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_ERROR) /* 0xaf */ 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci#define SLSB_ERROR_DURING_LOOKUP 0xff 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* additional CIWs returned by extended Sense-ID */ 738c2ecf20Sopenharmony_ci#define CIW_TYPE_EQUEUE 0x3 /* establish QDIO queues */ 748c2ecf20Sopenharmony_ci#define CIW_TYPE_AQUEUE 0x4 /* activate QDIO queues */ 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/* flags for st qdio sch data */ 778c2ecf20Sopenharmony_ci#define CHSC_FLAG_QDIO_CAPABILITY 0x80 788c2ecf20Sopenharmony_ci#define CHSC_FLAG_VALIDITY 0x40 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci/* SIGA flags */ 818c2ecf20Sopenharmony_ci#define QDIO_SIGA_WRITE 0x00 828c2ecf20Sopenharmony_ci#define QDIO_SIGA_READ 0x01 838c2ecf20Sopenharmony_ci#define QDIO_SIGA_SYNC 0x02 848c2ecf20Sopenharmony_ci#define QDIO_SIGA_WRITEM 0x03 858c2ecf20Sopenharmony_ci#define QDIO_SIGA_WRITEQ 0x04 868c2ecf20Sopenharmony_ci#define QDIO_SIGA_QEBSM_FLAG 0x80 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic inline int do_sqbs(u64 token, unsigned char state, int queue, 898c2ecf20Sopenharmony_ci int *start, int *count) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci unsigned long _queuestart = ((unsigned long)queue << 32) | *start; 928c2ecf20Sopenharmony_ci unsigned long _ccq = *count; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci asm volatile( 958c2ecf20Sopenharmony_ci " lgr 1,%[token]\n" 968c2ecf20Sopenharmony_ci " .insn rsy,0xeb000000008a,%[qs],%[ccq],0(%[state])" 978c2ecf20Sopenharmony_ci : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart) 988c2ecf20Sopenharmony_ci : [state] "a" ((unsigned long)state), [token] "d" (token) 998c2ecf20Sopenharmony_ci : "memory", "cc", "1"); 1008c2ecf20Sopenharmony_ci *count = _ccq & 0xff; 1018c2ecf20Sopenharmony_ci *start = _queuestart & 0xff; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci return (_ccq >> 32) & 0xff; 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic inline int do_eqbs(u64 token, unsigned char *state, int queue, 1078c2ecf20Sopenharmony_ci int *start, int *count, int ack) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci unsigned long _queuestart = ((unsigned long)queue << 32) | *start; 1108c2ecf20Sopenharmony_ci unsigned long _state = (unsigned long)ack << 63; 1118c2ecf20Sopenharmony_ci unsigned long _ccq = *count; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci asm volatile( 1148c2ecf20Sopenharmony_ci " lgr 1,%[token]\n" 1158c2ecf20Sopenharmony_ci " .insn rrf,0xb99c0000,%[qs],%[state],%[ccq],0" 1168c2ecf20Sopenharmony_ci : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart), 1178c2ecf20Sopenharmony_ci [state] "+&d" (_state) 1188c2ecf20Sopenharmony_ci : [token] "d" (token) 1198c2ecf20Sopenharmony_ci : "memory", "cc", "1"); 1208c2ecf20Sopenharmony_ci *count = _ccq & 0xff; 1218c2ecf20Sopenharmony_ci *start = _queuestart & 0xff; 1228c2ecf20Sopenharmony_ci *state = _state & 0xff; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci return (_ccq >> 32) & 0xff; 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistruct qdio_irq; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_cistruct siga_flag { 1308c2ecf20Sopenharmony_ci u8 input:1; 1318c2ecf20Sopenharmony_ci u8 output:1; 1328c2ecf20Sopenharmony_ci u8 sync:1; 1338c2ecf20Sopenharmony_ci u8 sync_after_ai:1; 1348c2ecf20Sopenharmony_ci u8 sync_out_after_pci:1; 1358c2ecf20Sopenharmony_ci u8:3; 1368c2ecf20Sopenharmony_ci} __attribute__ ((packed)); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistruct qdio_dev_perf_stat { 1398c2ecf20Sopenharmony_ci unsigned int adapter_int; 1408c2ecf20Sopenharmony_ci unsigned int qdio_int; 1418c2ecf20Sopenharmony_ci unsigned int pci_request_int; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci unsigned int tasklet_inbound; 1448c2ecf20Sopenharmony_ci unsigned int tasklet_inbound_resched; 1458c2ecf20Sopenharmony_ci unsigned int tasklet_inbound_resched2; 1468c2ecf20Sopenharmony_ci unsigned int tasklet_outbound; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci unsigned int siga_read; 1498c2ecf20Sopenharmony_ci unsigned int siga_write; 1508c2ecf20Sopenharmony_ci unsigned int siga_sync; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci unsigned int inbound_call; 1538c2ecf20Sopenharmony_ci unsigned int inbound_handler; 1548c2ecf20Sopenharmony_ci unsigned int stop_polling; 1558c2ecf20Sopenharmony_ci unsigned int inbound_queue_full; 1568c2ecf20Sopenharmony_ci unsigned int outbound_call; 1578c2ecf20Sopenharmony_ci unsigned int outbound_handler; 1588c2ecf20Sopenharmony_ci unsigned int outbound_queue_full; 1598c2ecf20Sopenharmony_ci unsigned int fast_requeue; 1608c2ecf20Sopenharmony_ci unsigned int target_full; 1618c2ecf20Sopenharmony_ci unsigned int eqbs; 1628c2ecf20Sopenharmony_ci unsigned int eqbs_partial; 1638c2ecf20Sopenharmony_ci unsigned int sqbs; 1648c2ecf20Sopenharmony_ci unsigned int sqbs_partial; 1658c2ecf20Sopenharmony_ci unsigned int int_discarded; 1668c2ecf20Sopenharmony_ci} ____cacheline_aligned; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistruct qdio_queue_perf_stat { 1698c2ecf20Sopenharmony_ci /* Sorted into order-2 buckets: 1, 2-3, 4-7, ... 64-127, 128. */ 1708c2ecf20Sopenharmony_ci unsigned int nr_sbals[8]; 1718c2ecf20Sopenharmony_ci unsigned int nr_sbal_error; 1728c2ecf20Sopenharmony_ci unsigned int nr_sbal_nop; 1738c2ecf20Sopenharmony_ci unsigned int nr_sbal_total; 1748c2ecf20Sopenharmony_ci}; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cienum qdio_irq_poll_states { 1778c2ecf20Sopenharmony_ci QDIO_IRQ_DISABLED, 1788c2ecf20Sopenharmony_ci}; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistruct qdio_input_q { 1818c2ecf20Sopenharmony_ci /* Batch of SBALs that we processed while polling the queue: */ 1828c2ecf20Sopenharmony_ci unsigned int batch_start; 1838c2ecf20Sopenharmony_ci unsigned int batch_count; 1848c2ecf20Sopenharmony_ci}; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_cistruct qdio_output_q { 1878c2ecf20Sopenharmony_ci /* PCIs are enabled for the queue */ 1888c2ecf20Sopenharmony_ci int pci_out_enabled; 1898c2ecf20Sopenharmony_ci /* cq: use asynchronous output buffers */ 1908c2ecf20Sopenharmony_ci int use_cq; 1918c2ecf20Sopenharmony_ci /* cq: aobs used for particual SBAL */ 1928c2ecf20Sopenharmony_ci struct qaob **aobs; 1938c2ecf20Sopenharmony_ci /* cq: sbal state related to asynchronous operation */ 1948c2ecf20Sopenharmony_ci struct qdio_outbuf_state *sbal_state; 1958c2ecf20Sopenharmony_ci /* timer to check for more outbound work */ 1968c2ecf20Sopenharmony_ci struct timer_list timer; 1978c2ecf20Sopenharmony_ci}; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci/* 2008c2ecf20Sopenharmony_ci * Note on cache alignment: grouped slsb and write mostly data at the beginning 2018c2ecf20Sopenharmony_ci * sbal[] is read-only and starts on a new cacheline followed by read mostly. 2028c2ecf20Sopenharmony_ci */ 2038c2ecf20Sopenharmony_cistruct qdio_q { 2048c2ecf20Sopenharmony_ci struct slsb slsb; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci union { 2078c2ecf20Sopenharmony_ci struct qdio_input_q in; 2088c2ecf20Sopenharmony_ci struct qdio_output_q out; 2098c2ecf20Sopenharmony_ci } u; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci /* 2128c2ecf20Sopenharmony_ci * inbound: next buffer the program should check for 2138c2ecf20Sopenharmony_ci * outbound: next buffer to check if adapter processed it 2148c2ecf20Sopenharmony_ci */ 2158c2ecf20Sopenharmony_ci int first_to_check; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci /* number of buffers in use by the adapter */ 2188c2ecf20Sopenharmony_ci atomic_t nr_buf_used; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci /* error condition during a data transfer */ 2218c2ecf20Sopenharmony_ci unsigned int qdio_error; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci /* last scan of the queue */ 2248c2ecf20Sopenharmony_ci u64 timestamp; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci struct tasklet_struct tasklet; 2278c2ecf20Sopenharmony_ci struct qdio_queue_perf_stat q_stats; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q] ____cacheline_aligned; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci /* queue number */ 2328c2ecf20Sopenharmony_ci int nr; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci /* bitmask of queue number */ 2358c2ecf20Sopenharmony_ci int mask; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci /* input or output queue */ 2388c2ecf20Sopenharmony_ci int is_input_q; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci /* upper-layer program handler */ 2418c2ecf20Sopenharmony_ci qdio_handler_t (*handler); 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci struct qdio_irq *irq_ptr; 2448c2ecf20Sopenharmony_ci struct sl *sl; 2458c2ecf20Sopenharmony_ci /* 2468c2ecf20Sopenharmony_ci * A page is allocated under this pointer and used for slib and sl. 2478c2ecf20Sopenharmony_ci * slib is 2048 bytes big and sl points to offset PAGE_SIZE / 2. 2488c2ecf20Sopenharmony_ci */ 2498c2ecf20Sopenharmony_ci struct slib *slib; 2508c2ecf20Sopenharmony_ci} __attribute__ ((aligned(256))); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistruct qdio_irq { 2538c2ecf20Sopenharmony_ci struct qib qib; 2548c2ecf20Sopenharmony_ci u32 *dsci; /* address of device state change indicator */ 2558c2ecf20Sopenharmony_ci struct ccw_device *cdev; 2568c2ecf20Sopenharmony_ci struct list_head entry; /* list of thinint devices */ 2578c2ecf20Sopenharmony_ci struct dentry *debugfs_dev; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci unsigned long int_parm; 2608c2ecf20Sopenharmony_ci struct subchannel_id schid; 2618c2ecf20Sopenharmony_ci unsigned long sch_token; /* QEBSM facility */ 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci enum qdio_irq_states state; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci struct siga_flag siga_flag; /* siga sync information from qdioac */ 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci int nr_input_qs; 2688c2ecf20Sopenharmony_ci int nr_output_qs; 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci struct ccw1 ccw; 2718c2ecf20Sopenharmony_ci struct ciw equeue; 2728c2ecf20Sopenharmony_ci struct ciw aqueue; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci struct qdio_ssqd_desc ssqd_desc; 2758c2ecf20Sopenharmony_ci void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci unsigned int scan_threshold; /* used SBALs before tasklet schedule */ 2788c2ecf20Sopenharmony_ci int perf_stat_enabled; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci struct qdr *qdr; 2818c2ecf20Sopenharmony_ci unsigned long chsc_page; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ]; 2848c2ecf20Sopenharmony_ci struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ]; 2858c2ecf20Sopenharmony_ci unsigned int max_input_qs; 2868c2ecf20Sopenharmony_ci unsigned int max_output_qs; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci void (*irq_poll)(struct ccw_device *cdev, unsigned long data); 2898c2ecf20Sopenharmony_ci unsigned long poll_state; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci debug_info_t *debug_area; 2928c2ecf20Sopenharmony_ci struct mutex setup_mutex; 2938c2ecf20Sopenharmony_ci struct qdio_dev_perf_stat perf_stat; 2948c2ecf20Sopenharmony_ci}; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci/* helper functions */ 2978c2ecf20Sopenharmony_ci#define queue_type(q) q->irq_ptr->qib.qfmt 2988c2ecf20Sopenharmony_ci#define SCH_NO(q) (q->irq_ptr->schid.sch_no) 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci#define is_thinint_irq(irq) \ 3018c2ecf20Sopenharmony_ci (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ 3028c2ecf20Sopenharmony_ci css_general_characteristics.aif_osa) 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci#define qperf(__qdev, __attr) ((__qdev)->perf_stat.(__attr)) 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci#define QDIO_PERF_STAT_INC(__irq, __attr) \ 3078c2ecf20Sopenharmony_ci({ \ 3088c2ecf20Sopenharmony_ci struct qdio_irq *qdev = __irq; \ 3098c2ecf20Sopenharmony_ci if (qdev->perf_stat_enabled) \ 3108c2ecf20Sopenharmony_ci (qdev->perf_stat.__attr)++; \ 3118c2ecf20Sopenharmony_ci}) 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci#define qperf_inc(__q, __attr) QDIO_PERF_STAT_INC((__q)->irq_ptr, __attr) 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_cistatic inline void account_sbals_error(struct qdio_q *q, int count) 3168c2ecf20Sopenharmony_ci{ 3178c2ecf20Sopenharmony_ci q->q_stats.nr_sbal_error += count; 3188c2ecf20Sopenharmony_ci q->q_stats.nr_sbal_total += count; 3198c2ecf20Sopenharmony_ci} 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* the highest iqdio queue is used for multicast */ 3228c2ecf20Sopenharmony_cistatic inline int multicast_outbound(struct qdio_q *q) 3238c2ecf20Sopenharmony_ci{ 3248c2ecf20Sopenharmony_ci return (q->irq_ptr->nr_output_qs > 1) && 3258c2ecf20Sopenharmony_ci (q->nr == q->irq_ptr->nr_output_qs - 1); 3268c2ecf20Sopenharmony_ci} 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci#define pci_out_supported(irq) ((irq)->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) 3298c2ecf20Sopenharmony_ci#define is_qebsm(q) (q->irq_ptr->sch_token != 0) 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci#define need_siga_in(q) (q->irq_ptr->siga_flag.input) 3328c2ecf20Sopenharmony_ci#define need_siga_out(q) (q->irq_ptr->siga_flag.output) 3338c2ecf20Sopenharmony_ci#define need_siga_sync(q) (unlikely(q->irq_ptr->siga_flag.sync)) 3348c2ecf20Sopenharmony_ci#define need_siga_sync_after_ai(q) \ 3358c2ecf20Sopenharmony_ci (unlikely(q->irq_ptr->siga_flag.sync_after_ai)) 3368c2ecf20Sopenharmony_ci#define need_siga_sync_out_after_pci(q) \ 3378c2ecf20Sopenharmony_ci (unlikely(q->irq_ptr->siga_flag.sync_out_after_pci)) 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci#define for_each_input_queue(irq_ptr, q, i) \ 3408c2ecf20Sopenharmony_ci for (i = 0; i < irq_ptr->nr_input_qs && \ 3418c2ecf20Sopenharmony_ci ({ q = irq_ptr->input_qs[i]; 1; }); i++) 3428c2ecf20Sopenharmony_ci#define for_each_output_queue(irq_ptr, q, i) \ 3438c2ecf20Sopenharmony_ci for (i = 0; i < irq_ptr->nr_output_qs && \ 3448c2ecf20Sopenharmony_ci ({ q = irq_ptr->output_qs[i]; 1; }); i++) 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci#define add_buf(bufnr, inc) QDIO_BUFNR((bufnr) + (inc)) 3478c2ecf20Sopenharmony_ci#define next_buf(bufnr) add_buf(bufnr, 1) 3488c2ecf20Sopenharmony_ci#define sub_buf(bufnr, dec) QDIO_BUFNR((bufnr) - (dec)) 3498c2ecf20Sopenharmony_ci#define prev_buf(bufnr) sub_buf(bufnr, 1) 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci#define queue_irqs_enabled(q) \ 3528c2ecf20Sopenharmony_ci (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) == 0) 3538c2ecf20Sopenharmony_ci#define queue_irqs_disabled(q) \ 3548c2ecf20Sopenharmony_ci (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0) 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ciextern u64 last_ai_time; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci/* prototypes for thin interrupt */ 3598c2ecf20Sopenharmony_ciint qdio_establish_thinint(struct qdio_irq *irq_ptr); 3608c2ecf20Sopenharmony_civoid qdio_shutdown_thinint(struct qdio_irq *irq_ptr); 3618c2ecf20Sopenharmony_civoid tiqdio_add_device(struct qdio_irq *irq_ptr); 3628c2ecf20Sopenharmony_civoid tiqdio_remove_device(struct qdio_irq *irq_ptr); 3638c2ecf20Sopenharmony_civoid tiqdio_inbound_processing(unsigned long q); 3648c2ecf20Sopenharmony_ciint qdio_thinint_init(void); 3658c2ecf20Sopenharmony_civoid qdio_thinint_exit(void); 3668c2ecf20Sopenharmony_ciint test_nonshared_ind(struct qdio_irq *); 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci/* prototypes for setup */ 3698c2ecf20Sopenharmony_civoid qdio_inbound_processing(unsigned long data); 3708c2ecf20Sopenharmony_civoid qdio_outbound_processing(unsigned long data); 3718c2ecf20Sopenharmony_civoid qdio_outbound_timer(struct timer_list *t); 3728c2ecf20Sopenharmony_civoid qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, 3738c2ecf20Sopenharmony_ci struct irb *irb); 3748c2ecf20Sopenharmony_ciint qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, 3758c2ecf20Sopenharmony_ci int nr_output_qs); 3768c2ecf20Sopenharmony_civoid qdio_setup_ssqd_info(struct qdio_irq *irq_ptr); 3778c2ecf20Sopenharmony_ciint qdio_setup_get_ssqd(struct qdio_irq *irq_ptr, 3788c2ecf20Sopenharmony_ci struct subchannel_id *schid, 3798c2ecf20Sopenharmony_ci struct qdio_ssqd_desc *data); 3808c2ecf20Sopenharmony_ciint qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data); 3818c2ecf20Sopenharmony_civoid qdio_shutdown_irq(struct qdio_irq *irq); 3828c2ecf20Sopenharmony_civoid qdio_print_subchannel_info(struct qdio_irq *irq_ptr); 3838c2ecf20Sopenharmony_civoid qdio_free_queues(struct qdio_irq *irq_ptr); 3848c2ecf20Sopenharmony_civoid qdio_free_async_data(struct qdio_irq *irq_ptr); 3858c2ecf20Sopenharmony_ciint qdio_setup_init(void); 3868c2ecf20Sopenharmony_civoid qdio_setup_exit(void); 3878c2ecf20Sopenharmony_ciint qdio_enable_async_operation(struct qdio_output_q *q); 3888c2ecf20Sopenharmony_civoid qdio_disable_async_operation(struct qdio_output_q *q); 3898c2ecf20Sopenharmony_cistruct qaob *qdio_allocate_aob(void); 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ciint debug_get_buf_state(struct qdio_q *q, unsigned int bufnr, 3928c2ecf20Sopenharmony_ci unsigned char *state); 3938c2ecf20Sopenharmony_ci#endif /* _CIO_QDIO_H */ 394