IgH EtherCAT Master  1.6.1
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 
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
40 int ec_dbgdev_open(struct net_device *);
41 int ec_dbgdev_stop(struct net_device *);
42 int ec_dbgdev_tx(struct sk_buff *, struct net_device *);
43 struct net_device_stats *ec_dbgdev_stats(struct net_device *);
44 
47 static 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 {
107  ec_debug_unregister(dbg);
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 
122  ec_debug_unregister(dbg);
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 
250 struct 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 /****************************************************************************/
void ec_debug_clear(ec_debug_t *dbg)
Debug interface destructor.
Definition: debug.c:103
Network interface for debugging purposes.
uint8_t registered
net_device is opened
Definition: debug.h:43
int ec_dbgdev_tx(struct sk_buff *, struct net_device *)
Transmits data via the virtual network device.
Definition: debug.c:232
Debugging network interface.
Definition: debug.h:38
Global definitions and macros.
EtherCAT master structure.
void ec_debug_unregister(ec_debug_t *dbg)
Unregister debug interface.
Definition: debug.c:144
EtherCAT device.
Definition: device.h:73
struct net_device * dev
net_device for virtual ethernet device
Definition: debug.h:41
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:86
ec_master_t * master
EtherCAT master.
Definition: device.h:75
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:74
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
void ec_debug_register(ec_debug_t *dbg, const struct net_device *net_dev)
Register debug interface.
Definition: debug.c:115
int ec_debug_init(ec_debug_t *dbg, ec_device_t *device, const char *name)
Debug interface constructor.
Definition: debug.c:64
int ec_dbgdev_stop(struct net_device *)
Stops the virtual network device.
Definition: debug.c:215
struct net_device_stats * ec_dbgdev_stats(struct net_device *)
Gets statistics about the virtual network device.
Definition: debug.c:250
int ec_dbgdev_open(struct net_device *)
Opens the virtual network device.
Definition: debug.c:198
static const struct net_device_ops ec_dbg_netdev_ops
Device operations for debug interfaces.
Definition: debug.c:47
ec_device_t * device
Parent device.
Definition: debug.h:40
uint8_t opened
net_device is opened
Definition: debug.h:44
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition: master.h:62
struct net_device_stats stats
device statistics
Definition: debug.h:42