IgH EtherCAT Master  1.6.9
device.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/module.h>
30#include <linux/skbuff.h>
31#include <linux/if_ether.h>
32#include <linux/netdevice.h>
33
34#include "device.h"
35#include "master.h"
36
37#ifdef EC_DEBUG_RING
38#define timersub(a, b, result) \
39 do { \
40 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
41 (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
42 if ((result)->tv_usec < 0) { \
43 --(result)->tv_sec; \
44 (result)->tv_usec += 1000000; \
45 } \
46 } while (0)
47#endif
48
49/****************************************************************************/
50
51enum {
52 /* genet driver needs extra headroom in skb for status block */
53 EXTRA_HEADROOM = 64,
54};
55
61 ec_device_t *device,
62 ec_master_t *master
63 )
64{
65 int ret;
66 unsigned int i;
67 struct ethhdr *eth;
68#ifdef EC_DEBUG_IF
69 char ifname[10];
70 char mb = 'x';
71#endif
72
73 device->master = master;
74 device->dev = NULL;
75 device->poll = NULL;
76 device->module = NULL;
77 device->open = 0;
78 device->link_state = 0;
79 for (i = 0; i < EC_TX_RING_SIZE; i++) {
80 device->tx_skb[i] = NULL;
81 }
82 device->tx_ring_index = 0;
83#ifdef EC_HAVE_CYCLES
84 device->cycles_poll = 0;
85#endif
86#ifdef EC_DEBUG_RING
87 device->timeval_poll.tv_sec = 0;
88 device->timeval_poll.tv_usec = 0;
89#endif
90 device->jiffies_poll = 0;
91
93
94#ifdef EC_DEBUG_RING
95 for (i = 0; i < EC_DEBUG_RING_SIZE; i++) {
96 ec_debug_frame_t *df = &device->debug_frames[i];
97 df->dir = TX;
98 df->t.tv_sec = 0;
99 df->t.tv_usec = 0;
100 memset(df->data, 0, EC_MAX_DATA_SIZE);
101 df->data_size = 0;
102 }
103#endif
104#ifdef EC_DEBUG_RING
105 device->debug_frame_index = 0;
106 device->debug_frame_count = 0;
107#endif
108
109#ifdef EC_DEBUG_IF
110 if (device == &master->devices[EC_DEVICE_MAIN]) {
111 mb = 'm';
112 }
113 else {
114 mb = 'b';
115 }
116
117 sprintf(ifname, "ecdbg%c%u", mb, master->index);
118
119 ret = ec_debug_init(&device->dbg, device, ifname);
120 if (ret < 0) {
121 EC_MASTER_ERR(master, "Failed to init debug device!\n");
122 goto out_return;
123 }
124#endif
125
126 for (i = 0; i < EC_TX_RING_SIZE; i++) {
127 if (!(device->tx_skb[i] = dev_alloc_skb(ETH_FRAME_LEN + EXTRA_HEADROOM))) {
128 EC_MASTER_ERR(master, "Error allocating device socket buffer!\n");
129 ret = -ENOMEM;
130 goto out_tx_ring;
131 }
132
133 // add Ethernet-II-header
134 skb_reserve(device->tx_skb[i], ETH_HLEN + EXTRA_HEADROOM);
135 eth = (struct ethhdr *) skb_push(device->tx_skb[i], ETH_HLEN);
136 eth->h_proto = htons(0x88A4);
137 memset(eth->h_dest, 0xFF, ETH_ALEN);
138 }
139
140 return 0;
141
142out_tx_ring:
143 for (i = 0; i < EC_TX_RING_SIZE; i++) {
144 if (device->tx_skb[i]) {
145 dev_kfree_skb(device->tx_skb[i]);
146 }
147 }
148#ifdef EC_DEBUG_IF
149 ec_debug_clear(&device->dbg);
150out_return:
151#endif
152 return ret;
153}
154
155/****************************************************************************/
156
160 ec_device_t *device
161 )
162{
163 unsigned int i;
164
165 if (device->open) {
166 ec_device_close(device);
167 }
168 for (i = 0; i < EC_TX_RING_SIZE; i++)
169 dev_kfree_skb(device->tx_skb[i]);
170#ifdef EC_DEBUG_IF
171 ec_debug_clear(&device->dbg);
172#endif
173}
174
175/****************************************************************************/
176
180 ec_device_t *device,
181 struct net_device *net_dev,
182 ec_pollfunc_t poll,
183 struct module *module
184 )
185{
186 unsigned int i;
187 struct ethhdr *eth;
188
189 ec_device_detach(device); // resets fields
190
191 device->dev = net_dev;
192 device->poll = poll;
193 device->module = module;
194
195 for (i = 0; i < EC_TX_RING_SIZE; i++) {
196 device->tx_skb[i]->dev = net_dev;
197 eth = (struct ethhdr *) (device->tx_skb[i]->data);
198 memcpy(eth->h_source, net_dev->dev_addr, ETH_ALEN);
199 }
200
201#ifdef EC_DEBUG_IF
202 ec_debug_register(&device->dbg, net_dev);
203#endif
204}
205
206/****************************************************************************/
207
211 ec_device_t *device
212 )
213{
214 unsigned int i;
215
216#ifdef EC_DEBUG_IF
217 ec_debug_unregister(&device->dbg);
218#endif
219
220 device->dev = NULL;
221 device->poll = NULL;
222 device->module = NULL;
223 device->open = 0;
224 device->link_state = 0; // down
225
226 ec_device_clear_stats(device);
227
228 for (i = 0; i < EC_TX_RING_SIZE; i++) {
229 device->tx_skb[i]->dev = NULL;
230 }
231}
232
233/****************************************************************************/
234
240 ec_device_t *device
241 )
242{
243 int ret;
244
245 if (!device->dev) {
246 EC_MASTER_ERR(device->master, "No net_device to open!\n");
247 return -ENODEV;
248 }
249
250 if (device->open) {
251 EC_MASTER_WARN(device->master, "Device already opened!\n");
252 return 0;
253 }
254
255 device->link_state = 0;
256
257 ec_device_clear_stats(device);
258
259 ret = device->dev->netdev_ops->ndo_open(device->dev);
260 if (!ret)
261 device->open = 1;
262
263 return ret;
264}
265
266/****************************************************************************/
267
273 ec_device_t *device
274 )
275{
276 int ret;
277
278 if (!device->dev) {
279 EC_MASTER_ERR(device->master, "No device to close!\n");
280 return -ENODEV;
281 }
282
283 if (!device->open) {
284 EC_MASTER_WARN(device->master, "Device already closed!\n");
285 return 0;
286 }
287
288 ret = device->dev->netdev_ops->ndo_stop(device->dev);
289 if (!ret)
290 device->open = 0;
291
292 return ret;
293}
294
295/****************************************************************************/
296
302 ec_device_t *device
303 )
304{
305 /* cycle through socket buffers, because otherwise there is a race
306 * condition, if multiple frames are sent and the DMA is not scheduled in
307 * between. */
308 device->tx_ring_index++;
310 return device->tx_skb[device->tx_ring_index]->data + ETH_HLEN;
311}
312
313/****************************************************************************/
314
321 ec_device_t *device,
322 size_t size
323 )
324{
325 struct sk_buff *skb = device->tx_skb[device->tx_ring_index];
326
327 // set the right length for the data
328 skb->len = ETH_HLEN + size;
329
330 if (unlikely(device->master->debug_level > 1)) {
331 EC_MASTER_DBG(device->master, 2, "Sending frame:\n");
332 ec_print_data(skb->data, ETH_HLEN + size);
333 }
334
335 // start sending
336 if (device->dev->netdev_ops->ndo_start_xmit(skb, device->dev) ==
337 NETDEV_TX_OK)
338 {
339 device->tx_count++;
340 device->master->device_stats.tx_count++;
341 device->tx_bytes += ETH_HLEN + size;
342 device->master->device_stats.tx_bytes += ETH_HLEN + size;
343#ifdef EC_DEBUG_IF
344 ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size);
345#endif
346#ifdef EC_DEBUG_RING
347 ec_device_debug_ring_append(
348 device, TX, skb->data + ETH_HLEN, size);
349#endif
350 } else {
351 device->tx_errors++;
352 }
353}
354
355/****************************************************************************/
356
360 ec_device_t *device
361 )
362{
363 unsigned int i;
364
365 // zero frame statistics
366 device->tx_count = 0;
367 device->last_tx_count = 0;
368 device->rx_count = 0;
369 device->last_rx_count = 0;
370 device->tx_bytes = 0;
371 device->last_tx_bytes = 0;
372 device->rx_bytes = 0;
373 device->last_rx_bytes = 0;
374 device->tx_errors = 0;
375
376 for (i = 0; i < EC_RATE_COUNT; i++) {
377 device->tx_frame_rates[i] = 0;
378 device->rx_frame_rates[i] = 0;
379 device->tx_byte_rates[i] = 0;
380 device->rx_byte_rates[i] = 0;
381 }
382}
383
384/****************************************************************************/
385
386#ifdef EC_DEBUG_RING
389void ec_device_debug_ring_append(
390 ec_device_t *device,
391 ec_debug_frame_dir_t dir,
392 const void *data,
393 size_t size
394 )
395{
396 ec_debug_frame_t *df = &device->debug_frames[device->debug_frame_index];
397
398 df->dir = dir;
399 if (dir == TX) {
400 do_gettimeofday(&df->t);
401 }
402 else {
403 df->t = device->timeval_poll;
404 }
405 memcpy(df->data, data, size);
406 df->data_size = size;
407
408 device->debug_frame_index++;
409 device->debug_frame_index %= EC_DEBUG_RING_SIZE;
410 if (unlikely(device->debug_frame_count < EC_DEBUG_RING_SIZE))
411 device->debug_frame_count++;
412}
413
414/****************************************************************************/
415
418void ec_device_debug_ring_print(
419 const ec_device_t *device
420 )
421{
422 int i;
423 unsigned int ring_index;
424 const ec_debug_frame_t *df;
425 struct timeval t0, diff;
426
427 // calculate index of the newest frame in the ring to get its time
428 ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE - 1)
429 % EC_DEBUG_RING_SIZE;
430 t0 = device->debug_frames[ring_index].t;
431
432 EC_MASTER_DBG(device->master, 1, "Debug ring %u:\n", ring_index);
433
434 // calculate index of the oldest frame in the ring
435 ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE
436 - device->debug_frame_count) % EC_DEBUG_RING_SIZE;
437
438 for (i = 0; i < device->debug_frame_count; i++) {
439 df = &device->debug_frames[ring_index];
440 timersub(&t0, &df->t, &diff);
441
442 EC_MASTER_DBG(device->master, 1, "Frame %u, dt=%u.%06u s, %s:\n",
443 i + 1 - device->debug_frame_count,
444 (unsigned int) diff.tv_sec,
445 (unsigned int) diff.tv_usec,
446 (df->dir == TX) ? "TX" : "RX");
447 ec_print_data(df->data, df->data_size);
448
449 ring_index++;
450 ring_index %= EC_DEBUG_RING_SIZE;
451 }
452}
453#endif
454
455/****************************************************************************/
456
464 ec_device_t *device
465 )
466{
467#ifdef EC_HAVE_CYCLES
468 device->cycles_poll = get_cycles();
469#endif
470 device->jiffies_poll = jiffies;
471#ifdef EC_DEBUG_RING
472 do_gettimeofday(&device->timeval_poll);
473#endif
474 device->poll(device->dev);
475}
476
477/****************************************************************************/
478
482 ec_device_t *device
483 )
484{
485 unsigned int i;
486
487 s32 tx_frame_rate = (device->tx_count - device->last_tx_count) * 1000;
488 s32 rx_frame_rate = (device->rx_count - device->last_rx_count) * 1000;
489 s32 tx_byte_rate = (device->tx_bytes - device->last_tx_bytes);
490 s32 rx_byte_rate = (device->rx_bytes - device->last_rx_bytes);
491
492 /* Low-pass filter:
493 * Y_n = y_(n - 1) + T / tau * (x - y_(n - 1)) | T = 1
494 * -> Y_n += (x - y_(n - 1)) / tau
495 */
496 for (i = 0; i < EC_RATE_COUNT; i++) {
497 s32 n = rate_intervals[i];
498 device->tx_frame_rates[i] +=
499 (tx_frame_rate - device->tx_frame_rates[i]) / n;
500 device->rx_frame_rates[i] +=
501 (rx_frame_rate - device->rx_frame_rates[i]) / n;
502 device->tx_byte_rates[i] +=
503 (tx_byte_rate - device->tx_byte_rates[i]) / n;
504 device->rx_byte_rates[i] +=
505 (rx_byte_rate - device->rx_byte_rates[i]) / n;
506 }
507
508 device->last_tx_count = device->tx_count;
509 device->last_rx_count = device->rx_count;
510 device->last_tx_bytes = device->tx_bytes;
511 device->last_rx_bytes = device->rx_bytes;
512}
513
514/*****************************************************************************
515 * Device interface
516 ****************************************************************************/
517
529{
530 ec_master_t *master = device->master;
531 char dev_str[20], mac_str[20];
532
533 ec_mac_print(device->dev->dev_addr, mac_str);
534
535 if (device == &master->devices[EC_DEVICE_MAIN]) {
536 sprintf(dev_str, "main");
537 } else if (device == &master->devices[EC_DEVICE_BACKUP]) {
538 sprintf(dev_str, "backup");
539 } else {
540 EC_MASTER_WARN(master, "%s() called with unknown device %s!\n",
541 __func__, mac_str);
542 sprintf(dev_str, "UNKNOWN");
543 }
544
545 EC_MASTER_INFO(master, "Releasing %s device %s.\n", dev_str, mac_str);
546
547 down(&master->device_sem);
548 ec_device_detach(device);
549 up(&master->device_sem);
550}
551
552/****************************************************************************/
553
560{
561 int ret;
562 ec_master_t *master = device->master;
563 unsigned int all_open = 1, dev_idx;
564
565 ret = ec_device_open(device);
566 if (ret) {
567 EC_MASTER_ERR(master, "Failed to open device: error %d!\n", ret);
568 return ret;
569 }
570
571 for (dev_idx = EC_DEVICE_MAIN;
572 dev_idx < ec_master_num_devices(device->master); dev_idx++) {
573 if (!master->devices[dev_idx].open) {
574 all_open = 0;
575 break;
576 }
577 }
578
579 if (all_open) {
580 ret = ec_master_enter_idle_phase(device->master);
581 if (ret) {
582 EC_MASTER_ERR(device->master, "Failed to enter IDLE phase!\n");
583 return ret;
584 }
585 }
586
587 return 0;
588}
589
590/****************************************************************************/
591
598{
599 ec_master_t *master = device->master;
600
601 if (master->phase == EC_IDLE) {
603 }
604
605 if (ec_device_close(device)) {
606 EC_MASTER_WARN(master, "Failed to close device!\n");
607 }
608}
609
610/****************************************************************************/
611
622 ec_device_t *device,
623 const void *data,
624 size_t size
625 )
626{
627 const void *ec_data = data + ETH_HLEN;
628 size_t ec_size = size - ETH_HLEN;
629
630 if (unlikely(!data)) {
631 EC_MASTER_WARN(device->master, "%s() called with NULL data.\n",
632 __func__);
633 return;
634 }
635
636 device->rx_count++;
637 device->master->device_stats.rx_count++;
638 device->rx_bytes += size;
639 device->master->device_stats.rx_bytes += size;
640
641 if (unlikely(device->master->debug_level > 1)) {
642 EC_MASTER_DBG(device->master, 2, "Received frame:\n");
643 ec_print_data(data, size);
644 }
645
646#ifdef EC_DEBUG_IF
647 ec_debug_send(&device->dbg, data, size);
648#endif
649#ifdef EC_DEBUG_RING
650 ec_device_debug_ring_append(device, RX, ec_data, ec_size);
651#endif
652
653 ec_master_receive_datagrams(device->master, device, ec_data, ec_size);
654}
655
656/****************************************************************************/
657
666 ec_device_t *device,
667 uint8_t state
668 )
669{
670 if (unlikely(!device)) {
671 EC_WARN("ecdev_set_link() called with null device!\n");
672 return;
673 }
674
675 if (likely(state != device->link_state)) {
676 device->link_state = state;
677 EC_MASTER_INFO(device->master,
678 "Link state of %s changed to %s.\n",
679 device->dev->name, (state ? "UP" : "DOWN"));
680 }
681}
682
683/****************************************************************************/
684
692 const ec_device_t *device
693 )
694{
695 if (unlikely(!device)) {
696 EC_WARN("ecdev_get_link() called with null device!\n");
697 return 0;
698 }
699
700 return device->link_state;
701}
702
703/****************************************************************************/
704
706
707EXPORT_SYMBOL(ecdev_withdraw);
708EXPORT_SYMBOL(ecdev_open);
709EXPORT_SYMBOL(ecdev_close);
710EXPORT_SYMBOL(ecdev_receive);
711EXPORT_SYMBOL(ecdev_get_link);
712EXPORT_SYMBOL(ecdev_set_link);
713
715
716/****************************************************************************/
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
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
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_device_detach(ec_device_t *device)
Disconnect from net_device.
Definition device.c:210
void ec_device_update_stats(ec_device_t *device)
Update device statistics.
Definition device.c:481
int ec_device_close(ec_device_t *device)
Stops the EtherCAT device.
Definition device.c:272
void ec_device_attach(ec_device_t *device, struct net_device *net_dev, ec_pollfunc_t poll, struct module *module)
Associate with net_device.
Definition device.c:179
int ec_device_init(ec_device_t *device, ec_master_t *master)
Constructor.
Definition device.c:60
uint8_t * ec_device_tx_data(ec_device_t *device)
Returns a pointer to the device's transmit memory.
Definition device.c:301
void ec_device_poll(ec_device_t *device)
Calls the poll function of the assigned net_device.
Definition device.c:463
void ec_device_clear_stats(ec_device_t *device)
Clears the frame statistics.
Definition device.c:359
void ec_device_clear(ec_device_t *device)
Destructor.
Definition device.c:159
void ec_device_send(ec_device_t *device, size_t size)
Sends the content of the transmit socket buffer.
Definition device.c:320
int ec_device_open(ec_device_t *device)
Opens the EtherCAT device.
Definition device.c:239
EtherCAT device structure.
#define EC_TX_RING_SIZE
Size of the transmit ring.
Definition device.h:43
void(* ec_pollfunc_t)(struct net_device *)
Device poll function type.
Definition ecdev.h:49
struct ec_device ec_device_t
Definition ecdev.h:45
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition globals.h:60
#define EC_MAX_DATA_SIZE
Resulting maximum data size of a single datagram in a frame.
Definition globals.h:79
#define EC_WARN(fmt, args...)
Convenience macro for printing EtherCAT-specific warnings to syslog.
Definition globals.h:234
ssize_t ec_mac_print(const uint8_t *, char *)
Print a MAC address to a buffer.
Definition module.c:245
@ EC_DEVICE_MAIN
Main device.
Definition globals.h:199
@ EC_DEVICE_BACKUP
Backup device.
Definition globals.h:200
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition module.c:344
struct ec_master ec_master_t
Definition ecrt.h:300
void ecdev_close(ec_device_t *device)
Makes the master leave IDLE phase and closes the network device.
Definition device.c:597
int ecdev_open(ec_device_t *device)
Opens the network device and makes the master enter IDLE phase.
Definition device.c:559
void ecdev_withdraw(ec_device_t *device)
Withdraws an EtherCAT device from the master.
Definition device.c:528
uint8_t ecdev_get_link(const ec_device_t *device)
Reads the link state.
Definition device.c:691
void ecdev_set_link(ec_device_t *device, uint8_t state)
Sets a new link state.
Definition device.c:665
void ecdev_receive(ec_device_t *device, const void *data, size_t size)
Accepts a received frame.
Definition device.c:621
void ec_master_leave_idle_phase(ec_master_t *master)
Transition function from IDLE to ORPHANED phase.
Definition master.c:695
const unsigned int rate_intervals[]
List of intervals for statistics [s].
Definition master.c:120
void ec_master_receive_datagrams(ec_master_t *master, ec_device_t *device, const uint8_t *frame_data, size_t size)
Processes a received frame.
Definition master.c:1147
int ec_master_enter_idle_phase(ec_master_t *master)
Transition function from ORPHANED to IDLE phase.
Definition master.c:662
EtherCAT master structure.
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition master.h:323
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition master.h:62
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition master.h:100
@ EC_IDLE
Idle phase.
Definition master.h:126
#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
u64 tx_count
Number of frames sent.
Definition master.h:149
u64 rx_bytes
Number of bytes received.
Definition master.h:156
u64 tx_bytes
Number of bytes sent.
Definition master.h:154
u64 rx_count
Number of frames received.
Definition master.h:151
u64 tx_errors
Number of transmit errors.
Definition device.h:102
uint8_t open
true, if the net_device has been opened
Definition device.h:79
u64 tx_count
Number of frames sent.
Definition device.h:92
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition device.h:103
ec_master_t * master
EtherCAT master.
Definition device.h:75
u64 last_rx_bytes
Number of bytes received of last statistics cycle.
Definition device.h:100
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition device.h:111
u64 last_rx_count
Number of frames received of last statistics cycle.
Definition device.h:95
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition device.h:109
struct sk_buff * tx_skb[EC_TX_RING_SIZE]
transmit skb ring
Definition device.h:81
struct module * module
pointer to the device's owning module
Definition device.h:78
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition device.h:106
struct net_device * dev
pointer to the assigned net_device
Definition device.h:76
u64 tx_bytes
Number of bytes sent.
Definition device.h:97
ec_pollfunc_t poll
pointer to the device's poll function
Definition device.h:77
u64 rx_count
Number of frames received.
Definition device.h:94
uint8_t link_state
device link state
Definition device.h:80
u64 last_tx_bytes
Number of bytes sent of last statistics cycle.
Definition device.h:98
unsigned int tx_ring_index
last ring entry used to transmit
Definition device.h:82
unsigned long jiffies_poll
jiffies of last poll
Definition device.h:89
u64 last_tx_count
Number of frames sent of last statistics cycle.
Definition device.h:93
u64 rx_bytes
Number of bytes received.
Definition device.h:99
unsigned int index
Index.
Definition master.h:188
ec_device_stats_t device_stats
Device statistics.
Definition master.h:208
unsigned int debug_level
Master debug level.
Definition master.h:275
struct semaphore device_sem
Device semaphore.
Definition master.h:207
ec_master_phase_t phase
Master phase.
Definition master.h:212
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition master.h:200