IgH EtherCAT Master  1.5.2
device.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/module.h>
38 #include <linux/skbuff.h>
39 #include <linux/if_ether.h>
40 #include <linux/netdevice.h>
41 #include <linux/jiffies.h>
42 
43 #include "device.h"
44 #include "master.h"
45 
46 #ifdef EC_DEBUG_RING
47 #define timersub(a, b, result) \
48  do { \
49  (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
50  (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
51  if ((result)->tv_usec < 0) { \
52  --(result)->tv_sec; \
53  (result)->tv_usec += 1000000; \
54  } \
55  } while (0)
56 #endif
57 
58 /*****************************************************************************/
59 
65  ec_device_t *device,
66  ec_master_t *master
67  )
68 {
69  int ret;
70  unsigned int i;
71  struct ethhdr *eth;
72 #ifdef EC_DEBUG_IF
73  char ifname[10];
74  char mb = 'x';
75 #endif
76 
77  device->master = master;
78  device->dev = NULL;
79  device->poll = NULL;
80  device->module = NULL;
81  device->open = 0;
82  device->link_state = 0;
83  for (i = 0; i < EC_TX_RING_SIZE; i++) {
84  device->tx_skb[i] = NULL;
85  }
86  device->tx_ring_index = 0;
87 #ifdef EC_HAVE_CYCLES
88  device->cycles_poll = 0;
89 #endif
90 #ifdef EC_DEBUG_RING
91  device->timeval_poll.tv_sec = 0;
92  device->timeval_poll.tv_usec = 0;
93 #endif
94  device->jiffies_poll = 0;
95 
96  ec_device_clear_stats(device);
97 
98 #ifdef EC_DEBUG_RING
99  for (i = 0; i < EC_DEBUG_RING_SIZE; i++) {
100  ec_debug_frame_t *df = &device->debug_frames[i];
101  df->dir = TX;
102  df->t.tv_sec = 0;
103  df->t.tv_usec = 0;
104  memset(df->data, 0, EC_MAX_DATA_SIZE);
105  df->data_size = 0;
106  }
107 #endif
108 #ifdef EC_DEBUG_RING
109  device->debug_frame_index = 0;
110  device->debug_frame_count = 0;
111 #endif
112 
113 #ifdef EC_DEBUG_IF
114  if (device == &master->devices[EC_DEVICE_MAIN]) {
115  mb = 'm';
116  }
117  else {
118  mb = 'b';
119  }
120 
121  sprintf(ifname, "ecdbg%c%u", mb, master->index);
122 
123  ret = ec_debug_init(&device->dbg, device, ifname);
124  if (ret < 0) {
125  EC_MASTER_ERR(master, "Failed to init debug device!\n");
126  goto out_return;
127  }
128 #endif
129 
130  for (i = 0; i < EC_TX_RING_SIZE; i++) {
131  if (!(device->tx_skb[i] = dev_alloc_skb(ETH_FRAME_LEN))) {
132  EC_MASTER_ERR(master, "Error allocating device socket buffer!\n");
133  ret = -ENOMEM;
134  goto out_tx_ring;
135  }
136 
137  // add Ethernet-II-header
138  skb_reserve(device->tx_skb[i], ETH_HLEN);
139  eth = (struct ethhdr *) skb_push(device->tx_skb[i], ETH_HLEN);
140  eth->h_proto = htons(0x88A4);
141  memset(eth->h_dest, 0xFF, ETH_ALEN);
142  }
143 
144  return 0;
145 
146 out_tx_ring:
147  for (i = 0; i < EC_TX_RING_SIZE; i++) {
148  if (device->tx_skb[i]) {
149  dev_kfree_skb(device->tx_skb[i]);
150  }
151  }
152 #ifdef EC_DEBUG_IF
153  ec_debug_clear(&device->dbg);
154 out_return:
155 #endif
156  return ret;
157 }
158 
159 /*****************************************************************************/
160 
164  ec_device_t *device
165  )
166 {
167  unsigned int i;
168 
169  if (device->open) {
170  ec_device_close(device);
171  }
172  for (i = 0; i < EC_TX_RING_SIZE; i++)
173  dev_kfree_skb(device->tx_skb[i]);
174 #ifdef EC_DEBUG_IF
175  ec_debug_clear(&device->dbg);
176 #endif
177 }
178 
179 /*****************************************************************************/
180 
184  ec_device_t *device,
185  struct net_device *net_dev,
186  ec_pollfunc_t poll,
187  struct module *module
188  )
189 {
190  unsigned int i;
191  struct ethhdr *eth;
192 
193  ec_device_detach(device); // resets fields
194 
195  device->dev = net_dev;
196  device->poll = poll;
197  device->module = module;
198 
199  for (i = 0; i < EC_TX_RING_SIZE; i++) {
200  device->tx_skb[i]->dev = net_dev;
201  eth = (struct ethhdr *) (device->tx_skb[i]->data);
202  memcpy(eth->h_source, net_dev->dev_addr, ETH_ALEN);
203  }
204 
205 #ifdef EC_DEBUG_IF
206  ec_debug_register(&device->dbg, net_dev);
207 #endif
208 }
209 
210 /*****************************************************************************/
211 
215  ec_device_t *device
216  )
217 {
218  unsigned int i;
219 
220 #ifdef EC_DEBUG_IF
221  ec_debug_unregister(&device->dbg);
222 #endif
223 
224  device->dev = NULL;
225  device->poll = NULL;
226  device->module = NULL;
227  device->open = 0;
228  device->link_state = 0; // down
229 
230  ec_device_clear_stats(device);
231 
232  for (i = 0; i < EC_TX_RING_SIZE; i++) {
233  device->tx_skb[i]->dev = NULL;
234  }
235 }
236 
237 /*****************************************************************************/
238 
244  ec_device_t *device
245  )
246 {
247  int ret;
248 
249  if (!device->dev) {
250  EC_MASTER_ERR(device->master, "No net_device to open!\n");
251  return -ENODEV;
252  }
253 
254  if (device->open) {
255  EC_MASTER_WARN(device->master, "Device already opened!\n");
256  return 0;
257  }
258 
259  device->link_state = 0;
260 
261  ec_device_clear_stats(device);
262 
263 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
264  ret = device->dev->netdev_ops->ndo_open(device->dev);
265 #else
266  ret = device->dev->open(device->dev);
267 #endif
268  if (!ret)
269  device->open = 1;
270 
271  return ret;
272 }
273 
274 /*****************************************************************************/
275 
281  ec_device_t *device
282  )
283 {
284  int ret;
285 
286  if (!device->dev) {
287  EC_MASTER_ERR(device->master, "No device to close!\n");
288  return -ENODEV;
289  }
290 
291  if (!device->open) {
292  EC_MASTER_WARN(device->master, "Device already closed!\n");
293  return 0;
294  }
295 
296 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
297  ret = device->dev->netdev_ops->ndo_stop(device->dev);
298 #else
299  ret = device->dev->stop(device->dev);
300 #endif
301  if (!ret)
302  device->open = 0;
303 
304  return ret;
305 }
306 
307 /*****************************************************************************/
308 
312 static void pcap_record(
313  ec_device_t *device,
314  const void *data,
315  size_t size
316  )
317 {
318  // check there's enough room to copy frame to pcap mem
319  if (unlikely(device->master->pcap_data)) {
320  // get current data pointer
321  void *curr_data = device->master->pcap_curr_data;
322  long available = pcap_size - (curr_data - device->master->pcap_data);
323  long reqd = size + sizeof(pcaprec_hdr_t);
324  if (unlikely(reqd <= available)) {
325  pcaprec_hdr_t *pcaphdr;
326  struct timeval t;
327 
328  // update curr data pointer
329  device->master->pcap_curr_data = curr_data + reqd;
330 
331  // fill in pcap frame header info
332  pcaphdr = curr_data;
333 #ifdef EC_RTDM
334  jiffies_to_timeval(device->jiffies_poll, &t);
335 #else
336  t = device->timeval_poll;
337 #endif
338  pcaphdr->ts_sec = t.tv_sec;
339  pcaphdr->ts_usec = t.tv_usec;
340  pcaphdr->incl_len = size;
341  pcaphdr->orig_len = size;
342  curr_data += sizeof(pcaprec_hdr_t);
343 
344  // copy frame
345  memcpy(curr_data, data, size);
346  }
347  }
348 }
349 
350 /*****************************************************************************/
351 
357  ec_device_t *device
358  )
359 {
360  /* cycle through socket buffers, because otherwise there is a race
361  * condition, if multiple frames are sent and the DMA is not scheduled in
362  * between. */
363  device->tx_ring_index++;
364  device->tx_ring_index %= EC_TX_RING_SIZE;
365  return device->tx_skb[device->tx_ring_index]->data + ETH_HLEN;
366 }
367 
368 /*****************************************************************************/
369 
376  ec_device_t *device,
377  size_t size
378  )
379 {
380  struct sk_buff *skb = device->tx_skb[device->tx_ring_index];
381 
382  // set the right length for the data
383  skb->len = ETH_HLEN + size;
384 
385  if (unlikely(device->master->debug_level > 1)) {
386  EC_MASTER_DBG(device->master, 2, "Sending frame:\n");
387  ec_print_data(skb->data, ETH_HLEN + size);
388  }
389 
390  // start sending
391 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
392  if (device->dev->netdev_ops->ndo_start_xmit(skb, device->dev) ==
393  NETDEV_TX_OK)
394 #else
395  if (device->dev->hard_start_xmit(skb, device->dev) == NETDEV_TX_OK)
396 #endif
397  {
398  device->tx_count++;
399  device->master->device_stats.tx_count++;
400  device->tx_bytes += ETH_HLEN + size;
401  device->master->device_stats.tx_bytes += ETH_HLEN + size;
402  pcap_record(device, skb->data, ETH_HLEN + size);
403 #ifdef EC_DEBUG_IF
404  ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size);
405 #endif
406 #ifdef EC_DEBUG_RING
407  ec_device_debug_ring_append(
408  device, TX, skb->data + ETH_HLEN, size);
409 #endif
410  } else {
411  device->tx_errors++;
412  }
413 }
414 
415 /*****************************************************************************/
416 
420  ec_device_t *device
421  )
422 {
423  unsigned int i;
424 
425  // zero frame statistics
426  device->tx_count = 0;
427  device->last_tx_count = 0;
428  device->rx_count = 0;
429  device->last_rx_count = 0;
430  device->tx_bytes = 0;
431  device->last_tx_bytes = 0;
432  device->rx_bytes = 0;
433  device->last_rx_bytes = 0;
434  device->tx_errors = 0;
435 
436  for (i = 0; i < EC_RATE_COUNT; i++) {
437  device->tx_frame_rates[i] = 0;
438  device->rx_frame_rates[i] = 0;
439  device->tx_byte_rates[i] = 0;
440  device->rx_byte_rates[i] = 0;
441  }
442 }
443 
444 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
445 
446 static void do_gettimeofday(struct timeval *tv)
447 {
448  struct timespec64 ts;
449 
450  ktime_get_ts64(&ts);
451  tv->tv_sec = ts.tv_sec;
452  tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
453 }
454 
455 #endif
456 
457 /*****************************************************************************/
458 
459 #ifdef EC_DEBUG_RING
460 
462 void ec_device_debug_ring_append(
463  ec_device_t *device,
464  ec_debug_frame_dir_t dir,
465  const void *data,
466  size_t size
467  )
468 {
469  ec_debug_frame_t *df = &device->debug_frames[device->debug_frame_index];
470 
471  df->dir = dir;
472  if (dir == TX) {
473  do_gettimeofday(&df->t);
474  }
475  else {
476  df->t = device->timeval_poll;
477  }
478  memcpy(df->data, data, size);
479  df->data_size = size;
480 
481  device->debug_frame_index++;
482  device->debug_frame_index %= EC_DEBUG_RING_SIZE;
483  if (unlikely(device->debug_frame_count < EC_DEBUG_RING_SIZE))
484  device->debug_frame_count++;
485 }
486 
487 /*****************************************************************************/
488 
491 void ec_device_debug_ring_print(
492  const ec_device_t *device
493  )
494 {
495  int i;
496  unsigned int ring_index;
497  const ec_debug_frame_t *df;
498  struct timeval t0, diff;
499 
500  // calculate index of the newest frame in the ring to get its time
501  ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE - 1)
502  % EC_DEBUG_RING_SIZE;
503  t0 = device->debug_frames[ring_index].t;
504 
505  EC_MASTER_DBG(device->master, 1, "Debug ring %u:\n", ring_index);
506 
507  // calculate index of the oldest frame in the ring
508  ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE
509  - device->debug_frame_count) % EC_DEBUG_RING_SIZE;
510 
511  for (i = 0; i < device->debug_frame_count; i++) {
512  df = &device->debug_frames[ring_index];
513  timersub(&t0, &df->t, &diff);
514 
515  EC_MASTER_DBG(device->master, 1, "Frame %u, dt=%u.%06u s, %s:\n",
516  i + 1 - device->debug_frame_count,
517  (unsigned int) diff.tv_sec,
518  (unsigned int) diff.tv_usec,
519  (df->dir == TX) ? "TX" : "RX");
520  ec_print_data(df->data, df->data_size);
521 
522  ring_index++;
523  ring_index %= EC_DEBUG_RING_SIZE;
524  }
525 }
526 #endif
527 
528 /*****************************************************************************/
529 
537  ec_device_t *device
538  )
539 {
540 #ifdef EC_HAVE_CYCLES
541  device->cycles_poll = get_cycles();
542 #endif
543  device->jiffies_poll = jiffies;
544 #ifdef EC_DEBUG_RING
545  do_gettimeofday(&device->timeval_poll);
546 #elif !defined(EC_RTDM)
547  if (pcap_size)
548  do_gettimeofday(&device->timeval_poll);
549 #endif
550  device->poll(device->dev);
551 }
552 
553 /*****************************************************************************/
554 
558  ec_device_t *device
559  )
560 {
561  unsigned int i;
562 
563  s32 tx_frame_rate = (device->tx_count - device->last_tx_count) * 1000;
564  s32 rx_frame_rate = (device->rx_count - device->last_rx_count) * 1000;
565  s32 tx_byte_rate = (device->tx_bytes - device->last_tx_bytes);
566  s32 rx_byte_rate = (device->rx_bytes - device->last_rx_bytes);
567 
568  /* Low-pass filter:
569  * Y_n = y_(n - 1) + T / tau * (x - y_(n - 1)) | T = 1
570  * -> Y_n += (x - y_(n - 1)) / tau
571  */
572  for (i = 0; i < EC_RATE_COUNT; i++) {
573  s32 n = rate_intervals[i];
574  device->tx_frame_rates[i] +=
575  (tx_frame_rate - device->tx_frame_rates[i]) / n;
576  device->rx_frame_rates[i] +=
577  (rx_frame_rate - device->rx_frame_rates[i]) / n;
578  device->tx_byte_rates[i] +=
579  (tx_byte_rate - device->tx_byte_rates[i]) / n;
580  device->rx_byte_rates[i] +=
581  (rx_byte_rate - device->rx_byte_rates[i]) / n;
582  }
583 
584  device->last_tx_count = device->tx_count;
585  device->last_rx_count = device->rx_count;
586  device->last_tx_bytes = device->tx_bytes;
587  device->last_rx_bytes = device->rx_bytes;
588 }
589 
590 /******************************************************************************
591  * Device interface
592  *****************************************************************************/
593 
605 {
606  ec_master_t *master = device->master;
607  char dev_str[20], mac_str[20];
608 
609  ec_mac_print(device->dev->dev_addr, mac_str);
610 
611  if (device == &master->devices[EC_DEVICE_MAIN]) {
612  sprintf(dev_str, "main");
613  } else if (device == &master->devices[EC_DEVICE_BACKUP]) {
614  sprintf(dev_str, "backup");
615  } else {
616  EC_MASTER_WARN(master, "%s() called with unknown device %s!\n",
617  __func__, mac_str);
618  sprintf(dev_str, "UNKNOWN");
619  }
620 
621  EC_MASTER_INFO(master, "Releasing %s device %s.\n", dev_str, mac_str);
622 
623  ec_lock_down(&master->device_sem);
624  ec_device_detach(device);
625  ec_lock_up(&master->device_sem);
626 }
627 
628 /*****************************************************************************/
629 
635 int ecdev_open(ec_device_t *device )
636 {
637  int ret;
638  ec_master_t *master = device->master;
639  unsigned int all_open = 1, dev_idx;
640 
641  ret = ec_device_open(device);
642  if (ret) {
643  EC_MASTER_ERR(master, "Failed to open device!\n");
644  return ret;
645  }
646 
647  for (dev_idx = EC_DEVICE_MAIN;
648  dev_idx < ec_master_num_devices(device->master); dev_idx++) {
649  if (!master->devices[dev_idx].open) {
650  all_open = 0;
651  break;
652  }
653  }
654 
655  if (all_open) {
656  ret = ec_master_enter_idle_phase(device->master);
657  if (ret) {
658  EC_MASTER_ERR(device->master, "Failed to enter IDLE phase!\n");
659  return ret;
660  }
661  }
662 
663  return 0;
664 }
665 
666 /*****************************************************************************/
667 
673 void ecdev_close(ec_device_t *device )
674 {
675  ec_master_t *master = device->master;
676 
677  if (master->phase == EC_IDLE) {
679  }
680 
681  if (ec_device_close(device)) {
682  EC_MASTER_WARN(master, "Failed to close device!\n");
683  }
684 }
685 
686 /*****************************************************************************/
687 
698  ec_device_t *device,
699  const void *data,
700  size_t size
701  )
702 {
703  const void *ec_data = data + ETH_HLEN;
704  size_t ec_size = size - ETH_HLEN;
705 
706  if (unlikely(!data)) {
707  EC_MASTER_WARN(device->master, "%s() called with NULL data.\n",
708  __func__);
709  return;
710  }
711 
712  device->rx_count++;
713  device->master->device_stats.rx_count++;
714  device->rx_bytes += size;
715  device->master->device_stats.rx_bytes += size;
716 
717  if (unlikely(device->master->debug_level > 1)) {
718  EC_MASTER_DBG(device->master, 2, "Received frame:\n");
719  ec_print_data(data, size);
720  }
721 
722  pcap_record(device, data, size);
723 #ifdef EC_DEBUG_IF
724  ec_debug_send(&device->dbg, data, size);
725 #endif
726 #ifdef EC_DEBUG_RING
727  ec_device_debug_ring_append(device, RX, ec_data, ec_size);
728 #endif
729 
730  ec_master_receive_datagrams(device->master, device, ec_data, ec_size);
731 }
732 
733 /*****************************************************************************/
734 
743  ec_device_t *device,
744  uint8_t state
745  )
746 {
747  if (unlikely(!device)) {
748  EC_WARN("ecdev_set_link() called with null device!\n");
749  return;
750  }
751 
752  if (likely(state != device->link_state)) {
753  device->link_state = state;
754  EC_MASTER_INFO(device->master,
755  "Link state of %s changed to %s.\n",
756  device->dev->name, (state ? "UP" : "DOWN"));
757  }
758 }
759 
760 /*****************************************************************************/
761 
769  const ec_device_t *device
770  )
771 {
772  if (unlikely(!device)) {
773  EC_WARN("ecdev_get_link() called with null device!\n");
774  return 0;
775  }
776 
777  return device->link_state;
778 }
779 
780 /*****************************************************************************/
781 
784 EXPORT_SYMBOL(ecdev_withdraw);
785 EXPORT_SYMBOL(ecdev_open);
786 EXPORT_SYMBOL(ecdev_close);
787 EXPORT_SYMBOL(ecdev_receive);
788 EXPORT_SYMBOL(ecdev_get_link);
789 EXPORT_SYMBOL(ecdev_set_link);
790 
793 /*****************************************************************************/
#define EC_WARN(fmt, args...)
Convenience macro for printing EtherCAT-specific warnings to syslog.
Definition: globals.h:272
struct sk_buff * tx_skb[EC_TX_RING_SIZE]
transmit skb ring
Definition: device.h:98
void * pcap_curr_data
pcap debug output current memory pointer
Definition: master.h:314
u64 tx_count
Number of frames sent.
Definition: master.h:164
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:673
ec_pollfunc_t poll
pointer to the device&#39;s poll function
Definition: device.h:94
void ec_debug_clear(ec_debug_t *dbg)
Debug interface destructor.
Definition: debug.c:119
unsigned long jiffies_poll
jiffies of last poll
Definition: device.h:106
void * pcap_data
pcap debug output memory pointer
Definition: master.h:313
u64 last_tx_count
Number of frames sent of last statistics cycle.
Definition: device.h:110
pcap packet header
Definition: device.h:163
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:359
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:71
int ecdev_open(ec_device_t *device)
Opens the network device and makes the master enter IDLE phase.
Definition: device.c:635
struct module * module
pointer to the device&#39;s owning module
Definition: device.h:95
void ec_device_clear(ec_device_t *device)
Destructor.
Definition: device.c:163
int ec_device_open(ec_device_t *device)
Opens the EtherCAT device.
Definition: device.c:243
static void pcap_record(ec_device_t *device, const void *data, size_t size)
Records a packet in the master&#39;s pcap buffer, if there is room.
Definition: device.c:312
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: device.h:120
void ec_device_update_stats(ec_device_t *device)
Update device statistics.
Definition: device.c:557
uint8_t link_state
device link state
Definition: device.h:97
u64 rx_count
Number of frames received.
Definition: device.h:111
u64 last_tx_bytes
Number of bytes sent of last statistics cycle.
Definition: device.h:115
int ec_master_enter_idle_phase(ec_master_t *master)
Transition function from ORPHANED to IDLE phase.
Definition: master.c:764
size_t ec_mac_print(const uint8_t *, char *)
Print a MAC address to a buffer.
Definition: module.c:256
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: device.h:123
EtherCAT master structure.
void ec_debug_unregister(ec_debug_t *dbg)
Unregister debug interface.
Definition: debug.c:156
void ec_device_send(ec_device_t *device, size_t size)
Sends the content of the transmit socket buffer.
Definition: device.c:375
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:106
ec_lock_t device_sem
Device semaphore.
Definition: master.h:226
#define EC_TX_RING_SIZE
Size of the transmit ring.
Definition: device.h:52
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:227
u64 last_rx_count
Number of frames received of last statistics cycle.
Definition: device.h:112
ec_master_phase_t phase
Master phase.
Definition: master.h:231
void(* ec_pollfunc_t)(struct net_device *)
Device poll function type.
Definition: ecdev.h:57
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: device.h:128
EtherCAT device.
Definition: device.h:90
unsigned int tx_ring_index
last ring entry used to transmit
Definition: device.h:99
unsigned int debug_level
Master debug level.
Definition: master.h:310
void ec_master_leave_idle_phase(ec_master_t *master)
Transition function from IDLE to ORPHANED phase.
Definition: master.c:819
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: device.h:126
Main device.
Definition: globals.h:237
int ec_device_init(ec_device_t *device, ec_master_t *master)
Constructor.
Definition: device.c:64
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:92
ec_master_t * master
EtherCAT master.
Definition: device.h:92
Definition: device.h:59
u64 rx_bytes
Number of bytes received.
Definition: device.h:116
u64 tx_count
Number of frames sent.
Definition: device.h:109
uint8_t ecdev_get_link(const ec_device_t *device)
Reads the link state.
Definition: device.c:768
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:80
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
void ec_debug_register(ec_debug_t *dbg, const struct net_device *net_dev)
Register debug interface.
Definition: debug.c:131
int ec_debug_init(ec_debug_t *dbg, ec_device_t *device, const char *name)
Debug interface constructor.
Definition: debug.c:74
uint8_t * ec_device_tx_data(ec_device_t *device)
Returns a pointer to the device&#39;s transmit memory.
Definition: device.c:356
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:355
Idle phase.
Definition: master.h:141
uint8_t open
true, if the net_device has been opened
Definition: device.h:96
u64 tx_errors
Number of transmit errors.
Definition: device.h:119
u64 last_rx_bytes
Number of bytes received of last statistics cycle.
Definition: device.h:117
u64 tx_bytes
Number of bytes sent.
Definition: master.h:169
void ecdev_receive(ec_device_t *device, const void *data, size_t size)
Accepts a received frame.
Definition: device.c:697
int ec_device_close(ec_device_t *device)
Stops the EtherCAT device.
Definition: device.c:280
u64 rx_count
Number of frames received.
Definition: master.h:166
void ecdev_set_link(ec_device_t *device, uint8_t state)
Sets a new link state.
Definition: device.c:742
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:183
void ec_device_detach(ec_device_t *device)
Disconnect from net_device.
Definition: device.c:214
EtherCAT device structure.
unsigned long pcap_size
Pcap buffer size in bytes.
Definition: module.c:67
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:93
void ec_device_poll(ec_device_t *device)
Calls the poll function of the assigned net_device.
Definition: device.c:536
unsigned int index
Index.
Definition: master.h:203
Backup device.
Definition: globals.h:238
void ecdev_withdraw(ec_device_t *device)
Withdraws an EtherCAT device from the master.
Definition: device.c:604
u64 rx_bytes
Number of bytes received.
Definition: master.h:171
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition: master.h:68
EtherCAT master.
Definition: master.h:202
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:1318
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:219
u64 tx_bytes
Number of bytes sent.
Definition: device.h:114
void ec_device_clear_stats(ec_device_t *device)
Clears the frame statistics.
Definition: device.c:419
#define EC_MAX_DATA_SIZE
Resulting maximum data size of a single datagram in a frame.
Definition: globals.h:95