summaryrefslogtreecommitdiff
path: root/ztcodec_dte.c
diff options
context:
space:
mode:
authormogorman <mogorman@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-12-11 19:45:18 +0000
committermogorman <mogorman@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-12-11 19:45:18 +0000
commit2f198d98a8150963b7154c18930173b8b871f6c3 (patch)
tree19e2a7ec583c6741bd008c01b7d3b167a46ab37b /ztcodec_dte.c
parent1bfb68dfe23e791a6dacc7b59a65e6f5341c4973 (diff)
updates for dynamic channel creation on transcoder card.
from jsloan's branch git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1703 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'ztcodec_dte.c')
-rw-r--r--ztcodec_dte.c855
1 files changed, 536 insertions, 319 deletions
diff --git a/ztcodec_dte.c b/ztcodec_dte.c
index 8db9a74..da43dfe 100644
--- a/ztcodec_dte.c
+++ b/ztcodec_dte.c
@@ -23,6 +23,7 @@
*
*/
+
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -37,6 +38,9 @@
#include <linux/mman.h>
#include <linux/delay.h>
#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
#ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h>
#endif
@@ -45,9 +49,7 @@
#else
#include <linux/zaptel.h>
#endif
-#ifdef LINUX26
#include <linux/moduleparam.h>
-#endif
#include "dte_firm.h"
@@ -59,6 +61,7 @@
#define NUM_CARDS 24
#define NUM_EC 4
+/* NUM_CHANNELS must be checked if new firmware (dte_firm.h) is used */
#define NUM_CHANNELS 97
#define DTE_FORMAT_ULAW 0x00
@@ -67,19 +70,21 @@
#define DTE_FORMAT_G729A 0x12
#define DTE_FORMAT_UNDEF 0xFF
-/* #define COMPLEX_CODEC DTE_FORMAT_G723_1 */
-#define COMPLEX_CODEC DTE_FORMAT_G729A
-#define SIMPLE_CODEC DTE_FORMAT_ULAW
+#define G729_LENGTH 20
+#define G723_LENGTH 30
-#define SAMPLE_LENGTH 20
+#define G729_SAMPLES 160 /* g.729 */
+#define G723_SAMPLES 240 /* g.723 */
+
+#define G729_BYTES 20 /* g.729 */
+#define G723_BYTES 20 /* g.723 */
-#define PACKET_OUT_SIZE 160 /* g.729 */
-/* #define PACKET_OUT_SIZE 240 */ /* g.723 */
#define ACK_SPACE 20
#define MAX_COMMANDS (NUM_CHANNELS + ACK_SPACE)
+#define MAX_RCV_COMMANDS 16
/* 1432 for boot, 274 for 30msec ulaw, 194 for 20mec ulaw */
#define BOOT_CMD_LEN 1500
@@ -95,126 +100,179 @@
-#define RCV_CSMENCAPS 1
-#define RCV_RTP 2
-#define RCV_OTHER 99
+#define RCV_CSMENCAPS 1
+#define RCV_RTP 2
+#define RCV_CSMENCAPS_ACK 3
+#define RCV_OTHER 99
/* TDM Commands */
#define CMD_MSG_TDM_SELECT_BUS_MODE_LEN 30
-#define CMD_MSG_TDM_SELECT_BUS_MODE(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x01, 0x00,0x06,0x17,0x04, 0xFF,0xFF, 0x04,0x00}
-
+#define CMD_MSG_TDM_SELECT_BUS_MODE(s) { \
+ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x01, 0x00,0x06,0x17,0x04, 0xFF,0xFF, \
+ 0x04,0x00 }
#define CMD_MSG_TDM_ENABLE_BUS_LEN 30
-#define CMD_MSG_TDM_ENABLE_BUS(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x02, 0x00,0x06,0x05,0x04, 0xFF,0xFF, 0x04,0x00}
-
+#define CMD_MSG_TDM_ENABLE_BUS(s) { \
+ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x02, 0x00,0x06,0x05,0x04, 0xFF,0xFF, \
+ 0x04,0x00 }
#define CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN 34
-#define CMD_MSG_SUPVSR_SETUP_TDM_PARMS(s,p1,p2,p3) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x10, p1, 0x00,0x06,0x07,0x04, 0xFF,0xFF, p2,0x83, 0x00,0x0C, 0x00,0x00, p3,0x00}
-
+#define CMD_MSG_SUPVSR_SETUP_TDM_PARMS(s,p1,p2,p3) { \
+ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x10, p1, 0x00,0x06,0x07,0x04, 0xFF,0xFF, \
+ p2,0x83, 0x00,0x0C, 0x00,0x00, p3,0x00 }
#define CMD_MSG_TDM_OPT_LEN 30
-#define CMD_MSG_TDM_OPT(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x35,0x04, 0xFF,0xFF, 0x00,0x00}
-
-
-
+#define CMD_MSG_TDM_OPT(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,0x35,0x04, 0xFF,0xFF, \
+ 0x00,0x00 }
#define CMD_MSG_DEVICE_SET_COUNTRY_CODE_LEN 30
-#define CMD_MSG_DEVICE_SET_COUNTRY_CODE(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x1B,0x04, 0xFF,0xFF, 0x00,0x00}
-
-
-
-
+#define CMD_MSG_DEVICE_SET_COUNTRY_CODE(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,0x1B,0x04, 0xFF,0xFF, \
+ 0x00,0x00 }
+/* CPU Commands */
#define CMD_MSG_SET_ARM_CLK_LEN 32
-#define CMD_MSG_SET_ARM_CLK(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0C, 0x00, 0x00,0x06,0x11,0x04, 0x00,0x00, 0x2C,0x01, 0x00,0x00}
-
+#define CMD_MSG_SET_ARM_CLK(s) { \
+ 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,0x11,0x04, 0x00,0x00, \
+ 0x2C,0x01, 0x00,0x00 }
#define CMD_MSG_SET_SPU_CLK_LEN 32
-#define CMD_MSG_SET_SPU_CLK(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0C, 0x00, 0x00,0x06,0x12,0x04, 0x00,0x00, 0x2C,0x01, 0x00,0x00}
-
-
-
-#define CMD_MSG_ACK_LEN 20
-#define CMD_MSG_ACK(s,c1,c2) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0xE0, c1, c2}
-
+#define CMD_MSG_SET_SPU_CLK(s) { \
+ 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,0x12,0x04, 0x00,0x00, \
+ 0x2C,0x01, 0x00,0x00 }
+#define CMD_MSG_SPU_FEATURES_CONTROL_LEN 30
+#define CMD_MSG_SPU_FEATURES_CONTROL(s,p1) { \
+ 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,0x13,0x00, 0xFF,0xFF, \
+ p1,0x00 }
+#define CMD_MSG_DEVICE_STATUS_CONFIG_LEN 30
+#define CMD_MSG_DEVICE_STATUS_CONFIG(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,0x0F,0x04, 0xFF,0xFF, \
+ 0x05,0x00 }
+/* General IP/RTP Commands */
#define CMD_MSG_SET_ETH_HEADER_LEN 44
-#define CMD_MSG_SET_ETH_HEADER(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x18, 0x00, 0x00,0x06,0x00,0x01, 0xFF,0xFF, 0x01,0x00, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55, 0x08,0x00};
-
-
-
+#define CMD_MSG_SET_ETH_HEADER(s) { \
+ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x18, 0x00, 0x00,0x06,0x00,0x01, 0xFF,0xFF, \
+ 0x01,0x00, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55, 0x08,0x00 }
#define CMD_MSG_IP_SERVICE_CONFIG_LEN 30
-#define CMD_MSG_IP_SERVICE_CONFIG(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x02,0x03, 0xFF,0xFF, 0x00,0x02}
-
-
+#define CMD_MSG_IP_SERVICE_CONFIG(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,0x02,0x03, 0xFF,0xFF, \
+ 0x00,0x02 }
#define CMD_MSG_ARP_SERVICE_CONFIG_LEN 30
-#define CMD_MSG_ARP_SERVICE_CONFIG(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x05,0x01, 0xFF,0xFF, 0x01,0x00}
-
+#define CMD_MSG_ARP_SERVICE_CONFIG(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,0x05,0x01, 0xFF,0xFF, \
+ 0x01,0x00 }
#define CMD_MSG_ICMP_SERVICE_CONFIG_LEN 30
-#define CMD_MSG_ICMP_SERVICE_CONFIG(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x04,0x03, 0xFF,0xFF, 0x01,0xFF}
-
-#define CMD_MSG_SPU_FEATURES_CONTROL_LEN 30
-#define CMD_MSG_SPU_FEATURES_CONTROL(s,p1) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x13,0x00, 0xFF,0xFF, p1,0x00}
-
+#define CMD_MSG_ICMP_SERVICE_CONFIG(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,0x04,0x03, 0xFF,0xFF, \
+ 0x01,0xFF }
#define CMD_MSG_IP_OPTIONS_LEN 30
-#define CMD_MSG_IP_OPTIONS(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x06,0x03, 0xFF,0xFF, 0x02,0x00}
-
-
-
-
+#define CMD_MSG_IP_OPTIONS(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,0x06,0x03, 0xFF,0xFF, \
+ 0x02,0x00 }
+/* Supervisor channel commands */
#define CMD_MSG_CREATE_CHANNEL_LEN 32
-#define CMD_MSG_CREATE_CHANNEL(s,t1,t2) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0C, 0x00, 0x00,0x06,0x10,0x00, 0x00,0x00, 0x02,0x00, t1, t2}
-
-
+#define CMD_MSG_CREATE_CHANNEL(s,t) { \
+ 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_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, \
+ 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x12, 0x00, 0x00,0x06,0x22,0x93, 0x00,0x00, \
+ e,0x00, (c1&0x00FF),((c1&0xFF00)>>8), f1,0x00, (c2&0x00FF),((c2&0xFF00)>>8), f2,0x00 }
+#define CMD_MSG_DESTROY_CHANNEL_LEN 32
+#define CMD_MSG_DESTROY_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, 0x00,0x06,0x11,0x00, 0x00,0x00, \
+ (t&0x00FF),((t&0xFF00)>>8), 0x00, 0x00 }
+
+/* Individual channel config commands */
#define CMD_MSG_SET_IP_HDR_CHANNEL_LEN 58
-#define CMD_MSG_SET_IP_HDR_CHANNEL(s,c1,c2,s1,s2,s3,s4) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, c1,c2, 0x26, 0x00, 0x00,0x02,0x00,0x90, 0x00,0x00, 0x00,0x00, 0x45,0x00, 0x00,0x00, 0x00,0x00, 0x40,0x00, 0x80,0x11, 0x00,0x00, 0xC0,0xA8,0x09,0x03, 0xC0,0xA8,0x09,0x03, s1,s2, s3,s4, 0x00,0x00, 0x00,0x00}
-
+#define CMD_MSG_SET_IP_HDR_CHANNEL(s,c,t2,t1) { \
+ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00) >> 8),(c&0x00FF), 0x26, 0x00, 0x00,0x02,0x00,0x90, 0x00,0x00, \
+ 0x00,0x00, 0x45,0x00, 0x00,0x00, 0x00,0x00, 0x40,0x00, 0x80,0x11, 0x00,0x00, \
+ 0xC0,0xA8,0x09,0x03, 0xC0,0xA8,0x09,0x03, \
+ ((t2&0xFF00)>>8)+0x50,(t2&0x00FF), ((t1&0xFF00)>>8)+0x50,(t1&0x00FF), 0x00,0x00, 0x00,0x00 }
#define CMD_MSG_VOIP_VCEOPT_LEN 40
-#define CMD_MSG_VOIP_VCEOPT(s,c1,c2,t,w) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, c1,c2, 0x12, 0x00, 0x00,0x02,0x01,0x80, 0x00,0x00, 0x31,t, 0x00,0x1C, 0x04,0x00, 0x00,0x00, w,0x00, 0x80,0x11}
-
-#define CMD_MSG_TRANS_CONNECT_LEN 38
-#define CMD_MSG_TRANS_CONNECT(s,e,c1,c2,c3,c4) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x12, 0x00, 0x00,0x06,0x22,0x93, 0x00,0x00, e,0x00, c1,c2, COMPLEX_CODEC,0x00, c3,c4, 0x00,0x00}
-
-
+#define CMD_MSG_VOIP_VCEOPT(s,c,l,w) { \
+ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x12, 0x00, 0x00,0x02,0x01,0x80, 0x00,0x00, \
+ 0x21,l, 0x00,0x1C, 0x04,0x00, 0x00,0x00, w,0x00, 0x80,0x11 }
#define CMD_MSG_VOIP_VOPENA_LEN 44
-#define CMD_MSG_VOIP_VOPENA(s,c1,c2,f) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, c1,c2, 0x16, 0x00, 0x00,0x02,0x00,0x80, 0x00,0x00, 0x01,0x00, 0x80,f, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x12,0x34, 0x56,0x78, 0x00,0x00}
-
+#define CMD_MSG_VOIP_VOPENA(s,c,f) { \
+ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x16, 0x00, 0x00,0x02,0x00,0x80, 0x00,0x00, \
+ 0x01,0x00, 0x80,f, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x12,0x34, 0x56,0x78, 0x00,0x00 }
#define CMD_MSG_VOIP_VOPENA_CLOSE_LEN 32
-#define CMD_MSG_VOIP_VOPENA_CLOSE(s,c1,c2,f) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, c1,c2, 0x0A, 0x00, 0x00,0x02,0x00,0x80, 0x00,0x00, 0x00,0x00, 0x00,0x00}
-
-
-#define CMD_MSG_DEVICE_STATUS_CONFIG_LEN 30
-#define CMD_MSG_DEVICE_STATUS_CONFIG(s) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, 0x00,0x01, s, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x0F,0x04, 0xFF,0xFF, 0x05,0x00}
-
-
+#define CMD_MSG_VOIP_VOPENA_CLOSE(s,c) { \
+ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x0A, 0x00, 0x00,0x02,0x00,0x80, 0x00,0x00, \
+ 0x00,0x00, 0x00,0x00 }
+#define CMD_MSG_VOIP_INDCTRL_LEN 32
+#define CMD_MSG_VOIP_INDCTRL(s,c) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x0A, 0x00, 0x00,0x02,0x84,0x80, 0x00,0x00, \
+ 0x07,0x00, 0x00,0x00 }
+
+/* CPU ACK command */
+#define CMD_MSG_ACK_LEN 20
+#define CMD_MSG_ACK(s,c) { \
+ 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \
+ 0x00,0x01, s, 0xE0, (c&0x00FF), ((c>>8)&0x00FF) }
+/* 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) {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}
-
-
+#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) { \
+ 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}
#define zt_send_cmd(wc, command, length, hex) \
({ \
+ int ret = 0; \
do { \
+ if (ret == 2) \
+ { \
+ wc->ztsnd_rtx++; \
+ if (hex == 0x0010) \
+ wc->ztsnd_0010_rtx++; \
+ } \
+ down(&wc->cmdqsem); \
+ wc->last_command_sent = hex; \
if ( (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) && debug ) \
printk("wcdte error: cmdq is full.\n"); \
else { \
unsigned char fifo[OTHER_CMD_LEN] = command; \
+ int i; \
wc->cmdq[wc->cmdq_wndx].cmdlen = length; \
for (i = 0; i < length; i++) \
wc->cmdq[wc->cmdq_wndx].cmd[i] = fifo[i]; \
wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS; \
} \
- transmit_demand(wc); \
- do { \
- ret = wcdte_waitfor_csmencaps(wc); \
- if (ret == 1) \
- return(1); \
- } while ((wc->last_rcommand != hex) && (ret != 2)); \
+ __transmit_demand(wc); \
+ up(&wc->cmdqsem); \
+ ret = wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS, 0); \
+ if (ret == 1) \
+ return(1); \
} while (ret == 2); \
})
-
-
/* define NOT_BLI to use a faster but not bit-level identical version */
/* #define NOT_BLI */
@@ -234,7 +292,6 @@ struct cmdq {
unsigned int cmd[MAX_COMMAND_LEN];
};
-
struct wcdte {
struct pci_dev *dev;
char *variety;
@@ -250,13 +307,24 @@ struct wcdte {
spinlock_t reglock;
wait_queue_head_t regq;
int rcvflags;
-
+
+ struct semaphore chansem;
+ struct semaphore cmdqsem;
struct cmdq cmdq[MAX_COMMANDS];
unsigned int cmdq_wndx;
unsigned int cmdq_rndx;
+
+ unsigned int last_command_sent;
unsigned int last_rcommand;
+ unsigned int last_rparm2;
unsigned int seq_num;
+ unsigned int ztsnd_rtx;
+ unsigned int ztsnd_0010_rtx;
+
+ unsigned char numchannels;
+ unsigned char complexname[40];
+
unsigned long iobase;
dma_addr_t readdma;
dma_addr_t writedma;
@@ -265,10 +333,16 @@ struct wcdte {
volatile unsigned int *readchunk; /* Double-word aligned read memory */
volatile unsigned int *descripchunk; /* Descriptors */
+ int wqueints;
+ struct workqueue_struct *dte_wq;
+ struct work_struct dte_work;
+
struct zt_transcoder *uencode;
struct zt_transcoder *udecode;
};
+static void dte_wque_run(struct wcdte *wc);
+
struct wcdte_desc {
char *name;
int flags;
@@ -296,9 +370,12 @@ struct dte_state {
unsigned int timestamp;
unsigned int seqno;
- unsigned int phys_in_chan; /* DTE chennel on which results we be received from */
- unsigned int phys_out_chan; /* DTE channel to send data to */
+ unsigned int timeslot_in_num; /* DTE chennel on which results we be received from */
+ unsigned int timeslot_out_num; /* DTE channel to send data to */
+ unsigned int chan_in_num; /* DTE chennel on which results we be received from */
+ unsigned int chan_out_num; /* DTE channel to send data to */
+
unsigned int packets_sent;
unsigned int packets_received;
@@ -307,12 +384,17 @@ struct dte_state {
};
-static int numchannels = NUM_CHANNELS - 1;
static struct zt_transcoder *uencode;
static struct zt_transcoder *udecode;
static struct dte_state *encoders;
static struct dte_state *decoders;
static int debug = 0;
+static char *mode;
+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_destroy_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2);
static void dte_init_state(struct dte_state *state_ptr, int encoder, unsigned int channel, struct wcdte *wc)
@@ -326,19 +408,22 @@ static void dte_init_state(struct dte_state *state_ptr, int encoder, unsigned in
state_ptr->packets_received = 0;
state_ptr->last_dte_seqno = 0;
state_ptr->dte_seqno_rcv = 0;
+
+ state_ptr->chan_in_num = 999;
+ state_ptr->chan_out_num = 999;
if (encoder == 1)
{
- state_ptr->phys_in_chan = channel * 2;
- state_ptr->phys_out_chan = channel * 2 + 1;
+ state_ptr->timeslot_in_num = channel * 2;
+ state_ptr->timeslot_out_num = channel * 2 + 1;
} else {
- state_ptr->phys_in_chan = channel * 2 + 1;
- state_ptr->phys_out_chan = channel * 2;
+ state_ptr->timeslot_in_num = channel * 2 + 1;
+ state_ptr->timeslot_out_num = channel * 2;
}
}
-static unsigned int dte_fmt_to_pt(unsigned int fmt)
+static unsigned int wcdte_zapfmt_to_dtefmt(unsigned int fmt)
{
unsigned int pt;
@@ -414,8 +499,8 @@ static inline int __transmit_demand(struct wcdte *wc)
int o2,i,j;
unsigned int reg, xmt_length;
- reg = __wcdte_getctl(wc, 0x0028) & 0x00700000;
-
+ reg = wcdte_getctl(wc, 0x0028) & 0x00700000;
+
/* Already transmiting, no need to demand another */
if (!((reg == 0) || (reg = 6)))
return(1);
@@ -449,10 +534,18 @@ static inline int __transmit_demand(struct wcdte *wc)
for (j = i; j < xmt_length; j++)
writechunk[j] = 0;
+ if (debug_packets && (writechunk[12] == 0x88) && (writechunk[13] == 0x9B))
+ {
+ printk("wcdte debug: TX: ");
+ for (i=0; i<debug_packets; i++)
+ printk("%02X ", writechunk[i]);
+ printk("\n");
+ }
+
wc->cmdq[wc->cmdq_rndx].cmdlen = 0;
wc->descripchunk[o2] = cpu_to_le32(0x80000000);
- __wcdte_setctl(wc, 0x0008, 0x00000000); /* Transmit Poll Demand */
+ wcdte_setctl(wc, 0x0008, 0x00000000); /* Transmit Poll Demand */
wc->tdbl = (wc->tdbl + 1) % ERING_SIZE;
@@ -463,18 +556,18 @@ static inline int __transmit_demand(struct wcdte *wc)
static inline int transmit_demand(struct wcdte *wc)
{
- unsigned long flags;
int val;
- spin_lock_irqsave(&wc->reglock, flags);
+ down(&wc->cmdqsem);
val = __transmit_demand(wc);
- spin_unlock_irqrestore(&wc->reglock, flags);
+ up(&wc->cmdqsem);
return val;
}
static int dte_operation(struct zt_transcoder_channel *ztc, int op)
{
- struct dte_state *st = ztc->pvt;
+ struct zt_transcoder_channel *compl_ztc;
+ struct dte_state *st = ztc->pvt, *compl_st;
struct zt_transcode_header *zth = ztc->tch;
struct wcdte *wc = st->wc;
unsigned char *chars;
@@ -482,18 +575,74 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op)
unsigned int timestamp_inc = 0;
int i = 0;
int res = 0;
- unsigned long flags;
- unsigned int ipchksum;
+ unsigned int ipchksum, ndx;
switch(op) {
case ZT_TCOP_RESET:
+ 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));
+ /* Mark this channel as built */
+ ztc->chan_built = 1;
+ ztc->built_fmts = zth->dstfmt | zth->srcfmt;
+
+ /* Mark the channel complement (other half of encoder/decoder pair) as built */
+ ndx = st->timeslot_in_num/2;
+ if (st->encoder == 1)
+ compl_ztc = &(wc->udecode->channels[ndx]);
+ else
+ compl_ztc = &(wc->uencode->channels[ndx]);
+ 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;
+ }
+ up(&wc->chansem);
break;
- case ZT_TCOP_TRANSCODE:
+ 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);
- spin_lock_irqsave(&wc->reglock, flags);
+ /* 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 ( (((zth->srcfmt == ZT_FORMAT_ULAW) || (zth->srcfmt == ZT_FORMAT_ALAW)) && (zth->srclen >= 160))
- || ((zth->srcfmt == ZT_FORMAT_G729A) && (zth->srclen >= 20))
- || ((zth->srcfmt == ZT_FORMAT_G723_1) && (zth->srclen >= 24)) )
+ 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)) )
{
do
{
@@ -501,42 +650,48 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op)
if ((zth->srcfmt == ZT_FORMAT_ULAW) || (zth->srcfmt == ZT_FORMAT_ALAW))
{
- inbytes = 160; /* 80; */
- timestamp_inc = 160; /* 80; */
+ if (zth->dstfmt == ZT_FORMAT_G729A) {
+ inbytes = G729_SAMPLES;
+ timestamp_inc = G729_SAMPLES;
+ } else if (zth->dstfmt == ZT_FORMAT_G723_1) {
+ inbytes = G723_SAMPLES;
+ timestamp_inc = G723_SAMPLES;
+ }
+
} else if (zth->srcfmt == ZT_FORMAT_G729A)
{
- inbytes = 20; /* 10; */
- timestamp_inc = 160; /* 80; */
+ inbytes = G729_BYTES;
+ timestamp_inc = G729_SAMPLES;
} else if (zth->srcfmt == ZT_FORMAT_G723_1)
{
- inbytes = 24;
- timestamp_inc = 240;
+ inbytes = G723_BYTES;
+ timestamp_inc = G723_SAMPLES;
}
zth->srclen -= inbytes;
{
unsigned char fifo[OTHER_CMD_LEN] = CMD_MSG_IP_UDP_RTP(
- ((inbytes+40) >> 8) & 0xFF,
- (inbytes+40) & 0xFF,
- st->seqno & 0xFF,
+ ((inbytes+40) >> 8) & 0xFF,
+ (inbytes+40) & 0xFF,
+ st->seqno & 0xFF,
0x00,
0x00,
- (((st->phys_out_chan) >> 8)+0x50) & 0xFF,
- (st->phys_out_chan) & 0xFF,
- (((st->phys_in_chan) >> 8)+0x50) & 0xFF,
- (st->phys_in_chan) & 0xFF,
- ((inbytes+20) >> 8) & 0xFF,
- (inbytes+20) & 0xFF,
+ (((st->timeslot_out_num) >> 8)+0x50) & 0xFF,
+ (st->timeslot_out_num) & 0xFF,
+ (((st->timeslot_in_num) >> 8)+0x50) & 0xFF,
+ (st->timeslot_in_num) & 0xFF,
+ ((inbytes+20) >> 8) & 0xFF,
+ (inbytes+20) & 0xFF,
0x00,
0x00,
- dte_fmt_to_pt(zth->srcfmt),
- ((st->seqno) >> 8) & 0xFF,
- (st->seqno) & 0xFF,
- ((st->timestamp) >> 24) & 0xFF,
- ((st->timestamp) >> 16) & 0xFF,
- ((st->timestamp) >> 8) & 0xFF,
- (st->timestamp) & 0xFF);
+ wcdte_zapfmt_to_dtefmt(zth->srcfmt),
+ ((st->seqno) >> 8) & 0xFF,
+ (st->seqno) & 0xFF,
+ ((st->timestamp) >> 24) & 0xFF,
+ ((st->timestamp) >> 16) & 0xFF,
+ ((st->timestamp) >> 8) & 0xFF,
+ (st->timestamp) & 0xFF);
ipchksum = 0x9869 + (fifo[16] << 8) + fifo[17]
+ (fifo[18] << 8) + fifo[19];
@@ -553,6 +708,8 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op)
for (i = 0; i < inbytes; i++)
fifo[i+CMD_MSG_IP_UDP_RTP_LEN]= chars[i];
+ down(&wc->cmdqsem);
+
if ( (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) && debug )
printk("wcdte error: cmdq is full.\n");
else
@@ -563,26 +720,24 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op)
wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS;
}
+ __transmit_demand(wc);
+ up(&wc->cmdqsem);
}
st->packets_sent++;
- __transmit_demand(wc);
zth->srcoffset += inbytes;
- } while ( (((zth->srcfmt == ZT_FORMAT_ULAW) || (zth->srcfmt == ZT_FORMAT_ALAW)) && (zth->srclen >= 160))
- || ((zth->srcfmt == ZT_FORMAT_G729A) && (zth->srclen >= 20))
- || ((zth->srcfmt == ZT_FORMAT_G723_1) && (zth->srclen >= 24)) );
+ } while ((((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)) );
} else {
zt_transcoder_alert(ztc);
}
- spin_unlock_irqrestore(&wc->reglock, flags);
-
-
res = 0;
break;
}
@@ -601,7 +756,7 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
struct dte_state *st = NULL;
int o2,i;
unsigned char rseq, rcodec;
- unsigned int reg, rchannel, rlen, rtp_rseq, rtp_eseq;
+ unsigned int rcommand, rchannel, rlen, rtp_rseq, rtp_eseq;
unsigned char *chars = NULL;
unsigned int ztc_ndx;
@@ -611,26 +766,29 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
o2 = dbl * 4;
o2 += ERING_SIZE * 4;
-
- reg = wcdte_getctl(wc, 0x0001);
-
/* Control in packet */
if ((readchunk[12] == 0x88) && (readchunk[13] == 0x9B))
{
- wc->rcvflags = RCV_CSMENCAPS;
- wc->last_rcommand = readchunk[24] | (readchunk[25] << 8);
-
+ if (debug_packets)
+ {
+ printk("wcdte debug: RX: ");
+ for (i=0; i<debug_packets; i++)
+ printk("%02X ", readchunk[i]);
+ printk("\n");
+ }
/* See if message must be ACK'd */
if ((readchunk[17] & 0xC0) == 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++)&0x0F, rchannel&0x00FF, (rchannel>>8)&0x00FF);
+ 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++)
@@ -638,7 +796,19 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS;
}
- transmit_demand(wc);
+ __transmit_demand(wc);
+
+
+ wc->rcvflags = RCV_CSMENCAPS;
+ wc->last_rcommand = rcommand;
+ wc->last_rparm2 = readchunk[30] | (readchunk[31] << 8);
+ wake_up_interruptible(&wc->regq);
+ up(&wc->cmdqsem);
+ }
+ else
+ {
+ wc->rcvflags = RCV_CSMENCAPS_ACK;
+ wake_up_interruptible(&wc->regq);
}
}
@@ -646,8 +816,6 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
else if ((readchunk[12] == 0x08) && (readchunk[13] == 0x00)
&& (readchunk[50] == 0x12) && (readchunk[51] == 0x34) && (readchunk[52] = 0x56) && (readchunk[53] == 0x78))
{
- wc->rcvflags = RCV_RTP;
-
rchannel = (readchunk[37] | (readchunk[36] << 8)) - 0x5000;
rlen = (readchunk[39] | (readchunk[38] << 8)) - 20;
rtp_rseq = (readchunk[45] | (readchunk[44] << 8));
@@ -655,10 +823,10 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
ztc_ndx = rchannel/2;
- if (ztc_ndx >= numchannels)
+ if (ztc_ndx >= wc->numchannels)
{
if (debug)
- printk("wcdte error: Invalid channel number received (ztc_ndx = %d) (numchannels = %d)\n", ztc_ndx, numchannels);
+ printk("wcdte error: Invalid channel number received (ztc_ndx = %d) (numchannels = %d)\n", ztc_ndx, wc->numchannels);
rcodec = DTE_FORMAT_UNDEF;
}
@@ -712,8 +880,7 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
if (rcodec == 0x00) /* ulaw */
{
- if (zt_tc_sanitycheck(zth, rlen) && (rlen == 160))
- {
+ if (zt_tc_sanitycheck(zth, rlen) && ((zth->srcfmt == ZT_FORMAT_G729A && rlen == G729_SAMPLES) || (zth->srcfmt == ZT_FORMAT_G723_1 && rlen == G723_SAMPLES))) {
for (i = 0; i < rlen; i++)
chars[i] = readchunk[i+54];
@@ -723,16 +890,12 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
} else {
ztc->errorstatus = -EOVERFLOW;
}
-
- if (!(zth->dstsamples % PACKET_OUT_SIZE))
- {
- zt_transcoder_alert(ztc);
- }
+ zt_transcoder_alert(ztc);
}
else if (rcodec == 0x08) /* alaw */
{
- if (zt_tc_sanitycheck(zth, rlen) && (rlen == 160))
- {
+ if (zt_tc_sanitycheck(zth, rlen) && ((zth->srcfmt == ZT_FORMAT_G729A && rlen == G729_SAMPLES) || (zth->srcfmt == ZT_FORMAT_G723_1 && rlen == G723_SAMPLES))) {
+
for (i = 0; i < rlen; i++)
chars[i] = readchunk[i+54];
@@ -742,32 +905,30 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
} else {
ztc->errorstatus = -EOVERFLOW;
}
-
zt_transcoder_alert(ztc);
-
}
else if (rcodec == 0x04) /* g.723.1 */
{
- if (zt_tc_sanitycheck(zth, rlen) && (rlen == 24))
+ if (zt_tc_sanitycheck(zth, rlen) && (rlen == G723_BYTES))
{
for (i = 0; i < rlen; i++)
chars[i] = readchunk[i+54];
zth->dstlen += rlen;
- zth->dstsamples = zth->dstlen * 10;
+ zth->dstsamples = zth->dstlen * 12;
} else {
ztc->errorstatus = -EOVERFLOW;
}
- if (!(zth->dstsamples % PACKET_OUT_SIZE))
+ if (!(zth->dstsamples % G723_SAMPLES))
{
zt_transcoder_alert(ztc);
}
}
else if (rcodec == 0x12) /* g.729a */
{
- if (zt_tc_sanitycheck(zth, rlen) && (rlen == 20))
+ if (zt_tc_sanitycheck(zth, rlen) && (rlen == G729_BYTES))
{
for (i = 0; i < rlen; i++)
chars[i] = readchunk[i+54];
@@ -779,20 +940,12 @@ static inline void wcdte_receiveprep(struct wcdte *wc, int dbl)
ztc->errorstatus = -EOVERFLOW;
}
- if (!(zth->dstsamples % PACKET_OUT_SIZE))
+ if (!(zth->dstsamples % G729_SAMPLES))
{
zt_transcoder_alert(ztc);
}
}
}
-
-
-
- else
- wc->rcvflags = RCV_OTHER;
-
- wake_up_interruptible(&wc->regq);
-
}
@@ -854,46 +1007,46 @@ static void wcdte_init_descriptors(struct wcdte *wc)
}
}
-#ifdef LINUX26
-static irqreturn_t wcdte_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-#else
-static void wcdte_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-#endif
+static void dte_wque_run(struct wcdte *wc)
{
- struct wcdte *wc = dev_id;
- unsigned int ints;
int res;
- /* Read and clear interrupts */
- ints = wcdte_getctl(wc, 0x0028);
- wcdte_setctl(wc, 0x0028, ints);
-
- if (!ints)
-#ifdef LINUX26
- return IRQ_NONE;
-#else
- return;
-#endif
- ints &= wc->intmask;
-
- /* Handle RX interrupts */
- if (ints & 0x00000040) {
+ if (wc->wqueints & 0x00000040) {
/* Loop descriptors is available */
do {
res = wcdte_check_descriptor(wc);
} while(res);
}
-
+
/* Handle TX interrupts */
- if (ints & 0x00000001)
+ if (wc->wqueints & 0x00000001)
{
wc->txints++;
transmit_demand(wc);
wc->intcount++;
}
+}
+
+static irqreturn_t wcdte_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct wcdte *wc = dev_id;
+ unsigned int ints;
+
+ /* Read and clear interrupts */
+ ints = wcdte_getctl(wc, 0x0028);
+ wcdte_setctl(wc, 0x0028, ints);
+
+ if (!ints)
+ return IRQ_NONE;
+ ints &= wc->intmask;
+ if (ints & 0x00000041) {
+ wc->wqueints = ints;
+ queue_work(wc->dte_wq, &wc->dte_work);
+ }
+
if ((ints & 0x00008000) && debug)
- printk("wcdte: Abormal Interrupt: ");
+ printk("wcdte: Abnormal Interrupt: ");
if ((ints & 0x00002000) && debug)
printk("wcdte: Fatal Bus Error INT\n");
@@ -916,9 +1069,7 @@ static void wcdte_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if ((ints & 0x00000002) && debug)
printk("wcdte: Transmit Processor Stopped INT\n");
-#ifdef LINUX26
return IRQ_RETVAL(1);
-#endif
}
@@ -1008,20 +1159,20 @@ static void wcdte_disable_interrupts(struct wcdte *wc)
}
-static int wcdte_waitfor_csmencaps(struct wcdte *wc)
+static long timeout = 1 * HZ; /* 1 sec */
+
+static int wcdte_waitfor_csmencaps(struct wcdte *wc, unsigned int mask, int use_mask)
{
int ret;
-#ifdef LINUX26
- ret = wait_event_interruptible_timeout(wc->regq, wc->rcvflags != 0, (1*HZ));
-#else
- /* Since timeout versions of wait_event... don't exist, */
- /* make a success ret look like ir didn't timeout */
- /* It may be good to look for a 2.4 compatible timeout mechanism */
- ret = wait_event_interruptible(wc->regq, wc->rcvflags != 0);
- if (ret == 0)
- ret = 1;
-#endif
+
+ if (use_mask)
+ ret = wait_event_interruptible_timeout(wc->regq, (wc->rcvflags == mask), timeout);
+ else
+ ret = wait_event_interruptible_timeout(wc->regq, (wc->last_rcommand == wc->last_command_sent), timeout);
+ wc->rcvflags = 0;
+ wc->last_rcommand = 0;
+ wc->last_command_sent = 0;
if (ret < 0)
{
@@ -1032,16 +1183,9 @@ static int wcdte_waitfor_csmencaps(struct wcdte *wc)
if (ret == 0)
{
if (debug)
- printk("wcdte error: Waitfor CSMENCAPS ACK timed out (ret = %d)\n", ret);
+ printk("wcdte error: Waitfor CSMENCAPS response timed out (ret = %d)\n", ret);
return(2);
}
-
- if (wc->rcvflags != RCV_CSMENCAPS)
- {
- printk("wcdte error: DTE processor failed to respond\n");
- return(1);
- }
- wc->rcvflags = 0;
return(0);
}
@@ -1085,11 +1229,11 @@ static int wcdte_boot_processor(struct wcdte *wc)
reg = wcdte_getctl(wc, 0x00fc);
if (debug)
- printk("LINK STATUS: reg(0xfc) = %X\n", reg);
+ printk("wcdte: LINK STATUS: reg(0xfc) = %X\n", reg);
reg = wcdte_getctl(wc, 0x00A0);
- byteloc = 0;
+ byteloc = 17;
j = 0;
do
@@ -1099,6 +1243,7 @@ static int wcdte_boot_processor(struct wcdte *wc)
length = (wcdte_firmware[byteloc] << 8) | wcdte_firmware[byteloc+1];
byteloc += 2;
+ down(&wc->cmdqsem);
if ( (((wc->cmdq_wndx + 1) % MAX_COMMANDS) == wc->cmdq_rndx) && debug )
printk("wcdte error: cmdq is full.\n");
else
@@ -1108,10 +1253,11 @@ static int wcdte_boot_processor(struct wcdte *wc)
wc->cmdq[wc->cmdq_wndx].cmd[i] = wcdte_firmware[byteloc++];
wc->cmdq_wndx = (wc->cmdq_wndx + 1) % MAX_COMMANDS;
}
-
- transmit_demand(wc);
+
+ __transmit_demand(wc);
+ up(&wc->cmdqsem);
- ret = wcdte_waitfor_csmencaps(wc);
+ ret = wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS_ACK, 1);
if (ret == 1)
return(1);
else if (ret == 2) /* Retransmit if dte processor times out */
@@ -1121,7 +1267,7 @@ static int wcdte_boot_processor(struct wcdte *wc)
} while (byteloc < sizeof(wcdte_firmware)-20);
/* Waitfor code to start */
- if (wcdte_waitfor_csmencaps(wc))
+ if (wcdte_waitfor_csmencaps(wc, RCV_CSMENCAPS, 1))
return(1);
/* Turn on booted LED */
@@ -1133,71 +1279,99 @@ static int wcdte_boot_processor(struct wcdte *wc)
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)
+{
+ int length = 0;
+ unsigned char chan1, chan2;
+ 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;
+
+ /* 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;
+
+ /* Configure complex channel */
+ zt_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(wc->seq_num++, chan1, part2_id, part1_id), CMD_MSG_SET_IP_HDR_CHANNEL_LEN, 0x9000);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(wc->seq_num++, chan1, length, 0), CMD_MSG_VOIP_VCEOPT_LEN, 0x8001);
+
+ /* Configure simple channel */
+ zt_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(wc->seq_num++, chan2, part1_id, part2_id), CMD_MSG_SET_IP_HDR_CHANNEL_LEN, 0x9000);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(wc->seq_num++, chan2, length, 0), CMD_MSG_VOIP_VCEOPT_LEN, 0x8001);
+
+ zt_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 1, chan1, chan2, complicated, simple), CMD_MSG_TRANS_CONNECT_LEN, 0x9322);
+ zt_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(wc->seq_num++, chan1), CMD_MSG_VOIP_INDCTRL_LEN, 0x8084);
+ zt_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(wc->seq_num++, chan2), CMD_MSG_VOIP_INDCTRL_LEN, 0x8084);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA(wc->seq_num++, chan1, complicated), CMD_MSG_VOIP_VOPENA_LEN, 0x8000);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA(wc->seq_num++, chan2, simple), CMD_MSG_VOIP_VOPENA_LEN, 0x8000);
+ debug_packets = 0;
+
+ *dte_chan1 = chan1;
+ *dte_chan2 = chan2;
+
+ return 1;
+}
-static int wcdte_setup_channels(struct wcdte *wc)
+static int wcdte_destroy_channel(struct wcdte *wc, unsigned int chan1, unsigned int chan2)
{
- int i, j, ret;
- unsigned int part1_id, part2_id;
+
+ /* Turn off both channels */
+ zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(wc->seq_num++, chan1), CMD_MSG_VOIP_VOPENA_CLOSE_LEN, 0x8000);
+ zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(wc->seq_num++, chan2), CMD_MSG_VOIP_VOPENA_CLOSE_LEN, 0x8000);
+
+ /* 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);
+
+ debug_packets=0;
+
+ return 1;
+}
+static int wcdte_setup_channels(struct wcdte *wc)
+{
#ifndef USE_TEST_HW
- zt_send_cmd(wc, CMD_MSG_SET_ARM_CLK((wc->seq_num++)&0x0F), CMD_MSG_SET_ARM_CLK_LEN, 0x0411);
- zt_send_cmd(wc, CMD_MSG_SET_SPU_CLK((wc->seq_num++)&0x0F), CMD_MSG_SET_SPU_CLK_LEN, 0x0412);
+ zt_send_cmd(wc, CMD_MSG_SET_ARM_CLK(wc->seq_num++), CMD_MSG_SET_ARM_CLK_LEN, 0x0411);
+ zt_send_cmd(wc, CMD_MSG_SET_SPU_CLK(wc->seq_num++), CMD_MSG_SET_SPU_CLK_LEN, 0x0412);
#endif
#ifdef USE_TDM_CONFIG
- zt_send_cmd(wc, CMD_MSG_TDM_SELECT_BUS_MODE((wc->seq_num++)&0x0F), CMD_MSG_TDM_SELECT_BUS_MODE_LEN, 0x0417);
- zt_send_cmd(wc, CMD_MSG_TDM_ENABLE_BUS((wc->seq_num++)&0x0F), CMD_MSG_TDM_ENABLE_BUS_LEN, 0x0405);
- zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS((wc->seq_num++)&0x0F, 0x03, 0x20, 0x00), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
- zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS((wc->seq_num++)&0x0F, 0x04, 0x80, 0x04), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
- zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS((wc->seq_num++)&0x0F, 0x05, 0x20, 0x08), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
- zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS((wc->seq_num++)&0x0F, 0x06, 0x80, 0x0C), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
+ zt_send_cmd(wc, CMD_MSG_TDM_SELECT_BUS_MODE(wc->seq_num++), CMD_MSG_TDM_SELECT_BUS_MODE_LEN, 0x0417);
+ zt_send_cmd(wc, CMD_MSG_TDM_ENABLE_BUS(wc->seq_num++), CMD_MSG_TDM_ENABLE_BUS_LEN, 0x0405);
+ zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x03, 0x20, 0x00), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
+ zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x04, 0x80, 0x04), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
+ zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x05, 0x20, 0x08), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
+ zt_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x06, 0x80, 0x0C), CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN, 0x0407);
#endif
- zt_send_cmd(wc, CMD_MSG_SET_ETH_HEADER((wc->seq_num++)&0x0F), CMD_MSG_SET_ETH_HEADER_LEN, 0x0100);
- zt_send_cmd(wc, CMD_MSG_IP_SERVICE_CONFIG((wc->seq_num++)&0x0F), CMD_MSG_IP_SERVICE_CONFIG_LEN, 0x0302);
- zt_send_cmd(wc, CMD_MSG_ARP_SERVICE_CONFIG((wc->seq_num++)&0x0F), CMD_MSG_ARP_SERVICE_CONFIG_LEN, 0x0105);
- zt_send_cmd(wc, CMD_MSG_ICMP_SERVICE_CONFIG((wc->seq_num++)&0x0F), CMD_MSG_ICMP_SERVICE_CONFIG_LEN, 0x0304);
+ zt_send_cmd(wc, CMD_MSG_SET_ETH_HEADER(wc->seq_num++), CMD_MSG_SET_ETH_HEADER_LEN, 0x0100);
+ zt_send_cmd(wc, CMD_MSG_IP_SERVICE_CONFIG(wc->seq_num++), CMD_MSG_IP_SERVICE_CONFIG_LEN, 0x0302);
+ zt_send_cmd(wc, CMD_MSG_ARP_SERVICE_CONFIG(wc->seq_num++), CMD_MSG_ARP_SERVICE_CONFIG_LEN, 0x0105);
+ zt_send_cmd(wc, CMD_MSG_ICMP_SERVICE_CONFIG(wc->seq_num++), CMD_MSG_ICMP_SERVICE_CONFIG_LEN, 0x0304);
#ifdef USE_TDM_CONFIG
- zt_send_cmd(wc, CMD_MSG_DEVICE_SET_COUNTRY_CODE((wc->seq_num++)&0x0F), CMD_MSG_DEVICE_SET_COUNTRY_CODE_LEN, 0x041B);
+ zt_send_cmd(wc, CMD_MSG_DEVICE_SET_COUNTRY_CODE(wc->seq_num++), CMD_MSG_DEVICE_SET_COUNTRY_CODE_LEN, 0x041B);
#endif
- zt_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL((wc->seq_num++)&0x0F, 0x02), CMD_MSG_SPU_FEATURES_CONTROL_LEN, 0x0013);
- zt_send_cmd(wc, CMD_MSG_IP_OPTIONS((wc->seq_num++)&0x0F), CMD_MSG_IP_OPTIONS_LEN, 0x0306);
- zt_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL((wc->seq_num++)&0x0F, 0x04), CMD_MSG_SPU_FEATURES_CONTROL_LEN, 0x0013);
+ zt_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x02), CMD_MSG_SPU_FEATURES_CONTROL_LEN, 0x0013);
+ zt_send_cmd(wc, CMD_MSG_IP_OPTIONS(wc->seq_num++), CMD_MSG_IP_OPTIONS_LEN, 0x0306);
+ zt_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x04), CMD_MSG_SPU_FEATURES_CONTROL_LEN, 0x0013);
#ifdef USE_TDM_CONFIG
- zt_send_cmd(wc, CMD_MSG_TDM_OPT((wc->seq_num++)&0x0F), CMD_MSG_TDM_OPT_LEN, 0x0435);
+ zt_send_cmd(wc, CMD_MSG_TDM_OPT(wc->seq_num++), CMD_MSG_TDM_OPT_LEN, 0x0435);
#endif
-
- part1_id = 0;
- part2_id = 1;
- for(j = 0; j < NUM_CHANNELS; j++)
- {
- /* Create complex channel */
- zt_send_cmd(wc, CMD_MSG_CREATE_CHANNEL((wc->seq_num++)&0x0F, (part1_id&0x00FF), (part1_id&0xFF00) >> 8), CMD_MSG_CREATE_CHANNEL_LEN, 0x0010);
- zt_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL((wc->seq_num++)&0x0F, (part1_id&0xFF00) >> 8, (part1_id&0x00FF),((part2_id&0xFF00) >> 8) + 0x50, (part2_id&0x00FF), ((part1_id&0xFF00) >> 8) + 0x50, (part1_id&0x00FF)), CMD_MSG_SET_IP_HDR_CHANNEL_LEN, 0x9000);
- zt_send_cmd(wc, CMD_MSG_VOIP_VCEOPT((wc->seq_num++)&0x0F, (part1_id&0xFF00) >> 8, (part1_id&0x00FF), SAMPLE_LENGTH, 0), CMD_MSG_VOIP_VCEOPT_LEN, 0x8001);
-
- /* Create simple channel */
- zt_send_cmd(wc, CMD_MSG_CREATE_CHANNEL((wc->seq_num++)&0x0F, (part2_id&0x00FF), (part2_id&0xFF00) >> 8), CMD_MSG_CREATE_CHANNEL_LEN, 0x0010);
- zt_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL((wc->seq_num++)&0x0F, (part2_id&0xFF00) >> 8, (part2_id&0x00FF),((part1_id&0xFF00) >> 8) + 0x50, (part1_id&0x00FF), ((part2_id&0xFF00) >> 8) + 0x50, (part2_id&0x00FF)), CMD_MSG_SET_IP_HDR_CHANNEL_LEN, 0x9000);
- zt_send_cmd(wc, CMD_MSG_VOIP_VCEOPT((wc->seq_num++)&0x0F, (part2_id&0xFF00) >> 8, (part2_id&0x00FF), SAMPLE_LENGTH, 0), CMD_MSG_VOIP_VCEOPT_LEN, 0x8001);
-
-
- zt_send_cmd(wc, CMD_MSG_TRANS_CONNECT((wc->seq_num++)&0x0F, 1, (part1_id&0x00FF), (part1_id&0xFF00) >> 8, (part2_id&0x00FF), (part2_id&0xFF00) >> 8), CMD_MSG_TRANS_CONNECT_LEN, 0x9322);
- zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA((wc->seq_num++)&0x0F, (part1_id&0xFF00) >> 8, (part1_id&0x00FF), COMPLEX_CODEC), CMD_MSG_VOIP_VOPENA_LEN, 0x8000);
- zt_send_cmd(wc, CMD_MSG_VOIP_VOPENA((wc->seq_num++)&0x0F, (part2_id&0xFF00) >> 8, (part2_id&0x00FF), SIMPLE_CODEC), CMD_MSG_VOIP_VOPENA_LEN, 0x8000);
-
- part1_id += 2;
- part2_id += 2;
- }
-
- if (debug)
- zt_send_cmd(wc, CMD_MSG_DEVICE_STATUS_CONFIG((wc->seq_num++)&0x0F), CMD_MSG_DEVICE_STATUS_CONFIG_LEN, 0x040F);
+ timeout = HZ/100 + 1; /* 10msec */
return(0);
}
@@ -1210,6 +1384,8 @@ 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 int complexfmts;
if(initd_ifaces){
memset((void *)ifaces,0,(sizeof(struct wcdte *))*WC_MAX_IFACES);
@@ -1218,7 +1394,7 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic
for (x=0;x<WC_MAX_IFACES;x++)
if (!ifaces[x]) break;
if (x >= WC_MAX_IFACES) {
- printk("Too many interfaces\n");
+ printk("wcdte: Too many interfaces\n");
return -EIO;
}
@@ -1231,6 +1407,8 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic
ifaces[x] = wc;
memset(wc, 0, sizeof(struct wcdte));
spin_lock_init(&wc->reglock);
+ sema_init(&wc->chansem, 1);
+ sema_init(&wc->cmdqsem, 1);
wc->cards = NUM_CARDS;
wc->iobase = pci_resource_start(pdev, 0);
wc->dev = pdev;
@@ -1240,10 +1418,14 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic
wc->tdbl = 0;
wc->rdbl = 0;
wc->rcvflags = 0;
+ wc->last_command_sent = 0;
wc->last_rcommand = 0;
+ wc->last_rparm2 = 0;
wc->cmdq_wndx = 0;
wc->cmdq_rndx = 0;
wc->seq_num = 6;
+ wc->ztsnd_rtx = 0;
+ wc->ztsnd_0010_rtx = 0;
/* Keep track of whether we need to free the region */
if (request_region(wc->iobase, 0xff, "wcdte"))
@@ -1269,14 +1451,53 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic
memset((void *)wc->readchunk, 0x00, SFRAME_SIZE * 2);
init_waitqueue_head(&wc->regq);
+
+ /* Initialize the work queue */
+ wc->dte_wq = create_workqueue("tc400b");
+ INIT_WORK(&wc->dte_work, (void (*)(void *))dte_wque_run, wc);
+
+ g729_numchannels = wcdte_firmware[1];
+ g723_numchannels = wcdte_firmware[2];
+ dte_firmware_ver = wcdte_firmware[0];
+
+ if (g723_numchannels < g729_numchannels)
+ min_numchannels = g723_numchannels;
+ else
+ min_numchannels = g729_numchannels;
/* Setup Encoders nad Decoders */
- uencode = zt_transcoder_alloc(numchannels);
- udecode = zt_transcoder_alloc(numchannels);
- encoders = vmalloc(sizeof(struct dte_state) * numchannels);
- decoders = vmalloc(sizeof(struct dte_state) * numchannels);
- memset(encoders, 0, sizeof(struct dte_state) * numchannels);
- memset(decoders, 0, sizeof(struct dte_state) * numchannels);
+
+ if (!mode)
+ {
+ sprintf(wc->complexname, "g.729a / g.723.1 5.3kbps");
+ complexfmts = ZT_FORMAT_G729A | ZT_FORMAT_G723_1;
+ wc->numchannels = min_numchannels;
+ }
+ else if (mode[3] == '9') /* "g729" */
+ {
+ sprintf(wc->complexname, "g.729a");
+ complexfmts = ZT_FORMAT_G729A;
+ wc->numchannels = g729_numchannels;
+ }
+ else if (mode[3] == '3') /* "g723" */
+ {
+ sprintf(wc->complexname, "g.723.1 5.3kbps");
+ complexfmts = ZT_FORMAT_G723_1;
+ wc->numchannels = g723_numchannels;
+ }
+ else
+ {
+ sprintf(wc->complexname, "g.729a / g.723.1 5.3kbps");
+ complexfmts = ZT_FORMAT_G729A | ZT_FORMAT_G723_1;
+ wc->numchannels = min_numchannels;
+ }
+
+ uencode = zt_transcoder_alloc(wc->numchannels);
+ udecode = zt_transcoder_alloc(wc->numchannels);
+ encoders = vmalloc(sizeof(struct dte_state) * wc->numchannels);
+ decoders = vmalloc(sizeof(struct dte_state) * wc->numchannels);
+ memset(encoders, 0, sizeof(struct dte_state) * wc->numchannels);
+ memset(decoders, 0, sizeof(struct dte_state) * wc->numchannels);
if (!uencode || !udecode || !encoders || !decoders) {
if (uencode)
zt_transcoder_free(uencode);
@@ -1291,14 +1512,12 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic
sprintf(udecode->name, "DTE Decoder");
sprintf(uencode->name, "DTE Encoder");
-/* udecode->srcfmts = uencode->dstfmts = ZT_FORMAT_G729A | ZT_FORMAT_G723_1; */
-/* udecode->dstfmts = uencode->srcfmts = ZT_FORMAT_ULAW | ZT_FORMAT_ALAW; */
- udecode->srcfmts = uencode->dstfmts = ZT_FORMAT_G729A;
- udecode->dstfmts = uencode->srcfmts = ZT_FORMAT_ULAW;
-
+ udecode->srcfmts = uencode->dstfmts = complexfmts;
+ udecode->dstfmts = uencode->srcfmts = ZT_FORMAT_ULAW | ZT_FORMAT_ALAW;
+
udecode->operation = uencode->operation = dte_operation;
- for (x=0;x<numchannels;x++) {
+ for (x=0;x<wc->numchannels;x++) {
dte_init_state(encoders + x, 1, x, wc);
encoders[x].encoder = 1;
decoders[x].encoder = 0;
@@ -1313,8 +1532,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 (G.729/G.723) Transcoder support LOADED\n");
-
+ printk("Zaptel DTE (%s) Transcoder support LOADED (firm ver = %d)\n", wc->complexname, dte_firmware_ver);
/* Enable bus mastering */
@@ -1348,13 +1566,12 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic
}
-
/* Enable interrupts */
wcdte_enable_interrupts(wc);
/* Start DMA */
wcdte_start_dma(wc);
-
+
if (wcdte_boot_processor(wc))
{
/* Set Reset Low */
@@ -1385,9 +1602,9 @@ static int __devinit wcdte_init_one(struct pci_dev *pdev, const struct pci_devic
reg = wcdte_getctl(wc, 0x00fc);
if (debug)
- printk("(post-boot) Reg fc is %08x\n", reg);
+ printk("wcdte debug: (post-boot) Reg fc is %08x\n", reg);
- printk("Found a Wildcard TC: %s \n", wc->variety);
+ printk("Found and successfully installed a Wildcard TC: %s \n", wc->variety);
res = 0;
} else
res = -ENOMEM;
@@ -1405,10 +1622,31 @@ static void wcdte_release(struct wcdte *wc)
static void __devexit wcdte_remove_one(struct pci_dev *pdev)
{
+ int i;
struct wcdte *wc = pci_get_drvdata(pdev);
+ struct zt_transcoder_channel *ztc_en, *ztc_de;
+ struct dte_state *st_en, *st_de;
if (wc) {
-
+
+ if (debug)
+ {
+ printk("wcdte debug: wc->ztsnd_rtx = %d\n", wc->ztsnd_rtx);
+ printk("wcdte debug: wc->ztsnd_0010_rtx = %d\n", wc->ztsnd_0010_rtx);
+
+ for(i = 0; i < wc->numchannels; i++)
+ {
+ ztc_en = &(wc->uencode->channels[i]);
+ st_en = ztc_en->pvt;
+
+ ztc_de = &(wc->udecode->channels[i]);
+ st_de = ztc_de->pvt;
+
+ printk("wcdte debug: en[%d] snt = %d, rcv = %d [%d]\n", i, st_en->packets_sent, st_en->packets_received, st_en->packets_sent - st_en->packets_received);
+ 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);
@@ -1421,6 +1659,9 @@ static void __devexit wcdte_remove_one(struct pci_dev *pdev)
/* In case hardware is still there */
wcdte_disable_interrupts(wc);
+
+ /* Kill workqueue */
+ destroy_workqueue(wc->dte_wq);
/* Immediately free resources */
pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
@@ -1436,7 +1677,7 @@ static struct pci_device_id wcdte_pci_tbl[] = {
#ifndef USE_TEST_HW
{ 0xd161, 0x3400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &wcdte }, /* digium board */
#else
- { 0x1317, 0x0985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &wcdte }, /*reference board */
+ { 0x1317, 0x0985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &wcdte }, /* reference board */
#endif
{ 0 }
};
@@ -1447,11 +1688,7 @@ MODULE_DEVICE_TABLE(pci, wcdte_pci_tbl);
static struct pci_driver wcdte_driver = {
name: "ztcodec_dte",
probe: wcdte_init_one,
-#ifdef LINUX26
remove: __devexit_p(wcdte_remove_one),
-#else
- remove: wcdte_remove_one,
-#endif
suspend: NULL,
resume: NULL,
id_table: wcdte_pci_tbl,
@@ -1470,32 +1707,12 @@ int ztdte_init(void)
void ztdte_cleanup(void)
{
-// int i;
-
-#if 0
- if (debug)
- {
- for(i = 0; i < NUM_CHANNELS; i++)
- {
- printk("encoder[%d] packets_sent = %d, packets_received = %d [%d]\n", i, encoders[i].packets_sent, encoders[i].packets_received, encoders[i].packets_sent - encoders[i].packets_received);
- printk("decoder[%d] packets_sent = %d, packets_received = %d [%d]\n", i, decoders[i].packets_sent, decoders[i].packets_received, decoders[i].packets_sent - decoders[i].packets_received);
- }
- }
-#endif
-
pci_unregister_driver(&wcdte_driver);
-
- printk("Zaptel DTE (G.729/G.723) Transcoder support unloaded.\n");
-
+ printk("Zaptel DTE Transcoder support unloaded.\n");
}
-#ifdef LINUX26
module_param(debug, int, 0600);
-module_param(numchannels, int, 0600);
-#else
-MODULE_PARM(debug, "i");
-MODULE_PARM(numchannels, "i");
-#endif
+module_param(mode, charp, 0600);
MODULE_DESCRIPTION("Zaptel DTE (G.729/G.723) Transcoder Support");
MODULE_AUTHOR("John Sloan <jsloan@digium.com>");
#ifdef MODULE_LICENSE