2018-06-28 19:05:13 +02:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef S390_ISM_H
# define S390_ISM_H
# include <linux/spinlock.h>
# include <linux/types.h>
# include <linux/pci.h>
# include <net/smc.h>
2019-04-23 11:57:46 +02:00
# include <asm/pci_insn.h>
2018-06-28 19:05:13 +02:00
# define UTIL_STR_LEN 16
/*
* Do not use the first word of the DMB bits to ensure 8 byte aligned access .
*/
# define ISM_DMB_WORD_OFFSET 1
# define ISM_DMB_BIT_OFFSET (ISM_DMB_WORD_OFFSET * 32)
# define ISM_NR_DMBS 1920
# define ISM_REG_SBA 0x1
# define ISM_REG_IEQ 0x2
# define ISM_READ_GID 0x3
# define ISM_ADD_VLAN_ID 0x4
# define ISM_DEL_VLAN_ID 0x5
# define ISM_SET_VLAN 0x6
# define ISM_RESET_VLAN 0x7
# define ISM_QUERY_INFO 0x8
# define ISM_QUERY_RGID 0x9
# define ISM_REG_DMB 0xA
# define ISM_UNREG_DMB 0xB
# define ISM_SIGNAL_IEQ 0xE
# define ISM_UNREG_SBA 0x11
# define ISM_UNREG_IEQ 0x12
struct ism_req_hdr {
u32 cmd ;
u16 : 16 ;
u16 len ;
} ;
struct ism_resp_hdr {
u32 cmd ;
u16 ret ;
u16 len ;
} ;
union ism_reg_sba {
struct {
struct ism_req_hdr hdr ;
u64 sba ;
} request ;
struct {
struct ism_resp_hdr hdr ;
} response ;
} __aligned ( 16 ) ;
union ism_reg_ieq {
struct {
struct ism_req_hdr hdr ;
u64 ieq ;
u64 len ;
} request ;
struct {
struct ism_resp_hdr hdr ;
} response ;
} __aligned ( 16 ) ;
union ism_read_gid {
struct {
struct ism_req_hdr hdr ;
} request ;
struct {
struct ism_resp_hdr hdr ;
u64 gid ;
} response ;
} __aligned ( 16 ) ;
union ism_qi {
struct {
struct ism_req_hdr hdr ;
} request ;
struct {
struct ism_resp_hdr hdr ;
u32 version ;
u32 max_len ;
u64 ism_state ;
u64 my_gid ;
u64 sba ;
u64 ieq ;
u32 ieq_len ;
u32 : 32 ;
u32 dmbs_owned ;
u32 dmbs_used ;
u32 vlan_required ;
u32 vlan_nr_ids ;
u16 vlan_id [ 64 ] ;
} response ;
} __aligned ( 64 ) ;
union ism_query_rgid {
struct {
struct ism_req_hdr hdr ;
u64 rgid ;
u32 vlan_valid ;
u32 vlan_id ;
} request ;
struct {
struct ism_resp_hdr hdr ;
} response ;
} __aligned ( 16 ) ;
union ism_reg_dmb {
struct {
struct ism_req_hdr hdr ;
u64 dmb ;
u32 dmb_len ;
u32 sba_idx ;
u32 vlan_valid ;
u32 vlan_id ;
u64 rgid ;
} request ;
struct {
struct ism_resp_hdr hdr ;
u64 dmb_tok ;
} response ;
} __aligned ( 32 ) ;
union ism_sig_ieq {
struct {
struct ism_req_hdr hdr ;
u64 rgid ;
u32 trigger_irq ;
u32 event_code ;
u64 info ;
} request ;
struct {
struct ism_resp_hdr hdr ;
} response ;
} __aligned ( 32 ) ;
union ism_unreg_dmb {
struct {
struct ism_req_hdr hdr ;
u64 dmb_tok ;
} request ;
struct {
struct ism_resp_hdr hdr ;
} response ;
} __aligned ( 16 ) ;
union ism_cmd_simple {
struct {
struct ism_req_hdr hdr ;
} request ;
struct {
struct ism_resp_hdr hdr ;
} response ;
} __aligned ( 8 ) ;
union ism_set_vlan_id {
struct {
struct ism_req_hdr hdr ;
u64 vlan_id ;
} request ;
struct {
struct ism_resp_hdr hdr ;
} response ;
} __aligned ( 16 ) ;
struct ism_eq_header {
u64 idx ;
u64 ieq_len ;
u64 entry_len ;
u64 : 64 ;
} ;
struct ism_eq {
struct ism_eq_header header ;
struct smcd_event entry [ 15 ] ;
} ;
struct ism_sba {
u32 s : 1 ; /* summary bit */
u32 e : 1 ; /* event bit */
u32 : 30 ;
u32 dmb_bits [ ISM_NR_DMBS / 32 ] ;
u32 reserved [ 3 ] ;
u16 dmbe_mask [ ISM_NR_DMBS ] ;
} ;
struct ism_dev {
spinlock_t lock ;
struct pci_dev * pdev ;
struct smcd_dev * smcd ;
struct ism_sba * sba ;
dma_addr_t sba_dma_addr ;
DECLARE_BITMAP ( sba_bitmap , ISM_NR_DMBS ) ;
struct ism_eq * ieq ;
dma_addr_t ieq_dma_addr ;
int ieq_idx ;
} ;
# define ISM_CREATE_REQ(dmb, idx, sf, offset) \
( ( dmb ) | ( idx ) < < 24 | ( sf ) < < 23 | ( offset ) )
2019-04-23 11:57:46 +02:00
static inline void __ism_read_cmd ( struct ism_dev * ism , void * data ,
unsigned long offset , unsigned long len )
{
struct zpci_dev * zdev = to_zpci ( ism - > pdev ) ;
u64 req = ZPCI_CREATE_REQ ( zdev - > fh , 2 , 8 ) ;
while ( len > 0 ) {
__zpci_load ( data , req , offset ) ;
offset + = 8 ;
data + = 8 ;
len - = 8 ;
}
}
static inline void __ism_write_cmd ( struct ism_dev * ism , void * data ,
unsigned long offset , unsigned long len )
{
struct zpci_dev * zdev = to_zpci ( ism - > pdev ) ;
u64 req = ZPCI_CREATE_REQ ( zdev - > fh , 2 , len ) ;
if ( len )
__zpci_store_block ( data , req , offset ) ;
}
2018-06-28 19:05:13 +02:00
static inline int __ism_move ( struct ism_dev * ism , u64 dmb_req , void * data ,
unsigned int size )
{
struct zpci_dev * zdev = to_zpci ( ism - > pdev ) ;
u64 req = ZPCI_CREATE_REQ ( zdev - > fh , 0 , size ) ;
2019-04-14 16:25:54 +02:00
return __zpci_store_block ( data , req , dmb_req ) ;
2018-06-28 19:05:13 +02:00
}
# endif /* S390_ISM_H */