#ifndef XPP_PROTO_H #define XPP_PROTO_H #include "xpd.h" #include "slic.h" #ifdef __KERNEL__ #include #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 */