# HG changeset patch # User Florian Pose # Date 1147354146 0 # Node ID 767548c75bf345358763ceaeb05519539f7ce6ea # Parent 382bdb9138ec739063a73940315365c7937ff937 Added debug interface for network monitors. diff -r 382bdb9138ec -r 767548c75bf3 devices/8139too.c --- a/devices/8139too.c Thu May 11 09:24:15 2006 +0000 +++ b/devices/8139too.c Thu May 11 13:29:06 2006 +0000 @@ -2224,8 +2224,7 @@ else { ecdev_receive(rtl_ec_dev, - &rx_ring[ring_offset + 4] + ETH_HLEN, - pkt_size - ETH_HLEN); + &rx_ring[ring_offset + 4], pkt_size); dev->last_rx = jiffies; tp->stats.rx_bytes += pkt_size; tp->stats.rx_packets++; diff -r 382bdb9138ec -r 767548c75bf3 master/Makefile --- a/master/Makefile Thu May 11 09:24:15 2006 +0000 +++ b/master/Makefile Thu May 11 13:29:06 2006 +0000 @@ -33,7 +33,7 @@ obj-m := ec_master.o ec_master-objs := module.o master.o device.o slave.o command.o types.o \ - domain.o mailbox.o canopen.o ethernet.o + domain.o mailbox.o canopen.o ethernet.o debug.o REV := $(shell svnversion $(src) 2>/dev/null) diff -r 382bdb9138ec -r 767548c75bf3 master/debug.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/debug.c Thu May 11 13:29:06 2006 +0000 @@ -0,0 +1,179 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 of the License. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +/** + \file + Ethernet interface for debugging purposes. +*/ + +/*****************************************************************************/ + +#include + +#include "globals.h" +#include "debug.h" + +/*****************************************************************************/ + +// net_device functions +int ec_dbgdev_open(struct net_device *); +int ec_dbgdev_stop(struct net_device *); +struct net_device_stats *ec_dbgdev_stats(struct net_device *); + +/*****************************************************************************/ + +/** + Debug constructor. + Initializes the debug object, creates a net_device and registeres it. +*/ + +int ec_debug_init(ec_debug_t *dbg /**< debug object */) +{ + int result; + + dbg->opened = 0; + memset(&dbg->stats, 0, sizeof(struct net_device_stats)); + + if (!(dbg->dev = + alloc_netdev(sizeof(ec_debug_t *), "ec%d", ether_setup))) { + EC_ERR("Unable to allocate net_device for debug object!\n"); + goto out_return; + } + + // initialize net_device + dbg->dev->open = ec_dbgdev_open; + dbg->dev->stop = ec_dbgdev_stop; + dbg->dev->get_stats = ec_dbgdev_stats; + + // initialize private data + *((ec_debug_t **) netdev_priv(dbg->dev)) = dbg; + + // connect the net_device to the kernel + if ((result = register_netdev(dbg->dev))) { + EC_ERR("Unable to register net_device: error %i\n", result); + goto out_free; + } + + return 0; + + out_free: + free_netdev(dbg->dev); + dbg->dev = NULL; + out_return: + return -1; +} + +/*****************************************************************************/ + +/** + Debug destructor. + Unregisteres the net_device and frees allocated memory. +*/ + +void ec_debug_clear(ec_debug_t *dbg /**< debug object */) +{ + if (dbg->dev) { + unregister_netdev(dbg->dev); + free_netdev(dbg->dev); + } +} + +/*****************************************************************************/ + +/** + Sends frame data to the interface. +*/ + +void ec_debug_send(ec_debug_t *dbg, /**< debug object */ + const uint8_t *data, /**< frame data */ + size_t size /**< size of the frame data */ + ) +{ + struct sk_buff *skb; + + if (!dbg->opened) return; + + // allocate socket buffer + if (!(skb = dev_alloc_skb(size))) { + dbg->stats.rx_dropped++; + return; + } + + // copy frame contents into socket buffer + memcpy(skb_put(skb, size), data, size); + + // update device statistics + dbg->stats.rx_packets++; + dbg->stats.rx_bytes += size; + + // pass socket buffer to network stack + skb->dev = dbg->dev; + skb->protocol = eth_type_trans(skb, dbg->dev); + skb->ip_summed = CHECKSUM_UNNECESSARY; + netif_rx(skb); +} + +/****************************************************************************** + * NET_DEVICE functions + *****************************************************************************/ + +/** + Opens the virtual network device. +*/ + +int ec_dbgdev_open(struct net_device *dev /**< debug net_device */) +{ + ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev)); + dbg->opened = 1; + EC_INFO("debug interface %s opened.\n", dev->name); + return 0; +} + +/*****************************************************************************/ + +/** + Stops the virtual network device. +*/ + +int ec_dbgdev_stop(struct net_device *dev /**< debug net_device */) +{ + ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev)); + dbg->opened = 0; + EC_INFO("debug interface %s stopped.\n", dev->name); + return 0; +} + +/*****************************************************************************/ + +/** + Gets statistics about the virtual network device. +*/ + +struct net_device_stats *ec_dbgdev_stats(struct net_device *dev + /**< debug net_device */) +{ + ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev)); + return &dbg->stats; +} + +/*****************************************************************************/ diff -r 382bdb9138ec -r 767548c75bf3 master/debug.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/debug.h Thu May 11 13:29:06 2006 +0000 @@ -0,0 +1,53 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 of the License. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +/** + \file + Network interface for debugging purposes. +*/ + +/*****************************************************************************/ + +#include + +/*****************************************************************************/ + +/** + Debugging network interface. +*/ + +typedef struct +{ + struct net_device *dev; /**< net_device for virtual ethernet device */ + struct net_device_stats stats; /**< device statistics */ + uint8_t opened; /**< net_device is opened */ +} +ec_debug_t; + +/*****************************************************************************/ + +int ec_debug_init(ec_debug_t *); +void ec_debug_clear(ec_debug_t *); +void ec_debug_send(ec_debug_t *, const uint8_t *, size_t); + +/*****************************************************************************/ diff -r 382bdb9138ec -r 767548c75bf3 master/device.c --- a/master/device.c Thu May 11 09:24:15 2006 +0000 +++ b/master/device.c Thu May 11 13:29:06 2006 +0000 @@ -61,9 +61,14 @@ device->open = 0; device->link_state = 0; // down + if (ec_debug_init(&device->dbg)) { + EC_ERR("Failed to init debug device!\n"); + goto out_return; + } + if (!(device->tx_skb = dev_alloc_skb(ETH_FRAME_LEN))) { EC_ERR("Error allocating device socket buffer!\n"); - return -1; + goto out_debug; } device->tx_skb->dev = net_dev; @@ -76,6 +81,11 @@ memset(eth->h_dest, 0xFF, net_dev->addr_len); return 0; + + out_debug: + ec_debug_clear(&device->dbg); + out_return: + return -1; } /*****************************************************************************/ @@ -88,6 +98,7 @@ { if (device->open) ec_device_close(device); if (device->tx_skb) dev_kfree_skb(device->tx_skb); + ec_debug_clear(&device->dbg); } /*****************************************************************************/ @@ -180,6 +191,8 @@ ec_print_data(device->tx_skb->data + ETH_HLEN, size); } + ec_debug_send(&device->dbg, device->tx_skb->data, ETH_HLEN + size); + // start sending device->dev->hard_start_xmit(device->tx_skb, device->dev); } @@ -210,16 +223,19 @@ */ void ecdev_receive(ec_device_t *device, /**< EtherCAT device */ - const void *data, /**< pointer to receibed data */ + const void *data, /**< pointer to received data */ size_t size /**< number of bytes received */ ) { if (unlikely(device->master->debug_level > 1)) { EC_DBG("Received frame:\n"); - ec_print_data_diff(device->tx_skb->data + ETH_HLEN, data, size); - } - - ec_master_receive(device->master, data, size); + ec_print_data_diff(device->tx_skb->data + ETH_HLEN, + data + ETH_HLEN, size - ETH_HLEN); + } + + ec_debug_send(&device->dbg, data, size); + + ec_master_receive(device->master, data + ETH_HLEN, size - ETH_HLEN); } /*****************************************************************************/ diff -r 382bdb9138ec -r 767548c75bf3 master/device.h --- a/master/device.h Thu May 11 09:24:15 2006 +0000 +++ b/master/device.h Thu May 11 13:29:06 2006 +0000 @@ -36,6 +36,7 @@ #include "../include/ecrt.h" #include "../devices/ecdev.h" #include "globals.h" +#include "debug.h" /*****************************************************************************/ @@ -54,6 +55,7 @@ ec_isr_t isr; /**< pointer to the device's interrupt service routine */ struct module *module; /**< pointer to the device's owning module */ uint8_t link_state; /**< device link state */ + ec_debug_t dbg; /**< debug device */ }; /*****************************************************************************/