[svn-commits] sruffell: branch sruffell/zaptel-1.4-transcoder r4312 - /team/sruffell/zaptel...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue May 20 16:58:57 CDT 2008
Author: sruffell
Date: Tue May 20 16:58:56 2008
New Revision: 4312
URL: http://svn.digium.com/view/zaptel?view=rev&rev=4312
Log:
- Extend the debug network interface to allow sending commands to the
transcoder directly.
- Update network interface for 2.6.24 kernels (NAPI changed).
Modified:
team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c
team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test.c
team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test_threaded.c
team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wcdte_net.c
team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wctc4xxp.h
Modified: team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c
URL: http://svn.digium.com/view/zaptel/team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c?view=diff&rev=4312&r1=4311&r2=4312
==============================================================================
--- team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c (original)
+++ team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/base.c Tue May 20 16:58:56 2008
@@ -581,7 +581,9 @@
static void wcdte_capture_packet(struct wcdte *wc, const struct dte_cmd *cmd)
{
- wcdte_net_capture_cmd(wc, cmd);
+ if (!(cmd->flags & DO_NOT_CAPTURE)) {
+ wcdte_net_capture_cmd(wc, cmd);
+ }
}
/**
@@ -597,8 +599,7 @@
spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
}
-static void
-dte_transmit_cmd(struct wcdte *wc, struct dte_cmd *cmd)
+void dte_transmit_cmd(struct wcdte *wc, struct dte_cmd *cmd)
{
int res;
@@ -1813,11 +1814,10 @@
return 0;
}
-static int
-wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmware)
-{
- unsigned int reg, ret;
-
+int wcdte_turn_off_booted_led(struct wcdte *wc)
+{
+ int ret = 0;
+ int reg;
#ifndef USE_TEST_HW
ENTERING();
/* Turn off auto negotiation */
@@ -1842,24 +1842,36 @@
/* Turn off booted LED */
wcdte_setctl(wc, 0x00A0, 0x04084000);
-
#endif
-
reg = wcdte_getctl(wc, 0x00fc);
DTE_DEBUG(DTE_DEBUG_GENERAL, "LINK STATUS: reg(0xfc) = %X\n", reg);
reg = wcdte_getctl(wc, 0x00A0);
+ return ret;
+}
+
+void wcdte_turn_on_booted_led(struct wcdte *wc)
+{
+ wcdte_setctl(wc, 0x00A0, 0x04080000);
+}
+
+static int
+wcdte_boot_processor(struct wcdte *wc, const struct firmware *firmware)
+{
+ int ret;
+
+ wcdte_turn_off_booted_led(wc);
+
if ((ret = wcdte_load_firmware(wc, firmware))) {
LEAVING();
return ret;
}
-
/* Turn on booted LED */
- wcdte_setctl(wc, 0x00A0, 0x04080000);
+ wcdte_turn_on_booted_led(wc);
+
DTE_DEBUG(DTE_DEBUG_GENERAL, "Successfully booted DTE processor.\n");
-
LEAVING();
return 0;
}
Modified: team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test.c
URL: http://svn.digium.com/view/zaptel/team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test.c?view=diff&rev=4312&r1=4311&r2=4312
==============================================================================
--- team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test.c (original)
+++ team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test.c Tue May 20 16:58:56 2008
@@ -148,7 +148,6 @@
if (ioctl(fd, ZT_TC_ALLOCATE, &fmts)) {
printf("Unable to attach transcoder: %s\n", strerror(errno));
close(fd);
-
return -1;
}
@@ -259,7 +258,7 @@
i += tctest_info.numchans[j];
if (open_transcoder(&ztp[i], AST_FORMAT_G729A, AST_FORMAT_ULAW)) {
- continue;
+ exit(-1);
}
memset(packet_out, 0, sizeof(packet_out));
Modified: team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test_threaded.c
URL: http://svn.digium.com/view/zaptel/team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test_threaded.c?view=diff&rev=4312&r1=4311&r2=4312
==============================================================================
--- team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test_threaded.c (original)
+++ team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/codec_test_threaded.c Tue May 20 16:58:56 2008
@@ -208,8 +208,8 @@
if (ioctl(fd, ZT_TC_ALLOCATE, &fmt)) {
printf("Unable to attach transcoder: %s\n", strerror(errno));
- close(fd);
-
+ /* close(fd); */
+ exit(-1);
return -1;
}
Modified: team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wcdte_net.c
URL: http://svn.digium.com/view/zaptel/team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wcdte_net.c?view=diff&rev=4312&r1=4311&r2=4312
==============================================================================
--- team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wcdte_net.c (original)
+++ team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wcdte_net.c Tue May 20 16:58:56 2008
@@ -33,11 +33,13 @@
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
-
#define HERE() printk(KERN_DEBUG "HERE: %s:%d\n", __FILE__, __LINE__)
+
+#define MAX_CAPTURED_PACKETS 5000
static struct sk_buff *
wcdte_cmd_to_skb(struct net_device *netdev, const struct dte_cmd *cmd)
@@ -53,119 +55,228 @@
return skb;
}
+static struct dte_cmd *
+wcdte_skb_to_cmd(struct wcdte *wc, const struct sk_buff *skb)
+{
+ const unsigned long alloc_flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
+ struct dte_cmd *cmd;
+ /* const static char dev_mac[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; */
+ if ((cmd = __alloc_cmd(alloc_flags, 0))) {
+ int res;
+ cmd->cmdlen = skb->len;
+ if ((res = skb_copy_bits(skb, 0, cmd->cmd, cmd->cmdlen))) {
+ DTE_PRINTK(WARNING,
+ "Failed call to skb_copy_bits.\n");
+ free_cmd(cmd);
+ cmd = NULL;
+ }
+ /* When we set up our interface we indicated that we do not
+ * support ARP. Therefore, the destination MAC on packets
+ * arriving from the kernel networking components are not
+ * going to be correct. Let's fix that here.
+ */
+ /* \todo let us just use whatever was in the packet already... */
+ /* memcpy(&cmd->cmd[6], dev_mac, sizeof(dev_mac)); */
+ }
+ return cmd;
+}
+
static void wcdte_net_set_multi(struct net_device *netdev)
{
struct wcdte *wc = netdev->priv;
+ DTE_DEBUG(DTE_DEBUG_GENERAL, "%s promiscuity:%d\n",
+ __FUNCTION__, netdev->promiscuity);
+}
+
+static int wcdte_net_up(struct net_device *netdev)
+{
+ struct wcdte *wc = netdev->priv;
DTE_DEBUG(DTE_DEBUG_GENERAL, "%s\n", __FUNCTION__);
-}
-
-static int wcdte_net_up(struct net_device *netdev)
+#if 1
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ netif_poll_enable(netdev);
+#else
+ napi_enable(&wc->napi);
+#endif
+#endif
+ return 0;
+}
+
+static int wcdte_net_down(struct net_device *netdev)
{
struct wcdte *wc = netdev->priv;
DTE_DEBUG(DTE_DEBUG_GENERAL, "%s\n", __FUNCTION__);
- netif_poll_enable(netdev);
+#if 1
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ netif_poll_disable(netdev);
+#else
+ napi_disable(&wc->napi);
+#endif
+#endif
return 0;
}
-static int wcdte_net_down(struct net_device *netdev)
-{
- struct wcdte *wc = netdev->priv;
- DTE_DEBUG(DTE_DEBUG_GENERAL, "%s\n", __FUNCTION__);
- netif_poll_disable(netdev);
- return 0;
-}
-
static int wcdte_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct wcdte *wc = netdev->priv;
- DTE_DEBUG(DTE_DEBUG_GENERAL, "%s\n", __FUNCTION__);
+ struct dte_cmd *cmd;
+
+ /* We set DO_NOT_CAPTURE because this packet was already captured by
+ * in code higher up in the networking stack. We don't want to
+ * capture it twice.
+ */
+ if ((cmd = wcdte_skb_to_cmd(wc, skb))) {
+ cmd->flags |= DO_NOT_CAPTURE;
+ dte_transmit_cmd(wc, cmd);
+ }
+
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
+static int wcdte_net_receive(struct wcdte *wc, int max)
+{
+ int count = 0;
+ struct sk_buff *skb;
+ WARN_ON(0 == max);
+ while ((skb = skb_dequeue(&wc->captured_packets))) {
+ netif_receive_skb(skb);
+ if (++count >= max) {
+ break;
+ }
+ }
+ return count;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
static int wcdte_poll(struct net_device *netdev, int *budget)
{
- int res;
- struct sk_buff *skb;
struct wcdte *wc = netdev->priv;
int count = 0;
int quota = min(netdev->quota, *budget);
- while ((skb = skb_dequeue(&wc->captured_packets)) && (count++ < quota)) {
- if ((res = netif_receive_skb(skb))) {
- if (NET_RX_DROP == res ) {
- DTE_DEBUG(DTE_DEBUG_GENERAL,
- "Kernel dropped packet.\n");
- } else {
- DTE_DEBUG(DTE_DEBUG_GENERAL,
- "ret = %d\n", res);
- }
- }
- }
+ count = wcdte_net_receive(wc, quota);
*budget -= count;
netdev->quota -= count;
- if (skb) {
- /* We still have socket buffers ready. */
- return -1;
- } else {
- /* There were not any more buffers in the queue, so we're
- * done. */
+ if (!skb_queue_len(&wc->captured_packets)) {
netif_rx_complete(netdev);
return 0;
- }
+ } else {
+ return -1;
+ }
+}
+#else
+static int wcdte_poll(struct napi_struct *napi, int budget)
+{
+ struct wcdte *wc = container_of(napi, struct wcdte, napi);
+ int count;
+
+ count = wcdte_net_receive(wc, budget);
+
+ if (!skb_queue_len(&wc->captured_packets)) {
+ netif_rx_complete(wc->netdev, &wc->napi);
+ }
+ return count;
+}
+#endif
+
+static struct net_device_stats *
+wcdte_net_get_stats(struct net_device *netdev)
+{
+ struct wcdte *wc = netdev->priv;
+ return &wc->net_stats;
+}
+
+/* Wait until this device is put into promiscuous mode, or we timeout. */
+static void wcdte_net_waitfor_promiscuous(struct wcdte *wc)
+{
+ unsigned int seconds = 15;
+ unsigned long start = jiffies;
+ struct net_device *netdev = wc->netdev;
+
+ DTE_PRINTK(INFO,
+ "Waiting %d seconds for adapter to be placed in " \
+ "promiscuous mode for early trace.\n", seconds);
+
+ while (!netdev->promiscuity) {
+ if (signal_pending(current)) {
+ DTE_PRINTK(INFO,
+ "Aborting wait due to signal.\n");
+ break;
+ }
+ msleep(100);
+ if (time_after(jiffies, start + (seconds * HZ))) {
+ DTE_PRINTK(INFO,
+ "Aborting wait due to timeout.\n");
+ break;
+ }
+ }
+}
+
+static int wcdte_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ struct wcdte *wc = netdev->priv;
+ DTE_PRINTK(INFO, "In %s with cmd %04x\n", __FUNCTION__, cmd);
+ switch(cmd) {
+ case 0x89f0:
+ down(&wc->chansem);
+ wcdte_turn_off_booted_led(wc);
+ break;
+ case 0x89f1:
+ wcdte_turn_on_booted_led(wc);
+ up(&wc->chansem);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ };
+ return 0;
}
int wcdte_net_register(struct wcdte *wc)
{
int res;
struct net_device *netdev;
- netdev = alloc_netdev(0, wc->board_name, ether_setup);
- if (NULL == netdev) {
+ const char our_mac[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
+
+ if (!(netdev = alloc_netdev(0, wc->board_name, ether_setup))) {
return -ENOMEM;
}
+ memcpy(netdev->dev_addr, our_mac, sizeof(our_mac));
netdev->priv = wc;
netdev->set_multicast_list = &wcdte_net_set_multi;
netdev->open = &wcdte_net_up;
netdev->stop = &wcdte_net_down;
netdev->hard_start_xmit = &wcdte_hard_start_xmit;
+ netdev->get_stats = &wcdte_net_get_stats;
+ netdev->do_ioctl = &wcdte_ioctl;
+ netdev->promiscuity = 0;
+ netdev->flags |= IFF_NOARP;
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
netdev->poll = &wcdte_poll;
netdev->weight = 64;
- set_bit(__LINK_STATE_START, &netdev->state);
+# else
+ netif_napi_add(netdev, &wc->napi, &wcdte_poll, 64);
+# endif
+
+ if ((res = register_netdev(netdev))) {
+ DTE_PRINTK(WARNING,
+ "Failed to register network device %s.\n",
+ wc->board_name);
+ goto error_sw;
+ }
wc->netdev = netdev;
-
skb_queue_head_init(&wc->captured_packets);
- DTE_PRINTK(DEBUG, "Creating network device %s for debug.\n", wc->board_name);
- if ((res = register_netdev(netdev))) {
- goto error_sw;
- }
-
- netif_poll_disable(netdev);
-
if (debug & DTE_DEBUG_NETWORK_EARLY) {
- unsigned int seconds = 15;
- DTE_PRINTK(INFO,
- "Waiting %d seconds for adapter to be placed in " \
- "promiscuous mode for early trace.\n", seconds);
- while (!netdev->promiscuity) {
- if (signal_pending(current)) {
- DTE_PRINTK(INFO,
- "Aborting wait due to signal.\n");
- break;
- }
- msleep(1000);
- if (!(seconds--)) {
- DTE_PRINTK(INFO,
- "Aborting wait due to timeout.\n");
- break;
- }
- }
- }
-
+ wcdte_net_waitfor_promiscuous(wc);
+ }
+
+ DTE_PRINTK(DEBUG,
+ "Created network device %s for debug.\n", wc->board_name);
return 0;
error_sw:
@@ -198,21 +309,35 @@
void wcdte_net_capture_cmd(struct wcdte *wc, const struct dte_cmd *cmd)
{
struct sk_buff *skb;
-
- if (!wc->netdev) {
- return;
- }
-
- if (!wc->netdev->promiscuity) {
- return;
- }
-
- if (!(skb = wcdte_cmd_to_skb(wc->netdev, cmd))) {
+ struct net_device *netdev = wc->netdev;
+
+ if (!netdev) {
+ return;
+ }
+
+ /* No need to capture if there isn't anyone listening. */
+ if (!(netdev->flags & IFF_UP)) {
+ return;
+ }
+
+ /* I don't think the packet queue should ever get this long, but just
+ * in case, we'll limit it.
+ */
+ if (skb_queue_len(&wc->captured_packets) > MAX_CAPTURED_PACKETS) {
+ WARN_ON_ONCE(1);
+ return;
+ }
+
+ if (!(skb = wcdte_cmd_to_skb(netdev, cmd))) {
return;
}
skb_queue_tail(&wc->captured_packets, skb);
- netif_rx_schedule(wc->netdev);
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ netif_rx_schedule(netdev);
+# else
+ netif_rx_schedule(netdev, &wc->napi);
+# endif
return;
}
Modified: team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wctc4xxp.h
URL: http://svn.digium.com/view/zaptel/team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wctc4xxp.h?view=diff&rev=4312&r1=4311&r2=4312
==============================================================================
--- team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wctc4xxp.h (original)
+++ team/sruffell/zaptel-1.4-transcoder/kernel/wctc4xxp/wctc4xxp.h Tue May 20 16:58:56 2008
@@ -37,6 +37,8 @@
#include <linux/netdevice.h>
#include <linux/completion.h>
+#define CONFIG_WCDTE_NETWORK_IF
+
#define WARN() WARN_ON(1)
#define DTE_PRINTK(_lvl, _fmt, _args...) \
printk(KERN_##_lvl "%s: " _fmt, (wc)->board_name, ## _args)
@@ -64,6 +66,7 @@
struct list_head node;
#define NO_AUTO_FREE_CMD (1 << 0)
#define TX_COMPLETE (1 << 1)
+#define DO_NOT_CAPTURE (1 << 2)
unsigned long flags;
struct completion complete;
/* cmd must be the last field. */
@@ -125,8 +128,13 @@
spinlock_t reglock;
wait_queue_head_t regq;
unsigned long rcvflags;
+ struct semaphore chansem;
+ atomic_t open_channel_count;
+
+#define DTEF_RESET_PENDING 0x001
+#define DTEF_SHUTDOWN_PENDING 0x002
+ unsigned long flags;
- struct semaphore chansem;
spinlock_t cmd_list_lock;
struct list_head cmd_list;
/* This is a list to hold those commands which were flagged to not
@@ -144,27 +152,53 @@
unsigned char numchannels;
unsigned char complexname[40];
+ /*
+ * This section contains the members necessary to communicate with the
+ * physical interface to the transcoding engine.
+ *
+ */
unsigned long iobase;
+ struct dte_descriptor_ring *txd;
+ struct dte_descriptor_ring *rxd;
#if DEFERRED_PROCESSING == WORKQUEUE
struct workqueue_struct *dte_wq;
struct work_struct dte_work;
#endif
-
- struct dte_descriptor_ring *txd;
- struct dte_descriptor_ring *rxd;
+ struct work_struct reset_work;
struct zt_transcoder *uencode;
struct zt_transcoder *udecode;
struct channel_pvt *encoders;
struct channel_pvt *decoders;
+
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_file;
#endif
+ /*
+ * This section contains the members necessary for exporting the
+ * network interface to the host system. This is only used for
+ * debugging purposes.
+ *
+ */
+#ifdef CONFIG_WCDTE_NETWORK_IF
struct sk_buff_head captured_packets;
struct net_device *netdev;
+ struct net_device_stats net_stats;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+ struct napi_struct napi;
+#endif
+#endif
+
};
+
+static inline int wcdte_reset_pending(struct wcdte *wc) {
+ return test_bit(DTEF_RESET_PENDING, &wc->flags);
+}
+
+extern int wcdte_turn_off_booted_led(struct wcdte *wc);
+extern void wcdte_turn_on_booted_led(struct wcdte *wc);
/* \todo This macro is a candidate for removal. It's still here because of
* how the commands are passed to this zt_send_cmd */
@@ -181,6 +215,8 @@
__res; \
})
-#define CONFIG_WCDTE_NETWORK_IF
+
+/* Functions exported from base.c */
+void dte_transmit_cmd(struct wcdte *, struct dte_cmd *);
#endif /* __WCTC4XXP_H__ */
More information about the svn-commits
mailing list