summaryrefslogtreecommitdiff
path: root/xpp/xpp_proto.h
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/xpp_proto.h')
-rw-r--r--xpp/xpp_proto.h188
1 files changed, 188 insertions, 0 deletions
diff --git a/xpp/xpp_proto.h b/xpp/xpp_proto.h
new file mode 100644
index 0000000..46713d5
--- /dev/null
+++ b/xpp/xpp_proto.h
@@ -0,0 +1,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 */