xref: /openbmc/linux/drivers/s390/net/lcs.h (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds /*lcs.h*/
31da177e4SLinus Torvalds 
41da177e4SLinus Torvalds #include <linux/interrupt.h>
51da177e4SLinus Torvalds #include <linux/netdevice.h>
61da177e4SLinus Torvalds #include <linux/skbuff.h>
71da177e4SLinus Torvalds #include <linux/workqueue.h>
8c380cd5aSElena Reshetova #include <linux/refcount.h>
91da177e4SLinus Torvalds #include <asm/ccwdev.h>
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds #define LCS_DBF_TEXT(level, name, text) \
121da177e4SLinus Torvalds 	do { \
131da177e4SLinus Torvalds 		debug_text_event(lcs_dbf_##name, level, text); \
141da177e4SLinus Torvalds 	} while (0)
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds #define LCS_DBF_HEX(level,name,addr,len) \
171da177e4SLinus Torvalds do { \
181da177e4SLinus Torvalds 	debug_event(lcs_dbf_##name,level,(void*)(addr),len); \
191da177e4SLinus Torvalds } while (0)
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds #define LCS_DBF_TEXT_(level,name,text...) \
221da177e4SLinus Torvalds 	do { \
238e6a8285SHendrik Brueckner 		if (debug_level_enabled(lcs_dbf_##name, level)) { \
24*1a079f3eSThorsten Winkler 			scnprintf(debug_buffer, sizeof(debug_buffer), text); \
251da177e4SLinus Torvalds 			debug_text_event(lcs_dbf_##name, level, debug_buffer); \
26f33780d3SPeter Tiedemann 		} \
271da177e4SLinus Torvalds 	} while (0)
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds /**
301da177e4SLinus Torvalds  *	sysfs related stuff
311da177e4SLinus Torvalds  */
321da177e4SLinus Torvalds #define CARD_FROM_DEV(cdev) \
33dff59b64SGreg Kroah-Hartman 	(struct lcs_card *) dev_get_drvdata( \
34dff59b64SGreg Kroah-Hartman 		&((struct ccwgroup_device *)dev_get_drvdata(&cdev->dev))->dev);
350ca8cc6fSUrsula Braun 
360ca8cc6fSUrsula Braun /**
370ca8cc6fSUrsula Braun  * Enum for classifying detected devices.
380ca8cc6fSUrsula Braun  */
390ca8cc6fSUrsula Braun enum lcs_channel_types {
400ca8cc6fSUrsula Braun 	/* Device is not a channel  */
410ca8cc6fSUrsula Braun 	lcs_channel_type_none,
420ca8cc6fSUrsula Braun 
430ca8cc6fSUrsula Braun 	/* Device is a 2216 channel */
440ca8cc6fSUrsula Braun 	lcs_channel_type_parallel,
450ca8cc6fSUrsula Braun 
460ca8cc6fSUrsula Braun 	/* Device is a 2216 channel */
470ca8cc6fSUrsula Braun 	lcs_channel_type_2216,
480ca8cc6fSUrsula Braun 
490ca8cc6fSUrsula Braun 	/* Device is a OSA2 card */
500ca8cc6fSUrsula Braun 	lcs_channel_type_osa2
510ca8cc6fSUrsula Braun };
520ca8cc6fSUrsula Braun 
531da177e4SLinus Torvalds /**
541da177e4SLinus Torvalds  * CCW commands used in this driver
551da177e4SLinus Torvalds  */
561da177e4SLinus Torvalds #define LCS_CCW_WRITE		0x01
571da177e4SLinus Torvalds #define LCS_CCW_READ		0x02
581da177e4SLinus Torvalds #define LCS_CCW_TRANSFER	0x08
591da177e4SLinus Torvalds 
601da177e4SLinus Torvalds /**
611da177e4SLinus Torvalds  * LCS device status primitives
621da177e4SLinus Torvalds  */
631da177e4SLinus Torvalds #define LCS_CMD_STARTLAN	0x01
641da177e4SLinus Torvalds #define LCS_CMD_STOPLAN		0x02
651da177e4SLinus Torvalds #define LCS_CMD_LANSTAT		0x04
661da177e4SLinus Torvalds #define LCS_CMD_STARTUP		0x07
671da177e4SLinus Torvalds #define LCS_CMD_SHUTDOWN	0x08
681da177e4SLinus Torvalds #define LCS_CMD_QIPASSIST	0xb2
691da177e4SLinus Torvalds #define LCS_CMD_SETIPM		0xb4
701da177e4SLinus Torvalds #define LCS_CMD_DELIPM		0xb5
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds #define LCS_INITIATOR_TCPIP	0x00
731da177e4SLinus Torvalds #define LCS_INITIATOR_LGW	0x01
741da177e4SLinus Torvalds #define LCS_STD_CMD_SIZE	16
751da177e4SLinus Torvalds #define LCS_MULTICAST_CMD_SIZE	404
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds /**
781da177e4SLinus Torvalds  * LCS IPASSIST MASKS,only used when multicast is switched on
791da177e4SLinus Torvalds  */
801da177e4SLinus Torvalds /* Not supported by LCS */
811da177e4SLinus Torvalds #define LCS_IPASS_ARP_PROCESSING	0x0001
821da177e4SLinus Torvalds #define LCS_IPASS_IN_CHECKSUM_SUPPORT	0x0002
831da177e4SLinus Torvalds #define LCS_IPASS_OUT_CHECKSUM_SUPPORT	0x0004
841da177e4SLinus Torvalds #define LCS_IPASS_IP_FRAG_REASSEMBLY	0x0008
851da177e4SLinus Torvalds #define LCS_IPASS_IP_FILTERING		0x0010
861da177e4SLinus Torvalds /* Supported by lcs 3172 */
871da177e4SLinus Torvalds #define LCS_IPASS_IPV6_SUPPORT		0x0020
881da177e4SLinus Torvalds #define LCS_IPASS_MULTICAST_SUPPORT	0x0040
891da177e4SLinus Torvalds 
901da177e4SLinus Torvalds /**
911da177e4SLinus Torvalds  * LCS sense byte definitions
921da177e4SLinus Torvalds  */
9374ef872cSKlaus Wacker #define LCS_SENSE_BYTE_0 		0
9474ef872cSKlaus Wacker #define LCS_SENSE_BYTE_1 		1
9574ef872cSKlaus Wacker #define LCS_SENSE_BYTE_2 		2
9674ef872cSKlaus Wacker #define LCS_SENSE_BYTE_3 		3
971da177e4SLinus Torvalds #define LCS_SENSE_INTERFACE_DISCONNECT	0x01
981da177e4SLinus Torvalds #define LCS_SENSE_EQUIPMENT_CHECK	0x10
991da177e4SLinus Torvalds #define LCS_SENSE_BUS_OUT_CHECK		0x20
1001da177e4SLinus Torvalds #define LCS_SENSE_INTERVENTION_REQUIRED 0x40
1011da177e4SLinus Torvalds #define LCS_SENSE_CMD_REJECT		0x80
10274ef872cSKlaus Wacker #define LCS_SENSE_RESETTING_EVENT	0x80
10374ef872cSKlaus Wacker #define LCS_SENSE_DEVICE_ONLINE		0x20
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds /**
1061da177e4SLinus Torvalds  * LCS packet type definitions
1071da177e4SLinus Torvalds  */
1081da177e4SLinus Torvalds #define LCS_FRAME_TYPE_CONTROL		0
1091da177e4SLinus Torvalds #define LCS_FRAME_TYPE_ENET		1
1101da177e4SLinus Torvalds #define LCS_FRAME_TYPE_TR		2
1111da177e4SLinus Torvalds #define LCS_FRAME_TYPE_FDDI		7
1121da177e4SLinus Torvalds #define LCS_FRAME_TYPE_AUTO		-1
1131da177e4SLinus Torvalds 
1141da177e4SLinus Torvalds /**
1151da177e4SLinus Torvalds  * some more definitions,we will sort them later
1161da177e4SLinus Torvalds  */
1171da177e4SLinus Torvalds #define LCS_ILLEGAL_OFFSET		0xffff
1181da177e4SLinus Torvalds #define LCS_IOBUFFERSIZE		0x5000
1190d613a27SFrank Pavlic #define LCS_NUM_BUFFS			32	/* needs to be power of 2 */
1201da177e4SLinus Torvalds #define LCS_MAC_LENGTH			6
1211da177e4SLinus Torvalds #define LCS_INVALID_PORT_NO		-1
1221da177e4SLinus Torvalds #define LCS_LANCMD_TIMEOUT_DEFAULT      5
1231da177e4SLinus Torvalds 
1241da177e4SLinus Torvalds /**
1251da177e4SLinus Torvalds  * Multicast state
1261da177e4SLinus Torvalds  */
1271da177e4SLinus Torvalds #define	 LCS_IPM_STATE_SET_REQUIRED	0
1281da177e4SLinus Torvalds #define	 LCS_IPM_STATE_DEL_REQUIRED	1
1291da177e4SLinus Torvalds #define	 LCS_IPM_STATE_ON_CARD		2
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds /**
1321da177e4SLinus Torvalds  * LCS IP Assist declarations
1331da177e4SLinus Torvalds  * seems to be only used for multicast
1341da177e4SLinus Torvalds  */
1351da177e4SLinus Torvalds #define	 LCS_IPASS_ARP_PROCESSING	0x0001
1361da177e4SLinus Torvalds #define	 LCS_IPASS_INBOUND_CSUM_SUPP	0x0002
1371da177e4SLinus Torvalds #define	 LCS_IPASS_OUTBOUND_CSUM_SUPP	0x0004
1381da177e4SLinus Torvalds #define	 LCS_IPASS_IP_FRAG_REASSEMBLY	0x0008
1391da177e4SLinus Torvalds #define	 LCS_IPASS_IP_FILTERING		0x0010
1401da177e4SLinus Torvalds #define	 LCS_IPASS_IPV6_SUPPORT		0x0020
1411da177e4SLinus Torvalds #define	 LCS_IPASS_MULTICAST_SUPPORT	0x0040
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds /**
1441da177e4SLinus Torvalds  * LCS Buffer states
1451da177e4SLinus Torvalds  */
1461da177e4SLinus Torvalds enum lcs_buffer_states {
1479163bb2eSUrsula Braun 	LCS_BUF_STATE_EMPTY,	/* buffer is empty */
1489163bb2eSUrsula Braun 	LCS_BUF_STATE_LOCKED,	/* buffer is locked, don't touch */
1499163bb2eSUrsula Braun 	LCS_BUF_STATE_READY,	/* buffer is ready for read/write */
1509163bb2eSUrsula Braun 	LCS_BUF_STATE_PROCESSED,
1511da177e4SLinus Torvalds };
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds /**
1541da177e4SLinus Torvalds  * LCS Channel State Machine declarations
1551da177e4SLinus Torvalds  */
1561da177e4SLinus Torvalds enum lcs_channel_states {
1579163bb2eSUrsula Braun 	LCS_CH_STATE_INIT,
1589163bb2eSUrsula Braun 	LCS_CH_STATE_HALTED,
1599163bb2eSUrsula Braun 	LCS_CH_STATE_STOPPED,
1609163bb2eSUrsula Braun 	LCS_CH_STATE_RUNNING,
1619163bb2eSUrsula Braun 	LCS_CH_STATE_SUSPENDED,
1629163bb2eSUrsula Braun 	LCS_CH_STATE_CLEARED,
16359579da3SKlaus D. Wacker 	LCS_CH_STATE_ERROR,
1641da177e4SLinus Torvalds };
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds /**
1671da177e4SLinus Torvalds  * LCS device state machine
1681da177e4SLinus Torvalds  */
1691da177e4SLinus Torvalds enum lcs_dev_states {
1701da177e4SLinus Torvalds 	DEV_STATE_DOWN,
1711da177e4SLinus Torvalds 	DEV_STATE_UP,
1721da177e4SLinus Torvalds 	DEV_STATE_RECOVER,
1731da177e4SLinus Torvalds };
1741da177e4SLinus Torvalds 
1751da177e4SLinus Torvalds enum lcs_threads {
1761da177e4SLinus Torvalds 	LCS_SET_MC_THREAD 	= 1,
17774ef872cSKlaus Wacker 	LCS_RECOVERY_THREAD 	= 2,
1781da177e4SLinus Torvalds };
17974ef872cSKlaus Wacker 
1801da177e4SLinus Torvalds /**
1811da177e4SLinus Torvalds  * LCS struct declarations
1821da177e4SLinus Torvalds  */
1831da177e4SLinus Torvalds struct lcs_header {
1841da177e4SLinus Torvalds 	__u16  offset;
1851da177e4SLinus Torvalds 	__u8   type;
1861da177e4SLinus Torvalds 	__u8   slot;
1871da177e4SLinus Torvalds }  __attribute__ ((packed));
1881da177e4SLinus Torvalds 
1891da177e4SLinus Torvalds struct lcs_ip_mac_pair {
1905a5a852eSAl Viro 	__be32  ip_addr;
1911da177e4SLinus Torvalds 	__u8   mac_addr[LCS_MAC_LENGTH];
1921da177e4SLinus Torvalds 	__u8   reserved[2];
1931da177e4SLinus Torvalds }  __attribute__ ((packed));
1941da177e4SLinus Torvalds 
1951da177e4SLinus Torvalds struct lcs_ipm_list {
1961da177e4SLinus Torvalds 	struct list_head list;
1971da177e4SLinus Torvalds 	struct lcs_ip_mac_pair ipm;
1981da177e4SLinus Torvalds 	__u8 ipm_state;
1991da177e4SLinus Torvalds };
2001da177e4SLinus Torvalds 
2011da177e4SLinus Torvalds struct lcs_cmd {
2021da177e4SLinus Torvalds 	__u16  offset;
2031da177e4SLinus Torvalds 	__u8   type;
2041da177e4SLinus Torvalds 	__u8   slot;
2051da177e4SLinus Torvalds 	__u8   cmd_code;
2061da177e4SLinus Torvalds 	__u8   initiator;
2071da177e4SLinus Torvalds 	__u16  sequence_no;
2081da177e4SLinus Torvalds 	__u16  return_code;
2091da177e4SLinus Torvalds 	union {
2101da177e4SLinus Torvalds 		struct {
2111da177e4SLinus Torvalds 			__u8   lan_type;
2121da177e4SLinus Torvalds 			__u8   portno;
2131da177e4SLinus Torvalds 			__u16  parameter_count;
2141da177e4SLinus Torvalds 			__u8   operator_flags[3];
2151da177e4SLinus Torvalds 			__u8   reserved[3];
2161da177e4SLinus Torvalds 		} lcs_std_cmd;
2171da177e4SLinus Torvalds 		struct {
2181da177e4SLinus Torvalds 			__u16  unused1;
2191da177e4SLinus Torvalds 			__u16  buff_size;
2201da177e4SLinus Torvalds 			__u8   unused2[6];
2211da177e4SLinus Torvalds 		} lcs_startup;
2221da177e4SLinus Torvalds 		struct {
2231da177e4SLinus Torvalds 			__u8   lan_type;
2241da177e4SLinus Torvalds 			__u8   portno;
2251da177e4SLinus Torvalds 			__u8   unused[10];
2261da177e4SLinus Torvalds 			__u8   mac_addr[LCS_MAC_LENGTH];
2271da177e4SLinus Torvalds 			__u32  num_packets_deblocked;
2281da177e4SLinus Torvalds 			__u32  num_packets_blocked;
2291da177e4SLinus Torvalds 			__u32  num_packets_tx_on_lan;
2301da177e4SLinus Torvalds 			__u32  num_tx_errors_detected;
2311da177e4SLinus Torvalds 			__u32  num_tx_packets_disgarded;
2321da177e4SLinus Torvalds 			__u32  num_packets_rx_from_lan;
2331da177e4SLinus Torvalds 			__u32  num_rx_errors_detected;
2341da177e4SLinus Torvalds 			__u32  num_rx_discarded_nobuffs_avail;
2351da177e4SLinus Torvalds 			__u32  num_rx_packets_too_large;
2361da177e4SLinus Torvalds 		} lcs_lanstat_cmd;
2371da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTICAST
2381da177e4SLinus Torvalds 		struct {
2391da177e4SLinus Torvalds 			__u8   lan_type;
2401da177e4SLinus Torvalds 			__u8   portno;
2411da177e4SLinus Torvalds 			__u16  num_ip_pairs;
2421da177e4SLinus Torvalds 			__u16  ip_assists_supported;
2431da177e4SLinus Torvalds 			__u16  ip_assists_enabled;
2441da177e4SLinus Torvalds 			__u16  version;
2451da177e4SLinus Torvalds 			struct {
2461da177e4SLinus Torvalds 				struct lcs_ip_mac_pair
2471da177e4SLinus Torvalds 				ip_mac_pair[32];
2481da177e4SLinus Torvalds 				__u32	  response_data;
2491da177e4SLinus Torvalds 			} lcs_ipass_ctlmsg __attribute ((packed));
2501da177e4SLinus Torvalds 		} lcs_qipassist __attribute__ ((packed));
2511da177e4SLinus Torvalds #endif /*CONFIG_IP_MULTICAST */
2521da177e4SLinus Torvalds 	} cmd __attribute__ ((packed));
2531da177e4SLinus Torvalds }  __attribute__ ((packed));
2541da177e4SLinus Torvalds 
2551da177e4SLinus Torvalds /**
2561da177e4SLinus Torvalds  * Forward declarations.
2571da177e4SLinus Torvalds  */
2581da177e4SLinus Torvalds struct lcs_card;
2591da177e4SLinus Torvalds struct lcs_channel;
2601da177e4SLinus Torvalds 
2611da177e4SLinus Torvalds /**
2621da177e4SLinus Torvalds  * Definition of an lcs buffer.
2631da177e4SLinus Torvalds  */
2641da177e4SLinus Torvalds struct lcs_buffer {
2651da177e4SLinus Torvalds 	enum lcs_buffer_states state;
2661da177e4SLinus Torvalds 	void *data;
2671da177e4SLinus Torvalds 	int count;
2681da177e4SLinus Torvalds 	/* Callback for completion notification. */
2691da177e4SLinus Torvalds 	void (*callback)(struct lcs_channel *, struct lcs_buffer *);
2701da177e4SLinus Torvalds };
2711da177e4SLinus Torvalds 
2721da177e4SLinus Torvalds struct lcs_reply {
2731da177e4SLinus Torvalds 	struct list_head list;
2741da177e4SLinus Torvalds 	__u16 sequence_no;
275c380cd5aSElena Reshetova 	refcount_t refcnt;
2761da177e4SLinus Torvalds 	/* Callback for completion notification. */
2771da177e4SLinus Torvalds 	void (*callback)(struct lcs_card *, struct lcs_cmd *);
2781da177e4SLinus Torvalds 	wait_queue_head_t wait_q;
2791da177e4SLinus Torvalds 	struct lcs_card *card;
2809c6c273aSKees Cook 	struct timer_list timer;
2811da177e4SLinus Torvalds 	int received;
2821da177e4SLinus Torvalds 	int rc;
2831da177e4SLinus Torvalds };
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds /**
2861da177e4SLinus Torvalds  * Definition of an lcs channel
2871da177e4SLinus Torvalds  */
2881da177e4SLinus Torvalds struct lcs_channel {
2891da177e4SLinus Torvalds 	enum lcs_channel_states state;
2901da177e4SLinus Torvalds 	struct ccw_device *ccwdev;
2911da177e4SLinus Torvalds 	struct ccw1 ccws[LCS_NUM_BUFFS + 1];
2921da177e4SLinus Torvalds 	wait_queue_head_t wait_q;
2931da177e4SLinus Torvalds 	struct tasklet_struct irq_tasklet;
2941da177e4SLinus Torvalds 	struct lcs_buffer iob[LCS_NUM_BUFFS];
2951da177e4SLinus Torvalds 	int io_idx;
2961da177e4SLinus Torvalds 	int buf_idx;
2971da177e4SLinus Torvalds };
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds 
3001da177e4SLinus Torvalds /**
3011da177e4SLinus Torvalds  * definition of the lcs card
3021da177e4SLinus Torvalds  */
3031da177e4SLinus Torvalds struct lcs_card {
3041da177e4SLinus Torvalds 	spinlock_t lock;
3051da177e4SLinus Torvalds 	spinlock_t ipm_lock;
3061da177e4SLinus Torvalds 	enum lcs_dev_states state;
3071da177e4SLinus Torvalds 	struct net_device *dev;
3081da177e4SLinus Torvalds 	struct net_device_stats stats;
3095a5a852eSAl Viro 	__be16 (*lan_type_trans)(struct sk_buff *skb,
3101da177e4SLinus Torvalds 					 struct net_device *dev);
31174ef872cSKlaus Wacker 	struct ccwgroup_device *gdev;
3121da177e4SLinus Torvalds 	struct lcs_channel read;
3131da177e4SLinus Torvalds 	struct lcs_channel write;
3141da177e4SLinus Torvalds 	struct lcs_buffer *tx_buffer;
3151da177e4SLinus Torvalds 	int tx_emitted;
3161da177e4SLinus Torvalds 	struct list_head lancmd_waiters;
3171da177e4SLinus Torvalds 	int lancmd_timeout;
3181da177e4SLinus Torvalds 
3191da177e4SLinus Torvalds 	struct work_struct kernel_thread_starter;
3201da177e4SLinus Torvalds 	spinlock_t mask_lock;
3211da177e4SLinus Torvalds 	unsigned long thread_start_mask;
3221da177e4SLinus Torvalds 	unsigned long thread_running_mask;
3231da177e4SLinus Torvalds 	unsigned long thread_allowed_mask;
3241da177e4SLinus Torvalds 	wait_queue_head_t wait_q;
3251da177e4SLinus Torvalds 
3261da177e4SLinus Torvalds #ifdef CONFIG_IP_MULTICAST
3271da177e4SLinus Torvalds 	struct list_head ipm_list;
3281da177e4SLinus Torvalds #endif
3291da177e4SLinus Torvalds 	__u8 mac[LCS_MAC_LENGTH];
3301da177e4SLinus Torvalds 	__u16 ip_assists_supported;
3311da177e4SLinus Torvalds 	__u16 ip_assists_enabled;
3321da177e4SLinus Torvalds 	__s8 lan_type;
3331da177e4SLinus Torvalds 	__u32 pkt_seq;
3341da177e4SLinus Torvalds 	__u16 sequence_no;
3351da177e4SLinus Torvalds 	__s16 portno;
3361da177e4SLinus Torvalds 	/* Some info copied from probeinfo */
3371da177e4SLinus Torvalds 	u8 device_forced;
3381da177e4SLinus Torvalds 	u8 max_port_no;
3391da177e4SLinus Torvalds 	u8 hint_port_no;
3401da177e4SLinus Torvalds 	s16 port_protocol_no;
3411da177e4SLinus Torvalds }  __attribute__ ((aligned(8)));
3421da177e4SLinus Torvalds 
343