18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef S390_ISM_H 38c2ecf20Sopenharmony_ci#define S390_ISM_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 68c2ecf20Sopenharmony_ci#include <linux/types.h> 78c2ecf20Sopenharmony_ci#include <linux/pci.h> 88c2ecf20Sopenharmony_ci#include <net/smc.h> 98c2ecf20Sopenharmony_ci#include <asm/pci_insn.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#define UTIL_STR_LEN 16 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * Do not use the first word of the DMB bits to ensure 8 byte aligned access. 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci#define ISM_DMB_WORD_OFFSET 1 178c2ecf20Sopenharmony_ci#define ISM_DMB_BIT_OFFSET (ISM_DMB_WORD_OFFSET * 32) 188c2ecf20Sopenharmony_ci#define ISM_NR_DMBS 1920 198c2ecf20Sopenharmony_ci#define ISM_IDENT_MASK 0x00FFFF 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define ISM_REG_SBA 0x1 228c2ecf20Sopenharmony_ci#define ISM_REG_IEQ 0x2 238c2ecf20Sopenharmony_ci#define ISM_READ_GID 0x3 248c2ecf20Sopenharmony_ci#define ISM_ADD_VLAN_ID 0x4 258c2ecf20Sopenharmony_ci#define ISM_DEL_VLAN_ID 0x5 268c2ecf20Sopenharmony_ci#define ISM_SET_VLAN 0x6 278c2ecf20Sopenharmony_ci#define ISM_RESET_VLAN 0x7 288c2ecf20Sopenharmony_ci#define ISM_QUERY_INFO 0x8 298c2ecf20Sopenharmony_ci#define ISM_QUERY_RGID 0x9 308c2ecf20Sopenharmony_ci#define ISM_REG_DMB 0xA 318c2ecf20Sopenharmony_ci#define ISM_UNREG_DMB 0xB 328c2ecf20Sopenharmony_ci#define ISM_SIGNAL_IEQ 0xE 338c2ecf20Sopenharmony_ci#define ISM_UNREG_SBA 0x11 348c2ecf20Sopenharmony_ci#define ISM_UNREG_IEQ 0x12 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistruct ism_req_hdr { 378c2ecf20Sopenharmony_ci u32 cmd; 388c2ecf20Sopenharmony_ci u16 : 16; 398c2ecf20Sopenharmony_ci u16 len; 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistruct ism_resp_hdr { 438c2ecf20Sopenharmony_ci u32 cmd; 448c2ecf20Sopenharmony_ci u16 ret; 458c2ecf20Sopenharmony_ci u16 len; 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ciunion ism_reg_sba { 498c2ecf20Sopenharmony_ci struct { 508c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 518c2ecf20Sopenharmony_ci u64 sba; 528c2ecf20Sopenharmony_ci } request; 538c2ecf20Sopenharmony_ci struct { 548c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 558c2ecf20Sopenharmony_ci } response; 568c2ecf20Sopenharmony_ci} __aligned(16); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ciunion ism_reg_ieq { 598c2ecf20Sopenharmony_ci struct { 608c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 618c2ecf20Sopenharmony_ci u64 ieq; 628c2ecf20Sopenharmony_ci u64 len; 638c2ecf20Sopenharmony_ci } request; 648c2ecf20Sopenharmony_ci struct { 658c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 668c2ecf20Sopenharmony_ci } response; 678c2ecf20Sopenharmony_ci} __aligned(16); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ciunion ism_read_gid { 708c2ecf20Sopenharmony_ci struct { 718c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 728c2ecf20Sopenharmony_ci } request; 738c2ecf20Sopenharmony_ci struct { 748c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 758c2ecf20Sopenharmony_ci u64 gid; 768c2ecf20Sopenharmony_ci } response; 778c2ecf20Sopenharmony_ci} __aligned(16); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ciunion ism_qi { 808c2ecf20Sopenharmony_ci struct { 818c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 828c2ecf20Sopenharmony_ci } request; 838c2ecf20Sopenharmony_ci struct { 848c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 858c2ecf20Sopenharmony_ci u32 version; 868c2ecf20Sopenharmony_ci u32 max_len; 878c2ecf20Sopenharmony_ci u64 ism_state; 888c2ecf20Sopenharmony_ci u64 my_gid; 898c2ecf20Sopenharmony_ci u64 sba; 908c2ecf20Sopenharmony_ci u64 ieq; 918c2ecf20Sopenharmony_ci u32 ieq_len; 928c2ecf20Sopenharmony_ci u32 : 32; 938c2ecf20Sopenharmony_ci u32 dmbs_owned; 948c2ecf20Sopenharmony_ci u32 dmbs_used; 958c2ecf20Sopenharmony_ci u32 vlan_required; 968c2ecf20Sopenharmony_ci u32 vlan_nr_ids; 978c2ecf20Sopenharmony_ci u16 vlan_id[64]; 988c2ecf20Sopenharmony_ci } response; 998c2ecf20Sopenharmony_ci} __aligned(64); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ciunion ism_query_rgid { 1028c2ecf20Sopenharmony_ci struct { 1038c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 1048c2ecf20Sopenharmony_ci u64 rgid; 1058c2ecf20Sopenharmony_ci u32 vlan_valid; 1068c2ecf20Sopenharmony_ci u32 vlan_id; 1078c2ecf20Sopenharmony_ci } request; 1088c2ecf20Sopenharmony_ci struct { 1098c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 1108c2ecf20Sopenharmony_ci } response; 1118c2ecf20Sopenharmony_ci} __aligned(16); 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ciunion ism_reg_dmb { 1148c2ecf20Sopenharmony_ci struct { 1158c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 1168c2ecf20Sopenharmony_ci u64 dmb; 1178c2ecf20Sopenharmony_ci u32 dmb_len; 1188c2ecf20Sopenharmony_ci u32 sba_idx; 1198c2ecf20Sopenharmony_ci u32 vlan_valid; 1208c2ecf20Sopenharmony_ci u32 vlan_id; 1218c2ecf20Sopenharmony_ci u64 rgid; 1228c2ecf20Sopenharmony_ci } request; 1238c2ecf20Sopenharmony_ci struct { 1248c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 1258c2ecf20Sopenharmony_ci u64 dmb_tok; 1268c2ecf20Sopenharmony_ci } response; 1278c2ecf20Sopenharmony_ci} __aligned(32); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ciunion ism_sig_ieq { 1308c2ecf20Sopenharmony_ci struct { 1318c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 1328c2ecf20Sopenharmony_ci u64 rgid; 1338c2ecf20Sopenharmony_ci u32 trigger_irq; 1348c2ecf20Sopenharmony_ci u32 event_code; 1358c2ecf20Sopenharmony_ci u64 info; 1368c2ecf20Sopenharmony_ci } request; 1378c2ecf20Sopenharmony_ci struct { 1388c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 1398c2ecf20Sopenharmony_ci } response; 1408c2ecf20Sopenharmony_ci} __aligned(32); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ciunion ism_unreg_dmb { 1438c2ecf20Sopenharmony_ci struct { 1448c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 1458c2ecf20Sopenharmony_ci u64 dmb_tok; 1468c2ecf20Sopenharmony_ci } request; 1478c2ecf20Sopenharmony_ci struct { 1488c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 1498c2ecf20Sopenharmony_ci } response; 1508c2ecf20Sopenharmony_ci} __aligned(16); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ciunion ism_cmd_simple { 1538c2ecf20Sopenharmony_ci struct { 1548c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 1558c2ecf20Sopenharmony_ci } request; 1568c2ecf20Sopenharmony_ci struct { 1578c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 1588c2ecf20Sopenharmony_ci } response; 1598c2ecf20Sopenharmony_ci} __aligned(8); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ciunion ism_set_vlan_id { 1628c2ecf20Sopenharmony_ci struct { 1638c2ecf20Sopenharmony_ci struct ism_req_hdr hdr; 1648c2ecf20Sopenharmony_ci u64 vlan_id; 1658c2ecf20Sopenharmony_ci } request; 1668c2ecf20Sopenharmony_ci struct { 1678c2ecf20Sopenharmony_ci struct ism_resp_hdr hdr; 1688c2ecf20Sopenharmony_ci } response; 1698c2ecf20Sopenharmony_ci} __aligned(16); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_cistruct ism_eq_header { 1728c2ecf20Sopenharmony_ci u64 idx; 1738c2ecf20Sopenharmony_ci u64 ieq_len; 1748c2ecf20Sopenharmony_ci u64 entry_len; 1758c2ecf20Sopenharmony_ci u64 : 64; 1768c2ecf20Sopenharmony_ci}; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistruct ism_eq { 1798c2ecf20Sopenharmony_ci struct ism_eq_header header; 1808c2ecf20Sopenharmony_ci struct smcd_event entry[15]; 1818c2ecf20Sopenharmony_ci}; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistruct ism_sba { 1848c2ecf20Sopenharmony_ci u32 s : 1; /* summary bit */ 1858c2ecf20Sopenharmony_ci u32 e : 1; /* event bit */ 1868c2ecf20Sopenharmony_ci u32 : 30; 1878c2ecf20Sopenharmony_ci u32 dmb_bits[ISM_NR_DMBS / 32]; 1888c2ecf20Sopenharmony_ci u32 reserved[3]; 1898c2ecf20Sopenharmony_ci u16 dmbe_mask[ISM_NR_DMBS]; 1908c2ecf20Sopenharmony_ci}; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistruct ism_dev { 1938c2ecf20Sopenharmony_ci spinlock_t lock; 1948c2ecf20Sopenharmony_ci struct pci_dev *pdev; 1958c2ecf20Sopenharmony_ci struct smcd_dev *smcd; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci struct ism_sba *sba; 1988c2ecf20Sopenharmony_ci dma_addr_t sba_dma_addr; 1998c2ecf20Sopenharmony_ci DECLARE_BITMAP(sba_bitmap, ISM_NR_DMBS); 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci struct ism_eq *ieq; 2028c2ecf20Sopenharmony_ci dma_addr_t ieq_dma_addr; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci int ieq_idx; 2058c2ecf20Sopenharmony_ci}; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci#define ISM_CREATE_REQ(dmb, idx, sf, offset) \ 2088c2ecf20Sopenharmony_ci ((dmb) | (idx) << 24 | (sf) << 23 | (offset)) 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistruct ism_systemeid { 2118c2ecf20Sopenharmony_ci u8 seid_string[24]; 2128c2ecf20Sopenharmony_ci u8 serial_number[4]; 2138c2ecf20Sopenharmony_ci u8 type[4]; 2148c2ecf20Sopenharmony_ci}; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic inline void __ism_read_cmd(struct ism_dev *ism, void *data, 2178c2ecf20Sopenharmony_ci unsigned long offset, unsigned long len) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci struct zpci_dev *zdev = to_zpci(ism->pdev); 2208c2ecf20Sopenharmony_ci u64 req = ZPCI_CREATE_REQ(zdev->fh, 2, 8); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci while (len > 0) { 2238c2ecf20Sopenharmony_ci __zpci_load(data, req, offset); 2248c2ecf20Sopenharmony_ci offset += 8; 2258c2ecf20Sopenharmony_ci data += 8; 2268c2ecf20Sopenharmony_ci len -= 8; 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic inline void __ism_write_cmd(struct ism_dev *ism, void *data, 2318c2ecf20Sopenharmony_ci unsigned long offset, unsigned long len) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci struct zpci_dev *zdev = to_zpci(ism->pdev); 2348c2ecf20Sopenharmony_ci u64 req = ZPCI_CREATE_REQ(zdev->fh, 2, len); 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci if (len) 2378c2ecf20Sopenharmony_ci __zpci_store_block(data, req, offset); 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic inline int __ism_move(struct ism_dev *ism, u64 dmb_req, void *data, 2418c2ecf20Sopenharmony_ci unsigned int size) 2428c2ecf20Sopenharmony_ci{ 2438c2ecf20Sopenharmony_ci struct zpci_dev *zdev = to_zpci(ism->pdev); 2448c2ecf20Sopenharmony_ci u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, size); 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci return __zpci_store_block(data, req, dmb_req); 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci#endif /* S390_ISM_H */ 250