18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2007
48c2ecf20Sopenharmony_ci * Authors:	Peter Tiedemann (ptiedem@de.ibm.com)
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * 	MPC additions:
78c2ecf20Sopenharmony_ci *		Belinda Thompson (belindat@us.ibm.com)
88c2ecf20Sopenharmony_ci *		Andy Richter (richtera@us.ibm.com)
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef _CTC_MPC_H_
128c2ecf20Sopenharmony_ci#define _CTC_MPC_H_
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
158c2ecf20Sopenharmony_ci#include <linux/skbuff.h>
168c2ecf20Sopenharmony_ci#include "fsm.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/*
198c2ecf20Sopenharmony_ci * MPC external interface
208c2ecf20Sopenharmony_ci * Note that ctc_mpc_xyz are called with a lock on ................
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/*  port_number is the mpc device 0, 1, 2 etc mpc2 is port_number 2 */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci/*  passive open  Just wait for XID2 exchange */
268c2ecf20Sopenharmony_ciextern int ctc_mpc_alloc_channel(int port,
278c2ecf20Sopenharmony_ci		void (*callback)(int port_num, int max_write_size));
288c2ecf20Sopenharmony_ci/* active open  Alloc then send XID2 */
298c2ecf20Sopenharmony_ciextern void ctc_mpc_establish_connectivity(int port,
308c2ecf20Sopenharmony_ci		void (*callback)(int port_num, int rc, int max_write_size));
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ciextern void ctc_mpc_dealloc_ch(int port);
338c2ecf20Sopenharmony_ciextern void ctc_mpc_flow_control(int port, int flowc);
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci/*
368c2ecf20Sopenharmony_ci * other MPC Group prototypes and structures
378c2ecf20Sopenharmony_ci */
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci#define ETH_P_SNA_DIX	0x80D5
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci/*
428c2ecf20Sopenharmony_ci * Declaration of an XID2
438c2ecf20Sopenharmony_ci *
448c2ecf20Sopenharmony_ci */
458c2ecf20Sopenharmony_ci#define ALLZEROS 0x0000000000000000
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#define XID_FM2		0x20
488c2ecf20Sopenharmony_ci#define XID2_0		0x00
498c2ecf20Sopenharmony_ci#define XID2_7		0x07
508c2ecf20Sopenharmony_ci#define XID2_WRITE_SIDE 0x04
518c2ecf20Sopenharmony_ci#define XID2_READ_SIDE	0x05
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cistruct xid2 {
548c2ecf20Sopenharmony_ci	__u8	xid2_type_id;
558c2ecf20Sopenharmony_ci	__u8	xid2_len;
568c2ecf20Sopenharmony_ci	__u32	xid2_adj_id;
578c2ecf20Sopenharmony_ci	__u8	xid2_rlen;
588c2ecf20Sopenharmony_ci	__u8	xid2_resv1;
598c2ecf20Sopenharmony_ci	__u8	xid2_flag1;
608c2ecf20Sopenharmony_ci	__u8	xid2_fmtt;
618c2ecf20Sopenharmony_ci	__u8	xid2_flag4;
628c2ecf20Sopenharmony_ci	__u16	xid2_resv2;
638c2ecf20Sopenharmony_ci	__u8	xid2_tgnum;
648c2ecf20Sopenharmony_ci	__u32	xid2_sender_id;
658c2ecf20Sopenharmony_ci	__u8	xid2_flag2;
668c2ecf20Sopenharmony_ci	__u8	xid2_option;
678c2ecf20Sopenharmony_ci	char  xid2_resv3[8];
688c2ecf20Sopenharmony_ci	__u16	xid2_resv4;
698c2ecf20Sopenharmony_ci	__u8	xid2_dlc_type;
708c2ecf20Sopenharmony_ci	__u16	xid2_resv5;
718c2ecf20Sopenharmony_ci	__u8	xid2_mpc_flag;
728c2ecf20Sopenharmony_ci	__u8	xid2_resv6;
738c2ecf20Sopenharmony_ci	__u16	xid2_buf_len;
748c2ecf20Sopenharmony_ci	char xid2_buffer[255 - (13 * sizeof(__u8) +
758c2ecf20Sopenharmony_ci				2 * sizeof(__u32) +
768c2ecf20Sopenharmony_ci				4 * sizeof(__u16) +
778c2ecf20Sopenharmony_ci				8 * sizeof(char))];
788c2ecf20Sopenharmony_ci} __attribute__ ((packed));
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci#define XID2_LENGTH  (sizeof(struct xid2))
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_cistruct th_header {
838c2ecf20Sopenharmony_ci	__u8	th_seg;
848c2ecf20Sopenharmony_ci	__u8	th_ch_flag;
858c2ecf20Sopenharmony_ci#define TH_HAS_PDU	0xf0
868c2ecf20Sopenharmony_ci#define TH_IS_XID	0x01
878c2ecf20Sopenharmony_ci#define TH_SWEEP_REQ	0xfe
888c2ecf20Sopenharmony_ci#define TH_SWEEP_RESP	0xff
898c2ecf20Sopenharmony_ci	__u8	th_blk_flag;
908c2ecf20Sopenharmony_ci#define TH_DATA_IS_XID	0x80
918c2ecf20Sopenharmony_ci#define TH_RETRY	0x40
928c2ecf20Sopenharmony_ci#define TH_DISCONTACT	0xc0
938c2ecf20Sopenharmony_ci#define TH_SEG_BLK	0x20
948c2ecf20Sopenharmony_ci#define TH_LAST_SEG	0x10
958c2ecf20Sopenharmony_ci#define TH_PDU_PART	0x08
968c2ecf20Sopenharmony_ci	__u8	th_is_xid;	/* is 0x01 if this is XID  */
978c2ecf20Sopenharmony_ci	__u32	th_seq_num;
988c2ecf20Sopenharmony_ci} __attribute__ ((packed));
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistruct th_addon {
1018c2ecf20Sopenharmony_ci	__u32	th_last_seq;
1028c2ecf20Sopenharmony_ci	__u32	th_resvd;
1038c2ecf20Sopenharmony_ci} __attribute__ ((packed));
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistruct th_sweep {
1068c2ecf20Sopenharmony_ci	struct th_header th;
1078c2ecf20Sopenharmony_ci	struct th_addon sw;
1088c2ecf20Sopenharmony_ci} __attribute__ ((packed));
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci#define TH_HEADER_LENGTH (sizeof(struct th_header))
1118c2ecf20Sopenharmony_ci#define TH_SWEEP_LENGTH (sizeof(struct th_sweep))
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci#define PDU_LAST	0x80
1148c2ecf20Sopenharmony_ci#define PDU_CNTL	0x40
1158c2ecf20Sopenharmony_ci#define PDU_FIRST	0x20
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_cistruct pdu {
1188c2ecf20Sopenharmony_ci	__u32	pdu_offset;
1198c2ecf20Sopenharmony_ci	__u8	pdu_flag;
1208c2ecf20Sopenharmony_ci	__u8	pdu_proto;   /*  0x01 is APPN SNA  */
1218c2ecf20Sopenharmony_ci	__u16	pdu_seq;
1228c2ecf20Sopenharmony_ci} __attribute__ ((packed));
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci#define PDU_HEADER_LENGTH  (sizeof(struct pdu))
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistruct qllc {
1278c2ecf20Sopenharmony_ci	__u8	qllc_address;
1288c2ecf20Sopenharmony_ci#define QLLC_REQ	0xFF
1298c2ecf20Sopenharmony_ci#define QLLC_RESP	0x00
1308c2ecf20Sopenharmony_ci	__u8	qllc_commands;
1318c2ecf20Sopenharmony_ci#define QLLC_DISCONNECT 0x53
1328c2ecf20Sopenharmony_ci#define QLLC_UNSEQACK	0x73
1338c2ecf20Sopenharmony_ci#define QLLC_SETMODE	0x93
1348c2ecf20Sopenharmony_ci#define QLLC_EXCHID	0xBF
1358c2ecf20Sopenharmony_ci} __attribute__ ((packed));
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci/*
1398c2ecf20Sopenharmony_ci * Definition of one MPC group
1408c2ecf20Sopenharmony_ci */
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci#define MAX_MPCGCHAN		10
1438c2ecf20Sopenharmony_ci#define MPC_XID_TIMEOUT_VALUE	10000
1448c2ecf20Sopenharmony_ci#define MPC_CHANNEL_ADD		0
1458c2ecf20Sopenharmony_ci#define MPC_CHANNEL_REMOVE	1
1468c2ecf20Sopenharmony_ci#define MPC_CHANNEL_ATTN	2
1478c2ecf20Sopenharmony_ci#define XSIDE	1
1488c2ecf20Sopenharmony_ci#define YSIDE	0
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistruct mpcg_info {
1518c2ecf20Sopenharmony_ci	struct sk_buff	*skb;
1528c2ecf20Sopenharmony_ci	struct channel	*ch;
1538c2ecf20Sopenharmony_ci	struct xid2	*xid;
1548c2ecf20Sopenharmony_ci	struct th_sweep	*sweep;
1558c2ecf20Sopenharmony_ci	struct th_header *th;
1568c2ecf20Sopenharmony_ci};
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_cistruct mpc_group {
1598c2ecf20Sopenharmony_ci	struct tasklet_struct mpc_tasklet;
1608c2ecf20Sopenharmony_ci	struct tasklet_struct mpc_tasklet2;
1618c2ecf20Sopenharmony_ci	int	changed_side;
1628c2ecf20Sopenharmony_ci	int	saved_state;
1638c2ecf20Sopenharmony_ci	int	channels_terminating;
1648c2ecf20Sopenharmony_ci	int	out_of_sequence;
1658c2ecf20Sopenharmony_ci	int	flow_off_called;
1668c2ecf20Sopenharmony_ci	int	port_num;
1678c2ecf20Sopenharmony_ci	int	port_persist;
1688c2ecf20Sopenharmony_ci	int	alloc_called;
1698c2ecf20Sopenharmony_ci	__u32	xid2_adj_id;
1708c2ecf20Sopenharmony_ci	__u8	xid2_tgnum;
1718c2ecf20Sopenharmony_ci	__u32	xid2_sender_id;
1728c2ecf20Sopenharmony_ci	int	num_channel_paths;
1738c2ecf20Sopenharmony_ci	int	active_channels[2];
1748c2ecf20Sopenharmony_ci	__u16	group_max_buflen;
1758c2ecf20Sopenharmony_ci	int	outstanding_xid2;
1768c2ecf20Sopenharmony_ci	int	outstanding_xid7;
1778c2ecf20Sopenharmony_ci	int	outstanding_xid7_p2;
1788c2ecf20Sopenharmony_ci	int	sweep_req_pend_num;
1798c2ecf20Sopenharmony_ci	int	sweep_rsp_pend_num;
1808c2ecf20Sopenharmony_ci	struct sk_buff	*xid_skb;
1818c2ecf20Sopenharmony_ci	char		*xid_skb_data;
1828c2ecf20Sopenharmony_ci	struct th_header *xid_th;
1838c2ecf20Sopenharmony_ci	struct xid2	*xid;
1848c2ecf20Sopenharmony_ci	char		*xid_id;
1858c2ecf20Sopenharmony_ci	struct th_header *rcvd_xid_th;
1868c2ecf20Sopenharmony_ci	struct sk_buff	*rcvd_xid_skb;
1878c2ecf20Sopenharmony_ci	char		*rcvd_xid_data;
1888c2ecf20Sopenharmony_ci	__u8		in_sweep;
1898c2ecf20Sopenharmony_ci	__u8		roll;
1908c2ecf20Sopenharmony_ci	struct xid2	*saved_xid2;
1918c2ecf20Sopenharmony_ci	void 		(*allochanfunc)(int, int);
1928c2ecf20Sopenharmony_ci	int		allocchan_callback_retries;
1938c2ecf20Sopenharmony_ci	void 		(*estconnfunc)(int, int, int);
1948c2ecf20Sopenharmony_ci	int		estconn_callback_retries;
1958c2ecf20Sopenharmony_ci	int		estconn_called;
1968c2ecf20Sopenharmony_ci	int		xidnogood;
1978c2ecf20Sopenharmony_ci	int		send_qllc_disc;
1988c2ecf20Sopenharmony_ci	fsm_timer	timer;
1998c2ecf20Sopenharmony_ci	fsm_instance	*fsm; /* group xid fsm */
2008c2ecf20Sopenharmony_ci};
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci#ifdef DEBUGDATA
2038c2ecf20Sopenharmony_civoid ctcmpc_dumpit(char *buf, int len);
2048c2ecf20Sopenharmony_ci#else
2058c2ecf20Sopenharmony_cistatic inline void ctcmpc_dumpit(char *buf, int len)
2068c2ecf20Sopenharmony_ci{
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci#endif
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci#ifdef DEBUGDATA
2118c2ecf20Sopenharmony_ci/*
2128c2ecf20Sopenharmony_ci * Dump header and first 16 bytes of an sk_buff for debugging purposes.
2138c2ecf20Sopenharmony_ci *
2148c2ecf20Sopenharmony_ci * skb	 The struct sk_buff to dump.
2158c2ecf20Sopenharmony_ci * offset Offset relative to skb-data, where to start the dump.
2168c2ecf20Sopenharmony_ci */
2178c2ecf20Sopenharmony_civoid ctcmpc_dump_skb(struct sk_buff *skb, int offset);
2188c2ecf20Sopenharmony_ci#else
2198c2ecf20Sopenharmony_cistatic inline void ctcmpc_dump_skb(struct sk_buff *skb, int offset)
2208c2ecf20Sopenharmony_ci{}
2218c2ecf20Sopenharmony_ci#endif
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_cistatic inline void ctcmpc_dump32(char *buf, int len)
2248c2ecf20Sopenharmony_ci{
2258c2ecf20Sopenharmony_ci	if (len < 32)
2268c2ecf20Sopenharmony_ci		ctcmpc_dumpit(buf, len);
2278c2ecf20Sopenharmony_ci	else
2288c2ecf20Sopenharmony_ci		ctcmpc_dumpit(buf, 32);
2298c2ecf20Sopenharmony_ci}
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_civoid ctcm_ccw_check_rc(struct channel *, int, char *);
2328c2ecf20Sopenharmony_civoid mpc_group_ready(unsigned long adev);
2338c2ecf20Sopenharmony_civoid mpc_channel_action(struct channel *ch, int direction, int action);
2348c2ecf20Sopenharmony_civoid mpc_action_send_discontact(unsigned long thischan);
2358c2ecf20Sopenharmony_civoid mpc_action_discontact(fsm_instance *fi, int event, void *arg);
2368c2ecf20Sopenharmony_civoid ctcmpc_bh(unsigned long thischan);
2378c2ecf20Sopenharmony_ci#endif
2388c2ecf20Sopenharmony_ci/* --- This is the END my friend --- */
239