IgH EtherCAT Master 1.5.2
debug.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
6 *
7 * This file is part of the IgH EtherCAT Master.
8 *
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version 2, as
11 * published by the Free Software Foundation.
12 *
13 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 * Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with the IgH EtherCAT Master; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * ---
23 *
24 * The license mentioned above concerns the source code only. Using the
25 * EtherCAT technology and brand is only permitted in compliance with the
26 * industrial property and similar rights of Beckhoff Automation GmbH.
27 *
28 *****************************************************************************/
29
35/*****************************************************************************/
36
37#include <linux/version.h>
38#include <linux/netdevice.h>
39#include <linux/etherdevice.h>
40
41#include "globals.h"
42#include "master.h"
43#include "debug.h"
44
45/*****************************************************************************/
46
47// net_device functions
48int ec_dbgdev_open(struct net_device *);
49int ec_dbgdev_stop(struct net_device *);
50int ec_dbgdev_tx(struct sk_buff *, struct net_device *);
51struct net_device_stats *ec_dbgdev_stats(struct net_device *);
52
53#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
56static const struct net_device_ops ec_dbg_netdev_ops =
57{
58 .ndo_open = ec_dbgdev_open,
59 .ndo_stop = ec_dbgdev_stop,
60 .ndo_start_xmit = ec_dbgdev_tx,
61 .ndo_get_stats = ec_dbgdev_stats,
62};
63#endif
64
65/*****************************************************************************/
66
75 ec_debug_t *dbg,
76 ec_device_t *device,
77 const char *name
78 )
79{
80 dbg->device = device;
81 dbg->registered = 0;
82 dbg->opened = 0;
83
84 memset(&dbg->stats, 0, sizeof(struct net_device_stats));
85
86 if (!(dbg->dev =
87 alloc_netdev(sizeof(ec_debug_t *), name, ether_setup))) {
88 EC_MASTER_ERR(device->master, "Unable to allocate net_device"
89 " for debug object!\n");
90 return -ENODEV;
91 }
92
93 // initialize net_device
94#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
95 dbg->dev->netdev_ops = &ec_dbg_netdev_ops;
96#else
97 dbg->dev->open = ec_dbgdev_open;
98 dbg->dev->stop = ec_dbgdev_stop;
99 dbg->dev->hard_start_xmit = ec_dbgdev_tx;
100 dbg->dev->get_stats = ec_dbgdev_stats;
101#endif
102
103 // initialize private data
104 *((ec_debug_t **) netdev_priv(dbg->dev)) = dbg;
105
106 return 0;
107}
108
109/*****************************************************************************/
110
116 ec_debug_t *dbg
117 )
118{
120 free_netdev(dbg->dev);
121}
122
123/*****************************************************************************/
124
128 ec_debug_t *dbg,
129 const struct net_device *net_dev
130 )
131{
132 int result;
133
135
136 // use the Ethernet address of the physical device for the debug device
137#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
138 eth_hw_addr_set(dbg->dev, net_dev->dev_addr);
139#else
140 memcpy(dbg->dev->dev_addr, net_dev->dev_addr, ETH_ALEN);
141#endif
142
143 // connect the net_device to the kernel
144 if ((result = register_netdev(dbg->dev))) {
145 EC_MASTER_WARN(dbg->device->master, "Unable to register net_device:"
146 " error %i\n", result);
147 } else {
148 dbg->registered = 1;
149 }
150}
151
152/*****************************************************************************/
153
157 ec_debug_t *dbg
158 )
159{
160 if (dbg->registered) {
161 dbg->opened = 0;
162 dbg->registered = 0;
163 unregister_netdev(dbg->dev);
164 }
165}
166
167/*****************************************************************************/
168
172 ec_debug_t *dbg,
173 const uint8_t *data,
174 size_t size
175 )
176{
177 struct sk_buff *skb;
178
179 if (!dbg->opened)
180 return;
181
182 // allocate socket buffer
183 if (!(skb = dev_alloc_skb(size))) {
184 dbg->stats.rx_dropped++;
185 return;
186 }
187
188 // copy frame contents into socket buffer
189 memcpy(skb_put(skb, size), data, size);
190
191 // update device statistics
192 dbg->stats.rx_packets++;
193 dbg->stats.rx_bytes += size;
194
195 // pass socket buffer to network stack
196 skb->dev = dbg->dev;
197 skb->protocol = eth_type_trans(skb, dbg->dev);
198 skb->ip_summed = CHECKSUM_UNNECESSARY;
199 netif_rx(skb);
200}
201
202/******************************************************************************
203 * NET_DEVICE functions
204 *****************************************************************************/
205
211 struct net_device *dev
212 )
213{
214 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
215 dbg->opened = 1;
216 EC_MASTER_INFO(dbg->device->master, "Debug interface %s opened.\n",
217 dev->name);
218 return 0;
219}
220
221/*****************************************************************************/
222
228 struct net_device *dev
229 )
230{
231 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
232 dbg->opened = 0;
233 EC_MASTER_INFO(dbg->device->master, "Debug interface %s stopped.\n",
234 dev->name);
235 return 0;
236}
237
238/*****************************************************************************/
239
245 struct sk_buff *skb,
246 struct net_device *dev
247 )
248{
249 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
250
251 dev_kfree_skb(skb);
252 dbg->stats.tx_dropped++;
253 return 0;
254}
255
256/*****************************************************************************/
257
262struct net_device_stats *ec_dbgdev_stats(
263 struct net_device *dev
264 )
265{
266 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
267 return &dbg->stats;
268}
269
270/*****************************************************************************/
static const struct net_device_ops ec_dbg_netdev_ops
Device operations for debug interfaces.
Definition: debug.c:56
int ec_dbgdev_open(struct net_device *)
Opens the virtual network device.
Definition: debug.c:210
void ec_debug_clear(ec_debug_t *dbg)
Debug interface destructor.
Definition: debug.c:115
void ec_debug_unregister(ec_debug_t *dbg)
Unregister debug interface.
Definition: debug.c:156
int ec_dbgdev_stop(struct net_device *)
Stops the virtual network device.
Definition: debug.c:227
void ec_debug_register(ec_debug_t *dbg, const struct net_device *net_dev)
Register debug interface.
Definition: debug.c:127
int ec_dbgdev_tx(struct sk_buff *, struct net_device *)
Transmits data via the virtual network device.
Definition: debug.c:244
int ec_debug_init(ec_debug_t *dbg, ec_device_t *device, const char *name)
Debug interface constructor.
Definition: debug.c:74
struct net_device_stats * ec_dbgdev_stats(struct net_device *)
Gets statistics about the virtual network device.
Definition: debug.c:262
void ec_debug_send(ec_debug_t *dbg, const uint8_t *data, size_t size)
Sends frame data to the interface.
Definition: debug.c:171
Network interface for debugging purposes.
Global definitions and macros.
EtherCAT master structure.
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition: master.h:73
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:85
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:97
Debugging network interface.
Definition: debug.h:47
struct net_device * dev
net_device for virtual ethernet device
Definition: debug.h:49
ec_device_t * device
Parent device.
Definition: debug.h:48
uint8_t opened
net_device is opened
Definition: debug.h:52
struct net_device_stats stats
device statistics
Definition: debug.h:50
uint8_t registered
net_device is opened
Definition: debug.h:51
EtherCAT device.
Definition: device.h:82
ec_master_t * master
EtherCAT master.
Definition: device.h:83