IgH EtherCAT Master  1.5.2
ethernet.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/version.h>
38 #include <linux/netdevice.h>
39 #include <linux/etherdevice.h>
40 
41 #include "globals.h"
42 #include "master.h"
43 #include "slave.h"
44 #include "mailbox.h"
45 #include "ethernet.h"
46 
47 /*****************************************************************************/
48 
56 #define EOE_DEBUG_LEVEL 1
57 
60 #define EC_EOE_TX_RING_SIZE 100
61 
64 #define EC_EOE_TRIES 100
65 
66 /*****************************************************************************/
67 
68 void ec_eoe_flush(ec_eoe_t *);
69 static unsigned int eoe_tx_unused_frames(ec_eoe_t *);
70 
71 // state functions
78 
79 // net_device functions
80 int ec_eoedev_open(struct net_device *);
81 int ec_eoedev_stop(struct net_device *);
82 int ec_eoedev_tx(struct sk_buff *, struct net_device *);
83 struct net_device_stats *ec_eoedev_stats(struct net_device *);
84 static int ec_eoedev_set_mac(struct net_device *netdev, void *p);
85 
86 /*****************************************************************************/
87 
88 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
89 
91 static const struct net_device_ops ec_eoedev_ops = {
92  .ndo_open = ec_eoedev_open,
93  .ndo_stop = ec_eoedev_stop,
94  .ndo_start_xmit = ec_eoedev_tx,
95  .ndo_get_stats = ec_eoedev_stats,
96  .ndo_set_mac_address = ec_eoedev_set_mac,
97 };
98 #endif
99 
100 /*****************************************************************************/
101 
109 static int
110 ec_eoedev_set_mac(struct net_device *netdev, void *p)
111 {
112  struct sockaddr *addr = p;
113 
114  if (!is_valid_ether_addr(addr->sa_data)) {
115  return -EADDRNOTAVAIL;
116  }
117 
118  memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
119 
120  return 0;
121 }
122 
123 /*****************************************************************************/
124 
132 int ec_eoe_parse(const char *eoe, int *master_idx,
133  uint16_t *alias, uint16_t *posn)
134 {
135  unsigned int value;
136  const char *orig = eoe;
137  char *rem;
138 
139  if (!strlen(eoe)) {
140  EC_ERR("EOE interface may not be empty.\n");
141  return -EINVAL;
142  }
143 
144  // must start with "eoe"
145  if (strncmp(eoe, "eoe", 3) != 0) {
146  EC_ERR("Invalid EOE interface \"%s\".\n", orig);
147  return -EINVAL;
148  }
149  eoe += 3;
150 
151  // get master index, this does not check if the master index
152  // is valid beyond checking that it is not negative
153  value = simple_strtoul(eoe, &rem, 10);
154  if (value < 0) {
155  EC_ERR("Invalid EOE interface \"%s\", master index: %d\n", orig, value);
156  return -EINVAL;
157  }
158  *master_idx = value;
159  eoe = rem;
160 
161  // get alias or position specifier
162  if (eoe[0] == 'a') {
163  eoe++;
164  value = simple_strtoul(eoe, &rem, 10);
165  if ((value <= 0) || (value >= 0xFFFF)) {
166  EC_ERR("Invalid EOE interface \"%s\", invalid alias: %d\n",
167  orig, value);
168  return -EINVAL;
169  }
170  *alias = value;
171  *posn = 0;
172  } else if (eoe[0] == 's') {
173  eoe++;
174  value = simple_strtoul(eoe, &rem, 10);
175  if ((value < 0) || (value >= 0xFFFF)) {
176  EC_ERR("Invalid EOE interface \"%s\", invalid ring position: %d\n",
177  orig, value);
178  return -EINVAL;
179  }
180  *alias = 0;
181  *posn = value;
182  } else {
183  EC_ERR("Invalid EOE interface \"%s\", invalid alias/position specifier: %c\n",
184  orig, eoe[0]);
185  return -EINVAL;
186  }
187 
188  // check no remainder
189  if (rem[0] != '\0') {
190  EC_ERR("Invalid EOE interface \"%s\", unexpected end characters: %s\n",
191  orig, rem);
192  return -EINVAL;
193  }
194 
195  return 0;
196 }
197 
198 /*****************************************************************************/
199 
208  ec_master_t *master,
209  ec_eoe_t *eoe,
210  uint16_t alias,
211  uint16_t ring_position
212  )
213 {
214  ec_eoe_t **priv;
215  int ret = 0;
216  char name[EC_DATAGRAM_NAME_SIZE];
217 
218  struct net_device *dev;
219  unsigned char lo_mac[ETH_ALEN] = {0};
220  unsigned int use_master_mac = 0;
221 
222  eoe->master = master;
223  eoe->slave = NULL;
224  eoe->have_mbox_lock = 0;
225  eoe->auto_created = 0;
226 
227  ec_datagram_init(&eoe->datagram);
228  eoe->queue_datagram = 0;
230  eoe->opened = 0;
231  eoe->rx_skb = NULL;
232  eoe->rx_expected_fragment = 0;
233 
235  eoe->tx_ring_size = sizeof(struct sk_buff *) * eoe->tx_ring_count;
236  eoe->tx_ring = kmalloc(eoe->tx_ring_size, GFP_KERNEL);
237  memset(eoe->tx_ring, 0, eoe->tx_ring_size);
238  eoe->tx_next_to_use = 0;
239  eoe->tx_next_to_clean = 0;
240  eoe->tx_skb = NULL;
241  eoe->tx_queue_active = 0;
242 
243  eoe->tx_frame_number = 0xFF;
244  memset(&eoe->stats, 0, sizeof(struct net_device_stats));
245 
246  eoe->rx_counter = 0;
247  eoe->tx_counter = 0;
248  eoe->rx_rate = 0;
249  eoe->tx_rate = 0;
250  eoe->rate_jiffies = 0;
251  eoe->rx_idle = 1;
252  eoe->tx_idle = 1;
253 
254  /* device name eoe<MASTER>[as]<SLAVE>, because networking scripts don't
255  * like hyphens etc. in interface names. */
256  if (alias) {
257  snprintf(name, EC_DATAGRAM_NAME_SIZE, "eoe%ua%u", master->index, alias);
258  } else {
259  snprintf(name, EC_DATAGRAM_NAME_SIZE, "eoe%us%u", master->index, ring_position);
260  }
261 
262  snprintf(eoe->datagram.name, EC_DATAGRAM_NAME_SIZE, name);
263 
264 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
265  eoe->dev = alloc_netdev(sizeof(ec_eoe_t *), name, NET_NAME_UNKNOWN,
266  ether_setup);
267 #else
268  eoe->dev = alloc_netdev(sizeof(ec_eoe_t *), name, ether_setup);
269 #endif
270  if (!eoe->dev) {
271  EC_MASTER_ERR(master, "Unable to allocate net_device %s"
272  " for EoE handler!\n", name);
273  ret = -ENODEV;
274  goto out_return;
275  }
276 
277  // initialize net_device
278 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
279  eoe->dev->netdev_ops = &ec_eoedev_ops;
280 #else
281  eoe->dev->open = ec_eoedev_open;
282  eoe->dev->stop = ec_eoedev_stop;
283  eoe->dev->hard_start_xmit = ec_eoedev_tx;
284  eoe->dev->get_stats = ec_eoedev_stats;
285 #endif
286 
287  // First check if the MAC address assigned to the master is globally
288  // unique
289  if ((master->devices[EC_DEVICE_MAIN].dev->dev_addr[0] & 0x02) !=
290  0x02) {
291  // The master MAC is unique and the NIC part can be used for the EoE
292  // interface MAC
293  use_master_mac = 1;
294  }
295  else {
296  // The master MAC is not unique, so we check for unique MAC in other
297  // interfaces
298  dev = first_net_device(&init_net);
299  while (dev) {
300  // Check if globally unique MAC address
301  if (dev->addr_len == ETH_ALEN) {
302  if (memcmp(dev->dev_addr, lo_mac, ETH_ALEN) != 0) {
303  if ((dev->dev_addr[0] & 0x02) != 0x02) {
304  // The first globally unique MAC address has been
305  // identified
306  break;
307  }
308  }
309  }
310  dev = next_net_device(dev);
311  }
312  if (eoe->dev->addr_len == ETH_ALEN) {
313  if (dev) {
314  // A unique MAC were identified in one of the other network
315  // interfaces and the NIC part can be used for the EoE
316  // interface MAC.
317  EC_MASTER_INFO(master, "%s MAC address derived from"
318  " NIC part of %s MAC address\n",
319  eoe->dev->name, dev->name);
320  eoe->dev->dev_addr[1] = dev->dev_addr[3];
321  eoe->dev->dev_addr[2] = dev->dev_addr[4];
322  eoe->dev->dev_addr[3] = dev->dev_addr[5];
323  }
324  else {
325  use_master_mac = 1;
326  }
327  }
328  }
329  if (eoe->dev->addr_len == ETH_ALEN) {
330  if (use_master_mac) {
331  EC_MASTER_INFO(master, "%s MAC address derived"
332  " from NIC part of %s MAC address\n",
333  eoe->dev->name,
334  master->devices[EC_DEVICE_MAIN].dev->name);
335  eoe->dev->dev_addr[1] =
336  master->devices[EC_DEVICE_MAIN].dev->dev_addr[3];
337  eoe->dev->dev_addr[2] =
338  master->devices[EC_DEVICE_MAIN].dev->dev_addr[4];
339  eoe->dev->dev_addr[3] =
340  master->devices[EC_DEVICE_MAIN].dev->dev_addr[5];
341  }
342  eoe->dev->dev_addr[0] = 0x02;
343  if (alias) {
344  eoe->dev->dev_addr[4] = (uint8_t)(alias >> 8);
345  eoe->dev->dev_addr[5] = (uint8_t)(alias);
346  } else {
347  eoe->dev->dev_addr[4] = (uint8_t)(ring_position >> 8);
348  eoe->dev->dev_addr[5] = (uint8_t)(ring_position);
349  }
350  }
351 
352  // initialize private data
353  priv = netdev_priv(eoe->dev);
354  *priv = eoe;
355 
356  // connect the net_device to the kernel
357  ret = register_netdev(eoe->dev);
358  if (ret) {
359  EC_MASTER_ERR(master, "Unable to register net_device for %s:"
360  " error %i\n", eoe->dev->name, ret);
361  goto out_free;
362  }
363 
364  // set carrier off status BEFORE open */
365  EC_MASTER_DBG(eoe->master, 1, "%s: carrier off.\n", eoe->dev->name);
366  netif_carrier_off(eoe->dev);
367 
368  return 0;
369 
370  out_free:
371  free_netdev(eoe->dev);
372  eoe->dev = NULL;
373  out_return:
374  return ret;
375 }
376 
377 /*****************************************************************************/
378 
386  ec_eoe_t *eoe,
387  ec_slave_t *slave
388  )
389 {
390  int ret = 0;
391 
392  if ((ret = ec_eoe_init(slave->master, eoe, slave->effective_alias,
393  slave->ring_position)) != 0) {
394  return ret;
395  }
396 
397  // set auto created flag
398  eoe->auto_created = 1;
399 
400  ec_eoe_link_slave(eoe, slave);
401 
402  return ret;
403 }
404 
405 /*****************************************************************************/
406 
413  ec_eoe_t *eoe,
414  ec_slave_t *slave
415  )
416 {
417  eoe->slave = slave;
418 
419  if (eoe->slave) {
420  EC_SLAVE_INFO(slave, "Linked to EoE handler %s\n",
421  eoe->dev->name);
422 
423  // Usually setting the MTU appropriately makes the upper layers
424  // do the frame fragmenting. In some cases this doesn't work
425  // so the MTU is left on the Ethernet standard value and fragmenting
426  // is done "manually".
427 #if 0
428  eoe->dev->mtu = slave->configured_rx_mailbox_size - ETH_HLEN - 10;
429 #endif
430 
431  EC_MASTER_DBG(eoe->master, 1, "%s: carrier on.\n", eoe->dev->name);
432  netif_carrier_on(eoe->dev);
433  } else {
434  EC_MASTER_ERR(eoe->master, "%s : slave not supplied to ec_eoe_link_slave().\n",
435  eoe->dev->name);
436  EC_MASTER_DBG(eoe->master, 1, "%s: carrier off.\n", eoe->dev->name);
437  netif_carrier_off(eoe->dev);
438  }
439 }
440 
441 /*****************************************************************************/
442 
449 {
450 #if EOE_DEBUG_LEVEL >= 1
451  ec_slave_t *slave = eoe->slave;
452 #endif
453 
454  EC_MASTER_DBG(eoe->master, 1, "%s: carrier off.\n", eoe->dev->name);
455  netif_carrier_off(eoe->dev);
456 
457  // empty transmit queue
458  ec_eoe_flush(eoe);
459 
460  if (eoe->tx_skb) {
461  dev_kfree_skb(eoe->tx_skb);
462  eoe->tx_skb = NULL;
463  eoe->stats.tx_errors++;
464  }
465 
466  if (eoe->rx_skb) {
467  dev_kfree_skb(eoe->rx_skb);
468  eoe->rx_skb = NULL;
469  eoe->stats.rx_errors++;
470  }
471 
473 
474  eoe->slave = NULL;
475 
476 #if EOE_DEBUG_LEVEL >= 1
477  if (slave) {
478  EC_MASTER_DBG(eoe->master, 0, "%s slave link cleared.\n", eoe->dev->name);
479  }
480 #endif
481 }
482 
483 /*****************************************************************************/
484 
490 {
491  unregister_netdev(eoe->dev); // possibly calls close callback
492 
493  // empty transmit queue
494  ec_eoe_flush(eoe);
495 
496  if (eoe->tx_skb)
497  dev_kfree_skb(eoe->tx_skb);
498 
499  if (eoe->rx_skb)
500  dev_kfree_skb(eoe->rx_skb);
501 
502  kfree(eoe->tx_ring);
503 
504  free_netdev(eoe->dev);
505 
507 }
508 
509 /*****************************************************************************/
510 
514 {
515  struct sk_buff *skb;
516 
517  if (eoe->have_mbox_lock) {
518  eoe->have_mbox_lock = 0;
520  }
521 
522  while (eoe->tx_next_to_clean != eoe->tx_next_to_use) {
523  skb = eoe->tx_ring[eoe->tx_next_to_clean];
524  dev_kfree_skb(skb);
525  eoe->tx_ring[eoe->tx_next_to_clean] = NULL;
526 
527  eoe->stats.tx_dropped++;
528 
529  if (unlikely(++eoe->tx_next_to_clean == eoe->tx_ring_count)) {
530  eoe->tx_next_to_clean = 0;
531  }
532  }
533 
534  eoe->tx_next_to_use = 0;
535  eoe->tx_next_to_clean = 0;
536 }
537 
538 /*****************************************************************************/
539 
540 unsigned int ec_eoe_tx_queued_frames(const ec_eoe_t *eoe )
541 {
542  unsigned int next_to_use = eoe->tx_next_to_use;
543  unsigned int next_to_clean = eoe->tx_next_to_clean;
544 
545  if (next_to_use >= next_to_clean) {
546  return next_to_use - next_to_clean;
547  } else {
548  return next_to_use + eoe->tx_ring_count - next_to_clean;
549  }
550 }
551 
552 /*****************************************************************************/
553 
554 static unsigned int eoe_tx_unused_frames(ec_eoe_t *eoe )
555 {
556  unsigned int next_to_use = eoe->tx_next_to_use;
557  unsigned int next_to_clean = eoe->tx_next_to_clean;
558 
559  // Note: -1 to avoid tail touching head
560  if (next_to_clean > next_to_use) {
561  return next_to_clean - next_to_use - 1;
562  } else {
563  return next_to_clean + eoe->tx_ring_count - next_to_use - 1;
564  }
565 }
566 
567 /*****************************************************************************/
568 
574 {
575  size_t remaining_size, current_size, complete_offset;
576  unsigned int last_fragment;
577  uint8_t *data;
578 #if EOE_DEBUG_LEVEL >= 3
579  unsigned int i;
580 #endif
581 
582  if (!eoe->slave) {
583  return -ECHILD;
584  }
585 
586  remaining_size = eoe->tx_skb->len - eoe->tx_offset;
587 
588  if (remaining_size <= eoe->slave->configured_tx_mailbox_size - 10) {
589  current_size = remaining_size;
590  last_fragment = 1;
591  } else {
592  current_size =
593  ((eoe->slave->configured_tx_mailbox_size - 10) / 32) * 32;
594  last_fragment = 0;
595  }
596 
597  if (eoe->tx_fragment_number) {
598  complete_offset = eoe->tx_offset / 32;
599  }
600  else {
601  // complete size in 32 bit blocks, rounded up.
602  complete_offset = remaining_size / 32 + 1;
603  }
604 
605 #if EOE_DEBUG_LEVEL >= 2
606  EC_SLAVE_DBG(eoe->slave, 0, "EoE %s TX sending fragment %u%s"
607  " with %zu octets (%zu). %u frames queued.\n",
608  eoe->dev->name, eoe->tx_fragment_number,
609  last_fragment ? "" : "+", current_size, complete_offset,
611 #endif
612 
613 #if EOE_DEBUG_LEVEL >= 3
614  EC_SLAVE_DBG(eoe->slave, 0, "");
615  for (i = 0; i < current_size; i++) {
616  printk(KERN_CONT "%02X ", eoe->tx_skb->data[eoe->tx_offset + i]);
617  if ((i + 1) % 16 == 0) {
618  printk(KERN_CONT "\n");
619  EC_SLAVE_DBG(eoe->slave, 0, "");
620  }
621  }
622  printk(KERN_CONT "\n");
623 #endif
624 
625  data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
626  EC_MBOX_TYPE_EOE, current_size + 4);
627  if (IS_ERR(data)) {
628  return PTR_ERR(data);
629  }
630 
631  EC_WRITE_U8 (data, EC_EOE_TYPE_FRAME_FRAG); // Initiate EoE Tx Request
632  EC_WRITE_U8 (data + 1, last_fragment);
633  EC_WRITE_U16(data + 2, ((eoe->tx_fragment_number & 0x3F) |
634  (complete_offset & 0x3F) << 6 |
635  (eoe->tx_frame_number & 0x0F) << 12));
636 
637  memcpy(data + 4, eoe->tx_skb->data + eoe->tx_offset, current_size);
638  eoe->queue_datagram = 1;
639 
640  eoe->tx_offset += current_size;
641  eoe->tx_fragment_number++;
642  return 0;
643 }
644 
645 /*****************************************************************************/
646 
649 void ec_eoe_run(ec_eoe_t *eoe )
650 {
651  if (!eoe->opened || !eoe->slave || !netif_carrier_ok(eoe->dev)) {
652  return;
653  }
654 
655  // if the datagram was not sent, or is not yet received, skip this cycle
656  if (eoe->queue_datagram || eoe->datagram.state == EC_DATAGRAM_SENT) {
657  return;
658  }
659 
660  // call state function
661  eoe->state(eoe);
662 
663  // update statistics
664  if (jiffies - eoe->rate_jiffies > HZ) {
665  eoe->rx_rate = eoe->rx_counter;
666  eoe->tx_rate = eoe->tx_counter;
667  eoe->rx_counter = 0;
668  eoe->tx_counter = 0;
669  eoe->rate_jiffies = jiffies;
670  }
671 
673 }
674 
675 /*****************************************************************************/
676 
680 {
681  if (eoe->queue_datagram && eoe->slave) {
683  eoe->queue_datagram = 0;
684  }
685 }
686 
687 /*****************************************************************************/
688 
693 int ec_eoe_is_open(const ec_eoe_t *eoe )
694 {
695  return eoe->opened;
696 }
697 
698 /*****************************************************************************/
699 
705 int ec_eoe_is_idle(const ec_eoe_t *eoe )
706 {
707  return eoe->rx_idle && eoe->tx_idle;
708 }
709 
710 /*****************************************************************************/
711 
716 char *ec_eoe_name(const ec_eoe_t *eoe )
717 {
718  return eoe->dev->name;
719 }
720 
721 /******************************************************************************
722  * STATE PROCESSING FUNCTIONS
723  *****************************************************************************/
724 
733 {
734  if (!eoe->slave || eoe->slave->error_flag ||
736  eoe->rx_idle = 1;
737  eoe->tx_idle = 1;
738  return;
739  }
740 
741  // mailbox read check is skipped if a read request is already ongoing
742  if (ec_read_mbox_locked(eoe->slave)) {
744  } else {
745  eoe->have_mbox_lock = 1;
747  eoe->queue_datagram = 1;
749  }
750 }
751 
752 /*****************************************************************************/
753 
760 {
761  if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
762 #if EOE_DEBUG_LEVEL >= 1
763  EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
764  " check datagram for %s.\n", eoe->dev->name);
765  eoe->stats.rx_errors++;
766 #endif
768  eoe->have_mbox_lock = 0;
770  return;
771  }
772 
773  if (!ec_slave_mbox_check(&eoe->datagram)) {
774  eoe->rx_idle = 1;
775  eoe->have_mbox_lock = 0;
777  // check that data is not already received by another read request
778  if (eoe->slave->mbox_eoe_frag_data.payload_size > 0) {
780  eoe->state(eoe);
781  } else {
783  }
784  return;
785  }
786 
787  eoe->rx_idle = 0;
789  eoe->queue_datagram = 1;
791 }
792 
793 /*****************************************************************************/
794 
801 {
802  if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
803  eoe->stats.rx_errors++;
804 #if EOE_DEBUG_LEVEL >= 1
805  EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
806  " fetch datagram for %s.\n", eoe->dev->name);
807 #endif
809  eoe->have_mbox_lock = 0;
811  return;
812  }
813  eoe->have_mbox_lock = 0;
816  eoe->state(eoe);
817 }
818 
819 
820 
821 /*****************************************************************************/
822 
828 {
829  size_t rec_size, data_size;
830  uint8_t *data, eoe_type, last_fragment, time_appended, mbox_prot;
831  uint8_t fragment_offset, fragment_number;
832 #if EOE_DEBUG_LEVEL >= 2
833  uint8_t frame_number;
834 #endif
835  off_t offset;
836 #if EOE_DEBUG_LEVEL >= 3
837  unsigned int i;
838 #endif
839 
840  if (eoe->slave->mbox_eoe_frag_data.payload_size > 0) {
842  } else {
843  // initiate a new mailbox read check if required data is not available
844  if (!ec_read_mbox_locked(eoe->slave)) {
845  eoe->have_mbox_lock = 1;
847  eoe->queue_datagram = 1;
849  }
850  return;
851  }
852 
854  &mbox_prot, &rec_size);
855  if (IS_ERR(data)) {
856  eoe->stats.rx_errors++;
857 #if EOE_DEBUG_LEVEL >= 1
858  EC_SLAVE_WARN(eoe->slave, "Invalid mailbox response for %s.\n",
859  eoe->dev->name);
860 #endif
862  return;
863  }
864 
865  if (mbox_prot != EC_MBOX_TYPE_EOE) { // FIXME mailbox handler necessary
866  eoe->stats.rx_errors++;
867 #if EOE_DEBUG_LEVEL >= 1
868  EC_SLAVE_WARN(eoe->slave, "Other mailbox protocol response for %s.\n",
869  eoe->dev->name);
870 #endif
872  return;
873  }
874 
875  eoe_type = EC_READ_U8(data) & 0x0F;
876 
877  if (eoe_type != EC_EOE_TYPE_FRAME_FRAG) {
878  EC_SLAVE_ERR(eoe->slave, "%s: EoE iface handler received other EoE type"
879  " response (type %x). Dropping.\n", eoe->dev->name, eoe_type);
880  eoe->stats.rx_dropped++;
882  return;
883  }
884 
885  // EoE Fragment Request received
886 
887  last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
888  time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
889  fragment_number = EC_READ_U16(data + 2) & 0x003F;
890  fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
891 #if EOE_DEBUG_LEVEL >= 2
892  frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
893 #endif
894 
895 #if EOE_DEBUG_LEVEL >= 2
896  EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX fragment %u%s, offset %u,"
897  " frame %u%s, %zu octets\n", eoe->dev->name, fragment_number,
898  last_fragment ? "" : "+", fragment_offset, frame_number,
899  time_appended ? ", + timestamp" : "",
900  time_appended ? rec_size - 8 : rec_size - 4);
901 #endif
902 
903 #if EOE_DEBUG_LEVEL >= 3
904  EC_SLAVE_DBG(eoe->slave, 0, "");
905  for (i = 0; i < rec_size - 4; i++) {
906  printk(KERN_CONT "%02X ", data[i + 4]);
907  if ((i + 1) % 16 == 0) {
908  printk(KERN_CONT "\n");
909  EC_SLAVE_DBG(eoe->slave, 0, "");
910  }
911  }
912  printk(KERN_CONT "\n");
913 #endif
914 
915  data_size = time_appended ? rec_size - 8 : rec_size - 4;
916 
917  if (!fragment_number) {
918  if (eoe->rx_skb) {
919  EC_SLAVE_WARN(eoe->slave, "EoE RX freeing old socket buffer.\n");
920  dev_kfree_skb(eoe->rx_skb);
921  }
922 
923  // new socket buffer
924  if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
925  if (printk_ratelimit())
926  EC_SLAVE_WARN(eoe->slave, "EoE RX low on mem,"
927  " frame dropped.\n");
928  eoe->stats.rx_dropped++;
930  return;
931  }
932 
933  eoe->rx_skb_offset = 0;
934  eoe->rx_skb_size = fragment_offset * 32;
935  eoe->rx_expected_fragment = 0;
936  }
937  else {
938  if (!eoe->rx_skb) {
939  eoe->stats.rx_dropped++;
941  return;
942  }
943 
944  offset = fragment_offset * 32;
945  if (offset != eoe->rx_skb_offset ||
946  offset + data_size > eoe->rx_skb_size ||
947  fragment_number != eoe->rx_expected_fragment) {
948  dev_kfree_skb(eoe->rx_skb);
949  eoe->rx_skb = NULL;
950  eoe->stats.rx_errors++;
951 #if EOE_DEBUG_LEVEL >= 1
952  EC_SLAVE_WARN(eoe->slave, "Fragmenting error at %s.\n",
953  eoe->dev->name);
954 #endif
956  return;
957  }
958  }
959 
960  // copy fragment into socket buffer
961  memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
962  eoe->rx_skb_offset += data_size;
963 
964  if (last_fragment) {
965  // update statistics
966  eoe->stats.rx_packets++;
967  eoe->stats.rx_bytes += eoe->rx_skb->len;
968  eoe->rx_counter += eoe->rx_skb->len;
969 
970 #if EOE_DEBUG_LEVEL >= 2
971  EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX frame completed"
972  " with %u octets.\n", eoe->dev->name, eoe->rx_skb->len);
973 #endif
974 
975  // pass socket buffer to network stack
976  eoe->rx_skb->dev = eoe->dev;
977  eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
978  eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
979  if (netif_rx_ni(eoe->rx_skb)) {
980  EC_SLAVE_WARN(eoe->slave, "EoE RX netif_rx failed.\n");
981  }
982  eoe->rx_skb = NULL;
983 
985  }
986  else {
987  eoe->rx_expected_fragment++;
988 #if EOE_DEBUG_LEVEL >= 2
989  EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX expecting fragment %u\n",
990  eoe->dev->name, eoe->rx_expected_fragment);
991 #endif
993  }
994 }
995 
996 /*****************************************************************************/
997 
1006 {
1007 #if EOE_DEBUG_LEVEL >= 2
1008  unsigned int wakeup = 0;
1009 #endif
1010 
1011  if (!eoe->slave || eoe->slave->error_flag ||
1013  eoe->rx_idle = 1;
1014  eoe->tx_idle = 1;
1015  return;
1016  }
1017 
1018  if (eoe->tx_next_to_use == eoe->tx_next_to_clean) {
1019  // check if the queue needs to be restarted
1020  if (!eoe->tx_queue_active) {
1021  eoe->tx_queue_active = 1;
1022  netif_wake_queue(eoe->dev);
1023  }
1024 
1025  eoe->tx_idle = 1;
1026  // no data available.
1027  // start a new receive immediately.
1028  ec_eoe_state_rx_start(eoe);
1029  return;
1030  }
1031 
1032  // get the frame and take it out of the ring
1033  eoe->tx_skb = eoe->tx_ring[eoe->tx_next_to_clean];
1034  eoe->tx_ring[eoe->tx_next_to_clean] = NULL;
1035  if (unlikely(++eoe->tx_next_to_clean == eoe->tx_ring_count)) {
1036  eoe->tx_next_to_clean = 0;
1037  }
1038 
1039  // restart queue?
1040  if (!eoe->tx_queue_active &&
1041  (ec_eoe_tx_queued_frames(eoe) <= eoe->tx_ring_count / 2)) {
1042  eoe->tx_queue_active = 1;
1043  netif_wake_queue(eoe->dev);
1044 #if EOE_DEBUG_LEVEL >= 2
1045  wakeup = 1;
1046 #endif
1047  }
1048 
1049  eoe->tx_idle = 0;
1050 
1051  eoe->tx_frame_number++;
1052  eoe->tx_frame_number %= 16;
1053  eoe->tx_fragment_number = 0;
1054  eoe->tx_offset = 0;
1055 
1056  if (ec_eoe_send(eoe)) {
1057  dev_kfree_skb(eoe->tx_skb);
1058  eoe->tx_skb = NULL;
1059  eoe->stats.tx_errors++;
1061 #if EOE_DEBUG_LEVEL >= 1
1062  EC_SLAVE_WARN(eoe->slave, "Send error at %s.\n", eoe->dev->name);
1063 #endif
1064  return;
1065  }
1066 
1067 #if EOE_DEBUG_LEVEL >= 2
1068  if (wakeup) {
1069  EC_SLAVE_DBG(eoe->slave, 0, "EoE %s waking up TX queue...\n",
1070  eoe->dev->name);
1071  }
1072 #endif
1073 
1074  eoe->tries = EC_EOE_TRIES;
1075  eoe->state = ec_eoe_state_tx_sent;
1076 }
1077 
1078 /*****************************************************************************/
1079 
1086 {
1087  if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
1088  if (eoe->tries) {
1089  eoe->tries--; // try again
1090  eoe->queue_datagram = 1;
1091  } else {
1092 #if EOE_DEBUG_LEVEL >= 1
1093  /* only log every 1000th */
1094  if (eoe->stats.tx_errors++ % 1000 == 0) {
1095  EC_SLAVE_WARN(eoe->slave, "Failed to receive send"
1096  " datagram for %s after %u tries.\n",
1097  eoe->dev->name, EC_EOE_TRIES);
1098  }
1099 #else
1100  eoe->stats.tx_errors++;
1101 #endif
1103  }
1104  return;
1105  }
1106 
1107  if (eoe->datagram.working_counter != 1) {
1108  if (eoe->tries) {
1109  eoe->tries--; // try again
1110  eoe->queue_datagram = 1;
1111  } else {
1112  eoe->stats.tx_errors++;
1113 #if EOE_DEBUG_LEVEL >= 1
1114  EC_SLAVE_WARN(eoe->slave, "No sending response"
1115  " for %s after %u tries.\n",
1116  eoe->dev->name, EC_EOE_TRIES);
1117 #endif
1119  }
1120  return;
1121  }
1122 
1123  // frame completely sent
1124  if (eoe->tx_offset >= eoe->tx_skb->len) {
1125  eoe->stats.tx_packets++;
1126  eoe->stats.tx_bytes += eoe->tx_skb->len;
1127  eoe->tx_counter += eoe->tx_skb->len;
1128  dev_kfree_skb(eoe->tx_skb);
1129  eoe->tx_skb = NULL;
1131  }
1132  else { // send next fragment
1133  if (ec_eoe_send(eoe)) {
1134  dev_kfree_skb(eoe->tx_skb);
1135  eoe->tx_skb = NULL;
1136  eoe->stats.tx_errors++;
1137 #if EOE_DEBUG_LEVEL >= 1
1138  EC_SLAVE_WARN(eoe->slave, "Send error at %s.\n", eoe->dev->name);
1139 #endif
1141  }
1142  }
1143 }
1144 
1145 /******************************************************************************
1146  * NET_DEVICE functions
1147  *****************************************************************************/
1148 
1153 int ec_eoedev_open(struct net_device *dev )
1154 {
1155  ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
1156 
1157  // set carrier to off until we know link status
1158  EC_MASTER_DBG(eoe->master, 1, "%s: carrier off.\n", dev->name);
1159  netif_carrier_off(dev);
1160 
1161  ec_eoe_flush(eoe);
1162  eoe->opened = 1;
1163  eoe->rx_idle = 0;
1164  eoe->tx_idle = 0;
1165  eoe->tx_queue_active = 1;
1166  netif_start_queue(dev);
1167 #if EOE_DEBUG_LEVEL >= 2
1168  EC_MASTER_DBG(eoe->master, 0, "%s opened.\n", dev->name);
1169 #endif
1170 
1171  // update carrier link status
1172  if (eoe->slave) {
1173  EC_MASTER_DBG(eoe->master, 1, "%s: carrier on.\n", dev->name);
1174  netif_carrier_on(dev);
1175  }
1176 
1177  return 0;
1178 }
1179 
1180 /*****************************************************************************/
1181 
1186 int ec_eoedev_stop(struct net_device *dev )
1187 {
1188  ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
1189 
1190  EC_MASTER_DBG(eoe->master, 1, "%s: carrier off.\n", dev->name);
1191  netif_carrier_off(dev);
1192  netif_stop_queue(dev);
1193  eoe->tx_queue_active = 0;
1194  eoe->rx_idle = 1;
1195  eoe->tx_idle = 1;
1196  eoe->opened = 0;
1197  ec_eoe_flush(eoe);
1198 #if EOE_DEBUG_LEVEL >= 2
1199  EC_MASTER_DBG(eoe->master, 0, "%s stopped.\n", dev->name);
1200 #endif
1201  return 0;
1202 }
1203 
1204 /*****************************************************************************/
1205 
1210 int ec_eoedev_tx(struct sk_buff *skb,
1211  struct net_device *dev
1212  )
1213 {
1214  ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
1215 
1216  if (!eoe->slave) {
1217  if (skb) {
1218  dev_kfree_skb(skb);
1219  eoe->stats.tx_dropped++;
1220  }
1221 
1222  return NETDEV_TX_OK;
1223  }
1224 
1225 #if 0
1226  if (skb->len > eoe->slave->configured_tx_mailbox_size - 10) {
1227  EC_SLAVE_WARN(eoe->slave, "EoE TX frame (%u octets)"
1228  " exceeds MTU. dropping.\n", skb->len);
1229  dev_kfree_skb(skb);
1230  eoe->stats.tx_dropped++;
1231  return 0;
1232  }
1233 #endif
1234 
1235  // set the skb in the ring
1236  eoe->tx_ring[eoe->tx_next_to_use] = skb;
1237 
1238  // increment index
1239  if (unlikely(++eoe->tx_next_to_use == eoe->tx_ring_count)) {
1240  eoe->tx_next_to_use = 0;
1241  }
1242 
1243  // stop the queue?
1244  if (eoe_tx_unused_frames(eoe) == 0) {
1245  netif_stop_queue(dev);
1246  eoe->tx_queue_active = 0;
1247  }
1248 
1249 #if EOE_DEBUG_LEVEL >= 2
1250  EC_SLAVE_DBG(eoe->slave, 0, "EoE %s TX queued frame"
1251  " with %u octets (%u frames queued).\n",
1252  eoe->dev->name, skb->len, ec_eoe_tx_queued_frames(eoe));
1253  if (!eoe->tx_queue_active) {
1254  EC_SLAVE_WARN(eoe->slave, "EoE TX queue is now full.\n");
1255  }
1256 #endif
1257 
1258  return 0;
1259 }
1260 
1261 /*****************************************************************************/
1262 
1267 struct net_device_stats *ec_eoedev_stats(
1268  struct net_device *dev
1269  )
1270 {
1271  ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
1272  return &eoe->stats;
1273 }
1274 
1275 /*****************************************************************************/
unsigned int tx_ring_size
Transmit ring size.
Definition: ethernet.h:96
void ec_eoe_queue(ec_eoe_t *eoe)
Queues the datagram, if necessary.
Definition: ethernet.c:679
ec_mbox_data_t mbox_eoe_frag_data
Received mailbox data for EoE, type frame fragment.
Definition: slave.h:288
int ec_eoedev_tx(struct sk_buff *, struct net_device *)
Transmits data via the virtual network device.
Definition: ethernet.c:1210
uint8_t * ec_slave_mbox_prepare_send(const ec_slave_t *slave, ec_datagram_t *datagram, uint8_t type, size_t size)
Prepares a mailbox-send datagram.
Definition: mailbox.c:51
uint16_t ring_position
Ring position.
Definition: slave.h:221
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Definition: globals.h:142
uint32_t tx_counter
octets transmitted during last second
Definition: ethernet.h:104
static const struct net_device_ops ec_eoedev_ops
Device operations for EoE interfaces.
Definition: ethernet.c:91
char * ec_eoe_name(const ec_eoe_t *eoe)
Returns the eoe device name.
Definition: ethernet.c:716
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
Definition: slave.h:248
void ec_eoe_state_rx_fetch(ec_eoe_t *)
State: RX_FETCH.
Definition: ethernet.c:800
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:108
uint8_t tx_fragment_number
number of the fragment
Definition: ethernet.h:102
int ec_eoe_send(ec_eoe_t *eoe)
Sends a frame or the next fragment.
Definition: ethernet.c:573
ec_slave_t * slave
pointer to the corresponding slave
Definition: ethernet.h:75
unsigned int tx_ring_count
Transmit ring count.
Definition: ethernet.h:95
void ec_master_queue_datagram_ext(ec_master_t *master, ec_datagram_t *datagram)
Places a datagram in the non-application datagram queue.
Definition: master.c:1140
size_t rx_skb_size
size of the allocated socket buffer memory
Definition: ethernet.h:88
size_t tx_offset
number of octets sent
Definition: ethernet.h:103
#define EC_EOE_TX_RING_SIZE
Size of the EoE tx ring.
Definition: ethernet.c:60
static unsigned int eoe_tx_unused_frames(ec_eoe_t *)
Definition: ethernet.c:554
EtherCAT slave structure.
int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram to fetch mailbox data.
Definition: mailbox.c:134
void ec_eoe_state_tx_start(ec_eoe_t *)
State: TX START.
Definition: ethernet.c:1005
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:91
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2642
void ec_eoe_state_rx_check(ec_eoe_t *)
State: RX_CHECK.
Definition: ethernet.c:759
unsigned int tx_queue_active
kernel netif queue started
Definition: ethernet.h:99
char name[EC_DATAGRAM_NAME_SIZE]
Description of the datagram.
Definition: datagram.h:114
int ec_eoe_parse(const char *eoe, int *master_idx, uint16_t *alias, uint16_t *posn)
Parse an eoe interface from a string.
Definition: ethernet.c:132
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, ec_mbox_data_t *response_data, uint8_t *type, size_t *size)
Processes received mailbox data.
Definition: mailbox.c:172
uint16_t working_counter
Working counter.
Definition: datagram.h:100
uint8_t link_state
device link state
Definition: device.h:97
#define EC_EOE_TRIES
Number of tries.
Definition: ethernet.c:64
Sent (still in the queue).
Definition: datagram.h:77
void ec_eoe_flush(ec_eoe_t *)
Empties the transmit queue.
Definition: ethernet.c:513
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:105
void ec_datagram_output_stats(ec_datagram_t *datagram)
Outputs datagram statistics at most every second.
Definition: datagram.c:644
Global definitions and macros.
uint8_t rx_expected_fragment
next expected fragment number
Definition: ethernet.h:89
EtherCAT master structure.
void ec_eoe_state_rx_start(ec_eoe_t *)
State: RX_START.
Definition: ethernet.c:732
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:106
EtherCAT slave.
Definition: slave.h:214
unsigned int tx_next_to_use
index of frames added to the ring
Definition: ethernet.h:97
unsigned int auto_created
auto created flag.
Definition: ethernet.h:84
Ethernet over EtherCAT (EoE)
ec_datagram_state_t state
State.
Definition: datagram.h:101
int ec_eoe_is_idle(const ec_eoe_t *eoe)
Returns the idle state.
Definition: ethernet.c:705
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:77
unsigned int tx_next_to_clean
index of frames being used from the ring
Definition: ethernet.h:98
unsigned long rate_jiffies
time of last rate output
Definition: ethernet.h:82
struct sk_buff ** tx_ring
ring for frames to send
Definition: ethernet.h:94
unsigned int have_mbox_lock
flag to track if we have the mbox lock
Definition: ethernet.h:83
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2659
ec_master_t * master
pointer to the corresponding master
Definition: ethernet.h:74
Main device.
Definition: globals.h:237
void ec_eoe_state_rx_fetch_data(ec_eoe_t *)
State: RX_FETCH DATA.
Definition: ethernet.c:827
ec_master_t * master
Master owning the slave.
Definition: slave.h:216
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:80
int ec_read_mbox_locked(ec_slave_t *slave)
Return the current mailbox lock status and lock it if not locked.
Definition: slave.c:229
void ec_eoe_state_tx_sent(ec_eoe_t *)
State: TX SENT.
Definition: ethernet.c:1085
unsigned int opened
net_device is opened
Definition: ethernet.h:81
static int ec_eoedev_set_mac(struct net_device *netdev, void *p)
ec_eoedev_set_mac - Change the Ethernet Address of the NIC : network interface device structure : poi...
Definition: ethernet.c:110
#define EC_SLAVE_INFO(slave, fmt, args...)
Convenience macro for printing slave-specific information to syslog.
Definition: slave.h:63
off_t rx_skb_offset
current write pointer in the socket buffer
Definition: ethernet.h:87
ec_datagram_t datagram
datagram
Definition: ethernet.h:76
void ec_read_mbox_lock_clear(ec_slave_t *slave)
Clears the mailbox lock.
Definition: slave.c:216
unsigned int ec_eoe_tx_queued_frames(const ec_eoe_t *eoe)
Definition: ethernet.c:540
struct net_device_stats stats
device statistics
Definition: ethernet.h:80
uint16_t effective_alias
Effective alias address.
Definition: slave.h:223
int ec_slave_mbox_prepare_check(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram for checking the mailbox state.
Definition: mailbox.c:103
unsigned int tx_idle
Idle flag.
Definition: ethernet.h:106
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2554
void ec_eoe_link_slave(ec_eoe_t *eoe, ec_slave_t *slave)
EoE link slave.
Definition: ethernet.c:412
uint32_t rx_rate
receive rate (bps)
Definition: ethernet.h:91
int ec_eoe_auto_init(ec_eoe_t *eoe, ec_slave_t *slave)
EoE auto constructor for slave.
Definition: ethernet.c:385
Mailbox functionality.
struct sk_buff * rx_skb
current rx socket buffer
Definition: ethernet.h:86
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
Definition: globals.h:262
void(* state)(ec_eoe_t *)
state function for the state machine
Definition: ethernet.h:78
void ec_datagram_init(ec_datagram_t *datagram)
Constructor.
Definition: datagram.c:88
struct sk_buff * tx_skb
current TX frame
Definition: ethernet.h:100
uint8_t tx_frame_number
number of the transmitted frame
Definition: ethernet.h:101
uint32_t rx_counter
octets received during last second
Definition: ethernet.h:90
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:244
int ec_eoedev_open(struct net_device *)
Opens the virtual network device.
Definition: ethernet.c:1153
unsigned int tries
Tries.
Definition: ethernet.h:108
void ec_eoe_run(ec_eoe_t *eoe)
Runs the EoE state machine.
Definition: ethernet.c:649
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2538
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:93
int ec_eoedev_stop(struct net_device *)
Stops the virtual network device.
Definition: ethernet.c:1186
void ec_eoe_clear_slave(ec_eoe_t *eoe)
EoE clear slave.
Definition: ethernet.c:448
void ec_eoe_clear(ec_eoe_t *eoe)
EoE destructor.
Definition: ethernet.c:489
unsigned int index
Index.
Definition: master.h:203
Received (dequeued).
Definition: datagram.h:78
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:71
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition: master.h:68
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:239
unsigned int rx_idle
Idle flag.
Definition: ethernet.h:92
EtherCAT master.
Definition: master.h:202
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:219
struct net_device_stats * ec_eoedev_stats(struct net_device *)
Gets statistics about the virtual network device.
Definition: ethernet.c:1267
int ec_eoe_is_open(const ec_eoe_t *eoe)
Returns the state of the device.
Definition: ethernet.c:693
size_t payload_size
Size of the mailbox response payload data.
Definition: datagram.h:125
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:122
struct net_device * dev
net_device for virtual ethernet device
Definition: ethernet.h:79
unsigned int queue_datagram
the datagram is ready for queuing
Definition: ethernet.h:77
int ec_eoe_init(ec_master_t *master, ec_eoe_t *eoe, uint16_t alias, uint16_t ring_position)
EoE explicit init constructor.
Definition: ethernet.c:207
void ec_datagram_clear(ec_datagram_t *datagram)
Destructor.
Definition: datagram.c:119