IgH EtherCAT Master  1.6.9
debug.c
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
4 *
5 * This file is part of the IgH EtherCAT Master.
6 *
7 * The IgH EtherCAT Master is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2, as
9 * published by the Free Software Foundation.
10 *
11 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 * Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with the IgH EtherCAT Master; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 ****************************************************************************/
21
26
27/****************************************************************************/
28
29#include <linux/version.h>
30#include <linux/netdevice.h>
31#include <linux/etherdevice.h>
32
33#include "globals.h"
34#include "master.h"
35#include "debug.h"
36
37/****************************************************************************/
38
39// net_device functions
40int ec_dbgdev_open(struct net_device *);
41int ec_dbgdev_stop(struct net_device *);
42int ec_dbgdev_tx(struct sk_buff *, struct net_device *);
43struct net_device_stats *ec_dbgdev_stats(struct net_device *);
44
47static const struct net_device_ops ec_dbg_netdev_ops =
48{
49 .ndo_open = ec_dbgdev_open,
50 .ndo_stop = ec_dbgdev_stop,
51 .ndo_start_xmit = ec_dbgdev_tx,
52 .ndo_get_stats = ec_dbgdev_stats,
53};
54
55/****************************************************************************/
56
65 ec_debug_t *dbg,
66 ec_device_t *device,
67 const char *name
68 )
69{
70 dbg->device = device;
71 dbg->registered = 0;
72 dbg->opened = 0;
73
74 memset(&dbg->stats, 0, sizeof(struct net_device_stats));
75
76#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
77 dbg->dev = alloc_netdev(sizeof(ec_debug_t *), name, NET_NAME_UNKNOWN, ether_setup);
78#else
79 dbg->dev = alloc_netdev(sizeof(ec_debug_t *), name, ether_setup);
80#endif
81 if (!(dbg->dev))
82 {
83 EC_MASTER_ERR(device->master, "Unable to allocate net_device"
84 " for debug object!\n");
85 return -ENODEV;
86 }
87
88 // initialize net_device
89 dbg->dev->netdev_ops = &ec_dbg_netdev_ops;
90
91 // initialize private data
92 *((ec_debug_t **) netdev_priv(dbg->dev)) = dbg;
93
94 return 0;
95}
96
97/****************************************************************************/
98
104 ec_debug_t *dbg
105 )
106{
108 free_netdev(dbg->dev);
109}
110
111/****************************************************************************/
112
116 ec_debug_t *dbg,
117 const struct net_device *net_dev
118 )
119{
120 int result;
121
123
124 // use the Ethernet address of the physical device for the debug device
125#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
126 eth_hw_addr_set(dbg->dev, net_dev->dev_addr);
127#else
128 memcpy(dbg->dev->dev_addr, net_dev->dev_addr, ETH_ALEN);
129#endif
130
131 // connect the net_device to the kernel
132 if ((result = register_netdev(dbg->dev))) {
133 EC_MASTER_WARN(dbg->device->master, "Unable to register net_device:"
134 " error %i\n", result);
135 } else {
136 dbg->registered = 1;
137 }
138}
139
140/****************************************************************************/
141
145 ec_debug_t *dbg
146 )
147{
148 if (dbg->registered) {
149 dbg->opened = 0;
150 dbg->registered = 0;
151 unregister_netdev(dbg->dev);
152 }
153}
154
155/****************************************************************************/
156
160 ec_debug_t *dbg,
161 const uint8_t *data,
162 size_t size
163 )
164{
165 struct sk_buff *skb;
166
167 if (!dbg->opened)
168 return;
169
170 // allocate socket buffer
171 if (!(skb = dev_alloc_skb(size))) {
172 dbg->stats.rx_dropped++;
173 return;
174 }
175
176 // copy frame contents into socket buffer
177 memcpy(skb_put(skb, size), data, size);
178
179 // update device statistics
180 dbg->stats.rx_packets++;
181 dbg->stats.rx_bytes += size;
182
183 // pass socket buffer to network stack
184 skb->dev = dbg->dev;
185 skb->protocol = eth_type_trans(skb, dbg->dev);
186 skb->ip_summed = CHECKSUM_UNNECESSARY;
187 netif_rx(skb);
188}
189
190/*****************************************************************************
191 * NET_DEVICE functions
192 ****************************************************************************/
193
199 struct net_device *dev
200 )
201{
202 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
203 dbg->opened = 1;
204 EC_MASTER_INFO(dbg->device->master, "Debug interface %s opened.\n",
205 dev->name);
206 return 0;
207}
208
209/****************************************************************************/
210
216 struct net_device *dev
217 )
218{
219 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
220 dbg->opened = 0;
221 EC_MASTER_INFO(dbg->device->master, "Debug interface %s stopped.\n",
222 dev->name);
223 return 0;
224}
225
226/****************************************************************************/
227
233 struct sk_buff *skb,
234 struct net_device *dev
235 )
236{
237 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
238
239 dev_kfree_skb(skb);
240 dbg->stats.tx_dropped++;
241 return 0;
242}
243
244/****************************************************************************/
245
250struct net_device_stats *ec_dbgdev_stats(
251 struct net_device *dev
252 )
253{
254 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
255 return &dbg->stats;
256}
257
258/****************************************************************************/
static const struct net_device_ops ec_dbg_netdev_ops
Device operations for debug interfaces.
Definition debug.c:47
int ec_dbgdev_open(struct net_device *)
Opens the virtual network device.
Definition debug.c:198
void ec_debug_clear(ec_debug_t *dbg)
Debug interface destructor.
Definition debug.c:103
void ec_debug_unregister(ec_debug_t *dbg)
Unregister debug interface.
Definition debug.c:144
int ec_dbgdev_stop(struct net_device *)
Stops the virtual network device.
Definition debug.c:215
void ec_debug_register(ec_debug_t *dbg, const struct net_device *net_dev)
Register debug interface.
Definition debug.c:115
int ec_dbgdev_tx(struct sk_buff *, struct net_device *)
Transmits data via the virtual network device.
Definition debug.c:232
int ec_debug_init(ec_debug_t *dbg, ec_device_t *device, const char *name)
Debug interface constructor.
Definition debug.c:64
struct net_device_stats * ec_dbgdev_stats(struct net_device *)
Gets statistics about the virtual network device.
Definition debug.c:250
void ec_debug_send(ec_debug_t *dbg, const uint8_t *data, size_t size)
Sends frame data to the interface.
Definition debug.c:159
Network interface for debugging purposes.
struct ec_device ec_device_t
Definition ecdev.h:45
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:62
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition master.h:74
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition master.h:86
Debugging network interface.
Definition debug.h:39
struct net_device * dev
net_device for virtual ethernet device
Definition debug.h:41
ec_device_t * device
Parent device.
Definition debug.h:40
uint8_t opened
net_device is opened
Definition debug.h:44
struct net_device_stats stats
device statistics
Definition debug.h:42
uint8_t registered
net_device is opened
Definition debug.h:43
ec_master_t * master
EtherCAT master.
Definition device.h:75