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