IgH EtherCAT Master  1.6.1
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 
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 
51 enum {
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 
92  ec_device_clear_stats(device);
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 
142 out_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);
150 out_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++;
309  device->tx_ring_index %= EC_TX_RING_SIZE;
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
387 
389 void 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 
418 void 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 
559 int ecdev_open(ec_device_t *device )
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 
597 void ecdev_close(ec_device_t *device )
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 
707 EXPORT_SYMBOL(ecdev_withdraw);
708 EXPORT_SYMBOL(ecdev_open);
709 EXPORT_SYMBOL(ecdev_close);
710 EXPORT_SYMBOL(ecdev_receive);
711 EXPORT_SYMBOL(ecdev_get_link);
712 EXPORT_SYMBOL(ecdev_set_link);
713 
716 /****************************************************************************/
#define EC_WARN(fmt, args...)
Convenience macro for printing EtherCAT-specific warnings to syslog.
Definition: globals.h:234
struct sk_buff * tx_skb[EC_TX_RING_SIZE]
transmit skb ring
Definition: device.h:81
u64 tx_count
Number of frames sent.
Definition: master.h:149
const unsigned int rate_intervals[]
List of intervals for statistics [s].
Definition: master.c:103
void ecdev_close(ec_device_t *device)
Makes the master leave IDLE phase and closes the network device.
Definition: device.c:597
ec_pollfunc_t poll
pointer to the device&#39;s poll function
Definition: device.h:77
void ec_debug_clear(ec_debug_t *dbg)
Debug interface destructor.
Definition: debug.c:103
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
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:321
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:60
int ecdev_open(ec_device_t *device)
Opens the network device and makes the master enter IDLE phase.
Definition: device.c:559
struct module * module
pointer to the device&#39;s owning module
Definition: device.h:78
void ec_device_clear(ec_device_t *device)
Destructor.
Definition: device.c:159
int ec_device_open(ec_device_t *device)
Opens the EtherCAT device.
Definition: device.c:239
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: device.h:103
void ec_device_update_stats(ec_device_t *device)
Update device statistics.
Definition: device.c:481
uint8_t link_state
device link state
Definition: device.h:80
u64 rx_count
Number of frames received.
Definition: device.h:94
u64 last_tx_bytes
Number of bytes sent of last statistics cycle.
Definition: device.h:98
int ec_master_enter_idle_phase(ec_master_t *master)
Transition function from ORPHANED to IDLE phase.
Definition: master.c:643
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: device.h:106
EtherCAT master structure.
void ec_debug_unregister(ec_debug_t *dbg)
Unregister debug interface.
Definition: debug.c:144
void ec_device_send(ec_device_t *device, size_t size)
Sends the content of the transmit socket buffer.
Definition: device.c:320
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:100
#define EC_TX_RING_SIZE
Size of the transmit ring.
Definition: device.h:43
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:208
u64 last_rx_count
Number of frames received of last statistics cycle.
Definition: device.h:95
ec_master_phase_t phase
Master phase.
Definition: master.h:212
void(* ec_pollfunc_t)(struct net_device *)
Device poll function type.
Definition: ecdev.h:49
struct semaphore device_sem
Device semaphore.
Definition: master.h:207
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: device.h:111
EtherCAT device.
Definition: device.h:73
unsigned int tx_ring_index
last ring entry used to transmit
Definition: device.h:82
unsigned int debug_level
Master debug level.
Definition: master.h:275
void ec_master_leave_idle_phase(ec_master_t *master)
Transition function from IDLE to ORPHANED phase.
Definition: master.c:676
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: device.h:109
Main device.
Definition: globals.h:199
int ec_device_init(ec_device_t *device, ec_master_t *master)
Constructor.
Definition: device.c:60
#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
u64 rx_bytes
Number of bytes received.
Definition: device.h:99
u64 tx_count
Number of frames sent.
Definition: device.h:92
uint8_t ecdev_get_link(const ec_device_t *device)
Reads the link state.
Definition: device.c:691
#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
uint8_t * ec_device_tx_data(ec_device_t *device)
Returns a pointer to the device&#39;s transmit memory.
Definition: device.c:301
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:344
Idle phase.
Definition: master.h:126
uint8_t open
true, if the net_device has been opened
Definition: device.h:79
u64 tx_errors
Number of transmit errors.
Definition: device.h:102
ssize_t ec_mac_print(const uint8_t *, char *)
Print a MAC address to a buffer.
Definition: module.c:245
u64 last_rx_bytes
Number of bytes received of last statistics cycle.
Definition: device.h:100
u64 tx_bytes
Number of bytes sent.
Definition: master.h:154
void ecdev_receive(ec_device_t *device, const void *data, size_t size)
Accepts a received frame.
Definition: device.c:621
int ec_device_close(ec_device_t *device)
Stops the EtherCAT device.
Definition: device.c:272
u64 rx_count
Number of frames received.
Definition: master.h:151
void ecdev_set_link(ec_device_t *device, uint8_t state)
Sets a new link state.
Definition: device.c:665
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
void ec_device_detach(ec_device_t *device)
Disconnect from net_device.
Definition: device.c:210
EtherCAT device structure.
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:76
void ec_device_poll(ec_device_t *device)
Calls the poll function of the assigned net_device.
Definition: device.c:463
unsigned int index
Index.
Definition: master.h:188
Backup device.
Definition: globals.h:200
void ecdev_withdraw(ec_device_t *device)
Withdraws an EtherCAT device from the master.
Definition: device.c:528
u64 rx_bytes
Number of bytes received.
Definition: master.h:156
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition: master.h:62
EtherCAT master.
Definition: master.h:187
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:1139
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:200
u64 tx_bytes
Number of bytes sent.
Definition: device.h:97
void ec_device_clear_stats(ec_device_t *device)
Clears the frame statistics.
Definition: device.c:359
#define EC_MAX_DATA_SIZE
Resulting maximum data size of a single datagram in a frame.
Definition: globals.h:79