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