From ebfa391bb98078c551439c6357bde687d0c1b6ee Mon Sep 17 00:00:00 2001 From: mattf Date: Sat, 3 Nov 2007 16:10:49 +0000 Subject: Major update for tc4xxp driver. Fixes many outstanding issues related to channel lockups, etc. It also raises the maximum channel count for g.729 to 120 channels. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3209 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wctc4xxp/base.c | 385 ++++++++++++++++++++++++++++++++----------- wctc4xxp/tc400m-firmware.bin | Bin 1400630 -> 1787818 bytes 2 files changed, 285 insertions(+), 100 deletions(-) (limited to 'wctc4xxp') diff --git a/wctc4xxp/base.c b/wctc4xxp/base.c index 42727d7..0bb4be2 100644 --- a/wctc4xxp/base.c +++ b/wctc4xxp/base.c @@ -70,7 +70,7 @@ extern void _binary_tc400m_firmware_bin_size; #define NUM_EC 4 /* NUM_CHANNELS must be checked if new firmware (dte_firm.h) is used */ -#define NUM_CHANNELS 97 +#define NUM_CHANNELS 120 #define DTE_FORMAT_ULAW 0x00 #define DTE_FORMAT_G723_1 0x04 @@ -201,6 +201,11 @@ extern void _binary_tc400m_firmware_bin_size; 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0C, 0x00, 0x00,0x06,0x10,0x00, 0x00,0x00, \ 0x02,0x00, (t&0x00FF), ((t&0xFF00) >> 8) } +#define CMD_MSG_QUERY_CHANNEL_LEN 30 +#define CMD_MSG_QUERY_CHANNEL(s,t) { \ + 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ + 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x01,0x06,0x10,0x00, 0x00,0x00, \ + (t&0x00FF), ((t&0xFF00) >> 8) } #define CMD_MSG_TRANS_CONNECT_LEN 38 #define CMD_MSG_TRANS_CONNECT(s,e,c1,c2,f1,f2) { \ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ @@ -259,12 +264,24 @@ extern void _binary_tc400m_firmware_bin_size; /* Wrapper for RTP packets */ #define CMD_MSG_IP_UDP_RTP_LEN 54 -#define CMD_MSG_IP_UDP_RTP(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20) { \ +#define CMD_MSG_IP_UDP_RTP(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,s) { \ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x08,0x00, \ 0x45,0x00, p1,p2, 0x00,p3, 0x40,0x00, 0x80,0x11, p4,p5, \ 0xC0,0xA8,0x09,0x03, 0xC0,0xA8,0x09,0x03, p6,p7, p8,p9, p10,p11, p12,p13, \ - 0x80,p14, p15,p16, p17,p18,p19,p20, 0x12,0x34,0x56,0x78} + 0x80,p14, p15,p16, p17,p18,p19,p20, 0x12,0x34,0x56,(s&0xFF)} +#define CMD_MSG_DW_WRITE_LEN 38 +#define CMD_MSG_DW_WRITE(s,a,d) { \ + 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ + 0x00,0x01,s&0x0F,0x00,0x00,0x00,0x00,0x00,0x04,0x17,0x00,0x00, \ + ((a>>24)&0x00FF),((a>>16)&0x00FF), ((a>>8)&0x00FF),(a&0x00FF), \ + ((d>>24)&0x00FF),((d>>16)&0x00FF), ((d>>8)&0x00FF),(d&0x00FF) } + +#define CMD_MSG_FORCE_ALERT_LEN 32 +#define CMD_MSG_FORCE_ALERT(s) { \ + 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ + 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x09,0x04, 0x00,0x00, \ + 0x24,0x00, 0x00,0x00 } #define zt_send_cmd(wc, command, length, hex) \ ({ \ @@ -291,7 +308,18 @@ extern void _binary_tc400m_firmware_bin_size; } \ __transmit_demand(wc); \ up(&wc->cmdqsem); \ - ret = wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS, 0); \ + if (hex == 0x0000) \ + ret = wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS_ACK, 2); \ + else { \ + ret = wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS, 0); \ + if (wc->dsp_crashed) \ + { \ + printk("Aborting zt_send_cmd()\n"); \ + return 1; \ + } \ + if ((ret == 2) && (wc->last_command_sent == 0x0010)) \ + printk("Detected timeout on 0x0010\n"); \ + } \ if (ret == 1) \ return(1); \ } while (ret == 2); \ @@ -329,10 +357,13 @@ struct wcdte { unsigned int last_rseqno; unsigned int last_command_sent; unsigned int last_rcommand; - unsigned int last_rparm2; + unsigned int last_rparm1; unsigned int seq_num; long timeout; + unsigned int dsp_crashed; + unsigned int dumping; + unsigned int ztsnd_rtx; unsigned int ztsnd_0010_rtx; @@ -396,6 +427,8 @@ struct dte_state { unsigned int last_dte_seqno; unsigned int dte_seqno_rcv; + + unsigned char ssrc; }; @@ -404,12 +437,74 @@ static struct zt_transcoder *udecode; static struct dte_state *encoders; static struct dte_state *decoders; static int debug = 0; +static int debug_des = 0; /* Set the number of descriptor packet bytes to output on errors, 0 disables output */ +static int debug_des_cnt = 0; /* Set the number of times descriptor packets are displayed before the output is disabled */ +static int force_alert = 0; +static int debug_notimeout = 0; static char *mode; -int debug_packets = 0; +static int debug_packets = 0; - -static int wcdte_create_channel(struct wcdte *wc, int simple, int complicated, int part1_id, int part2_id, unsigned int *dte_chan1, unsigned int *dte_chan2); +static int wcdte_create_channel(struct wcdte *wc, int part1_id, int part2_id, unsigned int *dte_chan1, unsigned int *dte_chan2); +static int wcdte_open_channel(struct wcdte *wc, int simple, int complicated, int part1_id, int part2_id, int chan1, int chan2); static int wcdte_destroy_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2); +static int wcdte_close_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2); +static int __wcdte_setup_channels(struct wcdte *wc); +static void wcdte_release(struct wcdte *wc); + +static int __dump_descriptors(struct wcdte *wc) +{ + volatile unsigned char *writechunk, *readchunk; + int o2, i, j; + + if (debug_des_cnt == 0) + return 1; + + printk("Transmit Descriptors (wc->tdbl = %d)\n", wc->tdbl); + for (i = 0; i < ERING_SIZE; i++) + { + writechunk = (volatile unsigned char *)(wc->writechunk); + writechunk += i * SFRAME_SIZE; + o2 = i * 4; + + if (i == wc->tdbl) + printk("->"); + else + printk(" "); + if ((le32_to_cpu(wc->descripchunk[o2]) & 0x80000000)) + printk("AN983 owns : "); + else + printk("Driver owns: "); + + for (j = 0; j < debug_des; j++) + printk("%02X ", writechunk[j]); + printk("\n"); + } + + printk("Receive Descriptors (wc->rdbl = %d)\n", wc->rdbl); + for (i = 0; i < ERING_SIZE; i++) + { + readchunk = (volatile unsigned char *)wc->readchunk; + readchunk += i * SFRAME_SIZE; + o2 = i * 4; + o2 += ERING_SIZE * 4; + + if (i == wc->rdbl) + printk("->"); + else + printk(" "); + if ((le32_to_cpu(wc->descripchunk[o2]) & 0x80000000)) + printk("AN983 owns : "); + else + printk("Driver owns: "); + + for (j = 0; j < debug_des; j++) + printk("%02X ", readchunk[j]); + printk("\n"); + } + if (debug_des_cnt > 0) + debug_des_cnt--; + return 0; +} /* Sanity check values */ static inline int zt_tc_sanitycheck(struct zt_transcode_header *zth, unsigned int outbytes) @@ -447,6 +542,8 @@ static void dte_init_state(struct dte_state *state_ptr, int encoder, unsigned in state_ptr->chan_in_num = 999; state_ptr->chan_out_num = 999; + + state_ptr->ssrc = 0x78; if (encoder == 1) { @@ -548,7 +645,7 @@ static inline int __transmit_demand(struct wcdte *wc) writechunk += wc->tdbl * SFRAME_SIZE; o2 = wc->tdbl * 4; - + do { } while ((le32_to_cpu(wc->descripchunk[o2]) & 0x80000000)); @@ -605,17 +702,34 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op) int i = 0; int res = 0; unsigned int ipchksum, ndx; + switch(op) { - case ZT_TCOP_ALLOCATE: + case ZT_TCOP_ALLOCATE: down(&wc->chansem); - if (ztc->chan_built == 0) - { - if (st->encoder == 1) - wcdte_create_channel(wc, wcdte_zapfmt_to_dtefmt(zth->srcfmt), wcdte_zapfmt_to_dtefmt(zth->dstfmt), - st->timeslot_in_num, st->timeslot_out_num, &(st->chan_in_num), &(st->chan_out_num)); - else - wcdte_create_channel(wc, wcdte_zapfmt_to_dtefmt(zth->dstfmt), wcdte_zapfmt_to_dtefmt(zth->srcfmt), - st->timeslot_out_num, st->timeslot_in_num, &(st->chan_out_num), &(st->chan_in_num)); + if (ztc->chan_built == 0) { + if (ztc->built_fmts == (zth->dstfmt | zth->srcfmt)) { + ztc->chan_built = 1; + st->ssrc += 1; + } else { + /* If channel is built for the wrong codecs, teardown and rebuild */ + if (st->encoder == 1) { + if (st->chan_in_num != 999) { + wcdte_close_channel(wc, st->chan_in_num, st->chan_out_num); + wcdte_destroy_channel(wc, st->chan_in_num, st->chan_out_num); + } + wcdte_create_channel(wc, st->timeslot_in_num, st->timeslot_out_num, &(st->chan_in_num), &(st->chan_out_num)); + wcdte_open_channel(wc, wcdte_zapfmt_to_dtefmt(zth->srcfmt), wcdte_zapfmt_to_dtefmt(zth->dstfmt), + st->timeslot_in_num, st->timeslot_out_num, st->chan_in_num, st->chan_out_num); + } else { + if (st->chan_in_num != 999) { + wcdte_close_channel(wc, st->chan_out_num, st->chan_in_num); + wcdte_destroy_channel(wc, st->chan_out_num, st->chan_in_num); + } + wcdte_create_channel(wc, st->timeslot_out_num, st->timeslot_in_num, &(st->chan_out_num), &(st->chan_in_num)); + wcdte_open_channel(wc, wcdte_zapfmt_to_dtefmt(zth->srcfmt), wcdte_zapfmt_to_dtefmt(zth->dstfmt), + st->timeslot_out_num, st->timeslot_in_num, st->chan_out_num, st->chan_in_num); + } + } /* Mark this channel as built */ ztc->chan_built = 1; ztc->built_fmts = zth->dstfmt | zth->srcfmt; @@ -626,9 +740,9 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op) compl_ztc = &(wc->udecode->channels[ndx]); else compl_ztc = &(wc->uencode->channels[ndx]); + compl_st = compl_ztc->pvt; compl_ztc->chan_built = 1; compl_ztc->built_fmts = zth->dstfmt | zth->srcfmt; - compl_st = compl_ztc->pvt; compl_st->chan_in_num = st->chan_out_num; compl_st->chan_out_num = st->chan_in_num; } @@ -637,39 +751,24 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op) case ZT_TCOP_RELEASE: down(&wc->chansem); ndx = st->timeslot_in_num/2; - + if (st->encoder == 1) compl_ztc = &(wc->udecode->channels[ndx]); else compl_ztc = &(wc->uencode->channels[ndx]); - /* If the channel complement (other half of the encoder/decoder pair) is not being used... */ if ((compl_ztc->flags & ZT_TC_FLAG_BUSY) == 0) - { - if (st->encoder == 1) - wcdte_destroy_channel(wc, st->chan_in_num, st->chan_out_num); - else - wcdte_destroy_channel(wc, st->chan_out_num, st->chan_in_num); - + { /* Mark this channel as not built */ ztc->chan_built = 0; - ztc->built_fmts = 0; - st->chan_in_num = 999; - st->chan_out_num = 999; - + /* Mark the channel complement as not built */ compl_ztc->chan_built = 0; - compl_ztc->built_fmts = 0; - compl_st = compl_ztc->pvt; - compl_st->chan_in_num = 999; - compl_st->chan_out_num = 999; } - st->dte_seqno_rcv = 0; + up(&wc->chansem); break; case ZT_TCOP_TRANSCODE: - if (ztc->chan_built == 0) - printk("wcdte error: Sending data to a channel that isn't built yet\n"); if ( (((zth->srcfmt == ZT_FORMAT_ULAW) || (zth->srcfmt == ZT_FORMAT_ALAW)) && ((zth->dstfmt == ZT_FORMAT_G729A && zth->srclen >= G729_SAMPLES) ||(zth->dstfmt == ZT_FORMAT_G723_1 && zth->srclen >= G723_SAMPLES)) ) || ((zth->srcfmt == ZT_FORMAT_G729A) && (zth->srclen >= G729_BYTES)) || ((zth->srcfmt == ZT_FORMAT_G723_1) && (zth->srclen >= G723_BYTES)) ) @@ -721,7 +820,8 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op) ((st->timestamp) >> 24) & 0xFF, ((st->timestamp) >> 16) & 0xFF, ((st->timestamp) >> 8) & 0xFF, - (st->timestamp) & 0xFF); + (st->timestamp) & 0xFF, + (st->ssrc) & 0xFF); ipchksum = 0x9869 + (fifo[16] << 8) + fifo[17] + (fifo[18] << 8) + fifo[19]; @@ -805,33 +905,34 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl) printk("\n"); } /* See if message must be ACK'd */ - if ((readchunk[17] & 0xC0) == 0) + if ((readchunk[17] & 0x80) == 0) { rcommand = readchunk[24] | (readchunk[25] << 8); rchannel = readchunk[18] | (readchunk[19] << 8); rseq = readchunk[16]; - + down(&wc->cmdqsem); - if ( (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) && debug ) - printk("wcdte error: cmdq is full (rndx = %d, wndx = %d).\n", wc->cmdq_rndx, wc->cmdq_wndx); - else - { - unsigned char fifo[OTHER_CMD_LEN] = CMD_MSG_ACK(rseq++, rchannel); + if ((readchunk[17] & 0x40) == 0) { + if ( (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) && debug ) + printk("wcdte error: cmdq is full (rndx = %d, wndx = %d).\n", wc->cmdq_rndx, wc->cmdq_wndx); + else + { + unsigned char fifo[OTHER_CMD_LEN] = CMD_MSG_ACK(rseq++, rchannel); - wc->cmdq[wc->cmdq_wndx].cmdlen = CMD_MSG_ACK_LEN; - for (i = 0; i < wc->cmdq[wc->cmdq_wndx].cmdlen; i++) - wc->cmdq[wc->cmdq_wndx].cmd[i] = fifo[i]; - wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS; - } - - __transmit_demand(wc); + wc->cmdq[wc->cmdq_wndx].cmdlen = CMD_MSG_ACK_LEN; + for (i = 0; i < wc->cmdq[wc->cmdq_wndx].cmdlen; i++) + wc->cmdq[wc->cmdq_wndx].cmd[i] = fifo[i]; + wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS; + } + __transmit_demand(wc); + } wc->rcvflags = RCV_CSMENCAPS; if (rcommand == wc->last_command_sent) { wc->last_rcommand = rcommand; - wc->last_rparm2 = readchunk[30] | (readchunk[31] << 8); - wake_up_interruptible(&wc->regq); + wc->last_rparm1 = readchunk[28] | (readchunk[29] << 8); + wake_up(&wc->regq); } else { if (debug) printk("wcdte error: unexpected command response received (sent: %04X, received: %04X)\n", wc->last_command_sent, rcommand); @@ -842,7 +943,27 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl) { wc->last_rseqno = readchunk[16]; wc->rcvflags = RCV_CSMENCAPS_ACK; - wake_up_interruptible(&wc->regq); + if (!wc->dumping) + wake_up_interruptible(&wc->regq); + else + wake_up(&wc->regq); + } + + if ((readchunk[22] == 0x75) && (readchunk[23] = 0xC1)) + { + if (debug) + printk("wcdte error: received alert (0x%02X%02X) from dsp\n", readchunk[29], readchunk[28]); + if (debug_des) { + down(&wc->cmdqsem); + __dump_descriptors(wc); + up(&wc->cmdqsem); + } + } + + if (wc->dumping && (readchunk[22] == 0x04) && (readchunk[23] = 0x14)) { + for (i = 27; i < 227; i++) + printk("%02X ", readchunk[i]); + printk("\n"); } } @@ -873,7 +994,12 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl) if (zth == NULL) { if (debug) - printk("wcdte error: Tried to put DTE data into a freed zth header!\n"); + printk("wcdte error: Tried to put DTE data into a freed zth header! (ztc_ndx = %d, ztc->chan_built = %d)\n", ztc_ndx, ztc->chan_built); + if (debug_des) { + down(&wc->cmdqsem); + __dump_descriptors(wc); + up(&wc->cmdqsem); + } rcodec = DTE_FORMAT_UNDEF; } else { chars = (unsigned char *)(zth->dstdata + zth->dstoffset + zth->dstlen); @@ -891,7 +1017,12 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl) if (zth == NULL) { if (debug) - printk("wcdte error: Tried to put DTE data into a freed zth header!\n"); + printk("wcdte error: Tried to put DTE data into a freed zth header! (ztc_ndx = %d, ztc->chan_built = %d)\n", ztc_ndx, ztc->chan_built); + if (debug_des) { + down(&wc->cmdqsem); + __dump_descriptors(wc); + up(&wc->cmdqsem); + } rcodec = DTE_FORMAT_UNDEF; } else { chars = (unsigned char *)(zth->dstdata + zth->dstoffset + zth->dstlen); @@ -907,7 +1038,7 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl) } else { rtp_eseq = (st->last_dte_seqno + 1) & 0xFFFF; if ( (rtp_rseq != rtp_eseq) && debug ) - printk("wcdte error: Bad seqno from DTE! [%d][%d][%d]\n", rchannel, rtp_rseq, st->last_dte_seqno); + printk("wcdte error: Bad seqno from DTE! [%04X][%d][%d][%d]\n", (readchunk[37] | (readchunk[36] << 8)), rchannel, rtp_rseq, st->last_dte_seqno); st->last_dte_seqno = rtp_rseq; } @@ -983,9 +1114,6 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl) } - - - /* static inline int wcdte_check_descriptor(struct wcdte *wc) */ static int wcdte_check_descriptor(struct wcdte *wc) { @@ -1197,9 +1325,17 @@ static int wcdte_waitfor_csmencaps(struct wcdte *wc, unsigned int mask, int wait if (wait_mode == 1) ret = wait_event_interruptible_timeout(wc->regq, (wc->rcvflags == mask), wc->timeout); else if (wait_mode == 2) - ret = wait_event_interruptible_timeout(wc->regq, ((wc->last_seqno == wc->last_rseqno) && (wc->rcvflags == mask)), wc->timeout); - else - ret = wait_event_interruptible_timeout(wc->regq, ((wc->last_rcommand == wc->last_command_sent) && (wc->last_seqno == wc->last_rseqno) && (wc->rcvflags == mask)), wc->timeout); + ret = wait_event_timeout(wc->regq, (wc->rcvflags == mask), wc->timeout); + else { + if (!debug_notimeout) { + ret = wait_event_timeout(wc->regq, ((wc->last_rcommand == wc->last_command_sent) && (wc->last_seqno == wc->last_rseqno) && (wc->rcvflags == mask)), wc->timeout); + } + else { + ret = wait_event_interruptible(wc->regq, ((wc->last_rcommand == wc->last_command_sent) && (wc->last_seqno == wc->last_rseqno) && (wc->rcvflags == mask))); + if (ret == 0) + ret = 1; + } + } wc->rcvflags = 0; wc->last_rcommand = 0; wc->last_seqno = 0; @@ -1214,6 +1350,11 @@ static int wcdte_waitfor_csmencaps(struct wcdte *wc, unsigned int mask, int wait { if (debug) printk("wcdte error: Waitfor CSMENCAPS response timed out (ret = %d) (cmd_snt = %04X)\n", ret, wc->last_command_sent); + if (debug_des) { + down(&wc->cmdqsem); + __dump_descriptors(wc); + up(&wc->cmdqsem); + } return(2); } if (wait_mode == 0) @@ -1290,7 +1431,7 @@ void wcdte_write_phy(struct wcdte *wc, int location, int value) return; } -static int wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmware) +static int wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmware, int full) { int i, j, byteloc, last_byteloc, length, delay_count; unsigned int reg, ret; @@ -1300,12 +1441,12 @@ static int wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmwar wcdte_write_phy(wc, 0, 0x2100); if (debug) printk("wcdte: PHY register 0 = %X", wcdte_read_phy(wc, 0)); - + /* Set reset */ wcdte_setctl(wc, 0x00A0, 0x04000000); /* Wait 1000msec to ensure processor reset */ - mdelay(1000); + mdelay(4); /* Clear reset */ wcdte_setctl(wc, 0x00A0, 0x04080000); @@ -1315,10 +1456,10 @@ static int wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmwar do { reg = wcdte_getctl(wc, 0x00fc); - mdelay(100); + mdelay(2); delay_count++; - if (delay_count >= 100) + if (delay_count >= 5000) { printk("wcdte error: Failed to link to DTE processor!\n"); return(1); @@ -1358,7 +1499,7 @@ static int wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmwar wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS; } - __transmit_demand(wc); + ret = __transmit_demand(wc); up(&wc->cmdqsem); ret = wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS_ACK, 1); @@ -1368,6 +1509,12 @@ static int wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmwar byteloc = last_byteloc; j++; + if (!full && (byteloc > 189)) { /* Quit if not fully booting */ + wcdte_setctl(wc, 0x00A0, 0x04080000); + return 0; + } + + } while (byteloc < firmware->size-20); wc->timeout = 10 * HZ; wc->last_command_sent = 0; @@ -1382,30 +1529,47 @@ static int wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmwar return(0); } -static int wcdte_create_channel(struct wcdte *wc, int simple, int complicated, int part1_id, int part2_id, unsigned int *dte_chan1, unsigned int *dte_chan2) + +static int wcdte_create_channel(struct wcdte *wc, int part1_id, int part2_id, unsigned int *dte_chan1, unsigned int *dte_chan2) { - int length = 0; unsigned char chan1, chan2; - struct zt_transcoder_channel *ztc1, *ztc2; - struct dte_state *st1, *st2; - if(complicated == DTE_FORMAT_G729A) - length = G729_LENGTH; - else if (complicated == DTE_FORMAT_G723_1) - length = G723_LENGTH; /* Create complex channel */ zt_send_cmd(wc, CMD_MSG_CREATE_CHANNEL(wc->seq_num++, part1_id), CMD_MSG_CREATE_CHANNEL_LEN, 0x0010); - chan1 = wc->last_rparm2; + zt_send_cmd(wc, CMD_MSG_QUERY_CHANNEL(wc->seq_num++, part1_id), CMD_MSG_QUERY_CHANNEL_LEN, 0x0010); + chan1 = wc->last_rparm1; /* Create simple channel */ zt_send_cmd(wc, CMD_MSG_CREATE_CHANNEL(wc->seq_num++, part2_id), CMD_MSG_CREATE_CHANNEL_LEN, 0x0010); - chan2 = wc->last_rparm2; + zt_send_cmd(wc, CMD_MSG_QUERY_CHANNEL(wc->seq_num++, part2_id), CMD_MSG_QUERY_CHANNEL_LEN, 0x0010); + chan2 = wc->last_rparm1; + + *dte_chan1 = chan1; + *dte_chan2 = chan2; + + return 0; +} + +static int wcdte_open_channel(struct wcdte *wc, int simple, int complicated, int part1_id, int part2_id, int chan1, int chan2) +{ + int length = 0; + struct zt_transcoder_channel *ztc1, *ztc2; + struct dte_state *st1, *st2; + if(complicated == DTE_FORMAT_G729A) + length = G729_LENGTH; + else if (complicated == DTE_FORMAT_G723_1) + length = G723_LENGTH; ztc1 = &(wc->uencode->channels[part1_id/2]); ztc2 = &(wc->udecode->channels[part2_id/2]); st1 = ztc1->pvt; st2 = ztc2->pvt; + if (force_alert) { + printk("Sending FORCE ALERT\n"); + zt_send_cmd(wc, CMD_MSG_FORCE_ALERT(wc->seq_num++), CMD_MSG_FORCE_ALERT_LEN, 0xFFFF); + } + /* Configure complex channel */ zt_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(st1->cmd_seqno++, chan1, part2_id, part1_id), CMD_MSG_SET_IP_HDR_CHANNEL_LEN, 0x9000); zt_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(st1->cmd_seqno++, chan1, length, 0), CMD_MSG_VOIP_VCEOPT_LEN, 0x8001); @@ -1427,13 +1591,19 @@ static int wcdte_create_channel(struct wcdte *wc, int simple, int complicated, i zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA(st1->cmd_seqno++, chan1, complicated), CMD_MSG_VOIP_VOPENA_LEN, 0x8000); zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA(st2->cmd_seqno++, chan2, simple), CMD_MSG_VOIP_VOPENA_LEN, 0x8000); - *dte_chan1 = chan1; - *dte_chan2 = chan2; - - return 1; + return 0; } static int wcdte_destroy_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2) +{ + /* Remove the channels */ + zt_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan1), CMD_MSG_DESTROY_CHANNEL_LEN, 0x0011); + zt_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan2), CMD_MSG_DESTROY_CHANNEL_LEN, 0x0011); + + return 0; +} + +static int wcdte_close_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2) { struct zt_transcoder_channel *ztc1, *ztc2; struct dte_state *st1, *st2; @@ -1450,16 +1620,13 @@ static int wcdte_destroy_channel(struct wcdte *wc, unsigned int chan1, unsigned /* Disconnect the channels */ zt_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 0, chan1, chan2, 0, 0), CMD_MSG_TRANS_CONNECT_LEN, 0x9322); - /* Remove the channels */ - zt_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan1), CMD_MSG_DESTROY_CHANNEL_LEN, 0x0011); - zt_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan2), CMD_MSG_DESTROY_CHANNEL_LEN, 0x0011); - - return 1; + return 0; } -static int wcdte_setup_channels(struct wcdte *wc) + +static int __wcdte_setup_channels(struct wcdte *wc) { - down(&wc->chansem); + wc->seq_num = 6; #ifndef USE_TEST_HW zt_send_cmd(wc, CMD_MSG_SET_ARM_CLK(wc->seq_num++), CMD_MSG_SET_ARM_CLK_LEN, 0x0411); @@ -1494,9 +1661,16 @@ static int wcdte_setup_channels(struct wcdte *wc) wc->timeout = HZ/10 + 1; /* 100msec */ + return(0); +} + +static int wcdte_setup_channels(struct wcdte *wc) +{ + down(&wc->chansem); + __wcdte_setup_channels(wc); up(&wc->chansem); - return(0); + return 0; } static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -1506,7 +1680,7 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic struct wcdte_desc *d = (struct wcdte_desc *)ent->driver_data; int x; static int initd_ifaces=0; - unsigned char g729_numchannels, g723_numchannels, min_numchannels, dte_firmware_ver; + unsigned char g729_numchannels, g723_numchannels, min_numchannels, dte_firmware_ver, dte_firmware_ver_minor; unsigned int complexfmts; struct firmware embedded_firmware = { #if !defined(HOTPLUG_FIRMWARE) @@ -1556,11 +1730,13 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic wc->last_seqno = 999; wc->last_command_sent = 0; wc->last_rcommand = 0; - wc->last_rparm2 = 0; + wc->last_rparm1 = 0; wc->cmdq_wndx = 0; wc->cmdq_rndx = 0; wc->seq_num = 6; wc->timeout = 1 * HZ; /* 1 sec */ + wc->dsp_crashed = 0; + wc->dumping = 0; wc->ztsnd_rtx = 0; wc->ztsnd_0010_rtx = 0; @@ -1604,6 +1780,7 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic } #endif dte_firmware_ver = firmware->data[0]; + dte_firmware_ver_minor = firmware->data[16]; g729_numchannels = firmware->data[1]; g723_numchannels = firmware->data[2]; @@ -1679,7 +1856,7 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic zt_transcoder_register(uencode); zt_transcoder_register(udecode); - printk("Zaptel DTE (%s) Transcoder support LOADED (firm ver = %d)\n", wc->complexname, dte_firmware_ver); + printk("Zaptel DTE (%s) Transcoder support LOADED (firm ver = %d.%d)\n", wc->complexname, dte_firmware_ver, dte_firmware_ver_minor); /* Enable bus mastering */ @@ -1718,7 +1895,7 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic /* Start DMA */ wcdte_start_dma(wc); - if (wcdte_boot_processor(wc,firmware)) { + if (wcdte_boot_processor(wc,firmware,1)) { if (firmware != &embedded_firmware) release_firmware(firmware); @@ -1733,7 +1910,6 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic vfree(wc); return -EIO; } - if (wcdte_setup_channels(wc)) { /* Set Reset Low */ @@ -1747,12 +1923,17 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic vfree(wc); return -EIO; } - + reg = wcdte_getctl(wc, 0x00fc); if (debug) printk("wcdte debug: (post-boot) Reg fc is %08x\n", reg); printk("Found and successfully installed a Wildcard TC: %s \n", wc->variety); + if (debug) { + printk("TC400B operating in DEBUG mode\n"); + printk("debug_des = %d, debug_des_cnt = %d, force_alert = %d,\n debug_notimeout = %d, debug_packets = %d\n", + debug_des, debug_des_cnt, force_alert, debug_notimeout, debug_packets); + } res = 0; } else res = -ENOMEM; @@ -1792,7 +1973,7 @@ static void __devexit wcdte_remove_one(struct pci_dev *pdev) printk("wcdte debug: de[%d] snt = %d, rcv = %d [%d]\n", i, st_de->packets_sent, st_de->packets_received, st_de->packets_sent - st_de->packets_received); } } - + zt_transcoder_unregister(wc->udecode); zt_transcoder_unregister(wc->uencode); zt_transcoder_free(wc->uencode); @@ -1855,6 +2036,10 @@ void ztdte_cleanup(void) } module_param(debug, int, S_IRUGO | S_IWUSR); +module_param(debug_des, int, S_IRUGO | S_IWUSR); +module_param(debug_des_cnt, int, S_IRUGO | S_IWUSR); +module_param(debug_notimeout, int, S_IRUGO | S_IWUSR); +module_param(force_alert, int, S_IRUGO | S_IWUSR); module_param(mode, charp, S_IRUGO | S_IWUSR); MODULE_DESCRIPTION("Wildcard TC400P+TC400M Driver"); MODULE_AUTHOR("John Sloan "); diff --git a/wctc4xxp/tc400m-firmware.bin b/wctc4xxp/tc400m-firmware.bin index 2e6c743..2412e28 100644 Binary files a/wctc4xxp/tc400m-firmware.bin and b/wctc4xxp/tc400m-firmware.bin differ -- cgit v1.2.3