diff options
Diffstat (limited to 'xpp/xpp_proto.h')
-rw-r--r-- | xpp/xpp_proto.h | 188 |
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 */ |