summaryrefslogtreecommitdiff
path: root/xpp/xpp_proto.h
blob: 46713d5713f0ef842cead9ba4320dcdbf9ea4e5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#ifndef	XPP_PROTO_H
#define	XPP_PROTO_H

#include "xpd.h"
#include "slic.h"
#ifdef	__KERNEL__
#include <linux/list.h>
#endif

#define	PCM_CHUNKSIZE	(CHANNELS_PERXPD * ZT_MAX_CHUNKSIZE)

typedef enum xpp_opcode {
	XPP_NOTIMP		= 0x00,
//
	XPP_DESC_REQ		= 0x04,
	XPP_DEV_DESC		= 0x05,
//
	XPP_SIG_CHANGED		= 0x06,
//
	XPP_SLIC_WRITE		= 0x0F,	// Write to SLIC
	XPP_CHAN_ENABLE		= 0x0F,	// Write to SLIC
	XPP_CHAN_POWER		= 0x0F,	// Write to SLIC
	XPP_RING		= 0x0F,	// Write to SLIC
	XPP_SETHOOK		= 0x0F,	// Write to SLIC
	XPP_LED			= 0x0F,	// Write to SLIC
	XPP_RELAY_OUT		= 0x0F,	// Write to SLIC
	XPP_SLIC_INIT		= 0x0F,	// Write to SLIC
	XPP_SLIC_QUERY		= 0x0F,	// Write to SLIC
//
	XPP_SLIC_REPLY		= 0x10,
//
	XPP_PCM_WRITE		= 0x11,
	XPP_PCM_READ		= 0x12,
//
	XPP_PCM_GEN		= 0x13,
//
	XPP_SYNC_SOURCE		= 0x19,
	XPP_SYNC_REPLY		= 0x1A,
//
	XPP_LOOPBACK_AX		= 0x31,
	XPP_LOOPBACK_XA		= 0x32,
	XPP_DIAG_FE		= 0xFE,
} xpp_opcode_t;

/*------------------------- PROTOCOL COMMANDS ----------------------*/

#define	XPP_MAX_DATA		50

typedef	struct slic_data {
	byte	len;
	byte	data[40];
} __attribute__((packed)) slic_data_t;

#define	PROTO_FUNC(name)	xpp_proto_ ## name
#define	CALL_PROTO(name, ...)	PROTO_FUNC(name)( __VA_ARGS__ )
#define	DECLARE_CMD(name, ...)	\
	int CALL_PROTO(name, xbus_t *xbus, xpd_t *xpd, ## __VA_ARGS__ )

/* 0x04 */ DECLARE_CMD(DESC_REQ, int xpd_num);
/* 0x0F */ DECLARE_CMD(CHAN_ENABLE, xpp_line_t lines, bool on);
/* 0x0F */ DECLARE_CMD(CHAN_POWER, xpp_line_t lines, bool on);
/* 0x0F */ DECLARE_CMD(RING, int pos, bool on);
/* 0x0F */ DECLARE_CMD(SETHOOK, xpp_line_t hook_status);
/* 0x0F */ DECLARE_CMD(LED, xpp_line_t lines, byte which, bool on);
/* 0x0F */ DECLARE_CMD(RELAY_OUT, byte which, bool on);
/* 0x0F */ DECLARE_CMD(SLIC_INIT);
/* 0x0F */ DECLARE_CMD(SLIC_QUERY, int pos, byte reg_num);
/* 0x11 */ DECLARE_CMD(PCM_WRITE, xpp_line_t hookstate,  volatile byte *buf);
/* 0x13 */ DECLARE_CMD(PCM_GEN, xpp_line_t lines,  volatile byte *buf);
/* 0x19 */ DECLARE_CMD(SYNC_SOURCE, bool setit, bool is_master);
/* 0x31 */ DECLARE_CMD(LOOPBACK_AX, byte *data, unsigned int size);

#define	H_(op, ...)	struct { \
				__VA_ARGS__ \
	} __attribute__((packed)) cmd_##op

/*
 * This struct must be packed exactly as the wire
 * representation of the packet header after the
 * XPD address byte
 */
typedef struct xpp_packet_r {
	byte		opcode;
	xpp_addr_t	addr;
	union {

		H_(NOTIMP);
		H_(DESC_REQ);
		H_(DEV_DESC,
			byte		rev;					/* Revision number */
			byte		type;
			xpp_line_t	line_status;	/* hook/ring status, depending on unit */
			);

		H_(SIG_CHANGED,
			byte		type;		/* unused -- we have it from DEV_DESC */
			xpp_line_t	sig_status;	/* channels: lsb=1, msb=8 */
			xpp_line_t	sig_toggles;	/* channels: lsb=1, msb=8 */
			);

		H_(SLIC_INIT,
			xpp_line_t      lines;
			slic_data_t     slic_data;
			);
		H_(SLIC_WRITE,
			slic_cmd_t	slic_cmd;
			);
		H_(SLIC_REPLY,					/* Get status of a single SLIC (for debugging) */
			xpp_line_t	lines;
			slic_reply_t	info;
			);

		H_(PCM_WRITE,
			xpp_line_t	lines;	// Must be 0xFF
			byte		pcm[PCM_CHUNKSIZE];
			);
		H_(PCM_READ,
			xpp_line_t	lines;	// Must be 0xFF
			byte		pcm[PCM_CHUNKSIZE];
			);

		H_(PCM_GEN,
			xpp_line_t	lines;
			byte		gen;
			byte		pcm_seq[ZT_CHUNKSIZE];
			);

		H_(SYNC_SOURCE,
			byte		mask;
			);
		H_(SYNC_REPLY,
			byte		mask;
			);

		H_(LOOPBACK_AX,
			byte		data[XPP_MAX_DATA];	// FIXME: what data size?
			);
		H_(LOOPBACK_XA,
			byte		data[XPP_MAX_DATA];	// FIXME: what data size?
			);
		H_(DIAG_FE);
		unsigned char	raw[0];
	};
} __attribute__((packed)) xpp_packet_r_t;
#undef	H_

#ifdef	__KERNEL__

enum {
	XPP_PACKET_FIREANDFORGET	= 0x1,
};

/**
 * The packet that will actually be sent on the wire.
 *
 * TODO: not a good medium-level abstrction
 */
struct xpp_packet {
	struct xpp_packet_r	content;
	unsigned int		flags;
	size_t				datalen;
	struct list_head	list;
};

#define DATA_LEN(p, name) \
	sizeof(p->content.cmd_ ## name)

#define	PACKET_LEN(p) \
	((p)->datalen + sizeof(xpp_addr_t) + 1)

#define	PACKET_INIT(p, name)		\
	p->content.opcode = XPP_ ## name;	\
	p->datalen = DATA_LEN(p, name)

#define	PACKET_FIELD(p, name, field)	\
	p->content.cmd_ ## name.field

void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg);
void enqueue_xmit(xbus_t *xbus, xpacket_t *pack);
void process_sim_queue(void *xbus);
int validate_reply(xpacket_t *reply);
int packet_receive(xbus_t *xbus, xpacket_t *pack);
int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data);

#endif

#endif	/* XPP_PROTO_H */